#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#define WLAN_SSID "Wokwi-GUEST"
#define WLAN_PASS ""
#define TFT_DC 2
#define TFT_CS 15
#define BUZZER 32
#define POTENTIOMETER 35
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "Idodol10"
#define AIO_FEED_ACCELERATOR_X "/feeds/accelerator-x"
#define AIO_FEED_ACCELERATOR_Y "/feeds/accelerator-y"
#define AIO_FEED_ACCELERATOR_Z "/feeds/accelerator-z"
#define AIO_FEED_THRESHOLD "/feeds/threshold"
#define AIO_KEY "aio_auGz83OQQb9Lqh7bEvDKNFs5UHlK"
#define SAMPLES 50
#define MAX_PUBLISH 10000
#define MIN_PUBLISH 5000
#define DEBUG false
WiFiClient client; //Simple wifi client
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY); //mqtt client
Adafruit_MQTT_Publish sendDataX = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME AIO_FEED_ACCELERATOR_X);
Adafruit_MQTT_Publish sendDataY = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME AIO_FEED_ACCELERATOR_Y);
Adafruit_MQTT_Publish sendDataZ = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME AIO_FEED_ACCELERATOR_Z);
Adafruit_MQTT_Publish sendDataT = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME AIO_FEED_THRESHOLD);
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
//mpu
Adafruit_MPU6050 mpu;
sensors_event_t a, g, temp;
int xsample=0;
int ysample=0;
int zsample=0;
float threshold, prev_threshold=0;
float valueX,valueY,valueZ,xValue,yValue,zValue;
byte x_scale = 1; //scale of graph x axis, controlled by touchscreen buttons
byte y_scale = 1;
int x_pos = (11 + x_scale); //position along the graph x axis
float y_pos_x; //current graph y axis position of X value
float y_pos_x_old = 120; //old y axis position of X value
float y_pos_y; //current graph y axis position of Y value
float y_pos_y_old = 120; //old y axis position of Y value
float y_pos_z; //current graph y axis position of Z value
float y_pos_z_old = 120; //old y axis position of Z value
float th_pos;
float th_pos_old = 0;
bool clear_alert = false;
unsigned long last_publish=0,publish_interval=MAX_PUBLISH;
void setup() {
Serial.begin(9600);
delay(10);
init_tft();
connectToWifi();
init_buzzer();
init_mpu();
init_potentiometer();
init_earthquake();
tftDrawColorKey();
tftDrawGraphObjects();
}
void loop()
{
//test_all ();
main_logic();
}
void main_logic()
{
threshold=get_threshold();
mpu.getEvent(&a, &g, &temp);
valueX=a.acceleration.x; //reading x out
valueY=a.acceleration.y; //reading y out
valueZ=a.acceleration.z; //reading z out
xValue=xsample-valueX; // finding change in x
yValue=ysample-valueY; // finding change in y
zValue=zsample-valueZ; // finding change in z
if(DEBUG)
{
Serial.print("threshold=");
Serial.println(threshold);
Serial.print(xValue);
Serial.print(" ");
Serial.print(yValue);
Serial.print(" ");
Serial.print(zValue);
Serial.println("");
}
tftDrawGraphData();
//Checking for earthquake
if(abs(xValue) >= threshold ||abs(yValue) >= threshold ||abs(zValue) >= threshold )
{
Serial.println("EARTHQUAKE ALLERT!!!");
publish_interval=MIN_PUBLISH;
tone(BUZZER,1000);
}
else
{
publish_interval=MAX_PUBLISH;
noTone(BUZZER);
}
if(millis()-last_publish>publish_interval)
{
update_IOT();
if (!mqtt.ping())
{
mqtt.disconnect();
}
last_publish=millis();
}
}
//init //הווייפיי למטה
void init_tft()
{
tft.begin();
tft.setRotation(1);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
}
void init_buzzer()
{
pinMode(BUZZER, OUTPUT);
}
void init_potentiometer()
{
pinMode(POTENTIOMETER , INPUT);
analogReadResolution(10);
}
void init_iot()
{
}
void init_earthquake()
{
Serial.println("EarthQuake Detector ");
Serial.println("Calibrating.....");
mpu.getEvent(&a, &g, &temp);
for(int i=0;i<SAMPLES;i++) // taking samples for calibration
{
xsample+=a.acceleration.x;
ysample+=a.acceleration.y;
zsample+=a.acceleration.z;
}
xsample/=SAMPLES; // taking avg for x
ysample/=SAMPLES; // taking avg for y
zsample/=SAMPLES; // taking avg for z
delay(3000);
Serial.println("Calibrated");
Serial.println("Device ready");
Serial.println("X Y Z ");
}
void init_mpu()
{
Serial.println("Adafruit MPU6050 test!");
// Try to initialize!
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
Serial.print("Accelerometer range set to: ");
switch (mpu.getAccelerometerRange()) {
case MPU6050_RANGE_2_G:
Serial.println("+-2G");
break;
case MPU6050_RANGE_4_G:
Serial.println("+-4G");
break;
case MPU6050_RANGE_8_G:
Serial.println("+-8G");
break;
case MPU6050_RANGE_16_G:
Serial.println("+-16G");
break;
}
mpu.setGyroRange(MPU6050_RANGE_2000_DEG);
Serial.print("Gyro range set to: ");
switch (mpu.getGyroRange()) {
case MPU6050_RANGE_250_DEG:
Serial.println("+- 250 deg/s");
break;
case MPU6050_RANGE_500_DEG:
Serial.println("+- 500 deg/s");
break;
case MPU6050_RANGE_1000_DEG:
Serial.println("+- 1000 deg/s");
break;
case MPU6050_RANGE_2000_DEG:
Serial.println("+- 2000 deg/s");
break;
}
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
Serial.print("Filter bandwidth set to: ");
switch (mpu.getFilterBandwidth()) {
case MPU6050_BAND_260_HZ:
Serial.println("260 Hz");
break;
case MPU6050_BAND_184_HZ:
Serial.println("184 Hz");
break;
case MPU6050_BAND_94_HZ:
Serial.println("94 Hz");
break;
case MPU6050_BAND_44_HZ:
Serial.println("44 Hz");
break;
case MPU6050_BAND_21_HZ:
Serial.println("21 Hz");
break;
case MPU6050_BAND_10_HZ:
Serial.println("10 Hz");
break;
case MPU6050_BAND_5_HZ:
Serial.println("5 Hz");
break;
}
Serial.println("");
delay(100);
Serial.println("Adafruit MPU6050 test!");
// Try to initialize!
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
Serial.print("Accelerometer range set to: ");
switch (mpu.getAccelerometerRange()) {
case MPU6050_RANGE_2_G:
Serial.println("+-2G");
break;
case MPU6050_RANGE_4_G:
Serial.println("+-4G");
break;
case MPU6050_RANGE_8_G:
Serial.println("+-8G");
break;
case MPU6050_RANGE_16_G:
Serial.println("+-16G");
break;
}
mpu.setGyroRange(MPU6050_RANGE_2000_DEG);
Serial.print("Gyro range set to: ");
switch (mpu.getGyroRange()) {
case MPU6050_RANGE_250_DEG:
Serial.println("+- 250 deg/s");
break;
case MPU6050_RANGE_500_DEG:
Serial.println("+- 500 deg/s");
break;
case MPU6050_RANGE_1000_DEG:
Serial.println("+- 1000 deg/s");
break;
case MPU6050_RANGE_2000_DEG:
Serial.println("+- 2000 deg/s");
break;
}
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
Serial.print("Filter bandwidth set to: ");
switch (mpu.getFilterBandwidth()) {
case MPU6050_BAND_260_HZ:
Serial.println("260 Hz");
break;
case MPU6050_BAND_184_HZ:
Serial.println("184 Hz");
break;
case MPU6050_BAND_94_HZ:
Serial.println("94 Hz");
break;
case MPU6050_BAND_44_HZ:
Serial.println("44 Hz");
break;
case MPU6050_BAND_21_HZ:
Serial.println("21 Hz");
break;
case MPU6050_BAND_10_HZ:
Serial.println("10 Hz");
break;
case MPU6050_BAND_5_HZ:
Serial.println("5 Hz");
break;
}
Serial.println("");
delay(100);
}
//test
void test_all()
{
test_tft();
test_buzzer();
test_mpu();
test_potentiometer();
test_iot();
}
void test_tft()
{
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(0,0);
tft.print("welcome");
}
void test_buzzer()
{
tone(BUZZER,1000);
delay(1000);
noTone(BUZZER);
delay(1000);
}
void test_potentiometer()
{
int val=analogRead(POTENTIOMETER);
Serial.print("Potentiometer is ");
Serial.println(val);
}
void test_iot ()
{
MQTTconnect();
if(sendDataX.publish(1.25))
{
Serial.println("x = " + String(1.25));
}
if(sendDataY.publish(2.0))
{
Serial.println("y = " + String(2.0));
}
if(sendDataZ.publish(9.81))
{
Serial.println("z = " + String(9.81));
}
if(sendDataT.publish(500))
{
Serial.println("Threshold = " + String(50));
}
delay(5000);
if (!mqtt.ping()) {
mqtt.disconnect();
}
}
void test_mpu()
{
/* Get new sensor events with the readings */
mpu.getEvent(&a, &g, &temp);
/* Print out the values */
Serial.print("Acceleration X: ");
Serial.print(a.acceleration.x);
Serial.print(", Y: ");
Serial.print(a.acceleration.y);
Serial.print(", Z: ");
Serial.print(a.acceleration.z);
Serial.println(" m/s^2");
Serial.print("Rotation X: ");
Serial.print(g.gyro.x);
Serial.print(", Y: ");
Serial.print(g.gyro.y);
Serial.print(", Z: ");
Serial.print(g.gyro.z);
Serial.println(" rad/s");
Serial.print("Temperature: ");
Serial.print(temp.temperature);
Serial.println(" degC");
Serial.println("");
delay(500);
}
//WIFI
void connectToWifi()
{
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void MQTTconnect() {
if (mqtt.connected()) {
return;
}
Serial.println("Connecting to MQTT server");
uint8_t retries = 3;
int8_t ret;
while ((ret = mqtt.connect()) != 0)
{
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds");
mqtt.disconnect();
delay(5000);
retries--;
if (retries == 0) {
Serial.println("Connection failed");
while (1);
}
}
Serial.println("Connected to MQTT server");
}
void update_IOT()
{
MQTTconnect();
if(sendDataX.publish(xValue))
{
Serial.println("x = " + String(xValue));
}
if(sendDataY.publish(yValue))
{
Serial.println("y = " + String(yValue));
}
if(sendDataZ.publish(zValue))
{
Serial.println("z = " + String(zValue));
}
if(sendDataT.publish(threshold))
{
Serial.println("Threshold = " + String(threshold));
}
}
//potentiometer
int get_threshold()
{
int thresh=map(analogRead(POTENTIOMETER),0,1023,0,20);
return thresh;
}
// TFT
///////////////////
void tftDrawGraphData()
{
if (x_pos > 320)
{
x_pos = (11 + x_scale);
}
th_pos = ((-(threshold) * (y_scale * 5)) + 120);
y_pos_x = ((-xValue * (y_scale * 5)) + 120); //values to use when displaying on LCD, these are floats, for more precision!
y_pos_y = ((-yValue * (y_scale * 5)) + 120); // 120 is axis, so value is displacement from axis, scaled for better visisility!
y_pos_z = ((-zValue * (y_scale * 5)) + 120);
//Plot Threshold lines
tft.drawLine(x_pos - x_scale, th_pos_old, x_pos, th_pos, ILI9341_YELLOW);
tft.drawLine(x_pos - x_scale, 240-th_pos_old, x_pos, 240-th_pos, ILI9341_YELLOW);
//Plot "X" value
tft.drawLine(x_pos - x_scale, y_pos_x_old, x_pos, y_pos_x, ILI9341_GREEN);
//Plot "Y" value
tft.drawLine(x_pos - x_scale, y_pos_y_old, x_pos, y_pos_y, ILI9341_RED);
//Plot "Z" value
tft.drawLine(x_pos - x_scale, y_pos_z_old, x_pos, y_pos_z, ILI9341_BLUE);
//Draw preceding black 'boxes' to erase old plot lines, !!!WEIRD CODE TO COMPENSATE FOR BUTTONS AND COLOR KEY SO 'ERASER' DOESN'T ERASE BUTTONS AND COLOR KEY!!!
if ((x_pos >= 198) && (x_pos <= 320)) //above x axis
{
tft.fillRect(x_pos+1, 28, 10, 92, ILI9341_BLACK); //compensate for buttons!
}
else
{
tft.fillRect(x_pos+1, 0, 10, 120, ILI9341_BLACK); //don't compensate for buttons!
}
if ((x_pos >= 254) && (x_pos <= 320)) //below x axis
{
tft.fillRect(x_pos+1, 121, 10, 88, ILI9341_BLACK);
}
else
{
tft.fillRect(x_pos+1, 121, 10, 100, ILI9341_BLACK);
}
if ( (y_pos_x == 120) || (y_pos_y == 120) || (y_pos_z == 120) )
{
tft.drawFastHLine(10, 120, 310, ILI9341_WHITE); // x axis
}
y_pos_x_old = y_pos_x; //set old y pos values to current y pos values
y_pos_y_old = y_pos_y;
y_pos_z_old = y_pos_z;
th_pos_old=th_pos;
x_pos += x_scale;
if(threshold!=prev_threshold)
{
tft.setTextSize(1);
tft.setTextColor(ILI9341_BLACK);
tft.setCursor(152, 232);
tft.fillRect(150, 230, 60, 10, ILI9341_YELLOW);
tft.print("Th-");
tft.print(threshold);
prev_threshold=threshold;
}
}
void tftDrawGraphObjects()
{
//draw the graph objects
tft.fillRect(11, 5, x_scale+1, 120, ILI9341_BLACK);
tft.fillRect(11, 121, x_scale+1, 119, ILI9341_BLACK);
tft.drawFastVLine(10, 5, 230, ILI9341_WHITE); // y axis
tft.drawFastHLine(10, 120, 310, ILI9341_WHITE); // x axis
tft.setTextColor(ILI9341_YELLOW);
tft.setTextSize(1); // set parameters for y axis labels
tft.setCursor(3, 116);
tft.print("0"); // "0" at center of ya axis
tft.setCursor(3, 6);
tft.print("+"); // "+' at top of y axis
tft.setCursor(3, 228);
tft.print("-"); // "-" at bottom of y axis
}
void tftDrawColorKey()
{
//Display color key
tft.setTextSize(1);
tft.setTextColor(ILI9341_BLACK);
tft.fillRect(150, 230, 60, 10, ILI9341_YELLOW);
tft.setCursor(152, 232);
tft.print("Th-");
tft.fillRect(210, 230, 25, 10, ILI9341_GREEN);
tft.setCursor(220, 232);
tft.print("X");
tft.fillRect(235, 230, 25, 10, ILI9341_RED);
tft.setCursor(245, 232);
tft.print("Y");
tft.fillRect(260, 230, 25, 10, ILI9341_BLUE);
tft.setCursor(270, 232);
tft.print("Z");
}