6. Embedding the IoT Concept

IoT Platforms

To have the smart shirt as an IOT sensing unit, the microcontroller -ESP32- should be programmed to communicate the sensed data to an IOT cloud server to log and display. There are many open source IOT platforms compatible with Arduino and ESP32 (refer to the link). I have tried two different platforms; Ubidots anf ThingSpeak.

Ubidots

First, I tried using Ubidots platfom. It was very easy and has a very nice display for the data. Ubidots platform is mainly used for data logging, management and display as shown in the following figure.

Image retrieved from Ubidots

I followed this tutorial with the following demo video for an ECG monitor project using AD8232 module with ESP32. Ubidots is used to display the ECG signal over the PC screen.

I have created my dashboard in a similar way; however, I have added variables and widgets for the rest of the signals I am retrieving from my controller board.

Althought in the tutorial it seemed easy to publish the signals and readings, in practical it did not work for all the data. In the following figure, I am displaying that sometimes the code was publishing the signals for ECG and EMG without steps and calories; however, I tried another code that was only displaying the number of steps and calories burned withouth rest of signals.

I tried to look into the issue by checking the Ubidots forum and I realized that a lot of people are facing similar issues when publishing more than two variables at the same time. I observed that most of the people were commenting on that the ESP32 itself is quite difficult to communicate the data through MQTT protocol over Ubidots. After all, I did not reach to a clear conclusion and could not manage to solve this issue with the time remaining to me for finishing the project.

After that, I started looking at other differnt options for an IOT platform and I realized that ThingSpeak could possibly be a better option due to its capabilities in data analysis and easy integration with ESP32 using Arduino language.

ThingSpeak

ThingSpeak is an interesting and powerful open source IOT platform provided by MathWorks. This platform is coupled with MATLAB software which makes it robust platform for IOT data logging and analysis. The highly advanced data analysis can be used to improve an IOT device by adding Artificial Intellegance (AI) to it. ThinkSpeak is mainly a data analytics IOT platform that deals with data as demonistrated below.

As mentioned and demonistrated in the figure below, the smart shirt was made an IOT device by having it connected to the cload server; in other words, by geving it an address. As illustrated in the figure the shirt represents the IOT sensing unit, ThingSpeak represents the IOT cloud server and the PC screen -for my case- represents the IOT client device. IOT client device could be a mobile App as well to display the data to the end users.

Getting started with ThingSpeak was quite straightfoward and easy. I followed the tutorial and the video below to create my Smart Shirt dashboard.

The created dashboard.

After that, I have uploaded the following code to ESP32 to establish communication between the main board and the IOT cloud and dahsboard.

#include <WiFi.h>
#include <Wire.h>
#include <ThingSpeak.h>

const char ssid[] = "Ooredoo_53_EXT";
const char password[] = "55864261";
WiFiClient client;

const long CHANNEL = 1036742;
const char *WRITE_API = "C18V4X4SUJ078SJA";

const int MPU_addr=0x68; // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,GyX,GyY,GyZ;
float gForceX, gForceY, gForceZ; // Defining gravitational forces in the X,Y and Z directions
float rotX, rotY, rotZ;  // Defining rotation output variables in the X,Y and Z directions

unsigned long previousMillis = 0;
const long interval = 1000;
float count = 0;
float Calories = 0;
unsigned long currentMillis;
int flag = 0; 

float ECG = 0;
float EMG_RA = 0;
float EMG_LA = 0;

long prevMillisSensor = 0;
int intervalSensor = 2000;
long prevMillisThingSpeak = 0;
int intervalThingSpeak = 20000; // Minimum ThingSpeak write interval is 15 seconds

void setup()
{

  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B); // PWR_MGMT_1 register
  Wire.write(0); // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);

  Serial.begin(115200);
  Serial.println();
  Serial.println("Send Sensor's Data to ThingSpeak Using ESP32");
  Serial.println();

  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(client);  // Initialize ThingSpeak
}

void loop()
{

  // Connect or reconnect to WiFi
  if (WiFi.status() != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    while (WiFi.status() != WL_CONNECTED) {
      WiFi.begin(ssid, password);
      Serial.print(".");
      delay(5000);
    }
    Serial.println("\nConnected.");
  }

  if (millis() - prevMillisSensor > intervalSensor) {

  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers

  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)

  gForceX = AcX / 1500.0;
  gForceY = AcY / 1500.0; 
  gForceZ = AcZ / 1500.0;

  rotX = GyX / 131.0;
  rotY = GyY / 131.0; 
  rotZ = GyZ / 131.0;

  if (gForceY > 0.4)
   {
    flag = 1;
    Serial.print ("Inside greater, flag = ");
    Serial.println(flag);
    previousMillis= millis(); // the function millis() is used to do real time monitoring. Defining the duration. 
    currentMillis= millis();
    delay (300);
  }

  if((currentMillis - previousMillis <= interval)&&(flag))
  {
    Serial.println("Inside time loop");
    if (gForceY< -0.4)
    {
      count++;
      flag = 0;
      Serial.print("Inside lesser, flag = ");
      Serial.print(flag);
      delay (300);
    }
  }

  currentMillis = millis();

  if (currentMillis - previousMillis > interval)
  {
    flag = 0; 
    Serial.print ("Inside clear, flag= ");
    Serial.println(flag);
    delay (300);
  }
      count++;

  float dis=count*0.70;
  Calories=0.04*count; 

  Serial.print ("Steps = ");
  Serial.println(count);
  Serial.print ("Calories Burned =  ");
  Serial.println(Calories);

    ECG = analogRead(35);
    EMG_RA = analogRead(34);
    EMG_LA = analogRead(39);

    Serial.println(" ECG ");
    Serial.print(ECG);
    Serial.println(" EMG_RA ");
    Serial.print(EMG_RA);
    Serial.println(" EMG_LA ");
    Serial.print(EMG_LA);

    prevMillisSensor = millis();
  }

  if (millis() - prevMillisThingSpeak > intervalThingSpeak) {

    // Set the fields with the values
    ThingSpeak.setField(1, ECG);
    ThingSpeak.setField(2, EMG_RA);
    ThingSpeak.setField(3, EMG_LA);
    ThingSpeak.setField(4, count);
    ThingSpeak.setField(5, Calories);

    // Write to the ThingSpeak channel
    int x = ThingSpeak.writeFields(CHANNEL, WRITE_API);
    if (x == 200) {
      Serial.println("Channel update successful.");
    }
    else {
      Serial.println("Problem updating channel. HTTP error code " + String(x));
    }

    prevMillisThingSpeak = millis();
  }
}

I have tested the shirt on my brother while he was running at our neighbourhood and I was getting real time data tracking over ThingSpeak.

Future Work

Adding AI

Use ThingSpeak platform to analyze the data and to develop a friendly graphical user interface.

Take actions based on the readings of the data. e.g. Develop alerts to warn or acknowledge the user based on the state of data (make sense of data).

Mobile App Development