<<<<Previous Blog     Next Blog>>>>

 

Audio & Visual Cue System for Anosmia (Smell Disorder) and Smart WheelChair - Ft. Amazon's Alexa

Week 9: Aug 28 - Sep 3

     The Smart Wheelchair has the following three sections: temperature monitoring, fall & collision detection, and home appliance control. These will be covered in a four-part blog series, the last part being the integration part. This blog is about the 'Integration' of the three sections of the Smart Wheelchair. This marks the completion of one system - Smart WheelChair - of my project. For the collection of this project's blogs published so far, visit this link and for the detailed plan of the 'Smart WheelChair' visit this link.

 

Smart WheelChair [Part 4 of 4]

               Temperature Monitoring     |  Fall & Collision Detection     |     Home Appliance Control     |    Integration

Outcome

 

     The below video is a complete demo of the integrated 'Smart WheelChair' section of my project. It is a great relief and joy that I have finally reached this stage. I really enjoyed the making.

 

 

List of Hardware and Software Involved

    

     Below is the list of hardware and software involved in the making of the 'Smart WheelChair' system. Click on the names in order to be directed to the site where you can buy or access the resource.

 

     Hardware

          Most of the hardware circuit components used for this project are available in the Sponsored kit.

 

     Software

 

Circuit Diagram

 

     Below is the circuit connection diagram for the integrated 'Smart WheelChair' part of my project. This comprises of the main and extra smell sensing units. For a more detailed explanation on the hardware part of the Smart WheelChair, visit this link - Cue System for Anosmia and Smart WheelChair #7 - Hardware Explained and Case That blog also includes gas sensors which will be used for 'Cue System for Anosmia' part of my project. So ignore the gas sensors alone, rest of the hardware is for 'Smart WheelChair'.

Main Smell Sensing Unit

 

Extra Smell Sensing Unit

 

Code

 

     The integrated code of the Smart WheelChair with the 'IoT Temperature Monitoring', Fall & Collision Detection' and 'Home Appliance Control' sections, is provided below. For GitHub repository page, Click here for main unit's code with 'arduino_secrets.h' file and here for the extra unit's code.

 

Arduino_Secrets.h File's Code:

 

#define SECRET_USERNAME ""
#define SECRET_DEVICECREDENTIAL ""
#define SECRET_DEVICEID ""

#define SECRET_SSID ""
#define SECRET_PASS ""

Arduino MKR1000 Main Unit (Master) Code

 

     Remove the below lines from the code to allow Arduino MKR1000 to execute the code when connected to an external battery, instead of the USB serial port of PC.

 

  while (!Serial) {
    ; /*Wait for serial port to connect. Needed for native USB port only*/
  }

 

 

/* This is the integrated code for the 'IoT Temperature measurement and monitoring', 'Fall and Collision Detection' and 'Home Appliance Control' sections of the 
 * Smart WheelChair deisgned for the Element14 Community's 'Design for a Cause' design challenge, sponsored by Arduino.
 * 
 * Design Challenge Page -
 * https://www.element14.com/community/community/design-challenges/designforacause/blog
 * 
 * This code contains extracts from the WiFi101 WebClient example code, 'created 13 July 2010 by dlf (Metodo2 srl) modified 31 May 2012 by Tom Igoe'
 * 
 * Author : Dixon Selvan
 * Date   : Sep 06, 2018
 * Project: Cue system for Anosmia and Smart WheelChair
 * Website: 
 * 
 * Hardware components Required (Main Unit)
 * ----------------------------------------
 * 1. Arduino MKR1000 board
 * 2. TMP36 temperature sensor
 * 3. HC-SR04 Ultrasonic Sensors - x2
 * 4. Accelerometer ADXL335Z Evaluation Board (any ADXL XXX should work)
 * 5. LEDs (Green/ Red) - x2
 * 6. Bluetooth module
 * 7. ProtoShield/ Breadboard and Few Jumper wires
 * 
 * Connections
 * -----------
 * Arduino MKR1000  |   TMP36 Temperature Sensor
 * ---------------------------------------------
 *      3.3V        |         +Vs
 *      Gnd         |         Gnd
 *      A1          |         Vout
 * Arduino MKR1000  |   Ultrasonic Sensor
 * ---------------------------------------------
 *      5V          |         Vcc
 *      Gnd         |         Gnd
 *      D2/3        |         Echo
 *      D5/4        |         Trig
 *      
 * Arduino MKR1000  |   ADXL335Z Evaluation Board
 * ---------------------------------------------
 *      VCC(3.3V)   |         VSS      
 *      Gnd         |         Gnd
 *      A2          |         Y
 *      A3          |         X
 *      
 * Arduino MKR1000  |   LED (Green/ Red)
 * ---------------------------------------------
 *      D0          |   Positive of Green LED      
 *      D1          |   Positive of Red LED
 *      Gnd         |   Negative of both the LEDs    
 * 
 * Blog Links 
 * ----------
 * 1. IoT Temperature Monitoring - https://www.element14.com/community/community/design-challenges/designforacause/blog/2018/07/28/cue-system-for-anosmia-and-smart-wheelchair-4-iot-temperature-monitoring-diy
 * 2. Fall and Collision Detection -  https://www.element14.com/community/community/design-challenges/designforacause/blog/2018/08/16/cue-system-for-anosmia-and-smart-wheelchair-5-fall-and-collision-detection
 * 3. Home Automation Control - https://www.element14.com/community/community/design-challenges/designforacause/blog/2018/09/05/cue-system-for-anosmia-and-smart-wheelchair-8b-home-appliance-control
 * 
 * Connecting Arduino MKR1000 with thinger.io, getting started guide - http://docs.thinger.io/arduino/
 * Create a new applet using IFTTT - https://ifttt.com/create
 * 
 */


