#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <PubSubClient.h>
#include <WiFi.h>
#include <time.h>
#include <twilio.hpp>
static const char *account_sid = "AC9cee9a08c7cf7f2bd4c21935810d505b";
static const char *auth_token = "0e677e26a75b84a3b6cf3ebb9007d2b9";
static const char *from_number = "+12676338371";
static const char *to_number = "+94784445246";
static const char *message = "Sent from my ESP32";
Twilio *twilio;
const int mpuAddress = 0x68; // I2C address of the MPU-6050
float xByGyro, yByGyro, zByGyro, xA, yA, zA; // Global variables for the rotation by gyro
int fallcheck = 0;
int sleepcheck = 0; // 0 for awake, 1 for asleep Assume device is placed when person is lying down
int walking = 0; // 0 for not walking, 1 for walking
int gotup = 0; // 0 for not got up, 1 for got up
float resAcc, resAccXZ;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "mqtt-dashboard.com";
const int mqtt_port = 1883;
const char* clientId = "clientId-j0x9ZjJyiB";
const char* mqtt_username = "";
const char* mqtt_password = "";
//Switch on the clients
WiFiClient espClient;
PubSubClient client(espClient);
Adafruit_MPU6050 mpu;
//messagebuffer
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg [MSG_BUFFER_SIZE];
//wificonnection setup
void setup_wifi() {
Serial.println();
Serial.print("Connecting to ");
Serial.println("\"" + String(ssid) + "\"");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
//MQTT Server Connection
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(clientId)) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("check", "Start sending");
// ... and resubscribe
client.subscribe("test data");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(1000);
}
}
}
//Message Sending
void publishMessage(const char* topic, String payload, boolean retained) {
if (client.publish (topic, payload.c_str(), true))
Serial.println("Message Published [" + String(topic) + "]: " + payload);
}
void setup() {
Serial.begin(9600);
Wire.begin();
while (!Serial) delay(1);
setup_wifi();
client.setServer (mqtt_server, mqtt_port);
twilio = new Twilio(account_sid, auth_token);
delay(1000);
String response;
bool success = twilio->send_message(to_number, from_number, message, response);
if (success) {
Serial.println("Sent message successfully!");
} else {
Serial.println(response);
}
Wire.beginTransmission( mpuAddress);
Wire.write( 0x6B); // PWR_MGMT_1 register
Wire.write( 0); // set to zero (wakes up the MPU-6050)
auto error = Wire.endTransmission();
if ( error != 0)
{
Serial.println(F( "Check connection with MPU 6050"));
for (;;); // halt the sketch if error encountered
}
// Initialize the time
configTime(19800, 0, "pool.ntp.org");
while (time(nullptr) < 1000) {
delay(1000);
Serial.println("Waiting for NTP time...");
}
}
void loop() {
String response;
if (!client.connected()) reconnect();
client.loop();
Wire.beginTransmission( mpuAddress);
Wire.write( 0x3B); // Starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission( false); // No stop condition for a repeated start
time_t now = time(nullptr);
char time_string[20];
strftime(time_string, sizeof(time_string), "%Y-%m-%d %H:%M:%S", localtime(&now));
Serial.print("Current time and date: ");
Serial.println(time_string);
// The MPU-6050 has the values as signed 16-bit integers.
// There are 7 values in 14 registers.
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
Wire.requestFrom( mpuAddress, 14); // request a total of 14 bytes
AcX = Wire.read()<<8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read()<<8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read()<<8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp = Wire.read()<<8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX = Wire.read()<<8 | Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY = Wire.read()<<8 | Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ = Wire.read()<<8 | Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
// The acceleration is directly mapped into the angles.
float xByAccel = (float) AcX * 0.0001; // static angle by accelerometer
float yByAccel = (float) AcY * 0.0001;
float zByAccel = (float) AcZ * 0.0001;
xByGyro += (float) GyX * 0.00001; // moving angle by gyro
yByGyro += (float) GyY * 0.00001;
zByGyro += (float) GyZ * 0.00001;
float x = xByAccel + xByGyro; // combine both angles
float y = yByAccel + yByGyro;
float z = zByAccel + zByGyro;
// converting acceleration values in to ms-2
xA = AcX/16384.0;
yA = AcY/16384.0;
zA = AcZ/16384.0;
// detecting whether person wakes up from bed
//Assume person is wearing it in the orientation
//Y axis is the longitunal axis of the body
//X axis is the frontal axis of the body
//Z axis is the sagital axis of the body
// approximate values
// When the person is standing up the acceleration in the Y axis is 1g
// When the person is lying down the acceleration in the Y axis is 0g
// When the person is lying down the resultant acceleration in the X, Z axis is 1g(aY = 0)
resAcc = sqrt(xA*xA + yA*yA + zA*zA);
resAccXZ = sqrt(xA*xA + zA*zA);
//detect whether person fallen when walking
if (resAcc < 0.3){
fallcheck = 1;
}
else if(fallcheck == 1){
if(resAcc>1.5) {
fallcheck = 0;
//send message to the server
publishMessage("Notifications", "[" + String(time_string) + "]: Abnormal Movement Detected - Fallen to ground", false);
bool success =twilio->send_message(to_number, from_number, ("Notifications", "[" + String(time_string) + "]: Abnormal Movement Detected - Fallen to ground"), response);
}
}
if(abs(yA)<1.15 && abs(yA)>0.85){
sleepcheck = 0;
if(resAcc > 1.1 && walking == 0){
walking = 1;
// send message to server he is walking
publishMessage("Notifications", "[" + String(time_string) + "]: Abnormal Movement Detected - Walking in the house", false);
bool success =twilio->send_message(to_number, from_number, ("Notifications", "[" + String(time_string) + "]: Abnormal Movement Detected - Walking in the house"), response);
}
if(resAccXZ < 0.1 && abs(xByGyro) + abs(zByGyro) >2 && gotup==0){
gotup = 1;
// send message to server he gotup from the bed
publishMessage("Notifications", "[" + String(time_string) + "]: Abnormal Movement Detected - Getup from the bed", false);
bool success =twilio->send_message(to_number, from_number, ("Notifications", "[" + String(time_string) + "]: Abnormal Movement Detected - Get up from bed"), response);
xByGyro = 0;
zByGyro = 0;
delay(10000);
}
}
if(resAccXZ > 0.8 && resAcc < 1.2){
sleepcheck = 1;
gotup = 0;
walking = 0;
}
}
esp:0
esp:2
esp:4
esp:5
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:21
esp:22
esp:23
esp:25
esp:26
esp:27
esp:32
esp:33
esp:34
esp:35
esp:3V3
esp:EN
esp:VP
esp:VN
esp:GND.1
esp:D2
esp:D3
esp:CMD
esp:5V
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:D1
esp:D0
esp:CLK
imu1:INT
imu1:AD0
imu1:XCL
imu1:XDA
imu1:SDA
imu1:SCL
imu1:GND
imu1:VCC
r1:1
r1:2
r2:1
r2:2