Antonio Amadeu
Published © LGPL

Monitor for Elderly that Lives Alone

Elderly normally live alone, this is a dangerous situation because of fragility. Monitoring them and warning closest people could save them.

IntermediateWork in progressOver 4 days1,779
Monitor for Elderly that Lives Alone

Things used in this project

Hardware components

Hexiwear
NXP Hexiwear
×1
Laptop
×1

Software apps and online services

Windows or Linux
C/C++ Read Hexiwear's sensors and transmit by serial to Laptop, future Bluetooth.
Ederly Monitoring (self development for smartphone)
Python, Read Serial on Laptop an send it to Artik Cloud.
ARTIK Cloud for IoT
Samsung ARTIK Cloud for IoT

Story

Read more

Schematics

Hexiwear sensor's info and status (Normal or Alarm)

This file is the example of the information that Hexiwear send to the Laptop. According with an equation on the accelerometer data, the code running on Hexiwear sends "Normal" or "ALARM" where "ALARM" means that the elderly could be falling.
The equation i ssimple, I got the module of the vector of the coordinates x, y and z and if this vector result is 1 or more, it indicates that one gravity movement was reached (in any direction). this behavior could hurt the elderly.

Code

Hexiwear Code to read sensors and send through Serial.

C/C++
It's a simple code just to get information from some sensors of Hexiwear and send it through serial to the laptop. Future implementation will be send it using Bluetooth.
#include "mbed.h"
#include "FXAS21002.h"
#include "FXOS8700.h"
#include "MPL3115A2.h"

/*  Check out the full featured example application for interfacing to the 
 *  Gyro device at the following URL
 *  https://developer.mbed.org/teams/ATT-Hackathon/code/Accel_Mag_Gyro_SensorStream_K64F_AGM01_M/
*/
 
//#define MPL3115A2_I2C_ADDRESS (0x60<<1)
 
DigitalOut led1(LED_RED);
Serial pc(USBTX, USBRX);

// Pin connections & address for Hexiwear
FXOS8700 accel(PTC11, PTC10);
FXOS8700 mag(PTC11, PTC10);
FXAS21002 gyro(PTC11,PTC10);
//MPL3115A2 MPL3115A2( PTC11, PTC10, MPL3115A2_I2C_ADDRESS);
/* pos [0] = altimeter or pressure value */
/* pos [1] = temperature value */


DigitalOut led2(LED_BLUE);

// Storage for the data from the sensor
float gyro_data[3];  float gyro_rms=0.0;

float sensor_data[2];

// I2C i2c(p9, p10);        // sda, scl
 
// MPL115A2 p_sensor(&i2c, &pc); //DEBUG verion
// MPL115A2 p_sensor(&i2c);