#define _DISABLE_TLS_


/*Adding Required Libraries*/
#include <SPI.h>
#include <WiFi101.h>
#include <ThingerWifi101.h>
#include "arduino_secrets.h"


/*Please enter your sensitive data and credential in the Secret tab/arduino_secrets.h*/
char ssid[] = SECRET_SSID;  /* Your network SSID (name)*/
char pass[] = SECRET_PASS;  /* Your network password (use for WPA, or use as key for WEP)*/
int keyIndex = 0;           /* Your network key Index number (needed only for WEP)*/


/*GPIO pin assignments*/
int tempSensor = A1;
int XAxis = A3, YAxis = A2;
int statusLED = 0;    /*Green LED for status*/
int collisionLED = 1; /*Red LED to Alert user in case of collision*/
int trigPinF = 5, trigPinR = 4;
int echoPinF = 2, echoPinR = 3;


/*Variable declartaion and initialisation*/
int XValue = 0, YValue = 0;
int XFlag = 0, YFlag = 0;
int fallCount = 0;
int distance;
int measDistanceF;
int measDistanceR;
float sensorVoltage = 0.0;
float tempinC = 0.0;
float tempinF = 0.0;
unsigned long previousMillis = 0;
unsigned long previousMillis1 = 0;
long tempFeedDelay = 5000;
long collisionDelay = 100;
long duration;
int relayState = 0;


int status = WL_IDLE_STATUS;
/*Find instructions to obtain the below value here - https://www.element14.com/community/community/design-challenges/designforacause/blog/2018/08/16/cue-system-for-anosmia-and-smart-wheelchair-5-fall-and-collision-detection#jive_content_id_Obtaining_the_Webhook_URL_to_trigger_an_event_from_Arduino_MKR1000  */
char server[] = "maker.ifttt.com"; 
/* Initialize the Ethernet client library with the IP address and port of the server that you want to connect to (port 80 is default for HTTP):*/
WiFiClient client;


/*ThingerWifi101 thing("username", "deviceId", "deviceCredential");*/
ThingerWifi101 thing(SECRET_USERNAME, "ArduinoMKR1000", SECRET_DEVICECREDENTIAL);


/*************************************Setup*************************************/
void setup() {
  /*GPIO Desclartion*/
  pinMode(tempSensor, INPUT);
  pinMode(trigPinF, OUTPUT);
  pinMode(echoPinF, OUTPUT);
  pinMode(trigPinR, OUTPUT);
  pinMode(echoPinR, OUTPUT);
  pinMode(statusLED, OUTPUT);
  pinMode(collisionLED, OUTPUT);
  pinMode(XAxis, INPUT);
  pinMode(YAxis, INPUT);


  /*Serial Initialisation*/
  Serial.begin(38400);
  Serial1.begin(38400);


  /*Connecting to Wi-Fi - Thinger.io*/
  Serial.println("Connecting to WiFi");
  /*thing.add_wifi("your_wifi_ssid", "your_wifi_ssid_password");*/
  thing.add_wifi(SECRET_SSID, SECRET_PASS);
  Serial.println("WiFi Connected");
  
  thing["Temperature"] >> [](pson& out){
      out = temperatureInC();
  };


  /*The relay state is obtained as an input resource (integer/ number) from thinger.io*/
  thing["RelayState"] << [](pson& in){
      relayState = in["state"];
      changeRelayState();
  };


  /*Connecting to Wi-Fi - IFTTT*/
  while (!Serial) {
    ; /*Wait for serial port to connect. Needed for native USB port only*/
  }
  /*Check for the presence of the WiFi shield:*/
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    /*Don't continue, to inidcate code is stuck here, turn on both the LEDs*/
    digitalWrite(collisionLED, HIGH);
    digitalWrite(statusLED, HIGH);
    while (true);
  }
  /*Attempt to connect to WiFi network:*/
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    /*Connect to WPA/WPA2 network. Change this line if using open or WEP network:*/
    status = WiFi.begin(ssid, pass);
    /*wait 10 seconds for connection:*/
    delay(10000);
  }
  Serial.println("Connected to wifi");
  printWiFiStatus();
  delay(5);
  digitalWrite(statusLED, LOW);
  digitalWrite(collisionLED, LOW);
}