// main() runs in its own thread in the OS
// (note the calls to Thread::wait below for delays)
int main() {

DigitalOut led3(LED_GREEN);

    // Set over sampling value (see MPL3115A2.h for details)
//    MPL3115A2.Oversample_Ratio(OVERSAMPLE_RATIO_64);
    // Configure the sensor as Barometer.
//    MPL3115A2.Barometric_Mode();

    // Configure Accelerometer FXOS8700, Magnetometer FXOS8700
    // Configure Gyro FXAS21002

    float accel_data[3]; float accel_rms=0.0;
    float mag_data[3];   float mag_rms=0.0;
    float accelalarm = 0.0;
    float gyroalarm = 0.0;

    accel.accel_config();
    mag.mag_config();        
    gyro.gyro_config();
    
    while (true) {
    
      gyro.acquire_gyro_data_dps(gyro_data);
      pc.printf("Gyroscope\r\nRoll(G)%4.4f\r\nPitch(G)%4.4f\r\nYaw(G)%4.4f\r\n",gyro_data[0],gyro_data[1],gyro_data[2]);
      gyro_rms = sqrt(((gyro_data[0]*gyro_data[0])+(gyro_data[1]*gyro_data[1])+(gyro_data[2]*gyro_data[2]))/3);
      pc.printf("RMS(G)%4.4f\r\n\n",gyro_rms);
      
      accel.acquire_accel_data_g(accel_data);
      accel_rms = sqrt(((accel_data[0]*accel_data[0])+(accel_data[1]*accel_data[1])+(accel_data[2]*accel_data[2]))/3);
      printf("Accelerometer\r\nX-Axis(G)%4.4f\r\nY-Axis(G)%4.4f\r\nZ-Axis(G)%4.4f\r\nRMS(G)%4.4f\r\n\n",accel_data[0],accel_data[1],accel_data[2],accel_rms);
      
      mag.acquire_mag_data_uT(mag_data);
      mag_rms = sqrt(((mag_data[0]*mag_data[0])+(mag_data[1]*mag_data[1])+(mag_data[2]*mag_data[2]))/3);
      printf("Magnetometer\r\nX-Axis(T)%4.4f\r\nY-Axis(T)%4.4f\r\nZ-Axis(T)%4.4f\r\nRMS(T)%4.4f ,\r\n\n",mag_data[0],mag_data[1],mag_data[2],mag_rms);
      
//      MPL3115A2.getAllData(&sensor_data[0]);
//      printf("Pressure ,\r\n%f \r\nTemperature ,\r\n%f\n", sensor_data[0], sensor_data[1]); 

      printf("accelalarm:%4.4f accel_rms:%4.4f gyroalarm:%4.4f gyro_rms:%4.4f\n",accelalarm,accel_rms,gyroalarm,gyro_rms);   
 
      accelalarm = accelalarm-accel_rms;
      gyroalarm = gyroalarm-gyro_rms;
      
      accelalarm = sqrt(accelalarm*accelalarm);
      gyroalarm = sqrt(gyroalarm*gyroalarm);
      
      printf("\rAccel:%4.4f Gyro:%4.4f \n\n", accelalarm,gyroalarm);
 
      if (accelalarm <= 1)
        printf("\n\nNormal\n\n");
      else
        printf("\n\nALARM!!!!!!!\n\n");
        
 
      led1 = !led1;
    }
}

Python code to read serial port of the laptop to get the sensors information from Hexiwear

Python
This is a simple Python code that reads serial port of the laptop, do some math and determine through it if the elderly is in normal behavior or falling or etc.
import serial

ser = serial.Serial(
    port='COM5',\
    baudrate=9600,\
    parity=serial.PARITY_NONE,\
    stopbits=serial.STOPBITS_ONE,\
    bytesize=serial.EIGHTBITS,\
        timeout=0)

print("connected to: " + ser.portstr)
#this will store the line
seq = []
count = 1

while True:
    for c in ser.read():
        seq.append(chr(c)) #convert from ANSII
        joined_seq = ''.join(str(v) for v in seq) #Make a string from array

        if chr(c) == '\n':
#        	print("Line " + str(count) + ': ' + joined_seq)
        	print(joined_seq)
        	seq = []
        	count += 1
        	break


ser.close()

Information from sensors example.

Plain text
This file is a capture of the Hexiwear serial data. It has many information, but, for now, the most important is the fall information. I did a simple equation where I got the module of the vector from the accelerometer using the info from its coordinates. If this vector is equal to one or more, it means that the elderly make a strong movement in any direction and this could indicate a fall or a risky situation. The code in Hexiwear detect this and send an "ALARM" signal that could be read by laptop and send the alerts to the respective person (relatives, elderly care and etc.)
connected to: COM5
6644 gyro_rms:0.9520


Accel:0.0277 Gyro:0.2876 

Gyroscope


Roll(G)-0.4375


Pitch(G)-0.1250


Yaw(G)-0.3750


RMS(G)0.3404




Accelerometer


X-Axis(G)0.0137


Y-Axis(G)0.0410


Z-Axis(G)-0.9941


RMS(G)0.5745




Magnetometer


X-Axis(T)-290.3000


Y-Axis(T)-49.1000


Z-Axis(T)-70.3000


RMS(T)174.7636 ,




accelalarm:0.0000 accel_rms:0.5745 gyroalarm:0.0000 gyro_rms:0.3404


Accel:0.5745 Gyro:0.3404 







Normal



Gyroscope


Roll(G)-0.7500


Pitch(G)0.8125


Yaw(G)0.1875


RMS(G)0.6475




Accelerometer


X-Axis(G)0.0156


Y-Axis(G)0.0342


Z-Axis(G)-0.9862


RMS(G)0.5698




Magnetometer


X-Axis(T)-288.3000


Y-Axis(T)-49.8000


Z-Axis(T)-67.4000


RMS(T)173.3394 ,




accelalarm:0.5745 accel_rms:0.5698 gyroalarm:0.3404 gyro_rms:0.6475


Accel:0.0046 Gyro:0.3071 







Normal



Gyroscope


Roll(G)-0.8750


Pitch(G)1.1875


Yaw(G)-0.5625


RMS(G)0.9114




Accelerometer


X-Axis(G)0.0088


Y-Axis(G)0.0381


Z-Axis(G)-0.9804


RMS(G)0.5665




Magnetometer


X-Axis(T)-291.5000


Y-Axis(T)-49.4000


Z-Axis(T)-70.0000


RMS(T)175.4163 ,




accelalarm:0.0046 accel_rms:0.5665 gyroalarm:0.3071 gyro_rms:0.9114


Accel:0.5618 Gyro:0.6044 







Normal



Gyroscope


Roll(G)-0.7500


Pitch(G)0.8125


Yaw(G)-0.0625


RMS(G)0.6394




Accelerometer


X-Axis(G)0.0122


Y-Axis(G)0.0371


Z-Axis(G)-0.9833


RMS(G)0.5682




Magnetometer


X-Axis(T)-289.7000


Y-Axis(T)-49.9000


Z-Axis(T)-68.2000


RMS(T)174.2291 ,




accelalarm:0.5618 accel_rms:0.5682 gyroalarm:0.6044 gyro_rms:0.6394


Accel:0.0063 Gyro:0.0351 







Normal



Gyroscope


Roll(G)-0.8125


Pitch(G)1.1250


Yaw(G)-0.3125


RMS(G)0.8213




Accelerometer


X-Axis(G)0.0063


Y-Axis(G)0.0361


Z-Axis(G)-0.9789


RMS(G)0.5656




Magnetometer


X-Axis(T)-288.6000


Y-Axis(T)-48.9000


Z-Axis(T)-65.8000


RMS(T)173.2155 ,




accelalarm:0.0063 accel_rms:0.5656 gyroalarm:0.0351 gyro_rms:0.8213


Accel:0.5593 Gyro:0.7862 







Normal



Gyroscope


Roll(G)-1.0000


Pitch(G)0.9375


Yaw(G)-0.1875


RMS(G)0.7988




Accelerometer


X-Axis(G)0.0093


Y-Axis(G)0.0410


Z-Axis(G)-0.9838


RMS(G)0.5685




Magnetometer


X-Axis(T)-288.3000


Y-Axis(T)-47.3000


Z-Axis(T)-71.0000


RMS(T)173.5849 ,




accelalarm:0.5593 accel_rms:0.5685 gyroalarm:0.7862 gyro_rms:0.7988


Accel:0.0093 Gyro:0.0126 







Normal



Gyroscope


Roll(G)-0.4375


Pitch(G)0.7500


Yaw(G)-0.2500


RMS(G)0.5217




Accelerometer


X-Axis(G)0.0107


Y-Axis(G)0.0356


Z-Axis(G)-0.9799


RMS(G)0.5662




Magnetometer


X-Axis(T)-287.6000


Y-Axis(T)-49.3000


Z-Axis(T)-68.7000


RMS(T)173.0741 ,




accelalarm:0.0093 accel_rms:0.5662 gyroalarm:0.0126 gyro_rms:0.5217


Accel:0.5569 Gyro:0.5091 







Normal



Gyroscope


Roll(G)-1.0000


Pitch(G)1.5000


Yaw(G)0.0000


RMS(G)1.0408




Accelerometer


X-Axis(G)0.0073


Y-Axis(G)0.0361


Z-Axis(G)-0.9828


RMS(G)0.5678




Magnetometer


X-Axis(T)-288.2000


Y-Axis(T)-51.1000


Z-Axis(T)-69.8000


RMS(T)173.7263 ,




accelalarm:0.5569 accel_rms:0.5678 gyroalarm:0.5091 gyro_rms:1.0408