/*************************************Loop*************************************/
void loop() {
  unsigned long currentMillis = millis();
  unsigned long currentMillis1 = millis();


  /*if (currentMillis - previousMillis >= tempFeedDelay){
    
    previousMillis = currentMillis;
  }*/
  thing.handle();
  
  Serial.println(temperatureInC());


  XValue = analogRead(XAxis);
  YValue = analogRead (YAxis);
  detectFall (XValue, YValue);
  digitalWrite(collisionLED, LOW);
  
  measDistanceF = calculateDistance(trigPinF, echoPinF);
  /*For Debugging purpose*/
  Serial.print(measDistanceF);
  Serial.print('\t');
  measDistanceR = calculateDistance(trigPinR, echoPinR);
  Serial.println(measDistanceR);


  if ((measDistanceF <= 10) || (measDistanceR <= 10)){
    Serial.println("Collision Alert!");
    if (currentMillis1 - previousMillis1 >= collisionDelay){
      digitalWrite(collisionLED, HIGH);
      previousMillis1 = currentMillis1;
    }
  }
  else if ((measDistanceF <= 30) || (measDistanceR <= 30)){
    digitalWrite(collisionLED, HIGH);
  }
  else
  {
    digitalWrite(collisionLED, LOW);
  }
  
}




/**************************User Defined Functions******************************
 * float temperatureInC()                           - To calculate temperature in degrees Celsius
 * void detectFall (int X, int Y)                   - To detect a fall
 * int calculateDistance(int trigPin, int echoPin)  - To calculate distance
 * void printWiFiStatus()                           - To print WiFi Status
 * void sendSMS()                                   - To send SMS 
 * void changeRelayState()                          - To change the relay state on the basis of input received from thinger.io
 */


float temperatureInC(){
  sensorVoltage = analogRead(tempSensor);
  sensorVoltage = (sensorVoltage * 3.3)/ 1024.0;
  tempinC = (sensorVoltage * 0.28828125) * 100.0;
  return tempinC;
}




void detectFall (int X, int Y){
  /*Code to detect fall, The values below are assessed keeping the center position around the value 530 from X & Y axes*/
  if ( X < 430 or X > 650 ){ XFlag = 1; }
  else { XFlag = 2; }


  if ( Y < 430 or Y > 650 ){ YFlag = 1; }
  else { YFlag = 2; }


  /* For Debugging purpose */
  Serial.print(XFlag);Serial.print('\t');
  Serial.print(YFlag);Serial.print('\t');
  Serial.print(X);Serial.print('\t');
  Serial.print(Y);Serial.print('\t');
  
  if (XFlag == 1 or YFlag == 1) {
    fallCount = fallCount + 1;
    Serial.print("Fall Detected! C: ");
    Serial.println(fallCount);
    digitalWrite(collisionLED, HIGH);
    delay(1000);


    if(fallCount >= 10){
      sendSMS();
      fallCount = 0;
      
      while(true);
    }
  }
}


int calculateDistance(int trigPin, int echoPin)
{
  /*Code to calculate Distance from Duration*/
  digitalWrite(trigPin, HIGH); 
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  duration = pulseIn(echoPin, HIGH);
  distance= duration*0.034/2;
  return distance;
}


void printWiFiStatus() {
  /*Print the SSID of the network you're attached to:*/
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());


  /*pPrint your WiFi shield's IP address:*/
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);


  /*Print the received signal strength:*/
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}


void sendSMS(){
  Serial.println("\nStarting connection to server...");
  /*If you get a connection, report back via serial:*/
  if (client.connect(server, 80)) {
    Serial.println("connected to server");
    /*Make a HTTP request:
    Find instructions to obtain the below value here - https://www.element14.com/community/community/design-challenges/designforacause/blog/2018/08/16/cue-system-for-anosmia-and-smart-wheelchair-5-fall-and-collision-detection#jive_content_id_Obtaining_the_Webhook_URL_to_trigger_an_event_from_Arduino_MKR1000  */
    client.println("GET /trigger/{YOUR_IFTTT_EVENT_NAME}/with/key/{YOUR_IFTTT_KEY} HTTP/1.1");
    client.println("Host: maker.ifttt.com");
    
    client.println("Connection: close");
    client.println();
    digitalWrite(statusLED, HIGH);
  }


  int reqReceived = 1;


  while(reqReceived){
  
    while (client.available()) {
      char c = client.read();
      Serial.write(c);
      reqReceived = 0;
    }
  
    /*If the server's disconnected, stop the client:*/
    if (!client.connected()) {
      Serial.println();
      Serial.println("disconnecting from server.");
      client.stop();
      digitalWrite(statusLED, LOW);
    }
  }
}