Accel:0.0109 Gyro:0.5317 







Normal



Gyroscope


Roll(G)-0.6250


Pitch(G)1.3750


Yaw(G)-0.4375


RMS(G)0.9079




Accelerometer


X-Axis(G)0.0068


Y-Axis(G)0.0337


Z-Axis(G)-0.9843


RMS(G)0.5686




Magnetometer


X-Axis(T)-287.0000


Y-Axis(T)-50.2000


Z-Axis(T)-68.2000


RMS(T)172.7621 ,




accelalarm:0.0109 accel_rms:0.5686 gyroalarm:0.5317 gyro_rms:0.9079


Accel:0.5577 Gyro:0.3761 







Normal



Gyroscope


Roll(G)-1.1250


Pitch(G)0.7500


Yaw(G)-0.1250


RMS(G)0.7840




Accelerometer


X-Axis(G)0.0098


Y-Axis(G)0.0381


Z-Axis(G)-0.9867


RMS(G)0.5701




Magnetometer


X-Axis(T)-286.7000


Y-Axis(T)-49.6000


Z-Axis(T)-69.2000


RMS(T)172.6709 ,




accelalarm:0.5577 accel_rms:0.5701 gyroalarm:0.3761 gyro_rms:0.7840


Accel:0.0125 Gyro:0.4078 







Normal



Gyroscope


Roll(G)-1.0000


Pitch(G)0.6250


Yaw(G)-0.1250


RMS(G)0.6847




Accelerometer


X-Axis(G)0.0112


Y-Axis(G)0.0371


Z-Axis(G)-0.9867


RMS(G)0.5701




Magnetometer


X-Axis(T)-288.6000


Y-Axis(T)-49.6000


Z-Axis(T)-68.5000


RMS(T)173.6302 ,




accelalarm:0.0125 accel_rms:0.5701 gyroalarm:0.4078 gyro_rms:0.6847


Accel:0.5577 Gyro:0.2768 







Normal



Gyroscope


Roll(G)-0.3750


Pitch(G)1.1875


Yaw(G)-0.3125


RMS(G)0.7413




Accelerometer


X-Axis(G)0.0068


Y-Axis(G)0.0429


Z-Axis(G)-0.9814


RMS(G)0.5671




Magnetometer


X-Axis(T)-290.9000


Y-Axis(T)-52.0000


Z-Axis(T)-69.8000


RMS(T)175.3082 ,




accelalarm:0.5577 accel_rms:0.5671 gyroalarm:0.2768 gyro_rms:0.7413


Accel:0.0095 Gyro:0.4644 







Normal



Gyroscope


Roll(G)-0.9375


Pitch(G)0.9375


Yaw(G)0.0625


RMS(G)0.7663




Accelerometer


X-Axis(G)0.0146


Y-Axis(G)0.0410


Z-Axis(G)-0.9887


RMS(G)0.5714




Magnetometer


X-Axis(T)-287.8000


Y-Axis(T)-48.9000


Z-Axis(T)-68.0000


RMS(T)173.0549 ,




accelalarm:0.0095 accel_rms:0.5714 gyroalarm:0.4644 gyro_rms:0.7663


Accel:0.5619 Gyro:0.3019 







Normal



Gyroscope


Roll(G)-0.9375


Pitch(G)1.0625


Yaw(G)-0.1875


RMS(G)0.8252




Accelerometer


X-Axis(G)0.0088


Y-Axis(G)0.0342


Z-Axis(G)-0.9906


RMS(G)0.5723




Magnetometer


X-Axis(T)-290.3000


Y-Axis(T)-49.3000


Z-Axis(T)-66.4000


RMS(T)174.2733 ,




accelalarm:0.5619 accel_rms:0.5723 gyroalarm:0.3019 gyro_rms:0.8252


Accel:0.0104 Gyro:0.5233 







Normal



Gyroscope


Roll(G)-0.9375


Pitch(G)1.3125


Yaw(G)-0.1875


RMS(G)0.9375




Accelerometer


X-Axis(G)-0.0166


Y-Axis(G)0.0381


Z-Axis(G)-0.9614


RMS(G)0.5556




Magnetometer


X-Axis(T)-289.3000


Y-Axis(T)-50.9000


Z-Axis(T)-68.4000


RMS(T)174.1301 ,




accelalarm:0.0104 accel_rms:0.5556 gyroalarm:0.5233 gyro_rms:0.9375


Accel:0.5451 Gyro:0.4142 







Normal



Gyroscope


Roll(G)80.9375
...

This file has been truncated, please download it to see its full contents.

Python code to write to Artik Cloud

Python
This is a code that get arguments from another Python code to write to Artik cloud and trigger an alarm when more than 1 G is reached. Unfortunately it´s not working well yet.
import argparse
import artikcloud
from artikcloud.rest import ApiException
import sys, getopt
import time, random, json
from pprint import pprint


# SDK reference for more details
# https://github.com/artikcloud/artikcloud-python

parser = argparse.ArgumentParser(description='Read from LeSerial.PY')
parser.add_argument('-a','--accellRMS', help='Float value of accelleration', required=True)
parser.add_argument('-f','--fall', help='Alarm of falling', required=True)
args = vars(parser.parse_args())


def main(argv):

      DEFAULT_CONFIG_PATH = 'C:/Users/anton/Documents/Hexiwear/config.json'

      with open(DEFAULT_CONFIG_PATH, 'r') as config_file:
        config = json.load(config_file)['LaDeVo']
      print(config)
      # Configure Oauth2 access_token for the client application.  Here we have used
      # the device token for the configuration
      artikcloud.configuration = artikcloud.Configuration();
      artikcloud.configuration.access_token = config['deviceToken']

      # We create an instance of the Message API class which provides
      # the send_message() and get_last_normalized_messages() api call
      # for our example
      api_instance = artikcloud.MessagesApi()

      # Device_message - data that is sent to your device
      device_message = {}


      # We send random values to the 'temp' field for this FireSensor.  
      # Let's send a random value between 0 and 200 for this demo.
      #device_message['accellRMS'] = random.randrange(0,200);
      device_message['accellRMS'] = args['accellRMS'];
      device_message['fall'] = args['fall'];
      # Set the 'device id' - value from your config.json file
      device_sdid = config['deviceId']

      # set your custom timestamp
      ts = None

      # Construct a Message object for your request
      data = artikcloud.Message(device_message, device_sdid, ts) 

      try: 
        # Debug Print oauth settings
        pprint(artikcloud.configuration.auth_settings())

        # Send Message
        api_response = api_instance.send_message(data)
        pprint(api_response)
      except ApiException as e:
        print("Exception when calling MessagesApi->send_message: %s\n" % e)


if __name__ == "__main__":
   main(sys.argv[1:])

Hexiwear Code to read sensors and send through Serial Version not finished

Python
This is a better version to get serial data and send to another Python code, but, it´s not finished.
import serial
import subprocess
import time
ser = serial.Serial(
    port='COM5',\
    baudrate=9600,\
    parity=serial.PARITY_NONE,\
    stopbits=serial.STOPBITS_ONE,\
    bytesize=serial.EIGHTBITS,\
        timeout=0)

print("connected to: " + ser.portstr)
#this will store the line
seq = []
count = 1
rms = 0.0
fall = 0.0
n = 0
x = 0

while True:
    for c in ser.read():
        seq.append(chr(c)) #convert from ANSII
        #joined_seq = ''.join(str(v) for v in seq) #Make a string from array
        joined_seq = ''.join(str(v) for v in seq) #Make a string from array

        if chr(c) == '\n':
            #print("Line " + str(count) + ': ' + joined_seq)
            if joined_seq == "N\n":
                print('Alarm!!!!')
                fall = int(1)
                n = 1000
            else:
                #print(joined_seq[:6])
                rms = joined_seq[:6]
                rms = float(rms)
                rms = rms * 10000.0
                print(int(round(rms)))
                rms = int(round(rms))
                seq = []
                count += 1
                break
    #comando = ['C:/Anaconda3/python.exe']
    comando = ['C:/Anaconda3/python.exe C:/Users/anton/Documents/Hexiwear/LaDeVo.py -a ',fall,' -f ',rms]
        

    if n == 1000 :
        subprocess.Popen('C:/Anaconda3/python.exe C:/Users/anton/Documents/Hexiwear/LaDeVo.py -a ',rms,' -f ',fall)
        n = 0
        x = 0
        while x < 10000:
            x += 1
            
            
            
    n += 1