void changeRelayState(){
  if(relayState == 1)
  {
    digitalWrite(statusLED, HIGH);
    Serial1.print(1);
  }
  else if (relayState == 2){
    digitalWrite(statusLED, LOW);
    Serial1.print(2);
  }
  else if(relayState == 3)
  {
    digitalWrite(statusLED, HIGH);
    Serial1.print(3);
  }
  else if (relayState == 4){
    digitalWrite(statusLED, LOW);
    Serial1.print(4);
  }
  else  if(relayState == 5)
  {
    digitalWrite(statusLED, HIGH);
    Serial1.print(5);
  }
  else if (relayState == 6){
    digitalWrite(statusLED, LOW);
    Serial1.print(6);
  }
}



















































 

Arduino UNO Extra Unit (Slave) Code:

 

/* This is the code for the 'Home Appliance Control' section of the Smart WheelChair deisgned for the Element14 Community's 'Design for a Cause' design challenge, 
 *  sponsored by Arduino. In particular, this is for the extra smell sensing unit with Bluetooth Slave Arduino UNO.
 * 
 * Design Challenge Page - https://www.element14.com/community/community/design-challenges/designforacause/blog
 * 
 * Blog Link - 
 * 
 * Author : Dixon Selvan
 * Date   : September 04, 2018
 * Project: Cue system for Anosmia and Smart WheelChair
 * Website: 
 * 
 * Hardware components Required (Main Unit)
 * ----------------------------------------
 * 1. Arduino UNO board
 * 2. Four Channel Relay Module
 * 3. Bluetooth module
 * 4. ProtoShield/ Breadboard and Few Jumper wires
 * 
 * Connections
 * -----------
 * Arduino UNO      |   Relay Module
 * ---------------------------------------------
 *      5V          |         VCC
 *      Gnd         |         Gnd
 *      IN1         |         D10     
 *      IN2         |         D11
 *      IN3         |         D5
 *      IN4         |         D6
 * Arduino UNO      |   Bluetooth Module
 * ---------------------------------------------
 *      5V          |         +5V
 *      Gnd         |         Gnd
 *      RX          |         RX     
 *      TX          |         TX
 * 
 */

int Relay1 = 10;
int Relay2 = 11;
int Relay3 = 5;
int Relay4 = 6;
int serialData = 0;


void setup() {
  // put your setup code here, to run once:
  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  pinMode(Relay3, OUTPUT);
  pinMode(Relay4, OUTPUT);
  Serial.begin(38400);
  digitalWrite(Relay1, HIGH);
  digitalWrite(Relay2, HIGH);
  digitalWrite(Relay3, HIGH);
  digitalWrite(Relay4, HIGH);
}


void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available()>0){
     serialData = Serial.read();
     Serial.println(serialData);
     if (serialData == 49){
      digitalWrite(Relay1, LOW);
     }
     else if (serialData == 50){
      digitalWrite(Relay1, HIGH);
     }
     else if (serialData == 51){
      digitalWrite(Relay2, LOW);  
     }
     else if (serialData == 52){
      digitalWrite(Relay2, HIGH); 
     }
     else if (serialData == 53){
      digitalWrite(Relay3, LOW);
     }
     else if (serialData == 54){
      digitalWrite(Relay3, HIGH);
     }
     else if (serialData == 55){
      digitalWrite(Relay4, LOW);  
     }
     else if (serialData == 56){
      digitalWrite(Relay4, HIGH); 
     }
  }
}

 

Hurdle

 

     The main hurdle I faced is in 'Serial Communication'. The Arduino MKR1000 uses Serial1 (14 - TX,13 - RX digital pins) for serial communication but the Arduino UNO uses Serial (1 - TX,0 - RX digital pins) for serial communication. So while programming Arduino MKR1000 you have to use Serial1 for initialization and for further use in the code. I usually test the setup with Arduino UNO and then migrate them to other dev boards. So the entire hardware setup is working in UNO but not in MKR1000. Since I had faced the same issue in my previous project Traffic Predictor, I was able to realize the mistake faster.

 

Have you got any suggestion or comment? Let me know in the comments section below.

Progress made so far,

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 75%

 

<<<<Previous Blog     Next Blog>>>>