ser.close()

Final code on Hexiwear

C/C++
The code send the accellerometer data to laptop and then by python code to Artik Cloud. In case of fall, the Hexiwear c++ code loops the alarm situation until it resets.
#include "mbed.h"
#include "FXAS21002.h"
#include "FXOS8700.h"
#include "MPL3115A2.h"

/*  Check out the full featured example application for interfacing to the 
 *  Gyro device at the following URL
 *  https://developer.mbed.org/teams/ATT-Hackathon/code/Accel_Mag_Gyro_SensorStream_K64F_AGM01_M/
*/
 
//#define MPL3115A2_I2C_ADDRESS (0x60<<1)
 
DigitalOut led1(LED_RED);
Serial pc(USBTX, USBRX);

// Pin connections & address for Hexiwear
FXOS8700 accel(PTC11, PTC10);
FXOS8700 mag(PTC11, PTC10);
FXAS21002 gyro(PTC11,PTC10);
//MPL3115A2 MPL3115A2( PTC11, PTC10, MPL3115A2_I2C_ADDRESS);
/* pos [0] = altimeter or pressure value */
/* pos [1] = temperature value */


DigitalOut led2(LED_BLUE);

// Storage for the data from the sensor
float gyro_data[3];  float gyro_rms=0.0;

float sensor_data[2];

// I2C i2c(p9, p10);        // sda, scl
 
// MPL115A2 p_sensor(&i2c, &pc); //DEBUG verion
// MPL115A2 p_sensor(&i2c);


// main() runs in its own thread in the OS
// (note the calls to Thread::wait below for delays)
int main() {

DigitalOut led3(LED_GREEN);

    // Set over sampling value (see MPL3115A2.h for details)
//    MPL3115A2.Oversample_Ratio(OVERSAMPLE_RATIO_64);
    // Configure the sensor as Barometer.
//    MPL3115A2.Barometric_Mode();

    // Configure Accelerometer FXOS8700, Magnetometer FXOS8700
    // Configure Gyro FXAS21002

    float accel_data[3]; float accel_rms=0.0;
    float mag_data[3];   float mag_rms=0.0;
    float accelalarm = 0.0;
    float gyroalarm = 0.0;

    accel.accel_config();
    mag.mag_config();        
    gyro.gyro_config();
    
    while (true) {
    
/*      gyro.acquire_gyro_data_dps(gyro_data);
      pc.printf("Gyroscope\r\nRoll(G)%4.4f\r\nPitch(G)%4.4f\r\nYaw(G)%4.4f\r\n",gyro_data[0],gyro_data[1],gyro_data[2]);
      gyro_rms = sqrt(((gyro_data[0]*gyro_data[0])+(gyro_data[1]*gyro_data[1])+(gyro_data[2]*gyro_data[2]))/3);
      pc.printf("RMS(G)%4.4f\r\n\n",gyro_rms); */
      
      accel.acquire_accel_data_g(accel_data);
      accel_rms = sqrt(((accel_data[0]*accel_data[0])+(accel_data[1]*accel_data[1])+(accel_data[2]*accel_data[2]))/3);
//      printf("Accelerometer\r\nX-Axis(G)%4.4f\r\nY-Axis(G)%4.4f\r\nZ-Axis(G)%4.4f\r\nRMS(G)%4.4f\r\n\n",accel_data[0],accel_data[1],accel_data[2],accel_rms);
      
/*      mag.acquire_mag_data_uT(mag_data);
      mag_rms = sqrt(((mag_data[0]*mag_data[0])+(mag_data[1]*mag_data[1])+(mag_data[2]*mag_data[2]))/3);
      printf("Magnetometer\r\nX-Axis(T)%4.4f\r\nY-Axis(T)%4.4f\r\nZ-Axis(T)%4.4f\r\nRMS(T)%4.4f ,\r\n\n",mag_data[0],mag_data[1],mag_data[2],mag_rms);
      
//      MPL3115A2.getAllData(&sensor_data[0]);
//      printf("Pressure ,\r\n%f \r\nTemperature ,\r\n%f\n", sensor_data[0], sensor_data[1]);

      printf("accelalarm:%4.4f accel_rms:%4.4f gyroalarm:%4.4f gyro_rms:%4.4f\n",accelalarm,accel_rms,gyroalarm,gyro_rms);   
*/ 
      accelalarm = accelalarm-accel_rms;
//      gyroalarm = gyroalarm-gyro_rms;
      
      accelalarm = sqrt(accelalarm*accelalarm);
//      gyroalarm = sqrt(gyroalarm*gyroalarm);
      
//      printf("\rAccel:%4.4f Gyro:%4.4f \n\n", accelalarm,gyroalarm);
      printf("%4.4f\n", accelalarm); 

      if (accelalarm > 1)
        while(true){
            printf("N\n");
//         else
//          printf("1\n");
        }
 
      led1 = !led1;
      led2 = !led2;
      led3 = !led3;            
    }
}

Final Code on Laptop

Python
This code gets the daa from Hexiwear and send it to Artik Cloud triggering an alarm when a fall is detected (more than 1G on the equation that extracts the module of te three vectors of accellerometer, x, y, z.
import serial
import artikcloud
from artikcloud.rest import ApiException
import sys
import json
from pprint import pprint

ser = serial.Serial(
    port='COM5',\
    baudrate=9600,\
    parity=serial.PARITY_NONE,\
    stopbits=serial.STOPBITS_ONE,\
    bytesize=serial.EIGHTBITS,\
        timeout=0)

print("connected to: " + ser.portstr)
#this will store the line
seq = []
count = 1
rms = 0.0
fall = 0

while True:
    for c in ser.read():
        seq.append(chr(c)) #convert from ANSII
        #joined_seq = ''.join(str(v) for v in seq) #Make a string from array
        joined_seq = ''.join(str(v) for v in seq) #Make a string from array

        if chr(c) == '\n':
            #print("Line " + str(count) + ': ' + joined_seq)
            if joined_seq == "N\n":
                print('Alarm!!!!')
                fall = 1
            else:
                rms = joined_seq
                print (joined_seq)
                seq = []
                count += 1
                break
            
    def main(argv):

      DEFAULT_CONFIG_PATH = 'C:/Users/anton/Documents/Hexiwear/config.json'

      with open(DEFAULT_CONFIG_PATH, 'r') as config_file:
        config = json.load(config_file)['LaDeVo']
      print(config)
      # Configure Oauth2 access_token for the client application.  Here we have used
      # the device token for the configuration
      artikcloud.configuration = artikcloud.Configuration();
      artikcloud.configuration.access_token = config['deviceToken']

      # We create an instance of the Message API class which provides
      # the send_message() and get_last_normalized_messages() api call
      # for our example
      api_instance = artikcloud.MessagesApi()

      # Device_message - data that is sent to your device
      device_message = {}


      # We send random values to the 'temp' field for this FireSensor.  
      # Let's send a random value between 0 and 200 for this demo.
      #device_message['accellRMS'] = random.randrange(0,200);
      device_message['accellRMS'] = rms;
      if fall == 0 :
          device_message['fall'] = '';
      else :
          device_message['fall'] = 'true';
      # Set the 'device id' - value from your config.json file
      device_sdid = config['deviceId']

      # set your custom timestamp
      ts = None

      # Construct a Message object for your request
      data = artikcloud.Message(device_message, device_sdid, ts) 

      try: 
        # Debug Print oauth settings
        pprint(artikcloud.configuration.auth_settings())

        # Send Message
        api_response = api_instance.send_message(data)
        pprint(api_response)
      except ApiException as e:
        print("Exception when calling MessagesApi->send_message: %s\n" % e)


    if __name__ == "__main__":
        main(sys.argv[1:])


ser.close()

Credits

Antonio Amadeu

Antonio Amadeu

3 projects • 5 followers
I do IoT since 30 years ago, learned microprocessors, step motor, hall effect sensors. I´m Data Scientist and R/C model aircraft practioner

Comments