In February 2017 Libelium launched the new version MySignals HW Thanks to feedback from the Community and several projects that have been created with it, we have improved the MySignals with new features such as:
In this tutorial we will explain how to work with MySignals HW V1. If you have MySignals HW V2 you can see how to use it at this link:
Tutorial: MySignals HW v2- eHealth and Medical IoT Development Platform for ArduinoMySignals is a development platform for medical devices and eHealth applications. You can use MySignals to develop your eHealth web applications or even to add your own sensors to build new medical devices.
MySignals allows you to measure more than 20 biometric parameters such as pulse, breath rate, oxygen in blood, electrocardiogram signals, blood pressure, muscle electromyography signals, glucose levels, galvanic skin response, lung capacity, snore waves, patient position, airflow and body scale parameters (weight, bone mass, body fat, muscle mass, body water, visceral fat, Basal Metabolic Rate and Body Mass Index). These broad sensing portfolio makes MySignals the most complete eHealth platform in the market.
All the data gathered by MySignals is encrypted and sent to the user's private account at Libelium Cloud through WiFi or Bluetooth. The data can be visualized in a tablet or smart phone with Android or iPhone Apps.
Libelium offers an API for developers to access the information. The Cloud API allows to access to the user's private account and get the information previously stored to be visualized in a third party platform.
You can find all the info at: http://www.my-signals.com
Disclaimer
MySignals Products are not medical devices or healthcare services, nor are they intended for medical diagnosis, cure, mitigation, treatment, advice or prevention of disease. MySignals Products are not finished products, so they are not intended to be purchased by End Users, but by developers, researchers and OEM Customers. Read our Terms & Conditions before buying for a complete understanding.
Buy nowMySignals is the new generation of eHealth and medical development products specifically oriented to researchers, developers and makers. It has new features that significantly improve the previous version commonly known as eHealth v2.
Discover MySignals, the new eHealth and medical development platform!
In the next tables you can see a complete comparative between eHealth v2 and the two different models of MySignals.
GENERAL FEATURES
There are several differences comparing the general features of MySignals and the previous product version eHealth V2.
SENSORS
FIRMWARE
The following list shows just some of the actions that produce the most common failures and warranty-voiding cases. Failure to comply with the recommendations of use will entail the guarantee cancellation.
Software:
Hardware:
MySignals allows you to measure 20 different biometric parameters such as pulse, breath rate, oxygen in blood, electrocardiogram signals, blood pressure, muscle electromyography signals, glucose levels, galvanic skin response, lung capacity, snore waves, patient position, airflow and body scale parameters (weight, bone mass, body fat, muscle mass, body water, visceral fat, Basal Metabolic Rate and Body Mass Index). These broad sensing portfolio makes MySignals the most complete eHealth platform in the market.
There is the possibility of integrating other new sensors such as electromyogram. Or Add your own sensors to build new medical devices.
This information is used to monitor in real time the state of a user or to get sensitive data in order to be subsequently analysed for medical diagnosis. Biometric information gathered can be wirelessly sent using two connectivity options available: Wi-Fi or Bluetooth Low Energy 4.0.
In addition the device can use other compatible communications modules: Bluetooth 2.0 or GPS/GPRS/3G.
Data can be visualized in standalone mode, sent to the Cloud in order to perform permanent storage or visualize and storage in real time by sending the data directly to a Smartphone. iPhone and Android applications have been designed in order to easily manage and storage the user's information.
MySignals Hardware Development Platform has many sensors available, but due to the limited internal memory of Arduino UNO is not possible to use all of them at the same time.
Please see our MySignals SW - eHealth and Medical IoT Development Platform version in order to work with several sensor or modules together at the same time.
1º - As a new product line we are updating the firmware and mobile App’s every week so please:
• Update regularly the MySignals Firmware to the last version. Go to the section “MySignals Firmware” of the guide for more info.
• Update regularly the version of the Android / iOS App.
2Âş- IMPORTANT: DO NOT UNPLUG MYSIGNALS WHILE IT IS BEING UPGRADED OR IT MAY BE RENDERED USELESS! (THIS CASE IS NOT COVERED BY THE WARRANTY).
3Âş - Do not connect or disconnect any sensor or connector while MySignals is ON. MySignals can become unstable or unresponsive, and internal parts can be damaged. Connect all the sensors that you want to use with MySignals and then turn it ON.
4Âş - MySignals includes a stick to navigate through the menu options of the touchscreen. Please use it for a correct function of the device interface.
5Âş - The Firmware of MySignals SW manages all the sensors at the same time and monitors the response of the screen and the touchscreen. For this reason sometimes during the measurement of different sensor like blood pressure or other wireless sensors it will be able to perform one action at the same time, you have to wait it to finish before being able to navigate or interact with the screen again.
6Âş - At any time you can Activate / Deactivate the synchronization of the information being sent to your Cloud Account by just pressing the Cloud icon on the top right corner.
7Âş - How can I see values older than one month in my Cloud account?
MySignals Cloud Web Service (section 5.2, page 25) allows currently to see graphics for values corresponding to the last month. By the end of 2017 a new version of the Cloud Service will allow to see the complete historical data of any of the users.
However, if you want to access to this data now, you can use the Cloud API Method 3 to get the sensor values of a member (see section 9.1.1, page 225), allows to retrieve values for any desired time slot.
If you have any doubt just write a post in the MySignals forum.
8º - In the “Detail view” only information coming from that specific sensor is received and sent to the Cloud. If you want to receive and store information coming from many sensors at the same time you should use the “General view” screen.
9Âş - Due to the high amount of information generated in the realtime pulse waves (ECG, EMG, airflow, snore), the information sent to the Cloud account is the summary of the information gathered (heart pulse, breath rate, snore rate and muscle contraction rate), not the continuous waves.
UPDATE: In 2017 there will be released new Firmware and App versions that allow to record continuous waves and send them to the Cloud.
10Âş - In the General view the update time to the Cloud is 20s. In the Detail view is 10s.
11Âş - BLE sensors are not compatible with the mobile App for the moment, however you can use them in standalone and web server mode.
12Âş - In order to make the MySignals App send to the Cloud you need:
· Have one Department created
· Have one user created and linked to one Department
· In the App to to Users, click on one and press "Select this user"
· Make sure the "Cloud" icon is active (upper right corner of the App)
13Âş - Connect the ECG Electrodes to the ECG sensor cables before placing them in the user body.
14Âş -The ECG signals need to be measured with the user lained back on the bed or stretcher.
15Âş - In order to keep the MySignals enclosure clean and without any mark we recommend to place it inside the plastic bad and put the chamois cloth provided or any other protector desired on top of it before closing the bag.
16Âş - In case you placed MySignals into the kit without the protection and got it maked in black use a common nail-varnish remover (with no acetone on it) along with a rag to clean it.
Can MySignals HW work against the Libelium Cloud server?
Yes. You can use it always sending the data via the Android / iOS App. Web server connection mode is not yet implemented.
Can MySignals work against our own cloud or a third party server?
Yes. You can send the information coming from MySignals to a third party Cloud server by two ways:
1Âş - Migrating the information stored in the Libelium Cloud to a third party Cloud server easily using the API Cloud provided
2Âş -Using directly the WiFi radio (HTTP, TCP/IP, etc). This last option just for MySignals HW.
Can I use all the sensors at the same time?
In the case of MySignals SW, yes you can. In the case of MySignals HW the Arduino processor is limited, so you can not manage all the sensors, wireless communication and others features at the same time. You should select a correct combination of the options available. Check the documentation for that.
Can I use my own sensors?
In the case of MySignals HW we provide the sensor pinout. You can use it to integrate your own sensors. WiFi, BLE, and BT2.0 connectivity is available too in order to integrate new wireless sensors.
- How can I see values older than one month in my Cloud account?
MySignals Cloud Web Service (section 5.2, page 25) allows currently to see graphics for values corresponding to the last month. By the end of 2017 a new version of the Cloud Service will allow to see the complete historical data of any of the users.
However, if you want to access to this data now, you can use the Cloud API Method 3 to get the sensor values of a member (see section 9.1.1, page 225), allows to retrieve values for any desired time slot.
If you have any doubt just write a post in the MySignals forum.
Included on the main MySignals board:
In order to connect MySignals Hardware Development an Arduino is needed.
The MySignals Hardware with an Arduino can be powered by the PC or by an external power supply. Some of the USB ports on computers are not able to give all the current the module needs to work, if your module have problems when it work, you can use an external power supply (12V - 2A) on the Arduino.
General power supply
Operating Current | 2 A |
Operating Voltage | 5V |
Input Voltage (recommended) | 12V |
Input Voltage (limit) | 10-20V |
Specific power supply
DC Current per I/O Pin | 20 mA [Max] |
DC Current for 3.3V | 1 A [Max] |
DC Current for 5V | 1 A [Max] |
DC Current for 4V Pin | 2 A [Max] |
Plug in /out the power supply adapter included with MySignals to turn ON or OFF the device. Make sure that the power adapter is placed indoors. Plug it into the corresponding power supply connector. Power supply unit is included with Mysignals. Do not use any third party power supply with it.
The green LED included in the Power Circuit indicate the correct power supply.
There is a reset button included in the Power Circuit. Use it if you want to do a hardware reset in the board.
MySignals Hardware Development Platform counts with a C++ library that lets you read easily all the sensors and compatible libraries to control and send the information by using any of the available radio interfaces or to control extra modules for general control uses. This library offers a simple-to-use open source system.
MySignals Hardware SDK is a ZIP file that include all the different libraries that you need to manages MySignals Hardware Development Platform.
MySignals Hardware SDK a high level libraries functions for a easy manage of the board. Before start using this functions you should download the files from this link. This zip includes all the files needed.
MySignals Hardware SDK installation
Libraries are often distributed as a ZIP file or folder. The name of the folder is the name of the library. Inside the folder will be the .cpp files, .h files and often a keywords.txt file, examples folder, and other files required by the library.
Importing a .zip Library: Libraries are often distributed as a ZIP file or folder. The name of the folder is the name of the library. Inside the folder will be a .cpp file, a .h file and often a keywords.txt file, examples folder, and other files required by the library. You can install 3rd party libraries in the IDE. Do not unzip the downloaded library, leave it as is. In the Arduino IDE, navigate to Sketch > Include Library. At the top of the drop down list, select the option to "Add .ZIP Library''.
First download and unzip “MySignals_HW_SDK_VX.X.X.zip”.
Do not unzip the libraries included in it, leave it as is.
In the Arduino IDE, navigate to Sketch > Include Library. At the top of the drop down list, select the option to "Add .ZIP Library''.
You will be prompted to select the library you would like to add. Navigate to the .zip file's location and open it.
Return to the Sketch > Import Library menu. You should now see the library at the bottom of the drop-down menu. It is ready to be used in your sketch. The zip file will have been expanded in the libraries folder in your Arduino sketches directory.
Manual installation: To install the library, first quit the Arduino application. Then uncompress the ZIP file containing the library. For example, if you're installing a library called "ArduinoParty", uncompress ArduinoParty.zip. It should contain a folder called ArduinoParty, with files like ArduinoParty.cpp and ArduinoParty.h inside. (If the .cpp and .h files aren't in a folder, you'll need to create one. In this case, you'd make a folder called "ArduinoParty" and move into it all the files that were in the ZIP file, like ArduinoParty.cpp and ArduinoParty.h.)
Drag the ArduinoParty folder into this folder (your libraries folder). Under Windows, it will likely be called "My Documents\Arduino\libraries". For Mac users, it will likely be called "Documents/Arduino/libraries". On Linux, it will be the "libraries" folder in your sketchbook. There may be more files than just the .cpp and .h files, just make sure they're all there. (The library won't work if you put the .cpp and .h files directly into the libraries folder or if they're nested in an extra folder. For example: Documents\Arduino\libraries\ArduinoParty.cpp and Documents\Arduino\libraries\ArduinoParty\ArduinoParty\ArduinoParty.cpp won't work.)
Restart the Arduino application. Make sure the new library appears in the Sketch->Import Library menu item of the software. That's it! You've installed a library!
The Arduino boards come with handy serial buffers. The default buffers are defined in two files named HardwareSerial.cpp and HardwareSerial.h . On my Ubuntu machine with default installation, those files are located in /usr/share/arduino/hardware/arduino/cores/arduino. By default, the size of both RX (receive) and TX (transmitt) buffers is 64 bits on a 2kB RAM Arduino Uno board, as defined in HardwareSerial.cpp:
#if (RAMEND < 1000) #define SERIAL_BUFFER_SIZE 16 #else #define SERIAL_BUFFER_SIZE 64 #endif
The size of the buffers is chosen to allow 'reasonable' communications without using too much of the scarce RAM available. However, MySignals need to increase the buffer size from 64 to 256 bytes in the Arduino.app package to have 7 measures available in the USB communication sensors: spirometer, blood pressure monitor, SPO2 and glucometer.
#if (RAMEND < 1000) #define SERIAL_BUFFER_SIZE 256 #else #define SERIAL_BUFFER_SIZE 256 #endif
You can find all the information about “Installing Additional Arduino Libraries” in this link.
The open-source Arduino Software (IDE) makes it easy to write code and upload it to the board. It runs on Windows, Mac OS X, and Linux. The environment is written in Java and based on Processing and other open-source software.
This software can be used with Arduino UNO board.
Refer to the Getting Started page for Installation instructions.
We have created a specific library to manage all the sensors integrated in the main board. Mysignals library is the basic group of function that you need to start to monitor biometric parameters.
General MySignals functions
/ Initializes the library void begin(); // Read state of the expander digital pins byte expanderRead(); // Write state of the expander digital pins void expanderWrite(byte data); // Read state of the analog to digital conversor pins int readADC(uint8_t adcnum); // Prints a wave formed by points in serial monitor void printWave(uint16_t air); // Initializes the UART expander for a specific sensor void initSensorUART(uint8_t number); // Initializes the UART expander void initSensorUART(void); // Enables the UART expander for a specific sensor void enableSensorUART(uint8_t number); // Disables the UART expander void disableSensorUART(void); // Intializes software interruptions void initInterrupt(uint16_t sampleRate); // Pauses software interruptions void pauseInterrupt(void); // Resumes software interruptions void resumeInterrupt(void); // Debug printing functions void print(char * msg); void println(char * msg); void println(); void PrintHex8(uint8_t *data, uint8_t length); void PrintHex16(uint16_t *data, uint8_t length); // Returns the library version int version(void);
There are several libraries Arduino compatible that you can use with MySignals Hardware Development Platform. Here you can find information about the libraries used to control wireless modules integrated with the board.
The BLE112 is a Bluetooth® Smart module targeted for low-power sensors and accessories. It integrates all features required for a Bluetooth Smart application, including Bluetooth radio, software stack, and GATT-based profiles. The BLE112 Bluetooth Smart module can also host end-user applications, which means no external microcontroller is required in size or price constrained devices. Moreover, it has flexible hardware interfaces to connect to different peripherals and sensors and can be powered directly from a standard 3 V coin cell battery or a pair of AAA batteries. In the lowest power sleep mode it merely consumes 500 nA and will wake up within a few hundred microseconds.
We have created a specific library to manage the BLE112 Bluegiga module integrated in the board. BLE library is the basic group of function that you need to start to bluetooth low energy communication.
General BLE functions
Pulsioximeter sensor functions:
// It opens the UART and powers the module int8_t initModule(); // It closes the UART and powers off the module void OFF(); // Set TX power. uint16_t setTXPower(uint8_t power); // sends software reset command to the module. Resets in normal mode uint8_t softwareReset(); // Reset the module via the hardware reset pin void hardwareReset(); // Makes an inquiry to discover specific device by its Mac. uint16_t scanDevice(char * Mac); // Makes an inquiry to discover specific device by its Mac. uint16_t scanDevice(char* Mac, uint8_t maxTime, uint8_t TXPower); // This function configures the discover mode. Default observation mode. uint16_t setDiscoverMode(uint8_t discover); // This functions configures the discoverability mode. default general discoverable mode. uint16_t setDiscoverableMode(uint8_t discoverable); // This functions configures the connectability mode. default directed conectable mode. uint16_t setConnectableMode(uint8_t connectable); // This function ends the current procedure, like a scan. uint16_t endProcedure(); // similar to AT -> OK uint8_t sayHello(); // This function will start direct connection establishment procedure to a dedicated BLE device. uint16_t connectDirect(char * BLEAddress, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t timeout, uint16_t latency); // This function will start direct connection establishment procedure to a dedicated BLE device. uint16_t connectDirect(char * BLEAddress); // This function disconnects an active connection uint16_t disconnect(uint8_t connection); // wait for specified time for an event. uint8_t waitEvent(unsigned long time); // Sets device to bondable mode uint16_t setBondableMode(uint8_t bondable); // deletes all devices bonded uint16_t deleteBonding(); // return number of bonded devices. maximum of 8 uint16_t getBonding(); // read an attribute from the local database of the BLE device. uint16_t readLocalAttribute(uint16_t handle, uint16_t offset); // read an attribute from the local database of the BLE device (default offset=0). uint16_t readLocalAttribute(uint16_t handle); // write local attribute to the local GATT database of the BLE device uint16_t writeLocalAttribute(uint16_t handle, char * data); // write local attribute to the local GATT database of the BLE device uint16_t writeLocalAttribute(uint16_t handle, uint8_t indicate, char * data); // write local attribute to the local GATT database of the BLE device uint16_t writeLocalAttribute(uint16_t handle, uint8_t * data, uint8_t length); // write local attribute of the BLE device, indicate enabled uint16_t writeLocalAttribute(uint16_t handle, uint8_t indicate, uint8_t * data, uint8_t length); // read an attribute from a remote BLE device uint16_t attributeRead(uint8_t connection_handle, uint16_t att_handle); // write an attribute from a remote BLE device uint16_t attributeWrite(uint8_t connection, uint16_t atthandle, char * data); // write an attribute from a remote BLE device uint16_t attributeWrite(uint8_t connection, uint16_t atthandle, uint8_t * data, uint8_t length); // get the current status of the BLE module uint8_t getStatus(uint8_t connection); // initializes all the Bluetooth variables void initialize_BLE_values(); // configures Security Manager parametes uint16_t setSMParameters(uint8_t protection);
BLE profile
Here you can see the BLE profile uploaded in the BLE module. This is the profile used to connect with MySignals Android and IOS APPs.
5.3.1.1 Examples of use
The MySignals SDK includes all the necessary functions to manage the BLE and send in real time the data sensor measures. In order to use this functions, before all, you should include the corresponding library.
BLE basic configuration example
Upload the next code to configure BLE module:
/* * * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * By using it you accept the MySignals Terms and Conditions. * You can find them at: http://libelium.com/legal * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Version: 0.1 * Design: David Gascon * Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <MySignals_BLE.h> #include <Wire.h> #include <SPI.h> char buffer_tft[30]; Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); unsigned long previous; // Sensor list bool selected_airflow; bool selected_ecg; bool selected_emg; bool selected_gsr; bool selected_position; bool selected_snore; bool selected_temp; bool selected_spiro; bool selected_eeg; bool selected_spo2_uart; bool selected_bp_uart; bool selected_gluco_uart; bool selected_scale_ble; bool selected_spo2_ble; bool selected_bp_ble; bool selected_gluco_ble; void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); //TFT message: Welcome to MySignals strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[0]))); tft.drawString(buffer_tft, 0, 0, 2); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { //TFT message: "BLE init ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[1]))); tft.drawString(buffer_tft, 0, 15, 2); } else { //TFT message:"BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } else { //TFT message: "BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } void loop() { //1. SET MODE: SLAVE (VISIBLE TO APP) while ((MySignals_BLE.ble_mode_flag == master_mode)) { if (MySignals_BLE.setMode(slave_mode) == 0) { //TFT message: "Slave mode ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[3]))); tft.drawString(buffer_tft, 0, 30, 2); MySignals_BLE.ble_mode_flag = slave_mode; } else { //TFT message: "Slave mode fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[4]))); tft.drawString(buffer_tft, 0, 30, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } //2. SET BONDABLE MODE if (MySignals_BLE.bond_mode_and_mitm == 0) { if (MySignals_BLE.setBondableMode(BLE_ENABLE_BONDING) == 0) { //TFT message: "Bondable mode ok" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[5]))); tft.drawString(buffer_tft, 0, 45, 2); //3. SET SM PARAMETERS if (MySignals_BLE.setSMParameters(BLE_ENABLE_MITM) == 0) { //TFT message: "SM parameters ok" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[7]))); tft.drawString(buffer_tft, 0, 60, 2); MySignals_BLE.bond_mode_and_mitm = 1; } else { //TFT message: "SM parameters fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[8]))); tft.drawString(buffer_tft, 0, 60, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } else { //TFT message: "Bondable mode fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[6]))); tft.drawString(buffer_tft, 0, 45, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
BLE basic connection example
Upload the next code to connect BLE module with other device:
/* * * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * By using it you accept the MySignals Terms and Conditions. * You can find them at: http://libelium.com/legal * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Version: 0.1 * Design: David Gascon * Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <MySignals_BLE.h> #include <Wire.h> #include <SPI.h> char buffer_tft[30]; Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); unsigned long previous; // Sensor list bool selected_airflow; bool selected_ecg; bool selected_emg; bool selected_gsr; bool selected_position; bool selected_snore; bool selected_temp; bool selected_spiro; bool selected_eeg; bool selected_spo2_uart; bool selected_bp_uart; bool selected_gluco_uart; bool selected_scale_ble; bool selected_spo2_ble; bool selected_bp_ble; bool selected_gluco_ble; void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); //TFT message: Welcome to MySignals strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[0]))); tft.drawString(buffer_tft, 0, 0, 2); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { //TFT message: "BLE init ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[1]))); tft.drawString(buffer_tft, 0, 15, 2); } else { //TFT message:"BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } else { //TFT message: "BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } void loop() { //1. SET MODE: SLAVE (VISIBLE TO APP) while ((MySignals_BLE.ble_mode_flag == master_mode)) { if (MySignals_BLE.setMode(slave_mode) == 0) { //TFT message: "Slave mode ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[3]))); tft.drawString(buffer_tft, 0, 30, 2); MySignals_BLE.ble_mode_flag = slave_mode; } else { //TFT message: "Slave mode fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[4]))); tft.drawString(buffer_tft, 0, 30, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } //2. SET BONDABLE MODE if (MySignals_BLE.bond_mode_and_mitm == 0) { if (MySignals_BLE.setBondableMode(BLE_ENABLE_BONDING) == 0) { //TFT message: "Bondable mode ok" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[5]))); tft.drawString(buffer_tft, 0, 45, 2); //3. SET SM PARAMETERS if (MySignals_BLE.setSMParameters(BLE_ENABLE_MITM) == 0) { //TFT message: "SM parameters ok" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[7]))); tft.drawString(buffer_tft, 0, 60, 2); MySignals_BLE.bond_mode_and_mitm = 1; } else { //TFT message: "SM parameters fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[8]))); tft.drawString(buffer_tft, 0, 60, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } else { //TFT message: "Bondable mode fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[6]))); tft.drawString(buffer_tft, 0, 45, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
The ESP8266 WiFi Module is a self contained SOC with integrated TCP/IP protocol stack that can give any microcontroller access to your WiFi network. The ESP8266 is capable of either hosting an application or offloading all Wi-Fi networking functions from another application processor. Each ESP8266 module comes pre-programmed with an AT command set firmware, meaning, you can simply hook this up to your Arduino device and get about as much WiFi-ability as a WiFi Shield offers (and that’s just out of the box)! The ESP8266 module is an extremely cost effective board with a huge, and ever growing, community.
You can control the module using AT COMMANDS.
You can use too the compatible ESP8266 library in order to manager the WiFi Module easily.
Here you can see more information about the ESP8266 library.
If you have problems with ESP8266 module you can find information in this link:
5.3.2.1 Examples of use
The MySignals SDK includes all the necessary functions to manage the BLE and send in real time the data sensor measures. In order to use this functions, before all, you should include the corresponding library.
WiFi basic configuration example
Upload the next code to configure WiFi module:
/* * * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * By using it you accept the MySignals Terms and Conditions. * You can find them at: http://libelium.com/legal * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Version: 0.1 * Design: David Gascon * Implementation: Luis Martin / Victor Boria */ int8_t answer; /*DEMUL*/ int S0Pin = 4; int S1Pin = 5; int S2Pin = 6; int ENABLE = 7; char aux_str[50]; void setup() { Serial.begin(115200); printlnMsg("Starting..."); pinMode(S0Pin, OUTPUT); pinMode(S1Pin, OUTPUT); pinMode(S2Pin, OUTPUT); pinMode(ENABLE, OUTPUT); delay(1000); digitalWrite(S0Pin, HIGH); digitalWrite(S1Pin, HIGH); digitalWrite(S2Pin, HIGH); delay(1000); digitalWrite(ENABLE, HIGH); delay(1000); // Checks if the WiFi module is started answer = sendATcommand("AT", "OK", 6000); if (answer == 0) { printlnMsg("Error"); // waits for an answer from the module while (answer == 0) { // Send AT every two seconds and wait for the answer answer = sendATcommand("AT", "OK", 6000); } } else if (answer == 1) { printlnMsg("WiFi succesfully working!"); } } void loop() { delay(5000); } int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout) { uint8_t x = 0, answer = 0; char response[500]; unsigned long previous; memset(response, '\0', 100); // Initialize the string delay(100); while ( Serial.available() > 0) Serial.read(); // Clean the input buffer delay(1000); Serial.println(ATcommand); // Send the AT command x = 0; previous = millis(); // this loop waits for the answer do { if (Serial.available() != 0) { response[x] = Serial.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer1) != NULL) { answer = 1; //Serial.print("Received: "); printlnMsg(response); } } // Waits for the asnwer with time out } while ((answer == 0) && ((millis() - previous) < timeout)); return answer; } void printMsg(char * msg) { digitalWrite(ENABLE, LOW); delay(10); Serial.print(msg); digitalWrite(ENABLE, HIGH); delay(10); } void printlnMsg(char * msg) { digitalWrite(ENABLE, LOW); delay(10); Serial.println(msg); digitalWrite(ENABLE, HIGH); delay(10); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
WiFi basic connection example
Upload the next code to connect WiFi module with other device:
/* * * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * By using it you accept the MySignals Terms and Conditions. * You can find them at: http://libelium.com/legal * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Version: 0.1 * Design: David Gascon * Implementation: Luis Martin / Victor Boria */ int8_t answer; /*DEMUL*/ int S0Pin = 4; int S1Pin = 5; int S2Pin = 6; int ENABLE = 7; char aux_str[50]; void setup() { Serial.begin(115200); printlnMsg("Starting..."); pinMode(S0Pin, OUTPUT); pinMode(S1Pin, OUTPUT); pinMode(S2Pin, OUTPUT); pinMode(ENABLE, OUTPUT); delay(1000); digitalWrite(S0Pin, HIGH); digitalWrite(S1Pin, HIGH); digitalWrite(S2Pin, HIGH); delay(1000); digitalWrite(ENABLE, HIGH); delay(1000); // Checks if the WiFi module is started answer = sendATcommand("AT", "OK", 6000); if (answer == 0) { printlnMsg("Error"); // waits for an answer from the module while (answer == 0) { // Send AT every two seconds and wait for the answer answer = sendATcommand("AT", "OK", 6000); } } else if (answer == 1) { printlnMsg("WiFi succesfully working!"); if(sendATcommand("AT+CWMODE=1", "OK", 6000)) { printlnMsg("AT+CWMODE=1 OK"); } else{ printlnMsg("AT+CWMODE=1 Error"); } if(sendATcommand("AT+CWJAP=\"WIFI_SSID\",\"WIFI_PASSWORD\"", "OK", 20000)) { printlnMsg("Successfully connected!"); } else{ printlnMsg("Error"); } } } void loop() { delay(5000); } int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout) { uint8_t x = 0, answer = 0; char response[500]; unsigned long previous; memset(response, '\0', 100); // Initialize the string delay(100); while ( Serial.available() > 0) Serial.read(); // Clean the input buffer delay(1000); Serial.println(ATcommand); // Send the AT command x = 0; previous = millis(); // this loop waits for the answer do { if (Serial.available() != 0) { response[x] = Serial.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer1) != NULL) { answer = 1; //Serial.print("Received: "); printlnMsg(response); } } // Waits for the asnwer with time out } while ((answer == 0) && ((millis() - previous) < timeout)); return answer; } void printMsg(char * msg) { digitalWrite(ENABLE, LOW); delay(10); Serial.print(msg); digitalWrite(ENABLE, HIGH); delay(10); } void printlnMsg(char * msg) { digitalWrite(ENABLE, LOW); delay(10); Serial.println(msg); digitalWrite(ENABLE, HIGH); delay(10); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
MySignals Hardware SDK include several examples to control extra wireless modules without libraries. You can find information about them in the next sections.
MySignals Hardware have integrated 3 modules for general application in order to improve the basic features of Arduino.
This module is controlled using I2C (Arduino A4 and A5 analog pins).
We can control 8 more digital pins.
Pin | Function | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
E0 | 3G Power(Exp. board) | X | X | X | X | X | X | X | Power on:0 Power off:1 |
E1 | TouchscreenCS (SPI) | X | X | X | X | X | X | Selected:1 Disabled:0 | X |
E2 | BT2.0 Power | X | X | X | X | X | Power on:1 Power off:0 | X | X |
E3 | BT2.0 Key | X | X | X | X | AT mode:0 Comm:1 | X | X | X |
E4 | ADC CS (SPI) | X | X | X | Selected:1 Disabled:0 | X | X | X | X |
E5 | Snore pot.CS (SPI) | X | X | Selected:1 Disabled:0 | X | X | X | X | X |
E6 | BLE reset | X | Reset: 1 Normal: 0 | X | X | X | X | X | X |
E7 | WiFi Power (Exp. board) | Power on:0 Power off:1 | X | X | X | X | X | X | X |
The are two ways to turn the expander pins on and off, writing first on a buffer variable or writing directly in the expander.
5.4.1.1 Using expander buffer
Controlling the digital pin expander with the variable “MySignals.expanderState”
We recommend using this way because it helps you to control the state of every pin acting first on a buffer variable called “ MySignals.expanderState”, and changing only the pin that you are interested on.
“MySignals.expanderState” is initialized with the value “B10000001” which as you can see in the table above sets all the modules turned off.
Here is an example code acting on every individual pin:
#include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); /* expanderState is initialized with B10000001 Expansor pin library names: EXP_3G_ON EXP_TOUCH_CS EXP_BT_POWER EXP_BT_KEY EXP_ADC_CS EXP_SNORE_POT EXP_RESET_BLE EXP_WIFI_ON */ } void loop() { //Enable 3G module power -> bit0:0 bitClear(MySignals.expanderState, EXP_3G_ON); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Disable 3G module power -> bit0:1 bitSet(MySignals.expanderState, EXP_3G_ON); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Enable Touchscreen SPI -> bit1:1 bitSet(MySignals.expanderState, EXP_TOUCH_CS); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Disable Touchscreen SPI -> bit1:0 bitClear(MySignals.expanderState, EXP_TOUCH_CS); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Enable BT2.0 module power -> bit2:1 bitSet(MySignals.expanderState, EXP_BT_POWER); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Disable BT2.0 module power -> bit2:0 bitClear(MySignals.expanderState, EXP_BT_POWER); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Enable BT2.0 Key to communication mode -> bit3:1 bitSet(MySignals.expanderState, EXP_BT_KEY); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Enable BT2.0 Key to AT mode -> bit3:0 bitClear(MySignals.expanderState, EXP_BT_KEY); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Enable ADC SPI -> bit4: 1 bitSet(MySignals.expanderState, EXP_ADC_CS); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Disable ADC SPI -> bit4: 0 bitClear(MySignals.expanderState, EXP_ADC_CS); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Enable Snore potentiometer SPI -> bit5: 1 bitSet(MySignals.expanderState, EXP_SNORE_POT); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Disable Snore potentiometer SPI -> bit5: 0 bitClear(MySignals.expanderState, EXP_SNORE_POT); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Enable BLE module reset -> bit6: 1 bitSet(MySignals.expanderState, EXP_RESET_BLE); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Disable BLE module reset -> bit6: 0 bitClear(MySignals.expanderState, EXP_RESET_BLE); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Enable WiFi module power (expansion board) -> bit7:0 bitClear(MySignals.expanderState, EXP_WIFI_ON); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Disable WiFi module power (expansion board) -> bit7:1 bitSet(MySignals.expanderState, EXP_WIFI_ON); MySignals.expanderWrite(MySignals.expanderState); delay(1000); }
The second option is writing directly in the digital expander, but to use this way you should always be aware of the state of every digital pin each time you use it.
Example general – All turned off. It allows to use the BLE or WiFi modules:
MySignals.expanderWrite(B10000001);
Example of 3G (expansion board) - Turned on:
MySignals.expanderWrite(B10000000);
Example of Touchscreen - Turned on:
MySignals.expanderWrite(B10000011);
Example of BT2.0: In order to change the HC-05 BT2.0 mode is necessary that first change the KEY pin to the correct level. Then, reset the module. Turned on in AT mode
MySignals.expanderWrite(B10000001); //Mode: AT - BT Power: off delay(100); MySignals.expanderWrite(B10000101); //Mode: AT - BT Power: on
Example of ADC – CS SPI control:
MySignals.expanderWrite(B10010001);
Example code:
#include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { MySignals.begin(); } void loop() { MySignals.expanderWrite(B00000000); delay(1000); expanderWrite(B11111111); delay(1000); }
This module is a ADC controlled using SPI ( D13, D12,D11, Expansor4). We use the I2C Expander to control the CS. This ADC have 10 bits of resolution.
We can control 8 more analog inputs.
Pin | Function |
C0 | ADC_EMG |
C1 | ADC_ECG |
C2 | ADC_AIRFLOW |
C3 | ADC_GSR |
C4 | ADC_TEMPERATURE |
C5 | ADC_SNORE |
C6 | - |
C7 | - |
Example code:
#include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { int read_adc = MySignals.readADC(ADC_AIRFLOW); Serial.println(read_adc); delay(1000); }
This module is a multiplexor controlled by digital pins (D4, D5, D6, D7). It multiplex the UART (D0/RX, D1/RX) and allow to connect 8 devices but it can not connect all at the same time.
Enable (D7) | S2 (D6) | S1 (D5) | S0 (D4) | Function |
1 | 0 | 0 | 0 | GLUCOMETER |
1 | 0 | 0 | 1 | BLOODPRESSURE |
1 | 0 | 1 | 0 | PULSIOXIMETER |
1 | 0 | 1 | 1 | SPIROMETER |
1 | 1 | 0 | 0 | EEG |
1 | 1 | 0 | 1 | BLE |
1 | 1 | 1 | 0 | EXPANSION |
1 | 1 | 1 | 1 | WIFI |
Example code:
#include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); MySignals.initSensorUART(); MySignals.enableSensorUART(GLUCOMETER); delay(1000); MySignals.enableSensorUART(BLOODPRESSURE); delay(1000); MySignals.enableSensorUART(PULSIOXIMETER); delay(1000); MySignals.enableSensorUART(SPIROMETER); delay(1000); } void loop() { }
MySignals Hardware Development Platform include extra modules focused in general control like TFT screen or touchscreen. Here you can find information about the libraries used to control these modules integrated with the board.
2.4 Inch TFT LCD Shield Touch Board Display Module For Arduino UNO.
You can use the compatible Adafruit_ILI9341_AS library in order to manager the TFT Module easily.
Here you can see more information about the library.
Official libraries:
https://github.com/adafruit/Adafruit_ILI9341
Revised libraries with optimized features:
http://www.instructables.com/id/Arduino-TFT-display-of-bitmap-images-from-an-SD-Ca/?ALLSTEPS
Here you can find aditionally Adafruit_GFX_AS library:
https://github.com/rogerclarkmelbourne/Arduino_STM32/tree/master/STM32F1/libraries/Adafruit_GFX_AS
You can use the compatible uTouch library in order to manager the touchscreen easily.
Here you can see more information about the uTouch library.
MySignals allows you to measure more than 15 different biometric parameters such as pulse, breath rate, oxygen in blood, electrocardiogram signals, blood pressure, muscle electromyography signals, glucose levels, galvanic skin response, lung capacity, snore waves, patient position, airflow and body scale parameters (weight, bone mass, body fat, muscle mass, body water, visceral fat, Basal Metabolic Rate and Body Mass Index). These broad sensing portfolio makes MySignals the most complete eHealth platform in the market.
We offer broad range of both wired and wireless sensors:
This information is used to monitor in real time the state of a user or to get sensitive data in order to be subsequently analysed for biometric analysis. Biometric information gathered can be wirelessly sent using two connectivity options integrated available: Wi-Fi or Bluetooth Low Energy 4.0.
MySignals Hardware Development Platform can work with 11 different wired biometric sensors.
MySignals have a new improved connection system. It is very easy-to-use jack-connectors method.
6.1.1.1 Sensor features
Description: Pulse oximetry a noninvasive method of indicating the arterial oxygen saturation of functional hemoglobin.
Oxygen saturation is defined as the measurement of the amount of oxygen dissolved in blood, based on the detection of Hemoglobin and Deoxyhemoglobin. Two different light wavelengths are used to measure the actual difference in the absorption spectra of HbO2 and Hb. The bloodstream is affected by the concentration of HbO2 and Hb, and their absorption coefficients are measured using two wavelengths 660 nm (red light spectra) and 940 nm (infrared light spectra). Deoxygenated and oxygenated hemoglobin absorb different wavelengths.
Deoxygenated hemoglobin (Hb) has a higher absorption at 660 nm and oxygenated hemoglobin (HbO2) has a higher absorption at 940 nm . Then a photo-detector perceives the non-absorbed light from the LEDs to calculate the arterial oxygen saturation.
A pulse oximeter sensor is useful in any setting where a patient's oxygenation is unstable, including intensive care, operating, recovery, emergency and hospital ward settings, pilots in unpressurized aircraft, for assessment of any patient's oxygenation, and determining the effectiveness of or need for supplemental oxygen.
Acceptable normal ranges for patients are from 95 to 99 percent, those with a hypoxic drive problem would expect values to be between 88 to 94 percent, values of 100 percent can indicate carbon monoxide poisoning.
The sensor needs to be connected to the specific SPO2 jack connector in MySignals board and it works with direct connector power supply.
Measurement:
Parameter | Unit | Range |
Pulse | ppm | 25~250 ppm |
SPO2 | % | 35-100% |
6.1.1.2 Connecting the sensor
Connect the sensor in the SPO2 connector indicated in the MySignals Hardware board. The sensor cable have only one way of connection to prevent errors and make the connection easier. Use the mini-USB connector to link the SPO2 with the MySignals board, using the jack connector of the cable in this side.
Place the SPO2 on your finger as shown in the image below.
Insert your finger into the sensor and press ON button.
After a few seconds you will get the values in the sensor screen of the sensor and in the visualization method programmed.
6.1.1.3 SDK functins
Getting data
The data read is accessible with two specific function.
{ // It returns SPO2 specific measure: //(PULSE) //(SPO2) int getPulsioximeter(uint8_t format); //Gets both SPO2 measures, pulse and SPO2: uint8_t getPulsioximeter(); }
6.1.1.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" int valuePulse; int valueSPO2; uint8_t pulsioximeter_state = 0; void setup() { Serial.begin(19200); MySignals.begin(); MySignals.initSensorUART(); MySignals.enableSensorUART(PULSIOXIMETER); } void loop() { // First way of getting sensor data MySignals.enableSensorUART(PULSIOXIMETER); Serial.println(); pulsioximeter_state = MySignals.getPulsioximeter(); if (pulsioximeter_state == 1) { Serial.print(F("Pulse:")); Serial.print(MySignals.pulsioximeterData.BPM); Serial.print(F("bpm / SPO2:")); Serial.print(MySignals.pulsioximeterData.O2); Serial.println(F("%")); } else if (pulsioximeter_state == 2) { Serial.println(F("Not valid data")); } else { Serial.println(F("No available data")); } MySignals.disableSensorUART(); delay(2000); // Second way of getting sensor data MySignals.enableSensorUART(PULSIOXIMETER); valuePulse = MySignals.getPulsioximeter(PULSE); Serial.println(); if (valuePulse == 2) { Serial.println(F("Not valid Pulse data")); } else if (valuePulse == 0) { Serial.println(F("No available data")); } else { Serial.print(F("Pulse:")); Serial.print(valuePulse); Serial.println(F("bpm")); } MySignals.disableSensorUART(); delay(2000); MySignals.enableSensorUART(PULSIOXIMETER); valueSPO2 = MySignals.getPulsioximeter(SPO2); if (valueSPO2 == 2) { Serial.println(F("Not valid SPO2 data")); } else if (valueSPO2 == 0) { Serial.println(F("No available data")); } else { Serial.print(F("SPO2:")); Serial.print(valueSPO2); Serial.println(F("%")); } MySignals.disableSensorUART(); delay(2000); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configures the sensor and shows the gathered data in the TFT.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); int valuePulse; int valueSPO2; uint8_t pulsioximeter_state = 0; void setup() { Serial.begin(19200); MySignals.begin(); MySignals.initSensorUART(); MySignals.enableSensorUART(PULSIOXIMETER); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.drawString("SPO2:", 0, 0, 2); } void loop() { pulsioximeter_state = MySignals.getPulsioximeter(); if (pulsioximeter_state == 1) { tft.drawNumber(MySignals.pulsioximeterData.BPM, 0, 30, 2); tft.drawNumber(MySignals.pulsioximeterData.O2, 0, 45, 2); } delay(1000); }
Upload the code to Arduino. Here is the TFT output.
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
The Electrocardiogram Sensor (ECG) has grown to be one of the most commonly used medical tests in modern medicine. Its utility in the diagnosis of a myriad of cardiac pathologies ranging from myocardial ischemia and infarction to syncope and palpitations has been invaluable to clinicians for decades.
The accuracy of the ECG depends on the condition being tested. A heart problem may not always show up on the ECG. Some heart conditions never produce any specific ECG changes. ECG leads are attached to the body while the patient lies flat on a bed or table.
6.1.2.1 Sensor features
Description: The electrocardiogram (ECG) is a diagnostic tool that is routinely used to assess the electrical and muscular functions of the heart. The sensor use “Continuous telemetry electrocardiogram" for a prolonged monitoring including the use of three ECG electrodes.
The sensor needs to be connected to the specific ECG jack connector in MySignals board and it works with direct connector power supply.
What is measured or can be detected on the ECG (EKG)?
Schematic representation of normal ECG
Measurement:
Parameter | Unit | Range |
Pulse rate | BPM (Beats per minute) | 0-200 bpm |
Electrocardiogram signal | Volts | 0-5V |
6.1.2.2 Connecting the sensor
Connect the ECG Electrodes to the ECG sensor cables before placing them in the user body.
The ECG signals need to be measured with the user lained back on the bed or stretcher.
Connect the jack sensor in the ECG connector indicated in the MySignals Hardware board. The sensor cable have only one way of connection to prevent errors and make the connection easier.
Connect the ECG lead to the electrodes.
Remove the protective plastic. You can use a specific conductive gel in order to improve the quality signal of the sensor.
This sensor use disposable pre-gelled electrodes.
These high quality disposable electrodes are to be used to measure EEG, ECG and EMG. They are to be used once and are very handy because of integrated gel. They adhere very well to the skin and are clean to use.
The snap-on connector can easily be pushed on or removed from the electrode lead.
Place the electrodes as shown below.
After a few seconds you will get the values in the visualization method programmed.
6.1.2.3 SDK functins
Getting data
This ECG returns an analog value in volts (0 – 5) to represent the ECG wave form.
{ float ECGvolt = eHealth.getECG();; }
6.1.2.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float ECG = MySignals.getECG(VOLTAGE); Serial.print("ECG value : "); Serial.print(ECG, 2); Serial.println(" V"); // wait for a millisecond delay(1); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
Calibrated example
This example configure the sensor and read the numeric parameters. In this example a specific calibration function is used in the measure.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float ECG = MySignals.getCalibratedECG(5,0,0,DATA); Serial.print("ECG value : "); Serial.print(ECG, 0); Serial.println(" V"); // wait for a millisecond delay(1); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
KST example
This example configure the sensor and send the data to KST. KST program shows the sensor value wave.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" extern volatile unsigned long timer0_overflow_count; float fanalog0; int analog0; unsigned long time; byte serialByte; void setup() { Serial.begin(9600); MySignals.begin(); Serial.println("Starting..."); } void loop() { while (Serial.available()>0) { serialByte=Serial.read(); if (serialByte=='C') { while(1){ fanalog0=MySignals.getECG(DATA); // Use the timer0 => 1 tick every 4 us time=(timer0_overflow_count << 8) + TCNT0; // Microseconds conversion. time=(time*4); //Print in a file for simulation Serial.print(time); Serial.print(";"); Serial.println(fanalog0,5); if (Serial.available()>0) { serialByte=Serial.read(); if (serialByte=='F') break; } } } } }
Upload the code to Arduino and follow the KST configuration steps available in the KST section.
Graphic Arduino example
This example configure the sensor and send the data to Arduino Graphic Tool. Graphic Tool integrated in Arduino IDE shows the sensor value wave.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { uint16_t ecg = (uint16_t)MySignals.getECG(DATA); ecg = map(ecg, 0,1023,1023,0); Serial.println(ecg); delay(5); }
Upload the code to Arduino and follow the Graphic Arduino tool configuration steps available in the Graphic Tool section.
Wave example
This example configure and read the sensor. Then use the Serial monitor to represent this values in a basic wave.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { int ECG = MySignals.getECG(DATA); ECG = map(ECG,0,1023,200,0); MySignals.printWave(ECG); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include "Wire.h" #include "SPI.h" Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //! It stores the current value of x position in the LCD. uint16_t graphic_x = 0; //! It stores the current value of the ECG or AirFlow sensor. uint16_t valRead; //! It stores the previous value of the ECG or AirFlow sensor. uint16_t graphic_prevRead; #define graphic_low_extrem 230 #define graphic_high_extrem 50 #define graphic_left_extrem 0 #define graphic_right_extrem 320 void setup() { Serial.begin(115200); MySignals.begin(); tft.init(); tft.setRotation(3); tft.fillScreen(ILI9341_WHITE); tft.fillRect(0,0,320,30,ILI9341_RED); tft.setTextColor(ILI9341_WHITE); tft.drawString("ECG",5,5,4); } void loop() { valRead = MySignals.getECG(DATA); //Serial.println(valRead); valRead = map(valRead, 150, 600, graphic_high_extrem, graphic_low_extrem); printGraphic(valRead,0); } void printGraphic(uint16_t value, uint8_t delay_time) { if (value < graphic_high_extrem) { value = graphic_high_extrem; } if (value > graphic_low_extrem) { value = graphic_low_extrem; } //Pinta la linea solo a partir de que ya exista al menos 1 valor if (graphic_x > graphic_left_extrem + 1) { tft.drawLine(graphic_x - 1, graphic_prevRead, graphic_x, value, ILI9341_RED); } //Wave refresh (barre pantalla pintando una linea) tft.drawLine(graphic_x + 1, graphic_high_extrem, graphic_x + 1, graphic_low_extrem, ILI9341_WHITE); graphic_prevRead = value; graphic_x++; delay(delay_time); if (graphic_x == graphic_right_extrem) { graphic_x = graphic_left_extrem; } SPI.end(); }
Upload the code to Arduino. Here is the TFT output.
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
Anormal respiratory rates and changes in respiratory rate are a broad indicator of major physiological instability, and in many cases, respiratory rate is one of the earliest indicators of this instability. Therefore, it is critical to monitor respiratory rate as an indicator of patient status. AirFlow sensor can provide an early warning of hypoxemia and apnea.
6.1.3.1 Sensor features
Description: The nasal / mouth airflow sensor is a device used to measure the breathing rate in a patient in need of respiratory help or person. This device consists of a flexible thread which fits behind the ears, and a set of two prongs which are placed in the nostrils. Breathing is measured by these prongs. The specifically designed cannula/holder allows the thermocouple sensor to be placed in the optimal position to accurately sense the oral/nasal thermal airflow changes as well as the nasal temperature air. Comfortable adjustable and easy to install.
The sensor needs to be connected to the specific Airflow jack connector in MySignals board and it works with direct connector power supply.
Parameter | Unit | Range |
Respiratory rate | PPM (Peaks per minute) | 0-60 ppm |
Breathing intensity | Volts | 0-3,3V |
6.1.3.2 Connecting the sensor
Connect the sensor in the Airflow connector indicated in the MySignals Hardware board. The sensor cable include 2 pieces and it have only one way of connection to prevent errors and make the connection easier.
The sensor integrate a extension cable with a “keyhole” connector. This middle connector have specific position in order to have the correct polarity. Please check the marks includes in the side of both connectors.
Place the sensor as shown below.
After a few seconds you will get the values in the visualization method programmed.
6.1.3.3 SDK functins
Getting data
The air flow sensor is connected to the Arduino/RasberryPi by an analog input and returns a value from 0 to 1024. With the next functions you can get this value directly and print a wave form in the serial monitor.
{ // Returns airflow value in a specific format //(VOLTAGE) - in Volts (0-5V) //(DATA) - in digital value (0-1023) float getAirflow(uint8_t format); // Returns airflow in DATA format float getAirflow(void); // Returns an analog value to represent the Electrocardiography (0-5V) float getCalibratedAirflow(uint8_t samples, uint16_t delaySample, float offset, uint8_t format); // Calculates airflow PPM void airflowPPM(void); }
6.1.3.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float air = MySignals.getAirflow(VOLTAGE); Serial.print("Airflow value : "); Serial.print(air, 2); Serial.println(" V"); delay(100); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
Calibrated example
This example configure the sensor and read the numeric parameters. In this example a specific calibration function is used in the measure.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float air = MySignals.getCalibratedAirflow(10,1,0,VOLTAGE); Serial.print("Airflow value : "); Serial.print(air, 2); Serial.println(" V"); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
KST example
This example configure the sensor and send the data to KST. KST program shows the sensor value wave.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" extern volatile unsigned long timer0_overflow_count; float fanalog0; int analog0; unsigned long time; byte serialByte; void setup() { Serial.begin(9600); MySignals.begin(); Serial.println("Starting..."); } void loop() { while (Serial.available()>0) { serialByte = Serial.read(); if (serialByte == 'C') { while(1) { fanalog0 = MySignals.getAirflow(DATA); // Use the timer0 => 1 tick every 4 us time = (timer0_overflow_count << 8) + TCNT0; // Microseconds conversion. time = time*4; //Print in a file for simulation Serial.print(time); Serial.print(";"); Serial.println(fanalog0,5); if (Serial.available()>0) { serialByte = Serial.read(); if (serialByte == 'F') break; } } } } }
Upload the code to Arduino and follow the KST configuration steps available in the KST section.
Graphic Arduino example
This example configure the sensor and send the data to Arduino Graphic Tool. Graphic Tool integrated in Arduino IDE shows the sensor value wave.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { uint16_t air = (uint16_t)MySignals.getAirflow(DATA); Serial.println(air); delay(20); }
Upload the code to Arduino and follow the Graphic Arduino tool configuration steps available in the Graphic Tool section.
Wave example
This example configure and read the sensor. Then use the Serial monitor to represent this values in a basic wave.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { int air = MySignals.getAirflow(DATA); MySignals.printWave(air); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #define graphic_low_extrem 230 #define graphic_high_extrem 30 #define graphic_left_extrem 0 #define graphic_right_extrem 320 Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //! It stores the current value of x position in the LCD. uint16_t graphic_x; //! It stores the current value of the MySignals. uint16_t valRead; //! It stores the previous value of the MySignals. uint16_t graphic_prevRead; void setup(void) { Serial.begin(115200); MySignals.begin(); tft.init(); tft.setRotation(3); tft.fillScreen(ILI9341_WHITE); tft.fillRect(0,0,320,30,ILI9341_RED); tft.setTextColor(ILI9341_WHITE); tft.drawString("Airflow",5,5,4); } void loop() { valRead = (uint16_t)MySignals.getAirflow(DATA); valRead = map(valRead, 0, 1023, 230, 30); printGraphic(valRead, 0); } void printGraphic(uint16_t value, uint8_t delay_time) { if (value < graphic_high_extrem) { value = graphic_high_extrem; } if (value > graphic_low_extrem) { value = graphic_low_extrem; } //Pinta la linea solo a partir de que ya exista al menos 1 valor if (graphic_x > graphic_left_extrem + 1) { tft.drawLine(graphic_x - 1, graphic_prevRead, graphic_x, value, ILI9341_RED); } //Wave refresh (barre pantalla pintando una linea) tft.drawLine(graphic_x + 1, graphic_high_extrem, graphic_x + 1, graphic_low_extrem, ILI9341_WHITE); graphic_prevRead = value; graphic_x++; delay(delay_time); if (graphic_x == graphic_right_extrem) { graphic_x = graphic_left_extrem; } SPI.end(); }
Upload the code to Arduino. Here is the TFT output.
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
Blood pressure is the pressure of the blood in the arteries as it is pumped around the body by the heart. When your heart beats, it contracts and pushes blood through the arteries to the rest of your body. This force creates pressure on the arteries. Blood pressure is recorded as two numbers—the systolic pressure (as the heart beats) over the diastolic pressure (as the heart relaxes between beats).
6.1.4.1 Sensor features
Description: Monitoring blood pressure at home is important for many people, especially if you have high blood pressure. Blood pressure does not stay the same all the time. It changes to meet your body’s needs. It is affected by various factors including body position, breathing or emotional state, exercise and sleep. It is best to measure blood pressure when you are relaxed and sitting or lying down.
Classification of blood pressure for adults (18 years and older)
Systolic (mm Hg) | Diastolic (mm Hg) | |
Hypotension | < 90 | < 60 |
Desired | 90–119 | 60–79 |
Prehypertension | 120–139 | 80–89 |
Stage 1 Hypertension | 140–159 | 90–99 |
Stage 2 Hypertension | 160–179 | 100–109 |
Hypertensive Crisis | ≥ 180 | ≥ 110 |
High blood pressure (hypertension) can lead to serious problems like heart attack, stroke or kidney disease. High blood pressure usually does not have any symptoms, so you need to have your blood pressure checked regularly.
SPECIAL FEATURES:
KEY SPECIFICATIONS
The sensor needs to be connected to the specific Blood Pressure Monitor jack connector in MySignals board and it works with internal rechargeable battery. Use the Blood pressure specific cable in order to charge the sensor connected to MySignals.
Measurement:
Parameter | Unit | Range |
Systolic pressure | mm Hg | 0-300 mmHg |
Diastolic pressure | mm Hg | 0-300 mmHg |
Pulse | ppm | 30~200 ppm |
6.1.4.2 Connecting the sensor
Connect the sensor in the Blood Pressure connector indicated in the MySignals Hardware board. The sensor cable have only one way of connection to prevent errors and make the connection easier. Use the mini-USB connector to link the Blood Pressure monitor with the MySignals board, using the normal jack connector (3.5mm) of the cable in this side.
Before start using the sphygmomanometer we need to connect the sensor in MySignals board. After that we can get all the information contained in the device.
Place the sphygmomanometer on your arm (biceps zone) as shown in the image below.
Turn on the sphygmomanometer cuff (press ON button). The sensor will begin to make a measurement. In order to measure correctly is important to maintain the arm and the cuff in the correct position.
Do not make abrupt movements or the measure will be not reliable.
The sphygmomanometer will take a few moments to calculate the blood pressure reading.
After a few seconds you will get the values in the visualization method programmed.
6.1.4.3 SDK functins
Getting data
The data read is accessible with a public function.
{ // Indicates if Blood Pressure sensor is connected and powered on uint8_t getStatusBP(); // Calculates all Blood Pressure measures bool getBloodPressure(void); }
6.1.4.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(19200); MySignals.begin(); MySignals.initSensorUART(); MySignals.enableSensorUART(BLOODPRESSURE); } void loop() { if (MySignals.getStatusBP()) { delay(1000); if (MySignals.getBloodPressure() == 1) { MySignals.disableMuxUART(); Serial.println(); Serial.print("Diastolic: "); Serial.println(MySignals.bloodPressureData.diastolic); Serial.print("Systolic: "); Serial.println(MySignals.bloodPressureData.systolic); Serial.print("Pulse/min: "); Serial.println(MySignals.bloodPressureData.pulse); MySignals.enableMuxUART(); } } delay(1000); }
TFT example
This example configures the sensor and shows the gathered data in the TFT.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <Wire.h> #include "SPI.h" Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); void setup() { Serial.begin(115200); MySignals.begin(); MySignals.initSensorUART(); MySignals.enableSensorUART(BLOODPRESSURE); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.drawString("Blood pressure:", 0, 0, 2); } void loop() { if (MySignals.getStatusBP()) { delay(1000); if (MySignals.getBloodPressure() == 1) { tft.drawString("Diastolic:", 0, 15, 2); tft.drawNumber(MySignals.bloodPressureData.diastolic, 100, 15, 2); tft.drawString("Systolic:", 0, 30, 2); tft.drawNumber(MySignals.bloodPressureData.systolic, 100, 30, 2); tft.drawString("Pulse/min:", 0, 45, 2); tft.drawNumber(MySignals.bloodPressureData.pulse, 100, 45, 2); } } delay(1000); }
Upload the code to Arduino. Here is the TFT output.
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
Despite widely variable intervals between meals or the occasional consumption of meals with a substantial carbohydrate load, human blood glucose levels tend to remain within the normal range. However, shortly after eating, the blood glucose level may rise, in non-diabetics, temporarily up to 7.8 mmol/L (140 mg/dL) or a bit more.
6.1.5.1 Sensor features
Description: Glucometer is a medical device for determining the approximate concentration of glucose in the blood. A small drop of blood, obtained by pricking the skin with a lancet, is placed on a disposable test strip that the meter reads and uses to calculate the blood glucose level. The meter then displays the level in mg/dl or mmol/l.
The sensor needs to be connected to the specific glucometer jack connector in MySignals board and it works with internal batteries.
6.1.5.2 Connecting the sensor
Connect the sensor in the Glucometer connector indicated in the MySignals Hardware board. The sensor cable have only one way of connection to prevent errors and make the connection easier. Use the mini-jack connector (2.5mm) to link the Glucometer with the MySignals board, using the normal jack connector (3.5mm) of the cable in this side.
Before start using the glucometer we need one measure at least in the memory of the glucometer. After that we can get all the information contained in the glucometer (date, glucose value).
Place a test strip in the machine when the machine is ready. Watch the indicator for placing the blood to the strip.
Clean the end of your index finger with rubbing alcohol before pricking it with an sterile needle or lancet.
Pierce your finger tip on the soft, fleshy pad and obtain a drop of blood. The type of drop of blood is determined by the type of strip you are using
Place the drop of blood on or at the side of the strip.
The glucometer will take a few moments to calculate the blood sugar reading.
The glucometer will store the value in the memory.
In order to extract the data from the glucometer to the Arduino, connect the cable as show in the picture.
You should view in the glucometer screen the message “P-C”, that indicates the correct connection.
The maximum recommended number of measures stored in the glucometer is 5. Please delete all the measureas after it using the glucometer button(press it several times and then use the M button).
You can turn off the device holding the M button during 3 seconds.
Setting time
In order to use the date and time in each measure it is necessary to set correctly this parameters in the device.
Set time information after insert new batteries. Use the button allocated in the batteries backpack in order to initialize the configuration of these parameters.
6.1.5.3 SDK functins
Getting data
With a simple function we can read all the measures stored in the glucometer and show them in the terminal. The function must be used before the initialization of the serial monitor.
{ // Gets glucose measures void getGlucose(void); }
The vector where data is a public variable of the MySignals class.
{ //!Struct to store data of the glucometer. struct glucoseDataVector { uint8_t year; uint8_t month; uint8_t day; uint8_t hour; uint8_t minutes; uint8_t glucose; uint8_t meridian; }; //!Vector to store the glucometer measures and dates. glucoseDataVector glucometerData[1]; }
6.1.5.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include <Wire.h> #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); MySignals.initSensorUART(); MySignals.enableSensorUART(GLUCOMETER); delay(1000); MySignals.getGlucose(); Serial.begin(115200); MySignals.disableMuxUART(); for (uint8_t i = 0; i < MySignals.glucoseLength; i++) { Serial.print(F("measure number:")); Serial.println(i + 1); Serial.print(F("year:")); Serial.println(MySignals.glucometerData[i].year); Serial.print(F("month:")); Serial.println(MySignals.glucometerData[i].month); Serial.print(F("day:")); Serial.println(MySignals.glucometerData[i].day); Serial.print(F("hour:")); Serial.println(MySignals.glucometerData[i].hour); Serial.print(F("minutes:")); Serial.println(MySignals.glucometerData[i].minutes); Serial.print(F("glucose:")); Serial.println(MySignals.glucometerData[i].glucose); Serial.print(F("meridian:")); Serial.println(MySignals.glucometerData[i].meridian); Serial.println(); } MySignals.enableMuxUART(); } void loop() { }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configures the sensor and shows the gathered data in the TFT.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <Wire.h> #include "SPI.h" Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); void setup() { Serial.begin(115200); MySignals.begin(); MySignals.initSensorUART(); MySignals.enableSensorUART(GLUCOMETER); delay(1000); MySignals.getGlucose(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.drawString("Glucometer last measure:", 0, 0, 2); tft.drawNumber(MySignals.glucometerData[MySignals.glucoseLength-1].glucose, 0, 30, 2); } void loop() { }
Upload the code to Arduino. Here is the TFT output.
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
Body temperature depends upon the place in the body at which the measurement is made, and the time of day and level of activity of the person. Different parts of the body have different temperatures.
The commonly accepted average core body temperature (taken internally) is 37.0°C (98.6°F). In healthy adults, body temperature fluctuates about 0.5°C (0.9°F) throughout the day, with lower temperatures in the morning and higher temperatures in the late afternoon and evening, as the body's needs and activities change.
6.1.6.1 Sensor features
Description: The temperature sensor allows you to measure this key parameter for body monitoring. Its measure the human body temperature with a 0.1 ÂşC maximum desviation.
It is of great medical importance to measure body temperature. The reason is that a number of diseases are accompanied by characteristic changes in body temperature. Likewise, the course of certain diseases can be monitored by measuring body temperature, and the efficiency of a treatment initiated can be evaluated by the physician.
Hypothermia: <35.0 °C (95.0 °F)
Normal: 36.5–37.5 °C (97.7–99.5 °F)
Fever or Hyperthermia >37.5–38.3 °C (99.5–100.9 °F)
Hyperpyrexia >40.0–41.5 °C (104–106.7 °F)
The sensor needs to be connected to the specific Temperature jack connector in MySignals board and it works with direct connector power supply.
Measurement:
Parameter | Unit | Range |
Body Temperature | Degree Celsius (°C) | 0-50ºC |
6.1.6.2 Connecting the sensor
Connect the sensor in the Temperature connector indicated in the MySignals Hardware board. The sensor cable have only one way of connection to prevent errors and make the connection easier.
Place your sensor as shown in the image below.
Make contact between the metallic part and your skin. Use a piece of adhesive tape to hold the sensor attached to the skin.
After a few seconds you will get the values in the visualization method programmed.
6.1.6.3 SDK functions
Getting data
The corporal temperature can be taken by a simple function. This function return a float with the last value of temperature measured by the Arduino.
{ // Returns the corporal temperature float getTemperature(void); // Returns the corporal temperature after applying measuring filter float getCalibratedTemperature(uint8_t samples, uint16_t delaySample, float offset, uint8_t format); }
6.1.6.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float temperature = MySignals.getTemperature(); Serial.print(F("Temperature (*C): ")); Serial.println(temperature, 2); delay(1000); // wait for a second }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
Calibrated example
This example configure the sensor and read the numeric parameters. In this example a specific calibration function is used in the measure.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float temperature = MySignals.getCalibratedTemperature(100,10,0.2); Serial.print("Temperature (ÂşC): "); Serial.print(temperature, 2); Serial.println(""); delay(1000); // wait for a second }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
Graphic Arduino example
This example configure the sensor and send the data to Arduino Graphic Tool. Graphic Tool integrated in Arduino IDE shows the sensor value wave.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float temperature = MySignals.getTemperature(); Serial.println(temperature+4, 2); delay(20); }
Upload the code to Arduino and follow the Graphic Arduino tool configuration steps available in the Graphic Tool section.
TFT example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #define graphic_low_extrem 230 #define graphic_high_extrem 30 #define graphic_left_extrem 0 #define graphic_right_extrem 320 Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //! It stores the current value of x position in the LCD. uint16_t graphic_x; //! It stores the current value of the MySignals. uint16_t valRead; //! It stores the previous value of the MySignals. uint16_t graphic_prevRead; void setup(void) { Serial.begin(115200); MySignals.begin(); tft.init(); tft.setRotation(3); tft.fillScreen(ILI9341_WHITE); tft.fillRect(0,0,320,30,ILI9341_RED); tft.setTextColor(ILI9341_WHITE); tft.drawString("Temperature",5,5,4); } void loop() { valRead = (float)MySignals.getTemperature()*10.0; Serial.println(valRead); valRead = map(valRead, 300, 400, 230, 30); printGraphic(valRead, 0); } void printGraphic(uint16_t value, uint8_t delay_time) { if (value < graphic_high_extrem) { value = graphic_high_extrem; } if (value > graphic_low_extrem) { value = graphic_low_extrem; } //Pinta la linea solo a partir de que ya exista al menos 1 valor if (graphic_x > graphic_left_extrem + 1) { tft.drawLine(graphic_x - 1, graphic_prevRead, graphic_x, value, ILI9341_RED); } //Wave refresh (barre pantalla pintando una linea) tft.drawLine(graphic_x + 1, graphic_high_extrem, graphic_x + 1, graphic_low_extrem, ILI9341_WHITE); graphic_prevRead = value; graphic_x++; delay(delay_time); if (graphic_x == graphic_right_extrem) { graphic_x = graphic_left_extrem; } SPI.end(); }
Upload the code to Arduino. Here is the TFT output.
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
Electromyography (EMG) is an electrodiagnostic medicine technique for evaluating and recording the electrical activity produced by skeletal muscles. EMG is performed using an instrument called an electromyograph, to produce a record called an electromyogram. An electromyograph detects the electric potential generated by muscle cells when these cells are electrically or neurologically activated. The signals can be analyzed to detect medical abnormalities, activation level, or recruitment order, or to analyze the biomechanics of human or animal movement.
EMG testing has a variety of clinical and biomedical applications. EMG is used as a diagnostics tool for identifying neuromuscular diseases, or as a research tool for studying kinesiology, and disorders of motor control. EMG signals are sometimes used to guide botulinum toxin or phenol injections into muscles. EMG signals are also used as a control signal for prosthetic devices such as prosthetic hands, arms, and lower limbs.
There are two kinds of EMG: surface EMG and intramuscular EMG. Surface EMG assesses muscle function by recording muscle activity from the surface above the muscle on the skin. Surface electrodes are able to provide only a limited assessment of the muscle activity. Surface EMG can be recorded by a pair of electrodes or by a more complex array of multiple electrodes. More than one electrode is needed because EMG recordings display the potential difference (voltage difference) between two separate electrodes. Limitations of this approach are the fact that surface electrode recordings are restricted to superficial muscles, are influenced by the depth of the subcutaneous tissue at the site of the recording which can be highly variable depending of the weight of a patient, and cannot reliably discriminate between the discharges of adjacent muscles.
6.1.7.1 Sensor features
Description: An electromyograph detects the electrical potential generated by muscle cells when these cells are electrically or neurologically activated. The signals can be analyzed to detect medical abnormalities, activation level, recruitment order or to analyze the biomechanics of human or animal movement.
EMG signals are used in many clinical and biomedical applications. EMG is used as a diagnostics tool for identifying neuromuscular diseases, assessing low-back pain, kinesiology, and disorders of motor control. EMG signals are also used as a control signal for prosthetic devices such as prosthetic hands, arms, and lower limbs.
This sensor will measure the filtered and rectified electrical activity of a muscle, depending the amount of activity in the selected muscle.
Use your muscles to control any type of actuator (motors, servos, lights ...) Interact with the environment with your own muscles. This sensor comes with everything you need to start sensing muscle activity with your Arduino.
The sensor needs to be connected to the specific EMG jack connector in MySignals board and it works with direct connector power supply.
Measurement:
Parameter | Unit | Range |
Muscle rate | CPM (contractions per minute) | 0-60 cpm |
Muscle signal | Volts | 0-5V |
6.1.7.2 Connecting the sensor
Connect the sensor in the EMG connector indicated in the MySignals Hardware board. The sensor cable have only one way of connection to prevent errors and make the connection easier.
Connect the EMG lead to the electrodes.
Remove the protective plastic. You can use a specific conductive gel in order to improve the quality signal of the sensor.
This sensor use disposable pre-gelled electrodes.
These high quality disposable electrodes are to be used to measure EEG, ECG and EMG. They are to be used once and are very handy because of integrated gel. They adhere very well to the skin and are clean to use.
The H124SG has a unique, patented pre-gelled adhesive side with non-irritating gel, especially developed to prevent allergic reactions. These foam electrode is latex free and therefore suitable for every skin type.
The snap-on connector can easily be pushed on or removed from the electrode lead.
After a few seconds you will get the values in the visualization method programmed.
6.1.7.3 SDK functins
Getting data
This EMG returns an analog value in volts (0 – 1024) to represent the EMG wave form.
{ // Returns EMG value in a specific format //(VOLTAGE) - in Volts (0-5V) //(DATA) - in digital value (0-1023) float getEMG(uint8_t format); // Returns EMG in DATA format float getEMG(void); // Returns EMG value after applying measuring filter float getCalibratedEMG(uint8_t samples, uint16_t delaySample, float offset, uint8_t format); // Calculates EMG CPM void EMGCPM(void); }
6.1.7.4 Examples of use
Basic Example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float EMG = MySignals.getEMG(VOLTAGE); Serial.print("EMG value : "); Serial.print(EMG, 2); Serial.println(" V"); delay(10); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
Calibrated example
This example configure the sensor and read the numeric parameters. In this example a specific calibration function is used in the measure.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float EMG = MySignals.getCalibratedEMG(5,0,0,VOLTAGE); Serial.print("EMG value : "); Serial.print(EMG, 2); Serial.println(" V"); delay(10); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
KST example
This example configure the sensor and send the data to KST. KST program shows the sensor value wave.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" extern volatile unsigned long timer0_overflow_count; float fanalog0; int analog0; unsigned long time; byte serialByte; void setup() { Serial.begin(9600); MySignals.begin(); Serial.println("Starting..."); } void loop() { while (Serial.available()>0) { serialByte=Serial.read(); if (serialByte=='C') { while(1) { fanalog0=MySignals.getEMG(DATA); // Use the timer0 => 1 tick every 4 us time=(timer0_overflow_count << 8) + TCNT0; // Microseconds conversion. time=(time*4); //Print in a file for simulation Serial.print(time); Serial.print(";"); Serial.println(fanalog0,5); if (Serial.available()>0) { serialByte=Serial.read(); if (serialByte=='F') break; } } } } }
Upload the code to Arduino and follow the KST configuration steps available in the KST section.
Graphic Arduino example
This example configure the sensor and send the data to Arduino Graphic Tool. Graphic Tool integrated in Arduino IDE shows the sensor value wave.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { uint16_t EMG = (uint16_t)MySignals.getEMG(DATA); Serial.println(EMG); delay(20); }
Upload the code to Arduino and follow the Graphic Arduino tool configuration steps available in the Graphic Tool section.
Wave example
This example configure and read the sensor. Then use the Serial monitor to represent this values in a basic wave.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float EMG = MySignals.getEMG(DATA); EMG = map(EMG,100, 600,0,300); MySignals.printWave(EMG); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #define graphic_low_extrem 230 #define graphic_high_extrem 30 #define graphic_left_extrem 0 #define graphic_right_extrem 320 Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //! It stores the current value of x position in the LCD. uint16_t graphic_x; //! It stores the current value of the MySignals. uint16_t valRead; //! It stores the previous value of the MySignals. uint16_t graphic_prevRead; void setup(void) { Serial.begin(115200); MySignals.begin(); tft.init(); tft.setRotation(3); tft.fillScreen(ILI9341_WHITE); tft.fillRect(0,0,320,30,ILI9341_RED); tft.setTextColor(ILI9341_WHITE); tft.drawString("EMG",5,5,4); } void loop() { valRead = (uint16_t)MySignals.getEMG(DATA); //Serial.println(valRead); valRead = map(valRead, 100, 600, 230, 30); printGraphic(valRead, 0); } void printGraphic(uint16_t value, uint8_t delay_time) { if (value < graphic_high_extrem) { value = graphic_high_extrem; } if (value > graphic_low_extrem) { value = graphic_low_extrem; } //Pinta la linea solo a partir de que ya exista al menos 1 valor if (graphic_x > graphic_left_extrem + 1) { tft.drawLine(graphic_x - 1, graphic_prevRead, graphic_x, value, ILI9341_RED); } //Wave refresh (barre pantalla pintando una linea) tft.drawLine(graphic_x + 1, graphic_high_extrem, graphic_x + 1, graphic_low_extrem, ILI9341_WHITE); graphic_prevRead = value; graphic_x++; delay(delay_time); if (graphic_x == graphic_right_extrem) { graphic_x = graphic_left_extrem; } SPI.end(); }
Upload the code to Arduino. Here is the TFT output.
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
Spirometry (meaning the measuring of breath) is the most common of the pulmonary function tests (PFTs), measuring lung function, specifically the amount (volume) and/or speed (flow) of air that can be inhaled and exhaled. Spirometry is an important tool used for generating pneumotachographs, which are helpful in assessing conditions such as asthma, pulmonary fibrosis, cystic fibrosis, and COPD.
6.1.8.1 Sensor features
Description: MySignals Spirometer Peak Flow Meter is a hand-held pulmonary function measuring device that measures your maximum possible exhalation which is called peak expiratory flow (PEF) and forced expiratory volume in 1 second (FEV1).
Forced expiratory flow (FEF)
Forced expiratory flow (FEF) is the flow (or speed) of air coming out of the lung during the middle portion of a forced expiration.
Forced expiratory volume in 1 second (FEV1)
FEV1 is the volume of air that can forcibly be blown out in one second, after full inspiration. Average values for FEV1 in healthy people depend mainly on sex and age, according to the diagram at left. Values of between 80% and 120% of the average value are considered normal.
It is suitable for children through adults who are capable of following the instructions for use. Because the Meter has an automatic memory, you can take the Meter with you the next time you connect to MySignals board for a review of many readings.
Accuracy requirement
Volume range | 0.01L~9.99L | Airflow range | 50 L/min ~900L/min |
Volume accuracy | ±0.050L or ±3% | Airflow accuracy | ±10% or ±20L/min |
Resolution
Volume resolution | 0.01L |
Airflow resolution | 1L/min |
Resistance to flow
Back pressure @ 660L/min | <0.11 KPa/sec |
Back pressure @ 900L/min | <0.15 KPa/sec |
The sensor needs to be connected to the specific Spirometer jack connector in MySignals board and it works with internal batteries.
Parameter | Unit | Range |
Volume | l | 0.01L~9.99L |
Air flow | l/min | 50 L/min ~900L/min |
6.1.8.2 Connecting the sensor
Connect the sensor in the Spirometer connector indicated in the MySignals Hardware board. The sensor cable have only one way of connection to prevent errors and make the connection easier. Use the mini-USB connector to link the Spirometer with the MySignals board, using the normal jack connector (3.5mm) of the cable in this side.
Before start using the glucometer we need one measure at least in the memory of the Spirometer. After that we can get all the information contained in the Spirometer (date, PEF, FEV1).
Place a new disposable mouthpiece for each new user in the machine and press the ON button. When the machine is ready you can start the measurement.
Sit on the edge of your bed if possible, or sit up as far as you can in bed. Hold the spirometer in an upright position.
Place the mouthpiece in your mouth and seal your lips tightly around it. Breathe in fastly and as deeply as possible.
The spirometer will take a few moments to calculate the spirometer reading.
Press the ON button in order to turn off the device. It is necessary in order to store the measure correctly.
The glucometer will store the value in the memory.
In order to extract the data from the glucometer to the Arduino, connect the cable as show in the picture.
You should view in the glucometer screen a USB logo indication, that indicates the correct connection.
Deleting data stored
The maximum recommended number of measures stored in the spirometer is 7. Please delete all the measures after it using the example code “spirometer_delete_measures” that you can find the the next sections.
Powering the sensor
It is very important to use batteries with more than 50% of charge in order to obtain correctly the biometric information.
Setting time
In order to use the date and time in each measure it is necessary to set correctly this parameters in the device.
Set time information after insert new batteries. When you start with new batteries the sensor it initialize the configuration of these parameters. Use the buttons to configure this information.
6.1.8.3 SDK functins
Getting data
With this simple functions we can read the values stored in the sensor.
{ // Indicates if Blood Pressure sensor is connected and powered on uint8_t getStatusSpiro(); // Gets up to 7 spirometer measures void getSpirometer(); }
Deleting data
With this delete functions we can delete the values stored in the sensor.
{ // Deletes all measures from spirometer device memory bool deleteSpiroMeasures(); }
6.1.8.4 Examples of use
Basic Example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include <Wire.h> #include "SPI.h" void setup() { Serial.begin(9600); MySignals.begin(); MySignals.initSensorUART(); MySignals.enableSensorUART(SPIROMETER); while (MySignals.getStatusSpiro() == 0) { delay(100); } Serial.println(F("Spirometer is ON")); } void loop() { MySignals.getSpirometer(); MySignals.disableMuxUART(); Serial.print(F("Number of measures:")); Serial.println(MySignals.spir_measures); Serial.println(); for (int i = 0; i < MySignals.spir_measures; i++) { Serial.print(MySignals.spirometerData[i].spir_pef); Serial.print(F("L/min ")); Serial.print(MySignals.spirometerData[i].spir_fev); Serial.print(F("L ")); Serial.print(MySignals.spirometerData[i].spir_hour); Serial.print(F(":")); Serial.print(MySignals.spirometerData[i].spir_minutes); Serial.print(F(" ")); Serial.print(MySignals.spirometerData[i].spir_year); Serial.print(F("-")); Serial.print(MySignals.spirometerData[i].spir_month); Serial.print(F("-")); Serial.println(MySignals.spirometerData[i].spir_day); } Serial.println(F("************")); MySignals.enableMuxUART(); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
Delete measures example
This example delete the measures of the sensor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include <Wire.h> #include "SPI.h" void setup() { Serial.begin(9600); MySignals.begin(); MySignals.initSensorUART(); MySignals.enableSensorUART(SPIROMETER); while (MySignals.getStatusSpiro() == 0) { delay(100); } MySignals.println("Spirometer is ON. Deleting measures"); MySignals.deleteSpiroMeasures(); } void loop() { MySignals.getSpirometer(); MySignals.disableMuxUART(); Serial.print(F("Number of measures:")); Serial.println(MySignals.spir_measures); Serial.println(); for (int i = 0; i < MySignals.spir_measures; i++) { Serial.print(MySignals.spirometerData[i].spir_pef); Serial.print(F("L/min ")); Serial.print(MySignals.spirometerData[i].spir_fev); Serial.print(F("L ")); Serial.print(MySignals.spirometerData[i].spir_hour); Serial.print(F(":")); Serial.print(MySignals.spirometerData[i].spir_minutes); Serial.print(F(" ")); Serial.print(MySignals.spirometerData[i].spir_year); Serial.print(F("-")); Serial.print(MySignals.spirometerData[i].spir_month); Serial.print(F("-")); Serial.println(MySignals.spirometerData[i].spir_day); } Serial.println(F("************")); MySignals.enableMuxUART(); delay(5000); }
TFT example
This example configures the sensor and shows the gathered data in the TFT.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); void setup(void) { Serial.begin(9600); MySignals.begin(); MySignals.initSensorUART(); MySignals.enableSensorUART(SPIROMETER); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.drawString("Spirometer last measure:", 0, 0, 2); while (MySignals.getStatusSpiro() == 0) { delay(100); } MySignals.getSpirometer(); uint16_t spir_pef_last = MySignals.spirometerData[MySignals.spir_measures - 1].spir_pef; tft.drawNumber(spir_pef_last, 0, 30, 2); } void loop() { delay(5000); }
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
Skin conductance, also known as galvanic skin response (GSR) is a method of measuring the electrical conductance of the skin, which varies with its moisture level. This is of interest because the sweat glands are controlled by the sympathetic nervous system, so moments of strong emotion, change the electrical resistance of the skin. Skin conductance is used as an indication of psychological or physiological arousal, The Galvanic Skin Response Sensor (GSR - Sweating) measures the electrical conductance between 2 points, and is essentially a type of ohmmeter.
6.1.9.1 Sensor features
Description: This sensor measures the electrical conductance of the skin, which varies with its moisture level. This is of interest because the sweat glands are controlled by the sympathetic nervous system, so moments of strong emotion, change the electrical resistance of the skin.
In skin conductance response method, conductivity of skin is measured at fingers of the palm. The principle or theory behind functioning of galvanic response sensor is to measure electrical skin resistance based on sweat produced by the body. When high level of sweating takes place, the electrical skin resistance drops down. A dryer skin records much higher resistance. The skin conductance response sensor measures the psycho galvanic reflex of the body. Emotions such as excitement, stress, shock, etc. can result in the fluctuation of skin conductivity. Skin conductance measurement is one component of polygraph devices and is used in scientific research of emotional or physiological arousal.
The sensor needs to be connected to the specific GSR jack connector in MySignals board and it works with direct connector power supply.
Parameter | Unit | Range |
Conductance | Siemens | 0-20 Siemens |
Resistance | Ohms | 10K-100KOhms |
Voltage | Volts | 0-5V |
6.1.9.2 Connecting the sensor
Connect the sensor in the GSR connector indicated in the MySignals Hardware board. The sensor cable have only one way of connection to prevent errors and make the connection easier.
Connect the GSR lead to the electrodes.
Place the electrodes as shown below.
The galvanic skin sensor has two contacts and it works like a ohmmeter measuring the resistance of the materials. Place your fingers in the metallic contacts and tighten the velcro as shown in the image below.
After a few seconds you will get the values in the visualization method programmed.
6.1.9.3 SDK functins
Getting data
With this simple functions we can read the value of the sensor. The library returns the value of the skin resistance and the skin conductance.
{ // Returns GSR value in a specific format //(VOLTAGE) - in Volts (0-5V) //(DATA) - in digital value (0-1023) float getGSR(uint8_t format); // Returns GSR in DATA format float getGSR(void); // Returns GSR value after applying measuring filter float getCalibratedGSR(uint8_t samples, uint16_t delaySample, float offset, uint8_t format); }
6.1.9.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float conductance = MySignals.getGSR(CONDUCTANCE); float resistance = MySignals.getGSR(RESISTANCE); float conductanceVol = MySignals.getGSR(VOLTAGE); Serial.print("Conductance : "); Serial.print(conductance, 2); Serial.println(""); Serial.print("Resistance : "); Serial.print(resistance, 2); Serial.println(""); Serial.print("Conductance Voltage : "); Serial.print(conductanceVol, 4); Serial.println(""); Serial.print("\n"); // wait for a second delay(1000); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
Calibrated example
This example configure the sensor and read the numeric parameters. In this example a specific calibration function is used in the measure.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float conductance = MySignals.getCalibratedGSR(100, 1, 0, CONDUCTANCE); float resistance = MySignals.getCalibratedGSR(100, 1, 0, RESISTANCE); float conductanceVol = MySignals.getCalibratedGSR(100, 1, 0, VOLTAGE); Serial.print("Conductance : "); Serial.print(conductance, 2); Serial.println(""); Serial.print("Resistance : "); Serial.print(resistance, 2); Serial.println(""); Serial.print("Conductance Voltage : "); Serial.print(conductanceVol, 4); Serial.println(""); Serial.print("\n"); // wait for a second delay(1000); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
KST example
This example configure the sensor and send the data to KST. KST program shows the sensor value wave.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" extern volatile unsigned long timer0_overflow_count; float fanalog0; int analog0; unsigned long time; byte serialByte; void setup() { Serial.begin(9600); MySignals.begin(); Serial.println("Starting..."); } void loop() { while (Serial.available()>0) { serialByte=Serial.read(); if (serialByte=='C'){ while(1){ fanalog0 = MySignals.getGSR(CONDUCTANCE); // Use the timer0 => 1 tick every 4 us time=(timer0_overflow_count << 8) + TCNT0; // Microseconds conversion. time=time*4; //Print in a file for simulation Serial.print(time); Serial.print(";"); Serial.println(fanalog0,5); if (Serial.available() > 0){ serialByte=Serial.read(); if (serialByte=='F') break; } } } } }
Upload the code to Arduino and follow the KST configuration steps available in the KST section.
Graphic Arduino example
This example configure the sensor and send the data to Arduino Graphic Tool. Graphic Tool integrated in Arduino IDE shows the sensor value wave.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { int valRead = (uint16_t)MySignals.getGSR(DATA); Serial.println(valRead); delay(20); }
Upload the code to Arduino and follow the Graphic Arduino tool configuration steps available in the Graphic Tool section.
Wave example
This example configure and read the sensor. Then use the Serial monitor to represent this values in a basic wave.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { int valRead = (uint16_t)MySignals.getGSR(DATA); MySignals.printWave(valRead); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT Example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #define graphic_low_extrem 230 #define graphic_high_extrem 30 #define graphic_left_extrem 0 #define graphic_right_extrem 320 Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //! It stores the current value of x position in the LCD. uint16_t graphic_x; //! It stores the current value of the MySignals. uint16_t valRead; //! It stores the previous value of the MySignals. uint16_t graphic_prevRead; void setup(void) { Serial.begin(115200); MySignals.begin(); tft.init(); tft.setRotation(3); tft.fillScreen(ILI9341_WHITE); tft.fillRect(0,0,320,30,ILI9341_RED); tft.setTextColor(ILI9341_WHITE); tft.drawString("GSR",5,5,4); } void loop() { valRead = (uint16_t)MySignals.getGSR(DATA); Serial.println(valRead); valRead = map(valRead, 100, 250, graphic_low_extrem, graphic_high_extrem); printGraphic(valRead, 0); } void printGraphic(uint16_t value, uint8_t delay_time) { if (value < graphic_high_extrem) { value = graphic_high_extrem; } if (value > graphic_low_extrem) { value = graphic_low_extrem; } //Pinta la linea solo a partir de que ya exista al menos 1 valor if (graphic_x > graphic_left_extrem + 1) { tft.drawLine(graphic_x - 1, graphic_prevRead, graphic_x, value, ILI9341_RED); } //Wave refresh (barre pantalla pintando una linea) tft.drawLine(graphic_x + 1, graphic_high_extrem, graphic_x + 1, graphic_low_extrem, ILI9341_WHITE); graphic_prevRead = value; graphic_x++; delay(delay_time); if (graphic_x == graphic_right_extrem) { graphic_x = graphic_left_extrem; } SPI.end(); }
Upload the code to Arduino. Here is the TFT output.
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
Positions and movements made because of their relationships to particular diseases (i.e., sleep apnea and restless legs syndrome). Analyzing movements during sleep also helps in determining sleep quality and irregular sleeping patterns. The body position sensor could help also to detect fainting or falling of elderly people or persons with disabilities.
6.1.10.1 Sensor features
Description: The Patient Position Sensor (Accelerometer) monitors five different patient positions (standing/sitting, supine, prone, left and right.). Body Position Sensor uses a triple axis accelerometer to obtain the patient's position.
Body Position Sensor uses a triple axis accelerometer to obtain the patient's position. It is an ultra small triaxial, low-g acceleration sensor I2C interface, aiming for lowpower consumer market applications. It allows measurement of accelerations in 3 perpendicular axes and thus senses tilt, motion, shock and vibration in cell phones, handhelds, computer peripherals, man-machine interfaces, virtual reality features and game controllers. The sensor needs to be connected to the specific Body Position jack connector in MySignals board and it works with direct connector power supply.
The sensor needs to be connected to the specific body position jack connector in MySignals board and it works with direct connector power supply.
Body positions:
Measurement:
Parameter | Unit | Range |
Body Position | Human Body Position | 5 different positions |
6.1.10.2 Connecting the sensor
+Connect the jack sensor in the Body Position connector indicated in the MySignals Hardware board. The sensor cable have only one way of connection to prevent errors and make the connection easier.
Place the tape around the chest and the connector placed down
After a few seconds you will get the values in the visualization method programmed.
6.1.10.3 SDK functins
Initializing sensor
Before start using the sensor, we have to initialize some parameters. Use the next function to configure the sensor.
{ // Initializes the position sensor and configure some values void initBodyPosition(void); }
Getting data
The next functions return the a value that represent the body position stored in private variables of the e-Health class.
{ // Returns the body position //1 == Supine position //2 == Left lateral decubitus //3 == Rigth lateral decubitus //4 == Prone position //5 == Stand or sit position uint8_t getBodyPosition(void); // Prints the current body position void printPosition(uint8_t position); // Prints the current body position acceleration void getAcceleration(); }
The position of the patient:
6.1.10.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include <Wire.h> #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); MySignals.initBodyPosition(); } void loop() { uint8_t position = MySignals.getBodyPosition(); Serial.print("Current position : "); //print body position MySignals.printPosition(position); delay(100); //print acc values MySignals.getAcceleration(); // convert float to strintg char bufferAcc[50]; char x_acc_string[10]; char y_acc_string[10]; char z_acc_string[10]; dtostrf (MySignals.x_data, 2, 2, x_acc_string); dtostrf (MySignals.y_data, 2, 2, y_acc_string); dtostrf (MySignals.z_data, 2, 2, z_acc_string); // print the X Y Z acceleration sprintf (bufferAcc, "Acceleration: X= %s Y= %s Z= %s ", x_acc_string, y_acc_string, z_acc_string); Serial.println(bufferAcc); delay(1000); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #define graphic_low_extrem 230 #define graphic_high_extrem 30 #define graphic_left_extrem 0 #define graphic_right_extrem 320 Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //! It stores the current value of x position in the LCD. uint16_t graphic_x; //! It stores the current value of the MySignals. uint16_t valRead; //! It stores the previous value of the MySignals. uint16_t graphic_prevRead; void setup(void) { Serial.begin(115200); MySignals.begin(); MySignals.initBodyPosition(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); } void loop() { tft.drawString("Body position:", 0, 0, 2); uint8_t position = MySignals.getBodyPosition(); if (position == 1) { tft.drawString("Prone position", 0, 30, 2); } else if (position == 2) { tft.drawString("Left lateral ", 0, 30, 2); } else if (position == 3) { tft.drawString("Rigth lateral ", 0, 30, 2); } else if (position == 4) { tft.drawString("Supine position ", 0, 30, 2); } else if (position == 5) { tft.drawString("Stand or sit ", 0, 30, 2); } else { tft.drawString("non-defined ", 0, 30, 2); } SPI.end(); }
Upload the code to Arduino. Here is the TFT output.
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
Snoring is a major symptom of obstructive sleep apnea (OSA). In most sleep studies, snoring is detected with a microphone. Since these studies analyze the acoustic properties of snoring, they need to acquire data at high sampling rates, so a large amount of data should be processed. Recently, several sleep studies have monitored snoring using a piezo snoring sensor. However, an automatic method for snoring detection using a piezo snoring sensor has not been reported in the literature. This study proposed the HMM-based method to detect snoring using this sensor, which is attached to the neck. The data from 21 patients with OSA were gathered for training and test sets. The short-time Fourier transform and short-time energy were computed so they could be applied to HMMs. The data were classified as snoring, noise and silence according to their HMMs. As a result, the sensitivity and the positive predictability values were 93.3% and 99.1% for snoring detection, respectively. The results demonstrated that the method produced simple, portable and user-friendly detection tools that provide an alternative to the microphone-based method.
6.1.11.1 Sensor features
Description: This sensor attaches to the neck and records vibration. The sensor converts snoring, and other sounds in the audio range picked up through the skin, to a small analog voltage that provides a clear, reliable indication of the presence of these sounds.
Sound is absorbed via vibrations from the throat and transferred to the device which is then converted into analog signal. So, the throat method eliminates most background noise whether in the battle field or on the job site.
Snore sensor maintains constant contact with the patient's skin throughout movements or sweating so that you will consistently receive quality signals throughout the night with little to no artifact.
Vibration-type sensor unit:
The sensor needs to be connected to the specific Snore double jack connector in MySignals board and it works with direct connector power supply.
Measurement:
Parameter | Unit | Range |
Snore rate | SPM (Snores per minute) | 0-60 spm |
Snore signal | Volts | 0-5V |
6.1.11.2 Connecting the sensor
Connect the sensor in the snore double connector indicated in the MySignals Hardware board. The sensor cable have only one way of connection to prevent errors and make the connection easier.
Place the sensor in your neck as you can see in the next image. You can use the translucent earbud speaker in your ear in order to detect acoustic alerts or messages.
Use your finger to press the Snore button if you want to use it.
After a few seconds you will get the values in the visualization method programmed.
6.1.11.3 SDK functins
Initializing sensorInitializes the snore sensor and configures the snore amplification gain
{ // Initializes the snore sensor and configures the snore amplification gain void initSnore(uint8_t gain); }
Configuring sensor
Configures the snore amplification gain
{ // Configures the snore amplification gain void setSnoreGain(uint8_t gain); }
Getting data
{ // Returns Snore value in a specific format //(VOLTAGE) - in Volts (0-5V) //(DATA) - in digital value (0-1023) float getSnore(uint8_t format); // Returns Snore in DATA format float getSnore(void); // Returns Snore value after applying measuring filter float getCalibratedSnore(uint8_t samples, uint16_t delaySample, float offset, uint8_t format); // Calculates Snore SPM void snoreSPM(void); }
Additional uses
{ // Reproduces a tone in a specific frequency and duration in the snore sensor earphone void playSoundSnore(uint16_t frequency, uint16_t duration); // Gets the state of the digital button in snore sensor bool getButtonSnore(void); }
6.1.11.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); MySignals.initSnore(30); } void loop() { float snore = MySignals.getSnore(VOLTAGE); Serial.print("Snore value : "); Serial.print(snore, 2); Serial.println(" V"); delay(10); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
Calibrated example
This example configure the sensor and read the numeric parameters. In this example a specific calibration function is used in the measure.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); MySignals.initSnore(30); } void loop() { float snore = MySignals.getCalibratedSnore(5,0,0,DATA); Serial.print("Snore value : "); Serial.print(snore, 2); Serial.println(" V"); delay(10); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
KST example
This example configure the sensor and send the data to KST. KST program shows the sensor value wave.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MyHospital.h> #include "Wire.h" #include "SPI.h" extern volatile unsigned long timer0_overflow_count; float fanalog0; int analog0; unsigned long time; byte serialByte; void setup() { Serial.begin(9600); MySignals.begin(); Serial.println("Starting..."); MySignals.initSnore(30); } void loop() { while (Serial.available()>0) { serialByte=Serial.read(); if (serialByte=='C'){ while(1){ fanalog0=MySignals.getSnore(DATA); // Use the timer0 => 1 tick every 4 us time=(timer0_overflow_count << 8) + TCNT0; // Microseconds conversion. time=(time*4); //Print in a file for simulation Serial.print(time); Serial.print(";"); Serial.println(fanalog0,5); if (Serial.available()>0){ serialByte=Serial.read(); if (serialByte=='F') break; } } } } }
Upload the code to Arduino and follow the KST configuration steps available in the KST section.
Graphic Arduino example
This example configure the sensor and send the data to Arduino Graphic Tool. Graphic Tool integrated in Arduino IDE shows the sensor value wave.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); MySignals.initSnore(30); } void loop() { uint16_t snore = MySignals.getSnore(DATA); Serial.println(snore); delay(20); }
The Arduino code used in this program is presented next:
Wave example
This example configure and read the sensor. Then use the Serial monitor to represent this values in a basic wave.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); MySignals.initSnore(0); } void loop() { float snore = MySignals.getSnore(DATA); MySignals.printWave(snore); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #define graphic_low_extrem 230 #define graphic_high_extrem 30 #define graphic_left_extrem 0 #define graphic_right_extrem 320 Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //! It stores the current value of x position in the LCD. uint16_t graphic_x; //! It stores the current value of the MySignals. uint16_t valRead; //! It stores the previous value of the MySignals. uint16_t graphic_prevRead; void setup(void) { Serial.begin(115200); MySignals.begin(); MySignals.initSnore(40); tft.init(); tft.setRotation(3); tft.fillScreen(ILI9341_WHITE); tft.fillRect(0,0,320,30,ILI9341_RED); tft.setTextColor(ILI9341_WHITE); tft.drawString("Snore",5,5,4); } void loop() { valRead = (uint16_t)MySignals.getSnore(DATA); valRead = map(valRead, 0, 1023, 230, 30); printGraphic(valRead, 0); } void printGraphic(uint16_t value, uint8_t delay_time) { if (value < graphic_high_extrem) { value = graphic_high_extrem; } if (value > graphic_low_extrem) { value = graphic_low_extrem; } //Pinta la linea solo a partir de que ya exista al menos 1 valor if (graphic_x > graphic_left_extrem + 1) { tft.drawLine(graphic_x - 1, graphic_prevRead, graphic_x, value, ILI9341_RED); } //Wave refresh (barre pantalla pintando una linea) tft.drawLine(graphic_x + 1, graphic_high_extrem, graphic_x + 1, graphic_low_extrem, ILI9341_WHITE); graphic_prevRead = value; graphic_x++; delay(delay_time); if (graphic_x == graphic_right_extrem) { graphic_x = graphic_left_extrem; } SPI.end(); }
Upload the code to Arduino. Here is the TFT output.
Other examples
This example use the button integrated with the Snore sensor.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { if(MySignals.getButtonSnore() == LOW) { Serial.println("Button pressed"); delay(10); } }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
This example use the speaker integrated with the Snore sensor.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { MySignals.begin(); } void loop() { MySignals.playSoundSnore(200,100); }
Upload the code to Arduino and press the button.
This example use digital potentiometer integrated with the Snore circuit to adjust the gain of the sensor.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); int gain = 30; MySignals.initSnore(gain); Serial.print(F("Gain:")); Serial.println(gain); } void loop() { }
MySignals APP
This is an example of sensor viewing in MySignals APP Mode.
First of all select the sensor that you want to measure in the Select Sensors screen. Use your smartphone touchscreen pressing in the correct symbol. You can see the selected sensors logos in blue color.
Then you can go to General Sensor screen using the left down corner logo. MySignals will start to monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Web Server
This is an example of sensor viewing in MySignals Web Server Mode.
First of all choose the sensor that you want to visualize. You can use the fast menu situated in the left side of the Web Server. Choose a user or a device.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
MySignals Hardware Development Platform can work with 4 different wireless biometric sensors using BLE connectivity.
My Signals can work too with a EEG optional BT2.0 device. If you are interested in this sensor, please contact with our commercial department.
Weighing scales (or weigh scales or scales) are devices to measure weight or calculate mass. Spring balances or spring scales measure weight (force) by balancing the force due to gravity against the force on a spring, whereas a balance or pair of scales using a balance beam compares masses by balancing the weight due to the mass of an object against the weight of a known mass or masses.
Sensor features
Weighing scales (or weigh scales or scales) are devices to measure weight or calculate mass. Spring balances or spring scales measure weight (force) by balancing the force due to gravity against the force on a spring, whereas a balance or pair of scales using a balance beam compares masses by balancing the weight due to the mass of an object against the weight of a known mass or masses.
5.2.1.1 Sensor features
Description: Multipurpose personal portable digital weight health body scale.
Monitor your body weight like never before with a digital wireless body fat monitor. This bathroom scale uses a BLE connection to sync your weight, BMI, and body fat readings with your personal health dashboard.
Max Capacity : 150kg/330lb
Display Readability : 0.1kg/0.2lb
Weighing Units : kg. lb. st
Platform : Tempered Glass + 18/8 SS
LED Display
The sensor works with internal batteries.
Measurement:
Parameter | Unit | Range |
Weight | Kilograms | 5-150Kg |
Bone | Percentage | 0-100% |
Body fat | Percentage | 0-100% |
Muscle mass | Percentage | 0-100% |
Body water | Percentage | 0-100% |
Visceral fat | Percentage | 0-100% |
BMI | Kcal | 0-500Kcal |
BMR | Kcal | 0-500Kcal |
6.2.1.2 Connecting the sensor
This sensor have not cable. This sensor send the data wirelessly to MySignals board.
This scale is available in kg or lb. You can set to the one you prefer by pressing the unit conversion button on the back of the scale (picture shown on the left). Press the unit conversion button when scale is powered off. LCD shows current weight unit. Press the button again to convert to another weight unit.
It is really important to remove your shoes and socks before stepping on the scale especially when you are using the scale in body analysis weighing mode. Assure that your feet are well positioned on the metallic sensors, otherwise the scale will not be able to determine your body composition.
The sensor will begin to make a measurement. In order to measure correctly is important to maintain body in the correct position.
Wait until MySignals program indicate that it is connected with the BLE sensor.
Do not make abrupt movements or the measure will be not reliable.
The Body Scale will take a few moments to calculate the human body reading and send them wirelessly.
After a few seconds you will get the values in the visualization method programmed.
Setting personal parameters
The first time you turn on your scale, it have defined default parameters (Gender, Height, Age...). Parameters can be set using MySignals APP.
6.2.1.3 SDK functions
The BLE sensor use a complex Bluetooth connection in order to obtain the value measured. There are several examples about how to write and read the correct attributes.
6.2.1.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include <MySignals_BLE.h> // Write here the MAC address of BLE device to find char MAC_SCALE[14] = "8CDE5260BCEF"; //Scale User profile uint8_t user_gender = 1; //1-Male 0-Female uint8_t user_height = 175; //in cm (0-255) uint8_t user_age = 29; //(0-255) uint8_t available_scale = 0; uint8_t connected_scale = 0; uint8_t connection_handle_scale = 0; #define SCALE_HANDLE 83 #define SCALE_PROFILE_HANDLE 85 //!Struct to store data of the glucometer. struct scaleDataVector { uint16_t weight; uint16_t bodyfat; uint16_t musclemass; uint16_t water; uint16_t calories; uint8_t visceralfat; uint8_t bonemass; }; //!Vector to store the glucometer measures and dates. scaleDataVector scaleData; void setup() { MySignals.begin(); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { MySignals.println("BLE init ok"); } else { MySignals.println("BLE init fail"); while (1) { }; } } else { MySignals.println("BLE init fail"); while (1) { }; } } void loop() { available_scale = MySignals_BLE.scanDevice(MAC_SCALE, 1000, TX_POWER_MAX); MySignals.disableMuxUART(); Serial.print("Scale available:"); Serial.println(available_scale); MySignals.enableMuxUART(); if (available_scale == 1) { if (MySignals_BLE.connectDirect(MAC_SCALE) == 1) { MySignals.println("Connected"); connected_scale = 1; delay(500); uint8_t attributeData[2] = { 0x01 , 0x00 }; if (MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, SCALE_HANDLE, attributeData, 2) == 0) { MySignals.println("Subscribed"); delay(4000); uint8_t scale_user_profile[8] = { 0xfe, // 0 BYTE 1 0x00, // 1 BYTE 2 -> user group 0x00, // 2 BYTE 3 -> gender 0x00, // 3 BYTE 4 -> level 0x00, // 4 BYTE 5 -> height 0x00, // 5 BYTE 6 -> age 0x00, // 6 BYTE 7 -> unit 0x00 // 7 BYTE 8 -> xor }; scale_user_profile[1] = 1; // User group scale_user_profile[2] = user_gender; // gender: 1=male, 0=female scale_user_profile[3] = 0; // level 0=normal scale_user_profile[4] = user_height; // height scale_user_profile[5] = user_age; // age scale_user_profile[6] = 1; // unit KG uint8_t xor_result = scale_user_profile[1] xor scale_user_profile[2]; xor_result = xor_result xor scale_user_profile[3]; xor_result = xor_result xor scale_user_profile[4]; xor_result = xor_result xor scale_user_profile[5]; scale_user_profile[7] = xor_result xor scale_user_profile[6]; if (MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, SCALE_PROFILE_HANDLE, scale_user_profile, 8) == 0) { delay(500); unsigned long previous = millis(); do { if (MySignals_BLE.waitEvent(1000) == BLE_EVENT_ATTCLIENT_ATTRIBUTE_VALUE) { uint8_t scale_weight_high = MySignals_BLE.event[13]; uint8_t scale_weight_low = MySignals_BLE.event[14]; uint8_t scale_bodyfat_high = MySignals_BLE.event[15]; uint8_t scale_bodyfat_low = MySignals_BLE.event[16]; uint8_t scale_musclemass_high = MySignals_BLE.event[18]; uint8_t scale_musclemass_low = MySignals_BLE.event[19]; scaleData.visceralfat = MySignals_BLE.event[20]; uint8_t scale_water_high = MySignals_BLE.event[21]; uint8_t scale_water_low = MySignals_BLE.event[22]; uint8_t scale_calories_high = MySignals_BLE.event[23]; uint8_t scale_calories_low = MySignals_BLE.event[24]; scaleData.weight = (scale_weight_high * 256) + scale_weight_low; scaleData.bodyfat = (scale_bodyfat_high * 256) + scale_bodyfat_low; scaleData.musclemass = (scale_musclemass_high * 256) + scale_musclemass_low; scaleData.water = (scale_water_high * 256) + scale_water_low; scaleData.calories = (scale_calories_high * 256) + scale_calories_low; scaleData.bonemass = MySignals_BLE.event[17] * 1000 / scaleData.weight; MySignals.disableMuxUART(); Serial.println(); Serial.print(F("Weight: ")); Serial.print((float(scaleData.weight) / 10), 1); Serial.println(F("Kg")); Serial.print(F("Body fat: ")); Serial.print((float(scaleData.bodyfat) / 10), 1); Serial.println(F("%")); Serial.print(F("Bone mass: ")); Serial.print((float(scaleData.bonemass) / 10), 1); Serial.println(F("%")); Serial.print(F("Muscle mass: ")); Serial.print((float(scaleData.musclemass) / 10), 1); Serial.println(F("%")); Serial.print(F("Visceral fat: ")); Serial.print(scaleData.visceralfat); Serial.println(F("%")); Serial.print(F("Water percentage: ")); Serial.print((float(scaleData.water) / 10), 1); Serial.println(F("%")); Serial.print(F("Calories: ")); Serial.print(scaleData.calories); Serial.println(F("Kcal")); MySignals.enableMuxUART(); delay(1000); uint8_t shutdown_command[8] = { 0xfd, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35 }; MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, SCALE_PROFILE_HANDLE, shutdown_command, 8); MySignals_BLE.disconnect(MySignals_BLE.connection_handle); delay(200); connected_scale = 0; } } while ((connected_scale == 1) && ((millis() - previous) < 20000)); connected_scale = 0; } else { MySignals.println("Error subscribing"); } } else { MySignals.println("Error subscribing"); } } else { connected_scale = 0; MySignals.println("Not Connected"); } } else if (available_scale == 0) { //Do nothing } else { MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); delay(100); } delay(1000); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <MySignals_BLE.h> // Write here the MAC address of BLE device to find char MAC_SCALE[14] = "8CDE5260BCEF"; //Scale User profile uint8_t user_gender = 1; //1-Male 0-Female uint8_t user_height = 175; //in cm (0-255) uint8_t user_age = 29; //(0-255) uint8_t available_scale = 0; uint8_t connected_scale = 0; uint8_t connection_handle_scale = 0; #define SCALE_HANDLE 83 #define SCALE_PROFILE_HANDLE 85 char buffer_tft[30]; Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //!Struct to store data of the glucometer. struct scaleDataVector { uint16_t weight; uint16_t bodyfat; uint16_t musclemass; uint16_t water; uint16_t calories; uint8_t visceralfat; uint8_t bonemass; }; //!Vector to store the glucometer measures and dates. scaleDataVector scaleData; void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); //TFT message: Welcome to MySignals strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[0]))); tft.drawString(buffer_tft, 0, 0, 2); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { //TFT message: "BLE init ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[1]))); tft.drawString(buffer_tft, 0, 15, 2); } else { //TFT message:"BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } else { //TFT message: "BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } void loop() { available_scale = MySignals_BLE.scanDevice(MAC_SCALE, 1000, TX_POWER_MAX); tft.drawString("Scale available:", 0, 30, 2); tft.drawNumber(available_scale, 110, 30, 2); if (available_scale == 1) { if (MySignals_BLE.connectDirect(MAC_SCALE) == 1) { tft.drawString("Connected ", 0, 45, 2); connected_scale = 1; delay(500); uint8_t attributeData[2] = { 0x01 , 0x00 }; if (MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, SCALE_HANDLE, attributeData, 2) == 0) { tft.drawString("Subscribed", 0, 60, 2); delay(4000); uint8_t scale_user_profile[8] = { 0xfe, // 0 BYTE 1 0x00, // 1 BYTE 2 -> user group 0x00, // 2 BYTE 3 -> gender 0x00, // 3 BYTE 4 -> level 0x00, // 4 BYTE 5 -> height 0x00, // 5 BYTE 6 -> age 0x00, // 6 BYTE 7 -> unit 0x00 // 7 BYTE 8 -> xor }; scale_user_profile[1] = 1; // User group scale_user_profile[2] = user_gender; // gender: 1=male, 0=female scale_user_profile[3] = 0; // level 0=normal scale_user_profile[4] = user_height; // height scale_user_profile[5] = user_age; // age scale_user_profile[6] = 1; // unit KG uint8_t xor_result = scale_user_profile[1] xor scale_user_profile[2]; xor_result = xor_result xor scale_user_profile[3]; xor_result = xor_result xor scale_user_profile[4]; xor_result = xor_result xor scale_user_profile[5]; scale_user_profile[7] = xor_result xor scale_user_profile[6]; if (MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, SCALE_PROFILE_HANDLE, scale_user_profile, 8) == 0) { delay(500); unsigned long previous = millis(); do { if (MySignals_BLE.waitEvent(1000) == BLE_EVENT_ATTCLIENT_ATTRIBUTE_VALUE) { uint8_t scale_weight_high = MySignals_BLE.event[13]; uint8_t scale_weight_low = MySignals_BLE.event[14]; uint8_t scale_bodyfat_high = MySignals_BLE.event[15]; uint8_t scale_bodyfat_low = MySignals_BLE.event[16]; uint8_t scale_musclemass_high = MySignals_BLE.event[18]; uint8_t scale_musclemass_low = MySignals_BLE.event[19]; scaleData.visceralfat = MySignals_BLE.event[20]; uint8_t scale_water_high = MySignals_BLE.event[21]; uint8_t scale_water_low = MySignals_BLE.event[22]; uint8_t scale_calories_high = MySignals_BLE.event[23]; uint8_t scale_calories_low = MySignals_BLE.event[24]; scaleData.weight = (scale_weight_high * 256) + scale_weight_low; scaleData.bodyfat = (scale_bodyfat_high * 256) + scale_bodyfat_low; scaleData.musclemass = (scale_musclemass_high * 256) + scale_musclemass_low; scaleData.water = (scale_water_high * 256) + scale_water_low; scaleData.calories = (scale_calories_high * 256) + scale_calories_low; scaleData.bonemass = MySignals_BLE.event[17] * 1000 / scaleData.weight; tft.drawString("Weight:", 0, 75, 2); tft.drawFloat((scaleData.weight / 10.0), 1, 100, 75, 2); tft.drawString("Body fat:", 0, 90, 2); tft.drawFloat((scaleData.bodyfat / 10.0), 1, 100, 90, 2); tft.drawString("Muscle mass:", 0, 105, 2); tft.drawFloat((scaleData.musclemass / 10.0), 1, 100, 105, 2); tft.drawString("Visceral fat:", 0, 120, 2); tft.drawNumber(scaleData.visceralfat, 100, 120, 2); tft.drawString("Water:", 0, 135, 2); tft.drawFloat((scaleData.water / 10.0), 1, 100, 135, 2); tft.drawString("Calories:", 0, 150, 2); tft.drawNumber(scaleData.calories, 100, 150, 2); tft.drawString("Bone mass:", 0, 165, 2); tft.drawFloat((scaleData.bonemass / 10.0), 1, 100, 165, 2); delay(1000); uint8_t shutdown_command[8] = { 0xfd, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35 }; MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, SCALE_PROFILE_HANDLE, shutdown_command, 8); MySignals_BLE.disconnect(MySignals_BLE.connection_handle); delay(200); connected_scale = 0; } } while ((connected_scale == 1) && ((millis() - previous) < 20000)); connected_scale = 0; } else { tft.drawString("Error subscribing", 0, 60, 2); } } else { tft.drawString("Not Connected", 0, 45, 2); } } else { connected_scale = 0; tft.drawString("Not Connected", 0, 45, 2); } } else if (available_scale == 0) { //Do nothing } else { MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); delay(100); } delay(1000); }
Upload the code to Arduino. Here is the TFT output.
6.2.2.1 Sensor features
Description: Pulse oximetry a noninvasive method of indicating the arterial oxygen saturation of functional hemoglobin.
Oxygen saturation is defined as the measurement of the amount of oxygen dissolved in blood, based on the detection of Hemoglobin and Deoxyhemoglobin. Two different light wavelengths are used to measure the actual difference in the absorption spectra of HbO2 and Hb. The bloodstream is affected by the concentration of HbO2 and Hb, and their absorption coefficients are measured using two wavelengths 660 nm (red light spectra) and 940 nm (infrared light spectra). Deoxygenated and oxygenated hemoglobin absorb different wavelengths.
Deoxygenated hemoglobin (Hb) has a higher absorption at 660 nm and oxygenated hemoglobin (HbO2) has a higher absorption at 940 nm . Then a photo-detector perceives the non-absorbed light from the LEDs to calculate the arterial oxygen saturation.
A pulse oximeter sensor is useful in any setting where a patient's oxygenation is unstable, including intensive care, operating, recovery, emergency and hospital ward settings, pilots in unpressurized aircraft, for assessment of any patient's oxygenation, and determining the effectiveness of or need for supplemental oxygen.
Acceptable normal ranges for patients are from 95 to 99 percent, those with a hypoxic drive problem would expect values to be between 88 to 94 percent, values of 100 percent can indicate carbon monoxide poisoning.
The sensor needs to be connected to the specific SPO2 jack connector in MySignals board and it works with direct connector power supply.
Measurement:
Parameter | Unit | Range |
Pulse | ppm | 25~250 ppm |
SPO2 | % | 35-100% |
6.2.2.2 Connecting the sensor
This sensor have not cable. This sensor send the data wirelessly to MySignals board.
Place the SPO2 on your finger as shown in the image below.
Turn on the SPO2 (press ON button). The sensor will begin to make a measurement. In order to measure correctly is important to maintain finger in the correct position.
Wait until MySignals program indicate that it is connected with the BLE sensor.
Do not make abrupt movements or the measure will be not reliable.
The SPO2 will take a few moments to calculate the pulsioximeter reading and send them wirelessly
After a few seconds you will get the values in the visualization method programmed.
6.2.2.3 SDK functions
The BLE sensor use a complex Bluetooth connection in order to obtain the value measured. There are several examples about how to write and read the correct attributes.
6.2.2.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include <MySignals_BLE.h> // Write here the MAC address of BLE device to find char MAC_SPO2[14] = "00A0500E1823"; uint8_t available_spo2 = 0; uint8_t connected_spo2 = 0; uint8_t connection_handle_spo2 = 0; uint8_t pulse_spo2 = 0; uint8_t spo2 = 0; #define SPO2_HANDLE 15 void setup() { MySignals.begin(); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { MySignals.println("BLE init ok"); } else { MySignals.println("BLE init fail"); while (1) { }; } } else { MySignals.println("BLE init fail"); while (1) { }; } } void loop() { available_spo2 = MySignals_BLE.scanDevice(MAC_SPO2, 1000, TX_POWER_MAX); MySignals.disableMuxUART(); Serial.print("SPO2 available:"); Serial.println(available_spo2); MySignals.enableMuxUART(); if (available_spo2 == 1) { MySignals.disableMuxUART(); Serial.println("SPO2 found.Connecting"); MySignals.enableMuxUART(); if (MySignals_BLE.connectDirect(MAC_SPO2) == 1) { connected_spo2 = 1; connection_handle_spo2 = MySignals_BLE.connection_handle; MySignals.println("Connected"); delay(6000); //To subscribe the spo2 measure write "1" in SPO2_HANDLE char attributeData[1] = { 0x01 }; if (MySignals_BLE.attributeWrite(connection_handle_spo2, SPO2_HANDLE, attributeData, 1) == 0) { unsigned long previous = millis(); do { if (MySignals_BLE.waitEvent(1000) == BLE_EVENT_ATTCLIENT_ATTRIBUTE_VALUE) { char attributeData[1] = { 0x00 }; MySignals_BLE.attributeWrite(connection_handle_spo2, SPO2_HANDLE, attributeData , 1); uint8_t pulse_low = MySignals_BLE.event[12]; pulse_low &= 0b01111111; uint8_t pulse_high = MySignals_BLE.event[11]; pulse_high &= 0b01000000; if (pulse_high == 0) { pulse_spo2 = pulse_low; } if (pulse_high == 0b01000000) { pulse_spo2 = pulse_low + 0b10000000; } spo2 = MySignals_BLE.event[13]; spo2 &= 0b01111111; if ((pulse_spo2 >= 25) && (pulse_spo2 <= 250) && (pulse_spo2 >= 35) && (pulse_spo2 <= 100)) { MySignals.disableMuxUART(); Serial.println(); Serial.print(F("SpO2: ")); Serial.print(spo2); Serial.print(F("% ")); Serial.print(F("Pulse: ")); Serial.print(pulse_spo2); Serial.println(F("ppm ")); uint16_t errorCode = MySignals_BLE.disconnect(connection_handle_spo2); Serial.print(F("Disconnecting error code: ")); Serial.println(errorCode, HEX); MySignals.enableMuxUART(); connected_spo2 = 0; } } } while ((connected_spo2 == 1) && ((millis() - previous) < 10000)); connected_spo2 = 0; } else { MySignals.println("Error subscribing"); } } else { connected_spo2 = 0; MySignals.println("Not Connected"); } } else if (available_spo2 == 0) { //Do nothing } else { MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); delay(100); } delay(1000); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <MySignals_BLE.h> // Write here the MAC address of BLE device to find char MAC_SPO2[14] = "00A0500E1823"; uint8_t available_spo2 = 0; uint8_t connected_spo2 = 0; uint8_t connection_handle_spo2 = 0; uint8_t pulse_spo2 = 0; uint8_t spo2 = 0; #define SPO2_HANDLE 15 char buffer_tft[30]; Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); //TFT message: Welcome to MySignals strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[0]))); tft.drawString(buffer_tft, 0, 0, 2); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { //TFT message: "BLE init ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[1]))); tft.drawString(buffer_tft, 0, 15, 2); } else { //TFT message:"BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } else { //TFT message: "BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } void loop() { available_spo2 = MySignals_BLE.scanDevice(MAC_SPO2, 1000, TX_POWER_MAX); tft.drawString("SPO2 available:", 0, 30, 2); tft.drawNumber(available_spo2, 110, 30, 2); if (available_spo2 == 1) { if (MySignals_BLE.connectDirect(MAC_SPO2) == 1) { connected_spo2 = 1; connection_handle_spo2 = MySignals_BLE.connection_handle; tft.drawString("Connected ", 0, 45, 2); delay(6000); //To subscribe the spo2 measure write "1" in SPO2_HANDLE char attributeData[1] = { 0x01 }; if (MySignals_BLE.attributeWrite(connection_handle_spo2, SPO2_HANDLE, attributeData, 1) == 0) { tft.drawString("Subscribed", 0, 60, 2); unsigned long previous = millis(); do { if (MySignals_BLE.waitEvent(1000) == BLE_EVENT_ATTCLIENT_ATTRIBUTE_VALUE) { char attributeData[1] = { 0x00 }; MySignals_BLE.attributeWrite(connection_handle_spo2, SPO2_HANDLE, attributeData , 1); uint8_t pulse_low = MySignals_BLE.event[12]; pulse_low &= 0b01111111; uint8_t pulse_high = MySignals_BLE.event[11]; pulse_high &= 0b01000000; if (pulse_high == 0) { pulse_spo2 = pulse_low; } if (pulse_high == 0b01000000) { pulse_spo2 = pulse_low + 0b10000000; } spo2 = MySignals_BLE.event[13]; spo2 &= 0b01111111; if ((pulse_spo2 >= 25) && (pulse_spo2 <= 250) && (pulse_spo2 >= 35) && (pulse_spo2 <= 100)) { sprintf(buffer_tft, "Pulse: %d ppm / SPO2: %d", pulse_spo2, spo2); tft.drawString(buffer_tft, 0, 75, 2); uint16_t errorCode = MySignals_BLE.disconnect(connection_handle_spo2); tft.drawString("Disconnected", 0, 45, 2); connected_spo2 = 0; } } } while ((connected_spo2 == 1) && ((millis() - previous) < 10000)); connected_spo2 = 0; } else { tft.drawString("Error subscribing", 0, 60, 2); } } else { connected_spo2 = 0; tft.drawString("Not Connected", 0, 45, 2); } } else if (available_spo2 == 0) { //Do nothing } else { MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); delay(100); } delay(1000); }
Upload the code to Arduino. Here is the TFT output.
Blood pressure is the pressure of the blood in the arteries as it is pumped around the body by the heart. When your heart beats, it contracts and pushes blood through the arteries to the rest of your body. This force creates pressure on the arteries. Blood pressure is recorded as two numbers—the systolic pressure (as the heart beats) over the diastolic pressure (as the heart relaxes between beats).
6.2.3.1 Sensor features
Description: Monitoring blood pressure at home is important for many people, especially if you have high blood pressure. Blood pressure does not stay the same all the time. It changes to meet your body’s needs. It is affected by various factors including body position, breathing or emotional state, exercise and sleep. It is best to measure blood pressure when you are relaxed and sitting or lying down.
Classification of blood pressure for adults (18 years and older)
Systolic (mm Hg) | Diastolic (mm Hg) | |
Hypotension | < 90 | < 60 |
Desired | 90–119 | 60–79 |
Prehypertension | 120–139 | 80–89 |
Stage 1 Hypertension | 140–159 | 90–99 |
Stage 2 Hypertension | 160–179 | 100–109 |
Hypertensive Crisis | ≥ 180 | ≥ 110 |
High blood pressure (hypertension) can lead to serious problems like heart attack, stroke or kidney disease. High blood pressure usually does not have any symptoms, so you need to have your blood pressure checked regularly.
SPECIAL FEATURES:
KEY SPECIFICATIONS
The sensor needs to be connected to the specific Blood Pressure Monitor jack connector in MySignals board and it works with internal rechargeable battery. Use the Blood pressure specific cable in order to charge the sensor connected to MySignals.
Measurement:
Parameter | Unit | Range |
Systolic pressure | mm Hg | 0-300 mmHg |
Diastolic pressure | mm Hg | 0-300 mmHg |
Pulse | ppm | 30~200 ppm |
6.2.3.2 Connecting the sensor
This sensor have not cable. This sensor send the data wirelessly to MySignals board.
Place the sphygmomanometer on your arm (biceps zone) as shown in the image below.
Turn on the sphygmomanometer cuff (press ON button). The sensor will begin to make a measurement. In order to measure correctly is important to maintain the arm and the cuff in the correct position.
Wait until MySignals program indicate that it is connected with the BLE sensor.
Do not make abrupt movements or the measure will be not reliable.
The sphygmomanometer will take a few moments to calculate the blood pressure reading and send them wirelessly
After a few seconds you will get the values in the visualization method programmed.
6.2.3.3 SDK functions
The BLE sensor use a complex Bluetooth connection in order to obtain the value measured. There are several examples about how to write and read the correct attributes.
6.2.3.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include <MySignals_BLE.h> // Write here the MAC address of BLE device to find char MAC_BP[14] = "A4D57812A409"; uint8_t available_bp = 0; uint8_t connected_bp = 0; uint8_t connection_handle_bp = 0; #define BP_HANDLE 18 //!Struct to store data of the glucometer. struct bloodPressureBLEDataVector { uint16_t systolic; uint16_t diastolic; uint16_t pulse; }; //!Vector to store the glucometer measures and dates. bloodPressureBLEDataVector bloodPressureBLEData; void setup() { MySignals.begin(); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { MySignals.println("BLE init ok"); } else { MySignals.println("BLE init fail"); while (1) { }; } } else { MySignals.println("BLE init fail"); while (1) { }; } } void loop() { available_bp = MySignals_BLE.scanDevice(MAC_BP, 1000, TX_POWER_MAX); MySignals.disableMuxUART(); Serial.print("BP available:"); Serial.println(available_bp); MySignals.enableMuxUART(); if (available_bp == 1) { if (MySignals_BLE.connectDirect(MAC_BP) == 1) { MySignals.println("Connected"); connected_bp = 1; delay(8000); //To subscribe the BP measure write an ASCII letter "e" if (MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, BP_HANDLE, "e", 1) == 0) { MySignals.println("Subscribed"); unsigned long previous = millis(); do { if (MySignals_BLE.waitEvent(1000) == BLE_EVENT_ATTCLIENT_ATTRIBUTE_VALUE) { //Search letter "g" in ASCII if (MySignals_BLE.event[9] == 0x67) { if (MySignals_BLE.event[10] == 0x2f) { //Ojo esto esta mal en la guia de comandos //Primero da la alta -> sistolica uint8_t sh = MySignals_BLE.event[11] - 48; uint8_t sm = MySignals_BLE.event[12] - 48; uint8_t sl = MySignals_BLE.event[13] - 48; bloodPressureBLEData.systolic = (sh * 100) + (sm * 10) + sl; //Primero da la baja -> diastolica uint8_t dh = MySignals_BLE.event[15] - 48; uint8_t dm = MySignals_BLE.event[16] - 48; uint8_t dl = MySignals_BLE.event[17] - 48; bloodPressureBLEData.diastolic = (dh * 100) + (dm * 10) + dl; uint8_t ph = MySignals_BLE.event[19] - 48; uint8_t pm = MySignals_BLE.event[20] - 48; uint8_t pl = MySignals_BLE.event[21] - 48; bloodPressureBLEData.pulse = (ph * 100) + (pm * 10) + pl; MySignals.disableMuxUART(); Serial.print(F("Systolic: ")); Serial.println(bloodPressureBLEData.systolic); Serial.print(F("Diastolic: ")); Serial.println( bloodPressureBLEData.diastolic); Serial.print(F("Pulse/min: ")); Serial.println(bloodPressureBLEData.pulse); Serial.println(F("Disconnected from device")); MySignals.enableMuxUART(); connected_bp = 0; } } } } while ((connected_bp == 1) && ((millis() - previous) < 40000)); MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, BP_HANDLE, "i" , 1); delay(100); MySignals_BLE.disconnect(MySignals_BLE.connection_handle); connected_bp = 0; } else { MySignals.println("Error subscribing"); } } else { connected_bp = 0; MySignals.println("Not Connected"); } } else if (available_bp == 0) { //Do nothing } else { MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); delay(100); } delay(1000); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <MySignals_BLE.h> // Write here the MAC address of BLE device to find char MAC_BP[14] = "A4D57812A409"; uint8_t available_bp = 0; uint8_t connected_bp = 0; uint8_t connection_handle_bp = 0; #define BP_HANDLE 18 char buffer_tft[30]; Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //!Struct to store data of the glucometer. struct bloodPressureBLEDataVector { uint16_t systolic; uint16_t diastolic; uint16_t pulse; }; //!Vector to store the glucometer measures and dates. bloodPressureBLEDataVector bloodPressureBLEData; void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); //TFT message: Welcome to MySignals strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[0]))); tft.drawString(buffer_tft, 0, 0, 2); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { //TFT message: "BLE init ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[1]))); tft.drawString(buffer_tft, 0, 15, 2); } else { //TFT message:"BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } else { //TFT message: "BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } void loop() { available_bp = MySignals_BLE.scanDevice(MAC_BP, 1000, TX_POWER_MAX); tft.drawString("BP available:", 0, 30, 2); tft.drawNumber(available_bp, 110, 30, 2); if (available_bp == 1) { if (MySignals_BLE.connectDirect(MAC_BP) == 1) { tft.drawString("Connected ", 0, 45, 2); connected_bp = 1; delay(8000); //To subscribe the BP measure write an ASCII letter "e" if (MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, BP_HANDLE, "e", 1) == 0) { tft.drawString("Subscribed", 0, 60, 2); unsigned long previous = millis(); do { if (MySignals_BLE.waitEvent(1000) == BLE_EVENT_ATTCLIENT_ATTRIBUTE_VALUE) { //Search letter "g" in ASCII if (MySignals_BLE.event[9] == 0x67) { if (MySignals_BLE.event[10] == 0x2f) { //Ojo esto esta mal en la guia de comandos //Primero da la alta -> sistolica uint8_t sh = MySignals_BLE.event[11] - 48; uint8_t sm = MySignals_BLE.event[12] - 48; uint8_t sl = MySignals_BLE.event[13] - 48; bloodPressureBLEData.systolic = (sh * 100) + (sm * 10) + sl; //Primero da la baja -> diastolica uint8_t dh = MySignals_BLE.event[15] - 48; uint8_t dm = MySignals_BLE.event[16] - 48; uint8_t dl = MySignals_BLE.event[17] - 48; bloodPressureBLEData.diastolic = (dh * 100) + (dm * 10) + dl; uint8_t ph = MySignals_BLE.event[19] - 48; uint8_t pm = MySignals_BLE.event[20] - 48; uint8_t pl = MySignals_BLE.event[21] - 48; bloodPressureBLEData.pulse = (ph * 100) + (pm * 10) + pl; sprintf(buffer_tft, "S:%d D:%d P:%d ", bloodPressureBLEData.systolic, bloodPressureBLEData.diastolic, bloodPressureBLEData.pulse); tft.drawString(buffer_tft, 0, 75, 2); connected_bp = 0; } } } } while ((connected_bp == 1) && ((millis() - previous) < 40000)); MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, BP_HANDLE, "i" , 1); delay(100); MySignals_BLE.disconnect(MySignals_BLE.connection_handle); connected_bp = 0; } else { tft.drawString("Error subscribing", 0, 60, 2); } } else { connected_bp = 0; tft.drawString("Not Connected", 0, 45, 2); } } else if (available_bp == 0) { //Do nothing } else { MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); delay(100); } delay(1000); }
Upload the code to Arduino. Here is the TFT output.
Despite widely variable intervals between meals or the occasional consumption of meals with a substantial carbohydrate load, human blood glucose levels tend to remain within the normal range. However, shortly after eating, the blood glucose level may rise, in non-diabetics, temporarily up to 7.8 mmol/L (140 mg/dL) or a bit more.
6.2.4.1 Sensor features
Description: Glucometer is a medical device for determining the approximate concentration of glucose in the blood. A small drop of blood, obtained by pricking the skin with a lancet, is placed on a disposable test strip that the meter reads and uses to calculate the blood glucose level. The meter then displays the level in mg/dl or mmol/l.
The sensor works with internal batteries.
6.2.4.2 Connecting the sensor
This sensor have not cable. This sensor send the data wirelessly to MySignals board.
Place a test strip in the machine when the machine is ready. Watch the indicator for placing the blood to the strip.
Wait until MySignals program indicate that it is connected with the BLE sensor.
Clean the end of your index finger with rubbing alcohol before pricking it with an sterile needle or lancet.
Pierce your finger tip on the soft, fleshy pad and obtain a drop of blood. The type of drop of blood is determined by the type of strip you are using
Place the drop of blood on or at the side of the strip.
The glucometer will take a few moments to calculate the blood sugar reading.
The glucometer send wirelessly the value to MySignals.
When the glucometer send all the information, turn off the device.
After a few seconds you will get the values in the visualization method programmed.
6.2.4.3 SDK functions
The BLE sensor use a complex Bluetooth connection in order to obtain the value measured. There are several examples about how to write and read the correct attributes.
6.2.4.4 Examples of use
Basic example
This example configure the sensor and read the numeric parameters.
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include <MySignals_BLE.h> #define GLUCO_HANDLE1 99 #define GLUCO_HANDLE2 83 // Write here the MAC address of BLE device to find char MAC_GLUCO[14] = "187A93001030"; uint8_t available_gluco = 0; uint8_t connected_gluco = 0; uint8_t connection_handle_gluco = 0; //!Struct to store data of the glucometer. struct glucometerBLEDataVector { uint16_t glucose; uint8_t info; }; //!Vector to store the glucometer measures and dates. glucometerBLEDataVector glucometerBLEData; void setup() { MySignals.begin(); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { MySignals.println("BLE init ok"); } else { MySignals.println("BLE init fail"); while (1) { }; } } else { MySignals.println("BLE init fail"); while (1) { }; } } void loop() { available_gluco = MySignals_BLE.scanDevice(MAC_GLUCO, 1000, TX_POWER_MAX); MySignals.disableMuxUART(); Serial.print(F("Gluco available:")); Serial.println(available_gluco); MySignals.enableMuxUART(); if (available_gluco == 1) { if (MySignals_BLE.connectDirect(MAC_GLUCO) == 1) { MySignals.println("Connected"); connected_gluco = 1; uint8_t gluco_subscribe_message[2] = { 0x01 , 0x00 }; delay(200); MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, GLUCO_HANDLE1, gluco_subscribe_message, 2); MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, GLUCO_HANDLE2, gluco_subscribe_message, 2); delay(200); MySignals.println("Insert blood stripe (20s)"); unsigned long previous = millis(); do { if (MySignals_BLE.waitEvent(1000) == BLE_EVENT_ATTCLIENT_ATTRIBUTE_VALUE) { MySignals.disableMuxUART(); Serial.print(F("Glucose(mg/dl):")); if (MySignals_BLE.event[8] == 0x0c) { uint8_t gh = MySignals_BLE.event[12] - 48; uint8_t gl = MySignals_BLE.event[13] - 48; glucometerBLEData.glucose = (gh * 10) + gl; glucometerBLEData.info = 0; Serial.println(glucometerBLEData.glucose); } if (MySignals_BLE.event[8] == 0x0d) { uint8_t gh = MySignals_BLE.event[12] - 48; uint8_t gm = MySignals_BLE.event[13] - 48; uint8_t gl = MySignals_BLE.event[14] - 48; glucometerBLEData.glucose = (gh * 100) + (gm * 10) + gl; glucometerBLEData.info = 0; Serial.println(glucometerBLEData.glucose); } if (MySignals_BLE.event[8] == 0x0e) { if (MySignals_BLE.event[12] == 0x4c) { glucometerBLEData.glucose = 0; glucometerBLEData.info = 0xAA; Serial.println(F("Low glucose")); } else if (MySignals_BLE.event[12] == 0x48) { glucometerBLEData.glucose = 360; glucometerBLEData.info = 0xBB; Serial.println(F("High glucose")); } } MySignals_BLE.disconnect(MySignals_BLE.connection_handle); connected_gluco = 0; } } while ((connected_gluco == 1) && ((millis() - previous) < 20000)); //Timeout 20 seconds connected_gluco = 0; } else { connected_gluco = 0; MySignals.println("Not Connected"); } } else if (available_gluco == 0) { //Do nothing } else { MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); delay(100); } delay(1000); }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
TFT example
This example configure the sensor and show the data to TFT. The TFT shows the information the nodes are sending which contains the sensor data gathered.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <MySignals_BLE.h> #define GLUCO_HANDLE1 99 #define GLUCO_HANDLE2 83 // Write here the MAC address of BLE device to find char MAC_GLUCO[14] = "187A93001030"; uint8_t available_gluco = 0; uint8_t connected_gluco = 0; uint8_t connection_handle_gluco = 0; char buffer_tft[30]; Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //!Struct to store data of the glucometer. struct glucometerBLEDataVector { uint16_t glucose; uint8_t info; }; //!Vector to store the glucometer measures and dates. glucometerBLEDataVector glucometerBLEData; void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); //TFT message: Welcome to MySignals strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[0]))); tft.drawString(buffer_tft, 0, 0, 2); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { //TFT message: "BLE init ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[1]))); tft.drawString(buffer_tft, 0, 15, 2); } else { //TFT message:"BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } else { //TFT message: "BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } void loop() { available_gluco = MySignals_BLE.scanDevice(MAC_GLUCO, 1000, TX_POWER_MAX); tft.drawString("Gluco available:", 0, 30, 2); tft.drawNumber(available_gluco, 110, 30, 2); if (available_gluco == 1) { if (MySignals_BLE.connectDirect(MAC_GLUCO) == 1) { tft.drawString("Connected", 0, 45, 2); connected_gluco = 1; uint8_t gluco_subscribe_message[2] = { 0x01 , 0x00 }; delay(200); MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, GLUCO_HANDLE1, gluco_subscribe_message, 2); MySignals_BLE.attributeWrite(MySignals_BLE.connection_handle, GLUCO_HANDLE2, gluco_subscribe_message, 2); delay(200); tft.drawString("Insert blood stripe (20s)", 0, 60, 2); //Serial.println(F("Waiting 20 seconds for a blood stripe")); unsigned long previous = millis(); do { if (MySignals_BLE.waitEvent(1000) == BLE_EVENT_ATTCLIENT_ATTRIBUTE_VALUE) { tft.drawString("Glucose(mg/dl):", 0, 75, 2); if (MySignals_BLE.event[8] == 0x0c) { uint8_t gh = MySignals_BLE.event[12] - 48; uint8_t gl = MySignals_BLE.event[13] - 48; glucometerBLEData.glucose = (gh * 10) + gl; glucometerBLEData.info = 0; tft.drawNumber(glucometerBLEData.glucose, 120, 75, 2); } if (MySignals_BLE.event[8] == 0x0d) { uint8_t gh = MySignals_BLE.event[12] - 48; uint8_t gm = MySignals_BLE.event[13] - 48; uint8_t gl = MySignals_BLE.event[14] - 48; glucometerBLEData.glucose = (gh * 100) + (gm * 10) + gl; glucometerBLEData.info = 0; tft.drawNumber(glucometerBLEData.glucose, 120, 75, 2); } if (MySignals_BLE.event[8] == 0x0e) { if (MySignals_BLE.event[12] == 0x4c) { glucometerBLEData.glucose = 0; glucometerBLEData.info = 0xAA; //Serial.println(F("LOW GLUCOSE")); tft.drawString("Low", 120, 75, 2); } else if (MySignals_BLE.event[12] == 0x48) { glucometerBLEData.glucose = 360; glucometerBLEData.info = 0xBB; //Serial.println(F("HIGH GLUCOSE")); tft.drawString("High", 120, 75, 2); } } MySignals_BLE.disconnect(MySignals_BLE.connection_handle); connected_gluco = 0; } } while ((connected_gluco == 1) && ((millis() - previous) < 20000)); //Timeout 20 seconds connected_gluco = 0; } else { connected_gluco = 0; tft.drawString("Not Connected", 0, 45, 2); } } else if (available_gluco == 0) { //Do nothing } else { MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); delay(100); } delay(1000); }
Upload the code to Arduino. Here is the TFT output.
Electroencephalography (EEG) is an electrophysiological monitoring method to record electrical activity of the brain. It is typically noninvasive, with the electrodes placed along the scalp, although invasive electrodes are sometimes used in specific applications. EEG measures voltage fluctuations resulting from ionic current within the neurons of the brain.[1] In clinical contexts, EEG refers to the recording of the brain's spontaneous electrical activity over a period of time,[1] as recorded from multiple electrodes placed on the scalp. Diagnostic applications generally focus on the spectral content of EEG, that is, the type of neural oscillations (popularly called "brain waves") that can be observed in EEG signals.
6.2.5.1 Sensor features
Description: This is the Mindwave Mobile from NeuroSky, an EEG headset that safely measures and transfers the power spectrum (alpha waves, beta waves, etc) data via Bluetooth to wirelessly communicate with your computer, iOS, or Android device. This headset can be simply slipped on to be able to see your brainwaves change in real time. With the Mindwave Mobile you can monitor your levels of attention and relaxation and even learn about how your brain responds to your favorite music. This headset is an excellent introduction to the world of brain-computer interface!
The Mindwave Mobile is surprisingly simple consisting only of a headset, an ear-clip, and a sensor arm. The headset’s reference and ground electrodes are on the ear clip, while the EEG electrode is on the sensor arm, resting on the forehead above the eye.
What’s really great about the Mindwave is the more than 100 brain training games, educational apps, and development tools available through the NeuroSky, iOS, and Android stores. You can also write your own programs to interact with MindWave Mobile by using the free developer tools.
The sensor works with internal batteries.
Measurement:
Parameter | Unit | Range |
Brain waves: alpha waves, beta waves.. | Percentage | 0-100% |
6.2.5.2 Connecting the sensor
To power on the MindWave, slide the switch to the ON position. To turn the MindWave off, slide the switch back to the OFF position.
While the MindWave is powered on, the LED light on the side of the headset will be turned on. If the MindWave has a low battery, the LED light will indicate low battery status.
You can find all the information about this sensor in this manual:
http://developer.neurosky.com/docs/lib/exe/fetch.php?media=mindwave_user_guide_en.pdf
The sensor need a configuration method before the first measure. Paired between BT2.0 module and EEG sensor is necessary. Use the configuration example in order to connect both devices.
Then, turn on the device situated in the correct position in your head.
After a few seconds you will get the values in the sensor screen of the sensor and in the visualization method programmed.
6.2.5.3 SDK functions
The BT2.0 sensor use a complex Bluetooth connection in order to obtain the value measured. There are several examples about how to receive all the data.
6.2.5.4 Examples of use
Configuration example
Upload the next code for configure the BT 2.0 module to connect with a specific EEG sensor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" int8_t answer; void setup() { //Serial.begin(57600); // Communication mode baudrate with mindwave Serial.begin(38400); // AT mode in HC-05 is always at this baudrate //You can use the configuration examples with the correct //AT+UART=**** command in order to change the baudrate MySignals.begin(); /* expanderState is initialized with B10000001 Expansor pin library names: EXP_3G_ON EXP_TOUCH_CS EXP_BT_POWER EXP_BT_KEY EXP_ADC_CS EXP_SNORE_POT EXP_RESET_BLE EXP_WIFI_ON */ //Enable BT2.0 module power -> bit2:1 bitSet(MySignals.expanderState, EXP_BT_POWER); //Enable BT2.0 Key to AT mode -> bit3:0 bitClear(MySignals.expanderState, EXP_BT_KEY); MySignals.expanderWrite(MySignals.expanderState); //Reset the module to enter command mode //Disable BT2.0 module power -> bit2:0 bitClear(MySignals.expanderState, EXP_BT_POWER); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Enable BT2.0 module power -> bit2:1 bitSet(MySignals.expanderState, EXP_BT_POWER); MySignals.expanderWrite(MySignals.expanderState); delay(1000); MySignals.initSensorUART(); MySignals.enableSensorUART(EEG); //After enabling UART EEG you always need to intilize the UART at the right baudrate Serial.begin(38400); // AT mode in HC-05 is always at this baudrate delay(1000); // Checks if the BT module is started answer = sendATcommand("AT", "OK", 6000); if (answer == 0) { MySignals.println("Error"); // waits for an answer from the module while (answer == 0) { // Send AT every two seconds and wait for the answer answer = sendATcommand("AT", "OK", 6000); } } else if (answer == 1) { MySignals.println("BT HC05 succesfully working!"); } //You better first try these commands via Gateway in a serial communication //program like Cutecom sendATcommand("AT+UART=57600,0,0", "0K", 2000); delay(5000); sendATcommand("AT+ROLE=1", "0K", 2000); delay(5000); sendATcommand("AT+PSWD=0000", "0K", 2000); delay(5000); sendATcommand("AT+CMODE=0", "0K", 2000); delay(5000); //Write you mindwave MAC for example: AT+PAIR=2068,9D,3F4DD1 sendATcommand("AT+BIND=****,**,******", "0K", 2000); delay(5000); sendATcommand("AT+INIT", "0K", 2000); delay(5000); sendATcommand("AT+IAC=9E8B33", "0K", 2000); delay(5000); sendATcommand("AT+CLASS=0", "0K", 2000); delay(5000); sendATcommand("AT+INQM=1,9,48", "0K", 2000); delay(5000); //Scan for BT devices MACS sendATcommand("AT+INQ", "0K", 2000); delay(20000); //For example: AT+PAIR=2068,9D,3F4DD1,20 sendATcommand("AT+PAIR=****,**,******,20", "0K", 2000); //mindwave mac delay(10000); //For example: AT+LINK=2068,9D,3F4DD1 sendATcommand("AT+LINK=****,**,****", "0K", 2000); //mindwave mac delay(10000); } void loop() { } int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout) { uint8_t x = 0, answer = 0; char response[500]; unsigned long previous; memset(response, '\0', 100); // Initialize the string delay(100); while ( Serial.available() > 0) Serial.read(); // Clean the input buffer delay(1000); Serial.println(ATcommand); // Send the AT command x = 0; previous = millis(); // this loop waits for the answer do { if (Serial.available() != 0) { response[x] = Serial.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer1) != NULL) { answer = 1; MySignals.println(response); } } // Waits for the asnwer with time out } while ((answer == 0) && ((millis() - previous) < timeout)); return answer; }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
Basic TFT example
This example configures the sensor and read the numeric parameters.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include "Wire.h" #include "SPI.h" Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); #define MAX_CONCENTRATION 300 #define REPETITION 3 int i; int m; byte generatedChecksum = 0; byte checksum = 0; byte payloadData[64] = {0}; byte poorQuality = 0; byte attention = 0; byte meditation = 0; int payloadLength = 0; long lastReceivedPacket = 0; boolean bigPacket = false; byte aux, concentration; uint8_t counter = 0; void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.drawString("Concentration:", 0, 0, 2); Serial.begin(57600); // Communication mode baudrate with mindwave //Serial.begin(38400); // AT mode in HC-05 is always at this baudrate /* expanderState is initialized with B10000001 Expansor pin library names: EXP_3G_ON EXP_TOUCH_CS EXP_BT_POWER EXP_BT_KEY EXP_ADC_CS EXP_SNORE_POT EXP_RESET_BLE EXP_WIFI_ON */ //Enable BT2.0 module power -> bit2:1 bitSet(MySignals.expanderState, EXP_BT_POWER); //Enable BT2.0 Key to communication mode -> bit3:1 bitSet(MySignals.expanderState, EXP_BT_KEY); MySignals.expanderWrite(MySignals.expanderState); //Reset the module to enter communication mode //Disable BT2.0 module power -> bit2:0 bitClear(MySignals.expanderState, EXP_BT_POWER); MySignals.expanderWrite(MySignals.expanderState); delay(1000); //Enable BT2.0 module power -> bit2:1 bitSet(MySignals.expanderState, EXP_BT_POWER); MySignals.expanderWrite(MySignals.expanderState); delay(1000); MySignals.initSensorUART(); MySignals.enableSensorUART(EEG); //After enabling UART EEG you always need to intilize the UART at the right baudrate Serial.begin(57600); delay(1000); tft.drawNumber(concentration, 0, 30, 2); } void loop() { if (ReadOneByte() == 170) { if (ReadOneByte() == 170) { if (ReadOneByte() == 32) { for (i = 0; i < 32; i++) { aux = ReadOneByte(); if (i == 28) { concentration = ReadOneByte(); tft.fillRect(0, 30, 40, 20, ILI9341_BLACK); tft.drawNumber(concentration, 0, 30, 2); if (concentration >= MAX_CONCENTRATION) { counter++; } else { counter = 0; } } } } } } if (counter >= REPETITION) { counter = 0; } } byte ReadOneByte() { int ByteRead; while (!Serial.available()); ByteRead = Serial.read(); return ByteRead; } int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout) { uint8_t x = 0, answer = 0; char response[500]; unsigned long previous; memset(response, '\0', 100); // Initialize the string delay(100); while ( Serial.available() > 0) Serial.read(); // Clean the input buffer delay(1000); Serial.println(ATcommand); // Send the AT command x = 0; previous = millis(); // this loop waits for the answer do { if (Serial.available() != 0) { response[x] = Serial.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer1) != NULL) { answer = 1; MySignals.println(response); } } // Waits for the asnwer with time out } while ((answer == 0) && ((millis() - previous) < timeout)); return answer; }
Upload the code to Arduino and watch the TFT. Here is the TFT output.
MySignals Hardware Development Platform can work with 16 different wired biometric sensors but you can use it as a prototyping platform for new devices or sensors.
If you are a hardware developer, a researcher or a maker and want to have complete access to the PCB and electronics, MySignals hardware development platform is the perfect solution.
MySignals have a new improved connection system. It is very easy-to-use jack-connectors method. Each connector have defined a specific pinout available in order to integrate new wired sensors.
WiFi, BLE, and BT2.0 connectivity is available too in order to integrate new wireless sensors.
All the data gathered by MySignals can be visualized using different graphic method: TFT, serial monitor or KST pc real-time software.
It can be too encrypted and sent to the user's private account at Libelium Cloud through WiFi or monitored in the smartphone MySignals APP through Bluetooth.
MySignals works with several examples in different modes, we have to think about a person who does not have a mobile phone and this person does not have internet connectivity, the simplest case, then let's explain each mode:
Standalone mode: MySignals does not send data. It show data using TFT screen, Arduino IDE serial monitor or KST real-time software.
Connectivity mode: MySignals send data wirelessly. MySignals device can send data to libelium's cloud service, send data to mobile phone feeding MySignals APP or use other compatible radio module.
- How can I see values older than one month in my Cloud account?
MySignals Cloud Web Service (section 5.2, page 25) allows currently to see graphics for values corresponding to the last month. By the end of 2017 a new version of the Cloud Service will allow to see the complete historical data of any of the users.
However, if you want to access to this data now, you can use the Cloud API Method 3 to get the sensor values of a member (see section 9.1.1, page 225), allows to retrieve values for any desired time slot.
If you have any doubt just write a post in the MySignals forum.
MySignals Hardware Development Platform include a graphic TFT for visualizing data. This 2.4S-inch TFT LCD serial SPI integrated features of compact, SPI interface, fully compatible with popular LCD5110 interface cable sequence.
As a bonus, this display has a resistive touchscreen attached to it already, so you can detect finger presses anywhere on the screen.
Feature:
uTFT and uTouch libraries includes functions to manage a graphic LCD for visualizing data.
You need to connect the device with the signals in the correct position.
The eHealth library includes all the necessary functions to manage the TFT and show in real time the data sensor measures. In order to use this functions, before all, you should include the corresponding library.
TFT analog example
This example configure the sensor and show the data from the analog sensors to TFT.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include "Wire.h" #include "SPI.h" Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //! It stores the current value of x position in the LCD. uint16_t graphic_x = 0; //! It stores the current value of the ECG or AirFlow sensor. uint16_t valRead; //! It stores the previous value of the ECG or AirFlow sensor. uint16_t graphic_prevRead; #define graphic_low_extrem 230 #define graphic_high_extrem 50 #define graphic_left_extrem 0 #define graphic_right_extrem 320 void setup() { Serial.begin(115200); MySignals.begin(); tft.init(); tft.setRotation(3); tft.fillScreen(ILI9341_WHITE); tft.fillRect(0,0,320,30,ILI9341_RED); tft.setTextColor(ILI9341_WHITE); tft.drawString("ECG",5,5,4); } void loop() { valRead = MySignals.getECG(DATA); //Serial.println(valRead); valRead = map(valRead, 150, 600, graphic_high_extrem, graphic_low_extrem); printGraphic(valRead,0); } void printGraphic(uint16_t value, uint8_t delay_time) { if (value < graphic_high_extrem) { value = graphic_high_extrem; } if (value > graphic_low_extrem) { value = graphic_low_extrem; } //Pinta la linea solo a partir de que ya exista al menos 1 valor if (graphic_x > graphic_left_extrem + 1) { tft.drawLine(graphic_x - 1, graphic_prevRead, graphic_x, value, ILI9341_RED); } //Wave refresh (barre pantalla pintando una linea) tft.drawLine(graphic_x + 1, graphic_high_extrem, graphic_x + 1, graphic_low_extrem, ILI9341_WHITE); graphic_prevRead = value; graphic_x++; delay(delay_time); if (graphic_x == graphic_right_extrem) { graphic_x = graphic_left_extrem; } SPI.end(); }
Upload the code to Arduino. Here is the TFT output.
TFT i2c example
This example configure the sensor and show the data from the i2c sensors to TFT.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #define graphic_low_extrem 230 #define graphic_high_extrem 30 #define graphic_left_extrem 0 #define graphic_right_extrem 320 Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); //! It stores the current value of x position in the LCD. uint16_t graphic_x; //! It stores the current value of the MySignals. uint16_t valRead; //! It stores the previous value of the MySignals. uint16_t graphic_prevRead; void setup(void) { Serial.begin(115200); MySignals.begin(); MySignals.initBodyPosition(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); } void loop() { tft.drawString("Body position:", 0, 0, 2); uint8_t position = MySignals.getBodyPosition(); if (position == 1) { tft.drawString("Prone position", 0, 30, 2); } else if (position == 2) { tft.drawString("Left lateral ", 0, 30, 2); } else if (position == 3) { tft.drawString("Rigth lateral ", 0, 30, 2); } else if (position == 4) { tft.drawString("Supine position ", 0, 30, 2); } else if (position == 5) { tft.drawString("Stand or sit ", 0, 30, 2); } else { tft.drawString("non-defined ", 0, 30, 2); } SPI.end(); }
Upload the code to Arduino. Here is the TFT output.
TFT BLE example
This example configure the sensor and show the data from the BLE sensor to TFT.
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <MySignals_BLE.h> // Write here the MAC address of BLE device to find char MAC_SPO2[14] = "00A0500E1823"; uint8_t available_spo2 = 0; uint8_t connected_spo2 = 0; uint8_t connection_handle_spo2 = 0; uint8_t pulse_spo2 = 0; uint8_t spo2 = 0; #define SPO2_HANDLE 15 char buffer_tft[30]; Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); //TFT message: Welcome to MySignals strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[0]))); tft.drawString(buffer_tft, 0, 0, 2); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { //TFT message: "BLE init ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[1]))); tft.drawString(buffer_tft, 0, 15, 2); } else { //TFT message:"BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } else { //TFT message: "BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } void loop() { available_spo2 = MySignals_BLE.scanDevice(MAC_SPO2, 1000, TX_POWER_MAX); tft.drawString("SPO2 available:", 0, 30, 2); tft.drawNumber(available_spo2, 110, 30, 2); if (available_spo2 == 1) { if (MySignals_BLE.connectDirect(MAC_SPO2) == 1) { connected_spo2 = 1; connection_handle_spo2 = MySignals_BLE.connection_handle; tft.drawString("Connected ", 0, 45, 2); delay(6000); //To subscribe the spo2 measure write "1" in SPO2_HANDLE char attributeData[1] = { 0x01 }; if (MySignals_BLE.attributeWrite(connection_handle_spo2, SPO2_HANDLE, attributeData, 1) == 0) { tft.drawString("Subscribed", 0, 60, 2); unsigned long previous = millis(); do { if (MySignals_BLE.waitEvent(1000) == BLE_EVENT_ATTCLIENT_ATTRIBUTE_VALUE) { char attributeData[1] = { 0x00 }; MySignals_BLE.attributeWrite(connection_handle_spo2, SPO2_HANDLE, attributeData , 1); uint8_t pulse_low = MySignals_BLE.event[12]; pulse_low &= 0b01111111; uint8_t pulse_high = MySignals_BLE.event[11]; pulse_high &= 0b01000000; if (pulse_high == 0) { pulse_spo2 = pulse_low; } if (pulse_high == 0b01000000) { pulse_spo2 = pulse_low + 0b10000000; } spo2 = MySignals_BLE.event[13]; spo2 &= 0b01111111; if ((pulse_spo2 >= 25) && (pulse_spo2 <= 250) && (pulse_spo2 >= 35) && (pulse_spo2 <= 100)) { sprintf(buffer_tft, "Pulse: %d ppm / SPO2: %d", pulse_spo2, spo2); tft.drawString(buffer_tft, 0, 75, 2); uint16_t errorCode = MySignals_BLE.disconnect(connection_handle_spo2); tft.drawString("Disconnected", 0, 45, 2); connected_spo2 = 0; } } } while ((connected_spo2 == 1) && ((millis() - previous) < 10000)); connected_spo2 = 0; } else { tft.drawString("Error subscribing", 0, 60, 2); } } else { connected_spo2 = 0; tft.drawString("Not Connected", 0, 45, 2); } } else if (available_spo2 == 0) { //Do nothing } else { MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); delay(100); } delay(1000); }
Upload the code to Arduino. Here is the TFT output.
TFT touchscreen example
This example configure the touchscreen and use it to control the TFT.
/* * * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * By using it you accept the MySignals Terms and Conditions. * You can find them at: http://libelium.com/legal * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Version: 0.1 * Design: David Gascon * Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <UTouch.h> #include <MySignals.h> #include <MySignals_BLE.h> #include <Wire.h> #include <SPI.h> Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); UTouch myTouch(14,NULL,15,16,17); int touch_x; int touch_y; void setup(void) { Serial.begin(115200); MySignals.expanderWrite(B11111111); Wire.begin(); myTouch.InitTouch(); myTouch.setPrecision(PREC_MEDIUM); } void loop() { if (myTouch.dataAvailable()) { myTouch.read(); touch_x=myTouch.getX(); touch_y=myTouch.getY(); Serial.print("x="); Serial.print(touch_x); Serial.print(" y="); Serial.println(touch_y); } }
Upload the code to Arduino.
All data can be visualized in the serial monitor of Arduino/RasberryPi by using the next serial console program.
Load a example related to Serial Console and open the serial monitor of Arduino IDE.
Use the USB connector included in Arduino to program and connect via Serial the device with a PC.
Basic example
Upload the next code for seeing data in the serial monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { float conductance = MySignals.getGSR(CONDUCTANCE); float resistance = MySignals.getGSR(RESISTANCE); float conductanceVol = MySignals.getGSR(VOLTAGE); Serial.print("Conductance : "); Serial.print(conductance, 2); Serial.println(""); Serial.print("Resistance : "); Serial.print(resistance, 2); Serial.println(""); Serial.print("Conductance Voltage : "); Serial.print(conductanceVol, 4); Serial.println(""); Serial.print("\n"); // wait for a second delay(1000); }
Upload the code to Arduino and watch the Serial monitor.Here is the USB output using the Arduino IDE serial port terminal.
There are several options if you want to monitor in real time a biometric parameter. Here you can find the best options for this purpose: KST or Arduino IDE.
KST is the fastest real-time large-dataset viewing and plotting tool available (you may be interested in some benchmarks) and has built-in data analysis functionality. It is very user-friendly and contains many powerful built-in features and is expandable with plugins and extensions.
KST is licensed under the GPL, and is as such freely available for anyone. What's more, as of 2.0.x it is available on all of the following platforms: Microsoft Windows, Linux, Mac OSX.
Before all, you have to install the KST program in your PC. You can downloaded the program from KST web page:
We need too Python available in our PC. We will use this script developed in Python to interconnect our Arduino with KST:
This example is for Linux OS.
You can find more information about how to use KST on this video tutorial
To begin working with our real-time data must first load the appropriate code in the Arduino.
Data Connection
Program configuration: Now with the file created and updated with data received, we have to open the program KST. To configure KST for each example, we will need to set up common parameters.
Program configuration:
The Arduino Serial Plotter is a Tool that comes pre-installed with your Arduino IDE (version 1.6.6 and above) that takes incoming serial data and displays them in a plot.
The vertical Y axis adjusts as the value of your serial data increases or decreases. The X axis has 500 points and each tick of the axis is equal to an executed Serial.println() command.
The plot is updated every time you use the Serial.println() command with a new value.
How to Open the Serial Plotter:
Go to your Arduino IDE, select “Tools” and from the drop-down menu open “Serial Plotter” (see Figure below).
KST example
This example configure the sensor and send the data to KST. KST program shows the sensor value wave.
In this example we configure the KST to show a defined period of x time (x=300). We are interested only in the most current values of the ECG.
The Arduino code used in this program is presented next:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" extern volatile unsigned long timer0_overflow_count; float fanalog0; int analog0; unsigned long time; byte serialByte; void setup() { Serial.begin(9600); MySignals.begin(); Serial.println("Starting..."); } void loop() { while (Serial.available()>0) { serialByte=Serial.read(); if (serialByte=='C') { while(1){ fanalog0=MySignals.getECG(DATA); // Use the timer0 => 1 tick every 4 us time=(timer0_overflow_count << 8) + TCNT0; // Microseconds conversion. time=(time*4); //Print in a file for simulation Serial.print(time); Serial.print(";"); Serial.println(fanalog0,5); if (Serial.available()>0) { serialByte=Serial.read(); if (serialByte=='F') break; } } } } }
Upload the code to Arduino and follow the KST configuration steps available in the KST section.
Serial Plotter example
Upload the next code for seeing data in the Serial Plotter monitor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { Serial.begin(115200); MySignals.begin(); } void loop() { uint16_t ecg = (uint16_t)MySignals.getECG(DATA); ecg = map(ecg, 0,1023,1023,0); Serial.println(ecg); delay(5); }
Upload the code to Arduino and watch the Serial monitor.Here is the USB output using the Arduino IDE serial port terminal.
The Bluetooth connectivity may perform direct communications with iPhone and Android devices without the need of an intermediate router.
First of all you must download MySignals app in your store. The app is available for Android and iPhone.
· Have one Department created
· Have one user created and linked to one Department
· In the App to to Users, click on one and press "Select this user"
· Make sure the "Cloud" icon is active (upper right corner of the App)
Below and to avoid any connection problems we recommend restarting the Bluetooth on your device if you already had it previously activated. We recommend doing this every time you open the app again. In order to do this go to Settings in your device, then Bluetooth and turn it off and on.
Sometimes you will need to configure the connection with MySignals using the Android or iOS settings.
The first time a user starts MySignals application, it will be needed a setup assistant to configure all aspects related to MySignals configuration like user name, password (already set in our back end), profile, WiFi settings and MySignals selection. The maximum number or characters that you can use in this settings are 20. We will create a setup assistant with straightforward screens with all field and information to guide the user through this assistant.
The first time you open the APP you will see some configuration screens:
-First of all in the "Login” screen enter your user and password. In case you don't have an username or password please contact our Sales Dep. at sales@libelium.com
An account can have one or more MySignals devices, this is why an user can purchase more than one device. Then we must create a MySignals Manager profile to provide a list of devices and perform some basic operation on them.
This Manager Profile can add/delete/modify/select an MySignals device. This information should be synchronized with cloud to get all devices up to date for a given account.
As each MySignals is tied to each single user, we should download a list of devices each time an user logs in, this way we do not mix MySignals from different accounts.
It is very important that you read carefully and accept the Terms and Conditions of our application.
Now we move to the next screen "Profile” and enter our Manager Profile personal info.
Go to the next screen “WiFi”. Here you will need to provide your WiFi SSID name and your WiFi password in order to transmit this information to the MySignals device (this way it will be able to connect to the WiFi AP directly). This is the only way that MySignals can connect to the WiFi network in your home if you are also interested in using the Server mode.
-Once arrived to the last configuration screen, before doing anything here in the phone app, you must power on MySignals.
Select your MySignals device on the list. Now if the bluetooth connection is working well, you will have to enter in your phone the code that you will see in blue color figures in MySignals screen. If you are using Android please check your notification center if your phone doesn't ask you to enter the code automatically.
-The next screen is “Sensors”, where you must select all the sensors that you want to measure. Selected sensors are in blue color and unselected sensors are in gray color.
MySignals device will send data to application using two modes:
You can see in this screen a color code in the sensor logos:
When the MySignals device establish a pairing with the application it send information in Datagram mode by default.
Once you have completed your selection you must click on “Data” button, which you can find at the left end of the bottom toolbar.
In “General mode” screen you will be able to see in one glance the main information of all sensors at once. The latest received sensor info will be green, the sensors with old received info will be orange and sensors that hasn't received info will be gray.
If you are interested in viewing all the information in one particular sensor simply go tot he "Detailed View" of that sensor. On this screen you can see a graph of one of the sensor values and all the detailed information on a list view.
At any time you can navigate back to return to the previous screen by clicking the arrow on the top left of the screen.
Using the users section you are able to select and modify the user profile.
Or organize them in different departments.
There are several basic configuration screens: language, profile, user…. Where you can change your basic configuration.
You can logout and login with another mysignals account:
You can change the language of the application
You can change the device MySignals connected to the APP.
7.4.1.1 Installing to an iPhone
Download the application from App Store:
Once installed, the app appears in your iPhone/iPod screen.
The App shows the information the nodes are sending which contains the sensor data gathered.
7.4.1.2 Installing to an Android
Download the application from Android Market:
Once installed, the app appears in your device screen.
The App shows the information the nodes are sending which contains the sensor data gathered.
The MySignals SDK includes all the necessary functions to manage the BLE and send in real time the data sensor measures. In order to use this functions, before all, you should include the corresponding library.
BLE APP connection example
Upload the next code for seeing connect MySignals with the APP:
/* * * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * By using it you accept the MySignals Terms and Conditions. * You can find them at: http://libelium.com/legal * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Version: 0.1 * Design: David Gascon * Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <MySignals_BLE.h> #include <Wire.h> #include <SPI.h> char buffer_tft[30]; Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); unsigned long previous; // Sensor list bool selected_airflow; bool selected_ecg; bool selected_emg; bool selected_gsr; bool selected_position; bool selected_snore; bool selected_temp; bool selected_spiro; bool selected_eeg; bool selected_spo2_uart; bool selected_bp_uart; bool selected_gluco_uart; bool selected_scale_ble; bool selected_spo2_ble; bool selected_bp_ble; bool selected_gluco_ble; uint8_t sensor_list_mode; uint8_t spir_measure_individual; uint8_t gluco_measure_individual; uint8_t last_measure_hour_spiro; uint8_t last_measure_minutes_spiro; uint8_t last_measure_number_spiro; uint8_t last_measure_hour_gluco; uint8_t last_measure_minutes_gluco; uint8_t last_measure_number_gluco; void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); //TFT message: Welcome to MySignals strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[0]))); tft.drawString(buffer_tft, 0, 0, 2); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { //TFT message: "BLE init ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[1]))); tft.drawString(buffer_tft, 0, 15, 2); } else { //TFT message:"BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } else { //TFT message: "BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } void loop() { //1. SET MODE: SLAVE (VISIBLE TO APP) while ((MySignals_BLE.ble_mode_flag == master_mode)) { if (MySignals_BLE.setMode(slave_mode) == 0) { //TFT message: "Slave mode ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[3]))); tft.drawString(buffer_tft, 0, 30, 2); MySignals_BLE.ble_mode_flag = slave_mode; } else { //TFT message: "Slave mode fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[4]))); tft.drawString(buffer_tft, 0, 30, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } //2. SET BONDABLE MODE if (MySignals_BLE.bond_mode_and_mitm == 0) { if (MySignals_BLE.setBondableMode(BLE_ENABLE_BONDING) == 0) { //TFT message: "Bondable mode ok" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[5]))); tft.drawString(buffer_tft, 0, 45, 2); //3. SET SM PARAMETERS if (MySignals_BLE.setSMParameters(BLE_ENABLE_MITM) == 0) { //TFT message: "SM parameters ok" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[7]))); tft.drawString(buffer_tft, 0, 60, 2); MySignals_BLE.bond_mode_and_mitm = 1; } else { //TFT message: "SM parameters fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[8]))); tft.drawString(buffer_tft, 0, 60, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } else { //TFT message: "Bondable mode fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[6]))); tft.drawString(buffer_tft, 0, 45, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } //3. BONDING AND CONNECTION CONFIGURATION if ((MySignals_BLE.ble_mode_flag == slave_mode) && (MySignals_BLE.bonded_and_connected_flag == 0)) { MySignals_BLE.bonding_correct = 0; MySignals_BLE.app_connected_flag = 0; MySignals_BLE.bonding_fail = 0; ///////////////////// //TFT message: "Waiting connections..." strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[9]))); tft.drawString(buffer_tft, 0, 75, 2); uint8_t flag = MySignals_BLE.waitEvent(500); if (flag == BLE_EVENT_CONNECTION_STATUS) { MySignals_BLE.app_connected_flag = 1; } else if (flag == BLE_EVENT_SM_BOND_STATUS) { if (MySignals_BLE.event[6] == 0x01) { MySignals_BLE.bonding_correct = 1; delay(1000); } } else if (flag == 0) { // If there are no events, then no one tried to connect } else if (flag == BLE_EVENT_ATTRIBUTES_VALUE) { //Already connected MySignals_BLE.app_connected_flag = 1; MySignals_BLE.bonding_correct = 1; MySignals_BLE.bonded_and_connected_flag = 1; } else { // Other event received from BLE module } ///////////////////// if ((MySignals_BLE.bonding_correct == 1) || MySignals_BLE.app_connected_flag == 1) { //TFT message: "Connection detected..." strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[10]))); tft.drawString(buffer_tft, 0, 90, 2); previous = millis(); while ((MySignals_BLE.bonded_and_connected_flag == 0) && (MySignals_BLE.bonding_fail == 0)) { // Timeout 30 sg if ((millis() - previous) > 30000) { MySignals_BLE.bonding_fail = 1; } flag = MySignals_BLE.waitEvent(1000); if (flag == 0) { //Do nothing } else if (flag == BLE_EVENT_SM_PASSKEY_DISPLAY) { uint32_t passkey_temp = uint32_t(MySignals_BLE.event[5]) + uint32_t(MySignals_BLE.event[6]) * 256 + uint32_t(MySignals_BLE.event[7]) * 65536 + uint32_t(MySignals_BLE.event[8]) * 16777216; //TFT message: "Passkey:";" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[11]))); tft.drawString(buffer_tft, 0, 105, 2); tft.drawNumber(passkey_temp, 50, 105, 2); } else if (flag == BLE_EVENT_ATTRIBUTES_VALUE) { //Already connected MySignals_BLE.app_connected_flag = 1; MySignals_BLE.bonding_correct = 1; MySignals_BLE.bonded_and_connected_flag = 1; } else if (flag == BLE_EVENT_SM_BOND_STATUS) { if (MySignals_BLE.event[6] == 0x01) { //Man-in-the-Middle mode correct MySignals_BLE.bonding_correct = 1; } } else if (flag == BLE_EVENT_CONNECTION_FEATURE_IND) { //Do nothing } else if (flag == BLE_EVENT_CONNECTION_VERSION_IND) { //Do nothing } else if (flag == BLE_EVENT_SM_BONDING_FAIL) { MySignals_BLE.bonded_and_connected_flag = 0; MySignals_BLE.bonding_fail = 1; } else if (flag == BLE_EVENT_CONNECTION_STATUS) { if (MySignals_BLE.event[5] == 0x03) { //Connection correct MySignals_BLE.app_connected_flag = 1; } } else if (flag == BLE_EVENT_CONNECTION_DISCONNECTED) { MySignals_BLE.bonded_and_connected_flag = 0; MySignals_BLE.bonding_fail = 1; } else { //Do nothing } if (MySignals_BLE.bonding_correct && MySignals_BLE.app_connected_flag) { //TFT message: "Connected!" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[12]))); tft.drawString(buffer_tft, 0, 120, 2); //TFT message: "Sensor list:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[14]))); tft.drawString(buffer_tft, 0, 135, 2); //// SENSORES //TFT message: "Airflow:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[20]))); tft.drawString(buffer_tft, 0, 150, 2); //TFT message: "Temperature:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[21]))); tft.drawString(buffer_tft, 0, 165, 2); //TFT message: "Position:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[22]))); tft.drawString(buffer_tft, 0, 180, 2); //TFT message: "GSR:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[23]))); tft.drawString(buffer_tft, 0, 195, 2); //TFT message: "ECG:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[24]))); tft.drawString(buffer_tft, 0, 210, 2); //TFT message: "EMG:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[25]))); tft.drawString(buffer_tft, 0, 225, 2); //TFT message: "Snore:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[26]))); tft.drawString(buffer_tft, 0, 240, 2); //TFT message: "SPO2:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[28]))); tft.drawString(buffer_tft, 0, 255, 2); //TFT message: "Glucometer:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[29]))); tft.drawString(buffer_tft, 0, 270, 2); //TFT message: "Spirometer:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[30]))); tft.drawString(buffer_tft, 0, 285, 2); MySignals_BLE.bonded_and_connected_flag = 1; } } // Si el bonding ha fallado reiniciar el modulo y recargar pagina if (MySignals_BLE.bonding_fail == 1) { //TFT message: "Connection failed. Reseting" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[13]))); tft.drawString(buffer_tft, 0, 120, 2); MySignals_BLE.bonded_and_connected_flag = 1; MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } } //4. READ SENSOR LIST AND UPDATE VALUES OF SENSORS if ((MySignals_BLE.ble_mode_flag == slave_mode) && (MySignals_BLE.app_connected_flag == 1)) { MySignals.enableSensorUART(BLE); //MySignals.pauseInterrupt(); if (MySignals_BLE.readLocalAttribute(handle_3_0) == 0) { sprintf(buffer_tft, "%X %X %X ", MySignals_BLE.attributeValue[1], MySignals_BLE.attributeValue[0], MySignals_BLE.attributeValue[2]); tft.drawString(buffer_tft, 100, 135, 2); sensor_list_mode = MySignals_BLE.attributeValue[2]; selected_airflow = MySignals_BLE.attributeValue[0] & 0b00000001; selected_gluco_uart = MySignals_BLE.attributeValue[0] & 0b00000010; selected_spiro = MySignals_BLE.attributeValue[0] & 0b00000100; selected_gluco_ble = MySignals_BLE.attributeValue[0] & 0b00001000; selected_bp_uart = MySignals_BLE.attributeValue[0] & 0b00010000; selected_bp_ble = MySignals_BLE.attributeValue[0] & 0b00100000; selected_scale_ble = MySignals_BLE.attributeValue[0] & 0b01000000; selected_ecg = MySignals_BLE.attributeValue[0] & 0b10000000; selected_eeg = MySignals_BLE.attributeValue[1] & 0b00000001; selected_emg = MySignals_BLE.attributeValue[1] & 0b00000010; selected_gsr = MySignals_BLE.attributeValue[1] & 0b00000100; selected_position = MySignals_BLE.attributeValue[1] & 0b00001000; selected_snore = MySignals_BLE.attributeValue[1] & 0b00010000; selected_spo2_uart = MySignals_BLE.attributeValue[1] & 0b00100000; selected_spo2_ble = MySignals_BLE.attributeValue[1] & 0b01000000; selected_temp = MySignals_BLE.attributeValue[1] & 0b10000000; } //MySignals.resumeInterrupt(); if (selected_gluco_uart) { MySignals.enableSensorUART(GLUCOMETER); delay(10); MySignals.getGlucose(); if ( ((MySignals.glucoseLength > 0) && (MySignals.glucometerData[0].hour != last_measure_hour_gluco) && (MySignals.glucometerData[0].minutes != last_measure_minutes_gluco) && (MySignals.glucometerData[0].hour != 255)) || ((MySignals.glucoseLength > 0) && (last_measure_number_gluco != MySignals.glucoseLength) && (MySignals.glucometerData[0].hour != 255)) ) { last_measure_hour_gluco = MySignals.glucometerData[0].hour; last_measure_minutes_gluco = MySignals.glucometerData[0].minutes; last_measure_number_gluco = MySignals.glucoseLength; if (MySignals.glucometerData[MySignals.glucoseLength - 1].glucose != 0) { //Last measure uint8_t gluco_vector[9] = { MySignals.glucometerData[MySignals.glucoseLength - 1].year, MySignals.glucometerData[MySignals.glucoseLength - 1].month, MySignals.glucometerData[MySignals.glucoseLength - 1].day, MySignals.glucometerData[MySignals.glucoseLength - 1].hour, MySignals.glucometerData[MySignals.glucoseLength - 1].minutes, MySignals.glucometerData[MySignals.glucoseLength - 1].glucose, MySignals.glucometerData[MySignals.glucoseLength - 1].meridian, MySignals.glucoseLength, MySignals.glucoseLength }; tft.fillRect(70, 272, 100, 11, ILI9341_BLACK); tft.drawNumber(MySignals.glucometerData[MySignals.glucoseLength - 1].glucose, 80, 270, 2); SPI.end(); //MySignals.pauseInterrupt(); // Write local attributes MySignals.enableSensorUART(BLE); MySignals_BLE.writeLocalAttribute(handle_3_9, gluco_vector, 9); //MySignals.resumeInterrupt(); } } } if (selected_spiro) { MySignals.enableSensorUART(SPIROMETER); if (MySignals.getStatusSpiro() == 1) { delay(10); MySignals.getSpirometer(); if ( ((MySignals.spir_measures > 0) && (MySignals.spirometerData[MySignals.spir_measures - 1].spir_pef < 1000) && (MySignals.spirometerData[0].spir_hour != last_measure_hour_spiro) && (MySignals.spirometerData[0].spir_minutes != last_measure_minutes_spiro)) || ((MySignals.spir_measures > 0) && (MySignals.spirometerData[MySignals.spir_measures - 1].spir_pef < 1000) && (last_measure_number_spiro != MySignals.spir_measures)) ) { last_measure_hour_spiro = MySignals.spirometerData[0].spir_hour; last_measure_minutes_spiro = MySignals.spirometerData[0].spir_minutes; last_measure_number_spiro = MySignals.spir_measures; if (MySignals.spirometerData[MySignals.spir_measures - 1].spir_pef < 1000) { uint8_t spir_pef_low = MySignals.spirometerData[MySignals.spir_measures - 1].spir_pef & 0b0000000011111111; uint8_t spir_pef_high = (MySignals.spirometerData[MySignals.spir_measures - 1].spir_pef & 0b1111111100000000) / 256; uint8_t spir_fev_low = MySignals.spirometerData[MySignals.spir_measures - 1].spir_fev & 0b0000000011111111; uint8_t spir_fev_high = (MySignals.spirometerData[MySignals.spir_measures - 1].spir_fev & 0b1111111100000000) / 256; //Last measure uint8_t spir_vector[11] = { MySignals.spirometerData[MySignals.spir_measures - 1].spir_year, MySignals.spirometerData[MySignals.spir_measures - 1].spir_month, MySignals.spirometerData[MySignals.spir_measures - 1].spir_day, MySignals.spirometerData[MySignals.spir_measures - 1].spir_hour, MySignals.spirometerData[MySignals.spir_measures - 1].spir_minutes, spir_pef_low, spir_pef_high, spir_fev_low, spir_fev_high, MySignals.spir_measures, MySignals.spir_measures }; tft.fillRect(70, 287, 100, 11, ILI9341_BLACK); tft.drawNumber(MySignals.spirometerData[MySignals.spir_measures - 1].spir_pef, 80, 285, 2); SPI.end(); //MySignals.pauseInterrupt(); // Write local attributes MySignals.enableSensorUART(BLE); MySignals_BLE.writeLocalAttribute(handle_3_10, spir_vector, 11); //MySignals.resumeInterrupt(); } } } } if (selected_spo2_uart) { MySignals.enableSensorUART(PULSIOXIMETER); if (MySignals.getPulsioximeter() == 1) { uint8_t spo2_vector[2] = { MySignals.pulsioximeterData.O2, MySignals.pulsioximeterData.BPM }; tft.fillRect(70, 257, 100, 11, ILI9341_BLACK); tft.drawNumber(MySignals.pulsioximeterData.BPM, 80, 255, 2); tft.drawNumber(MySignals.pulsioximeterData.O2, 150, 255, 2); SPI.end(); //MySignals.pauseInterrupt(); // Write local attributes MySignals.enableSensorUART(BLE); MySignals_BLE.writeLocalAttribute(handle_3_8, spo2_vector, 2); //MySignals.resumeInterrupt(); } } if (selected_airflow) { // PPM flag initialization //MySignals.airflowFlagPPM = 1; //MySignals.airflow_ppm = MySignals.airflowDataPPMBalanced; SPI.end(); uint16_t airflow_raw = (uint16_t)MySignals.getAirflow(DATA); uint8_t airflow_raw_low = airflow_raw & 0b0000000011111111; uint8_t airflow_raw_high = (airflow_raw & 0b1111111100000000) / 256; tft.fillRect(70, 152, 100, 11, ILI9341_BLACK); tft.drawNumber(airflow_raw, 80, 150, 2); tft.drawNumber(MySignals.airflow_ppm, 150, 150, 2); uint8_t airflow_vector[3] = { airflow_raw_low, airflow_raw_high, MySignals.airflow_ppm }; MySignals.enableSensorUART(BLE); //MySignals.pauseInterrupt(); MySignals_BLE.writeLocalAttribute(handle_3_5, airflow_vector, 3); //MySignals.resumeInterrupt(); } if (selected_temp) { SPI.end(); uint16_t temp_dummy = MySignals.getTemperature() * 100; uint8_t temp_low = temp_dummy & 0b0000000011111111; uint8_t temp_high = (temp_dummy & 0b1111111100000000) / 256; tft.fillRect(70, 167, 100, 11, ILI9341_BLACK); tft.drawFloat(float(temp_dummy / 100.0), 1, 80, 165, 2); uint8_t temp_vector[2] = { temp_low, temp_high }; MySignals.enableSensorUART(BLE); MySignals_BLE.writeLocalAttribute(handle_3_2, temp_vector, 2); } if (selected_position) { SPI.end(); uint8_t position = MySignals.getBodyPosition(); tft.fillRect(70, 182, 100, 11, ILI9341_BLACK); tft.drawNumber(position, 80, 180, 2); uint8_t position_vector[4] = { position, MySignals.x_data, MySignals.y_data, MySignals.z_data }; MySignals.enableSensorUART(BLE); MySignals_BLE.writeLocalAttribute(handle_3_1, position_vector, 4); } if (selected_gsr) { SPI.end(); MySignals.getGSR(); tft.fillRect(70, 197, 100, 11, ILI9341_BLACK); tft.drawNumber(MySignals.gsr_raw, 80, 195, 2); uint8_t gsr_raw_low = MySignals.gsr_raw & 0b0000000011111111; uint8_t gsr_raw_high = (MySignals.gsr_raw & 0b1111111100000000) / 256; uint8_t gsr_vector[2] = { gsr_raw_low, gsr_raw_high }; MySignals.enableSensorUART(BLE); MySignals_BLE.writeLocalAttribute(handle_3_6, gsr_vector, 2); } if (selected_ecg) { SPI.end(); MySignals.ECGFlagBPM = 1; uint16_t ecg_raw = MySignals.getECG(); tft.fillRect(70, 212, 100, 11, ILI9341_BLACK); tft.drawNumber(ecg_raw, 80, 210, 2); uint8_t ecg_raw_low = ecg_raw & 0b0000000011111111; uint8_t ecg_raw_high = (ecg_raw & 0b1111111100000000) / 256; uint8_t ecg_vector[3] = { ecg_raw_low, ecg_raw_high, MySignals.ECGDataBPMBalanced }; MySignals.enableSensorUART(BLE); MySignals_BLE.writeLocalAttribute(handle_3_4, ecg_vector, 3); } if (selected_emg) { SPI.end(); //MySignals.EMGFlagCPM = 1; uint16_t emg_raw = MySignals.getEMG(); uint8_t emg_raw_low = emg_raw & 0b0000000011111111; uint8_t emg_raw_high = (emg_raw & 0b1111111100000000) / 256; tft.fillRect(70, 227, 100, 11, ILI9341_BLACK); tft.drawNumber(emg_raw, 80, 225, 2); uint8_t emg_vector[3] = { emg_raw_low, emg_raw_high, MySignals.EMGDataCPMBalanced }; MySignals.enableSensorUART(BLE); MySignals_BLE.writeLocalAttribute(handle_3_3, emg_vector, 3); } if (selected_snore) { SPI.end(); //MySignals.snoreFlagSPM = 1; uint16_t snore_raw = MySignals.getSnore(); uint8_t snore_raw_low = snore_raw & 0b0000000011111111; uint8_t snore_raw_high = (snore_raw & 0b1111111100000000) / 256; tft.fillRect(70, 242, 100, 11, ILI9341_BLACK); tft.drawNumber(snore_raw, 80, 240, 2); uint8_t snore_vector[3] = { snore_raw_low, snore_raw_high, MySignals.snoreDataSPMBalanced }; MySignals.enableSensorUART(BLE); MySignals_BLE.writeLocalAttribute(handle_3_11, snore_vector, 3); } // parse the status: 0 not connected; 1 connected; 2 encrypted; // 4 connection completed; 8 parameters changed MySignals.enableSensorUART(BLE); //MySignals.pauseInterrupt(); if (MySignals_BLE.getStatus(MySignals_BLE.connection_handle) == 0) { //TFT message: "Disconnected" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[15]))); tft.drawString(buffer_tft, 0, 120, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } //MySignals.resumeInterrupt(); } }
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <MySignals_BLE.h> #include <Wire.h> #include <SPI.h> char buffer_tft[30]; Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); unsigned long previous; // Sensor list bool selected_airflow; bool selected_ecg; bool selected_emg; bool selected_gsr; bool selected_position; bool selected_snore; bool selected_temp; bool selected_spiro; bool selected_eeg; bool selected_spo2_uart; bool selected_bp_uart; bool selected_gluco_uart; bool selected_scale_ble; bool selected_spo2_ble; bool selected_bp_ble; bool selected_gluco_ble; uint8_t blood_syst_low; uint8_t blood_syst_high; uint8_t blood_dias_low; uint8_t blood_dias_high; uint8_t blood_bpm_low; uint8_t blood_bpm_high; void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.drawString("Connect blood pressure to continue", 0, 0, 2); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLOODPRESSURE); while (MySignals.getStatusBP() == 0) { delay(100); } delay(100); if (MySignals.getBloodPressure() == 1) { if (MySignals.bloodPressureData.systolic != 0) { blood_syst_low = MySignals.bloodPressureData.systolic & 0b0000000011111111; blood_syst_high = (MySignals.bloodPressureData.systolic & 0b1111111100000000) / 256; blood_dias_low = MySignals.bloodPressureData.diastolic & 0b0000000011111111; blood_dias_high = (MySignals.bloodPressureData.diastolic & 0b1111111100000000) / 256; blood_bpm_low = MySignals.bloodPressureData.pulse & 0b0000000011111111; blood_bpm_high = (MySignals.bloodPressureData.pulse & 0b1111111100000000) / 256; } } MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { //TFT message: "BLE init ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[1]))); tft.drawString(buffer_tft, 0, 15, 2); } else { //TFT message:"BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } else { //TFT message: "BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } void loop() { //1. SET MODE: SLAVE (VISIBLE TO APP) while ((MySignals_BLE.ble_mode_flag == master_mode)) { if (MySignals_BLE.setMode(slave_mode) == 0) { //TFT message: "Slave mode ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[3]))); tft.drawString(buffer_tft, 0, 30, 2); MySignals_BLE.ble_mode_flag = slave_mode; } else { //TFT message: "Slave mode fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[4]))); tft.drawString(buffer_tft, 0, 30, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } //2. SET BONDABLE MODE if (MySignals_BLE.bond_mode_and_mitm == 0) { if (MySignals_BLE.setBondableMode(BLE_ENABLE_BONDING) == 0) { //TFT message: "Bondable mode ok" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[5]))); tft.drawString(buffer_tft, 0, 45, 2); //3. SET SM PARAMETERS if (MySignals_BLE.setSMParameters(BLE_ENABLE_MITM) == 0) { //TFT message: "SM parameters ok" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[7]))); tft.drawString(buffer_tft, 0, 60, 2); MySignals_BLE.bond_mode_and_mitm = 1; } else { //TFT message: "SM parameters fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[8]))); tft.drawString(buffer_tft, 0, 60, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } else { //TFT message: "Bondable mode fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[6]))); tft.drawString(buffer_tft, 0, 45, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } //3. BONDING AND CONNECTION CONFIGURATION if ((MySignals_BLE.ble_mode_flag == slave_mode) && (MySignals_BLE.bonded_and_connected_flag == 0)) { MySignals_BLE.bonding_correct = 0; MySignals_BLE.app_connected_flag = 0; MySignals_BLE.bonding_fail = 0; ///////////////////// //TFT message: "Waiting connections..." strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[9]))); tft.drawString(buffer_tft, 0, 75, 2); uint8_t flag = MySignals_BLE.waitEvent(500); if (flag == BLE_EVENT_CONNECTION_STATUS) { MySignals_BLE.app_connected_flag = 1; } else if (flag == BLE_EVENT_SM_BOND_STATUS) { if (MySignals_BLE.event[6] == 0x01) { MySignals_BLE.bonding_correct = 1; delay(1000); } } else if (flag == 0) { // If there are no events, then no one tried to connect } else if (flag == BLE_EVENT_ATTRIBUTES_VALUE) { //Already connected MySignals_BLE.app_connected_flag = 1; MySignals_BLE.bonding_correct = 1; MySignals_BLE.bonded_and_connected_flag = 1; } else { // Other event received from BLE module } ///////////////////// if ((MySignals_BLE.bonding_correct == 1) || MySignals_BLE.app_connected_flag == 1) { //TFT message: "Connection detected..." strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[10]))); tft.drawString(buffer_tft, 0, 90, 2); previous = millis(); while ((MySignals_BLE.bonded_and_connected_flag == 0) && (MySignals_BLE.bonding_fail == 0)) { // Timeout 30 sg if ((millis() - previous) > 30000) { MySignals_BLE.bonding_fail = 1; } flag = MySignals_BLE.waitEvent(1000); if (flag == 0) { //Do nothing } else if (flag == BLE_EVENT_SM_PASSKEY_DISPLAY) { uint32_t passkey_temp = uint32_t(MySignals_BLE.event[5]) + uint32_t(MySignals_BLE.event[6]) * 256 + uint32_t(MySignals_BLE.event[7]) * 65536 + uint32_t(MySignals_BLE.event[8]) * 16777216; //TFT message: "Passkey:";" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[11]))); tft.drawString(buffer_tft, 0, 105, 2); tft.drawNumber(passkey_temp, 50, 105, 2); } else if (flag == BLE_EVENT_ATTRIBUTES_VALUE) { //Already connected MySignals_BLE.app_connected_flag = 1; MySignals_BLE.bonding_correct = 1; MySignals_BLE.bonded_and_connected_flag = 1; } else if (flag == BLE_EVENT_SM_BOND_STATUS) { if (MySignals_BLE.event[6] == 0x01) { //Man-in-the-Middle mode correct MySignals_BLE.bonding_correct = 1; } } else if (flag == BLE_EVENT_CONNECTION_FEATURE_IND) { //Do nothing } else if (flag == BLE_EVENT_CONNECTION_VERSION_IND) { //Do nothing } else if (flag == BLE_EVENT_SM_BONDING_FAIL) { MySignals_BLE.bonded_and_connected_flag = 0; MySignals_BLE.bonding_fail = 1; } else if (flag == BLE_EVENT_CONNECTION_STATUS) { if (MySignals_BLE.event[5] == 0x03) { //Connection correct MySignals_BLE.app_connected_flag = 1; } } else if (flag == BLE_EVENT_CONNECTION_DISCONNECTED) { MySignals_BLE.bonded_and_connected_flag = 0; MySignals_BLE.bonding_fail = 1; } else { //Do nothing } if (MySignals_BLE.bonding_correct && MySignals_BLE.app_connected_flag) { //TFT message: "Connected!" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[12]))); tft.drawString(buffer_tft, 0, 120, 2); //TFT message: "Sensor list:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[14]))); tft.drawString(buffer_tft, 0, 135, 2); //// SENSORS //TFT message: "Blood pressure:" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[27]))); tft.drawString(buffer_tft, 0, 150, 2); MySignals_BLE.bonded_and_connected_flag = 1; } } // Si el bonding ha fallado reiniciar el modulo y recargar pagina if (MySignals_BLE.bonding_fail == 1) { //TFT message: "Connection failed. Reseting" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[13]))); tft.drawString(buffer_tft, 0, 120, 2); MySignals_BLE.bonded_and_connected_flag = 1; MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } } } //4. READ SENSOR LIST AND UPDATE VALUES OF SENSORS if ((MySignals_BLE.ble_mode_flag == slave_mode) && (MySignals_BLE.app_connected_flag == 1)) { //MySignals.enableSensorUART(BLE); //MySignals.pauseInterrupt(); if (MySignals_BLE.readLocalAttribute(handle_3_0) == 0) { sprintf(buffer_tft, "%X %X %X ", MySignals_BLE.attributeValue[1], MySignals_BLE.attributeValue[0], MySignals_BLE.attributeValue[2]); tft.drawString(buffer_tft, 100, 135, 2); selected_airflow = MySignals_BLE.attributeValue[0] & 0b00000001; selected_gluco_uart = MySignals_BLE.attributeValue[0] & 0b00000010; selected_spiro = MySignals_BLE.attributeValue[0] & 0b00000100; selected_gluco_ble = MySignals_BLE.attributeValue[0] & 0b00001000; selected_bp_uart = MySignals_BLE.attributeValue[0] & 0b00010000; selected_bp_ble = MySignals_BLE.attributeValue[0] & 0b00100000; selected_scale_ble = MySignals_BLE.attributeValue[0] & 0b01000000; selected_ecg = MySignals_BLE.attributeValue[0] & 0b10000000; selected_eeg = MySignals_BLE.attributeValue[1] & 0b00000001; selected_emg = MySignals_BLE.attributeValue[1] & 0b00000010; selected_gsr = MySignals_BLE.attributeValue[1] & 0b00000100; selected_position = MySignals_BLE.attributeValue[1] & 0b00001000; selected_snore = MySignals_BLE.attributeValue[1] & 0b00010000; selected_spo2_uart = MySignals_BLE.attributeValue[1] & 0b00100000; selected_spo2_ble = MySignals_BLE.attributeValue[1] & 0b01000000; selected_temp = MySignals_BLE.attributeValue[1] & 0b10000000; } if (selected_bp_uart) { uint8_t bp_vector[6] = { blood_dias_low, blood_dias_high, blood_syst_low, blood_syst_high, blood_bpm_low, blood_bpm_high }; SPI.end(); tft.fillRect(70, 152, 160, 11, ILI9341_BLACK); tft.drawNumber(MySignals.bloodPressureData.diastolic, 110, 150, 2); tft.drawNumber(MySignals.bloodPressureData.systolic, 140, 150, 2); tft.drawNumber(MySignals.bloodPressureData.pulse, 170, 150, 2); // Write local attributes MySignals.enableSensorUART(BLE); //sensor.pauseInterrupt(); MySignals_BLE.writeLocalAttribute(handle_3_7, bp_vector, 6); //sensor.resumeInterrupt(); } // parse the status: 0 not connected; 1 connected; 2 encrypted; // 4 connection completed; 8 parameters changed MySignals.enableSensorUART(BLE); //MySignals.pauseInterrupt(); if (MySignals_BLE.getStatus(MySignals_BLE.connection_handle) == 0) { //TFT message: "Disconnected" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[15]))); tft.drawString(buffer_tft, 0, 120, 2); MySignals_BLE.hardwareReset(); delay(100); MySignals_BLE.initialize_BLE_values(); } //MySignals.resumeInterrupt(); } }
Follow the previous steps depending of the smartphone platform used.
Delete bonding example:
/* * * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * By using it you accept the MySignals Terms and Conditions. * You can find them at: http://libelium.com/legal * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Version: 0.1 * Design: David Gascon * Implementation: Luis Martin / Victor Boria */ #include <Adafruit_GFX_AS.h> #include <Adafruit_ILI9341_AS.h> #include <MySignals.h> #include <MySignals_BLE.h> #include <Wire.h> #include <SPI.h> char buffer_tft[30]; Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(TFT_CS, TFT_DC); void setup() { MySignals.begin(); tft.init(); tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); //TFT message: Welcome to MySignals strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[0]))); tft.drawString(buffer_tft, 0, 0, 2); Serial.begin(115200); MySignals.initSensorUART(); MySignals.enableSensorUART(BLE); MySignals_BLE.hardwareReset(); MySignals_BLE.initialize_BLE_values(); if (MySignals_BLE.initModule() == 1) { if (MySignals_BLE.sayHello() == 1) { //TFT message: "BLE init ok"; strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[1]))); tft.drawString(buffer_tft, 0, 15, 2); } else { //TFT message:"BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } } else { //TFT message: "BLE init fail" strcpy_P((char*)buffer_tft, (char*)pgm_read_word(&(table_MISC[2]))); tft.drawString(buffer_tft, 0, 15, 2); while (1) { }; } delay(5000); uint16_t bonding_number = MySignals_BLE.getBonding(); sprintf(buffer_tft, "Bondings before: %d", bonding_number); tft.drawString(buffer_tft, 0, 30, 2); MySignals_BLE.deleteBonding(); bonding_number = MySignals_BLE.getBonding(); sprintf(buffer_tft, "Bondings after: %d", bonding_number); tft.drawString(buffer_tft, 0, 45, 2); } void loop() { }
Here you can find a solution for all possible know issues the user can face on MySignals applications (iPhone/iPad and Android).
Android
iPhone/iPad
MySignals mobile applications was tested on these devices:
BQ | Edison 3 | 4.4.2 | 2 GB | v3.4.67 |
Apple | iPad 2 | 8.4.1 | 512 MB | v5.4.00 |
Apple | iPhone 4S | 8.3 | 512 MB | v5.4.00 |
LG | G2 | 5.0.2 | 2 GB | v3.4.0 |
Moto | G2 | 6 | 1 GB | v3.4.42 |
Nexus | 10 | 5.1.1 | 2 GB | v3.4.67 |
Nexus | 4 | 5.1.1 | 2 GB | v3.4.0 |
BQ | AquarisE5 HD | 4.4.2 | 2 GB | v3.4.67 |
Huawei | T17.0 | 4.4.2 | 1 GB | v3.10.17 |
The data sent via BLE through the APP can be visualized on MySignals website.
Navigate through the history of previously stored data or even create many users in order to save the biometric information linked to a specific profile.
How do I ensure the privacy of the biometric data sent?
Privacy is one of the key points in this kind of applications. For this reason the platform includes several security levels:
If you are interested in using this mode you should connect MySignals HW through BLE with our Smartphone APP.
- How can I see values older than one month in my Cloud account?
MySignals Cloud Web Service (section 5.2, page 25) allows currently to see graphics for values corresponding to the last month. By the end of 2017 a new version of the Cloud Service will allow to see the complete historical data of any of the users.
However, if you want to access to this data now, you can use the Cloud API Method 3 to get the sensor values of a member (see section 9.1.1, page 225), allows to retrieve values for any desired time slot.
If you have any doubt just write a post in the MySignals forum.
MySignals application will have an user account to login into the system, this account is important to make cloud call and store information. If the user does not have an account the user cannot use MySignals application.
To access to the Libelium Cloud using your web browser go to: https://cloud.libelium.com/mysignals/
If you don't have user/passw please contact to our Sales Dep. at: sales@libelium.com
In each account you may have several user profiles. You can create, delete or modify your users.
When the user starts the MySignals application for the first time and setup assistant prompts the user will be able to create a profile once the user logs in. It will show you a “First Steps” wizard in order to help you with the profile and device configuration.
Each profile should be synchronized with cloud to be up-to-date with user information.
To configure MySignals application for each device, we will need to set up common parameters.
You can see all the data of each device or user in the user's data section.
Using the Department, User or Device configuration sections you can create, configure or delete them.
You can configure too your personal profile.
Now you can select the patient or device that you want monitor.
First of all choose the sensor that you want to visualize. You can use the fast access menu situated on the left side of the Web Server.
In the General view the update time to the Cloud is 20s. In the Detail view is 10s.
Then you can see the General Sensor page. MySignals Web Server will monitor all the parameters in General Mode where it only show numeric values.
You can see in this screen a color code in the sensor logos:
Finally, you can go to detail mode for each sensor selected. Press in the logo of the sensor in General Mode if you want to see the graphical and numeric values of a specific sensor.
The tabs 'day', 'week', 'month' in the charts represent the historical data of the member for this last periods of time.
You will need to provide some data to the cloud before you can see values here.
For instance the 'day' tab shows data sorted by hours. you will need to wait 1 hour until you can see values here. The same applies to the other tabs.
If an appropriate sensor data on the finger is not measured, it is necessary to use other more sensitive areas like the armpit.
General view
The interface for viewing the stored measurements has the following elements.
Sensors Detail view improvement
The sensors “Detail view” enables access to the history of the information previously stored. You can visualize data by choosing the month, the day and the hour.
In this view, you can interact with these three elements:
Now you can access to the Admin Dashboard to check the the global Database Storage, the Traffic I/O consumption and the API Calls (for the Dev Mode).
You can delete the registers of your users in order to free up space in the database using the “Usage by Member” panel.
There are plans for regular users and for developers depending on what usage you want to give to MySignals.
User Cloud Plans
The user plans are meant to be used to test the performance of MySignals. These are the best plans if you want to try in a quick and easy way the MySignals Kit including all the sensors on different users as each one can have its own profile. All the data is sent to the Libelium Cloud, so users do not need to set up their own servers.
IMPORTANT: You can always use MySignals at no cost in the standalone and Bluetooth modes (only visualization not storage).
*1 Note that each licence is per MySignals Device.
*2 To avoid illicit use of the network, there is a daily and monthly maximum transmission rate.
*3 For specific plans contact our Business Dev Team (sales@libelium.com).
You can purchase the license which best suits your project from February 20th. There will be two modalities of acquisition:
Developer Cloud Plans
The developers plans are the best option for users who want to store the data gathered by MySignals in their own servers. This type of plans allow to use the Cloud API to read the information from the Libelium Cloud and write it in their own Cloud platforms.
IMPORTANT: You can always use MySignals at no cost in the standalone and Bluetooth modes (only visualization not storage).
*1 Note that each licence is per MySignals Device.
*2 To avoid illicit use of the network, there is a daily and monthly maximum transmission rate.
*3 For specific plans contact our Business Dev Team (sales@libelium.com).
You can purchase the license which best suits your project from February 20th. There will be two modalities of acquisition:
You can purchase the license which best suits your project from February 20th. There will be two modalities of acquisition:
MySignals allows to share data with the cloud, and perform real-time analysis.
MySignals Web Server Application is a real-time large-dataset viewing and plotting tool and has built-in data analysis functionality. It is very user-friendly and contains many powerful built-in features. MySignals Web Server Application is an application that allows you to configure MySignals for creating profiles and users and help you to visualize all the data measured.
This application is available in:
https://cloud.libelium.com/mysignals/
MySignals web allows you to playback your previously recorded sessions and zoom in and out of specific periods. MySignals is our easy-to-use, versatile, and scalable software for real-time biosignals visualization, capable of direct interaction with MySignals. It includes sensor data acquisition from multiple devices, and multiples users.
Users can read the data stored in the Cloud by using the Open API available
In order to access to the MySignals web application is necessary to have SCM account and a valid license.
SCM stands for “Services Cloud Manager”, and is Libelium's platform from where you can manage your devices an Cloud Services
After this steps you can start using MySignals Cloud service with the Website, Mobile APP and Developer API, in the terms and quotas contained in the license that you purchased.
The “Licenses” section gives control of the licenses for the SCM. Licenses enable services for your devices. The “My Licenses” panel lists the currently active licenses and the historic data of all the expired licenses. If you recently purchased a License, go to the “Get Licenses” panel to enter its activation code.
License activation codes are unique and only one use is allowed (one license only applies to one user, to one account). Despite the ownership of one device can be transferred (and one device can be managed by several users), the ownership of a license cannot be transferred.
Any license has an expiration time associated to it. It is important to note that time starts running from the moment the user activates it by entering its activation code (after entering the activation code of a license, it may be required to activate it in the “Service” panel).
If the user has one active license and activates a new one, time keeps running for both the old and the new licenses (in other words, time is never paused).
The “My Licenses” panel shows the licenses and the status of each one. The “Active” tab shows the list of the licenses which are currently active, and the “Expired” tab shows the list of previously used licenses.
The information displayed is:
The MySignals Cloud Licenses activation process will be ready-to-use from February 20th.License registration is done in the “Get Licenses” panel. It is a 2-step procedure: enter a valid license activation code and confirm the action.
Entering a Single Activation Code will register one license. A Group Activation Code will register all devices belonging to the Sales Order, but not the licenses it may contain.
The SCM will validate the activation code, displaying a visual confirmation. When the process is finished successfully, a message will show that the license has been correctly added to the “My Licenses” panel.
If the process could not be finished correctly, a message will notify the error. For example, “invalid activation code: please check that the activation code you entered is valid”.
Developers may migrate the information stored in the Libelium Cloud to a third party Cloud server easily using the API Cloud provided.
Telemedicine is the use of telecommunication and information technologies in order to provide clinical health care at a distance. It helps eliminate distance barriers and can improve access to medical services that would often not be consistently available in distant rural communities. It is also used to save lives in critical care and emergency situations.
Although there were distant precursors to telemedicine, it is essentially a product of 20th century telecommunication and information technologies. These technologies permit communications between patient and medical staff with both convenience and fidelity, as well as the transmission of medical, imaging and health informatics data from one site to another.
If you need some extra WiFi features for your project. We have a more powerful WiFi available for these purposes:
Roving RN-171 module fits in the XBee socket of our Communication Shield and allows to connect your My Signals to a WiFi network.
Example code
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include <Wire.h> #include "SPI.h" //Enter here your wifi network data #define wifi_ssid "libelium_wsn2" #define wifi_password "libelium.2012_" void setup() { //Write here you correct baud rate Serial.begin(9600); MySignals.begin(); /* expanderState is initialized with B10000001 Expansor pin library names: EXP_3G_ON EXP_TOUCH_CS EXP_BT_POWER EXP_BT_KEY EXP_ADC_CS EXP_SNORE_POT EXP_RESET_BLE EXP_WIFI_ON */ //Enable WiFi module power (expansion board) -> bit7:0 bitClear(MySignals.expanderState, EXP_WIFI_ON); MySignals.expanderWrite(MySignals.expanderState); MySignals.initSensorUART(); MySignals.enableSensorUART(EXPANSION); sendCommand("exit\r", "EXIT", 2000); delay(2000); if (enterConfig(2000)) { sendCommand("leave\r", "DeAuth", 2000); delay(1000); // Sets DHCP and TCP protocol sendCommand("set ip dhcp 1\r", "AOK", 2000); delay(1000); sendCommand("set ip protocol 18\r", "AOK", 2000); delay(1000); // Configures the way to join the network AP, sets the encryption of the // network and joins it sendCommand("set wlan join 0\r", "AOK", 2000); //The auto-join feature is disabled delay(1000); char aux_str[50]; snprintf(aux_str, sizeof(aux_str), "set wlan phrase %s\r", wifi_password); sendCommand(aux_str, "AOK", 2000); delay(1000); snprintf(aux_str, sizeof(aux_str), "join %s\r", wifi_ssid); uint8_t answer = sendCommand(aux_str, "Associated", 10000); if (answer == 1) { snprintf(aux_str, sizeof(aux_str), "Connected to \"%s\"", wifi_ssid); MySignals.println(aux_str); delay(5000); } else { snprintf(aux_str, sizeof(aux_str), "Error connecting to: \"%s\"", wifi_ssid); MySignals.println(aux_str); delay(1000); } } else { MySignals.println("Wifi no OK"); } } void loop() { delay(5000); } int8_t sendCommand(const char* Command, const char* expected_answer, unsigned int timeout) { char response[300]; uint8_t x = 0, answer = 0; unsigned long previous; memset(response, 0, 300); // Initialize the string delay(100); while ( Serial.available() > 0) Serial.read(); // Clean the input buffer Serial.println(Command); // Send Command x = 0; previous = millis(); // this loop waits for the answer do { if (Serial.available() != 0) { // if there are data in the UART input buffer, reads it and checks for the asnwer response[x] = Serial.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer) != NULL) { answer = 1; } } } // Waits for the asnwer with time out while ((answer == 0) && ((millis() - previous) < timeout)); return answer; } int8_t enterConfig(unsigned int timeout) { char response[100]; uint8_t x = 0, answer = 0; unsigned long previous; memset(response, 0, 100); // Initialize the string delay(100); while ( Serial.available() > 0) Serial.read(); // Clean the input buffer Serial.print("$$$"); // Send Command x = 0; previous = millis(); // this loop waits for the answer do { if (Serial.available() != 0) { // if there are data in the UART input buffer, reads it and checks for the asnwer response[x] = Serial.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, "CMD") != NULL) { answer = 1; } } } // Waits for the asnwer with time out while ((answer == 0) && ((millis() - previous) < timeout)); return answer; }
HC-05 module is an easy to use Bluetooth SPP (Serial Port Protocol) module, designed for transparent wireless serial connection setup.
Serial port Bluetooth module is fully qualified Bluetooth V2.0+EDR (Enhanced Data Rate) 3Mbps Modulation with complete 2.4GHz radio transceiver and baseband. It uses CSR Bluecore 04-External single chip Bluetooth system with CMOS technology and with AFH(Adaptive Frequency Hopping Feature).
Technical steps for pairing with EEG sensor.
BT 2.0 basic configuration example
Upload the next code for configure the BT 2.0 module to connect with a specific EEG sensor:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { //Try different baudrates, for example: //Serial.begin(57600); Serial.begin(38400); //You can use the configuration examples with the correct //AT+UART=**** command in order to change the baudrate MySignals.begin(); MySignals.expanderWrite(B00000100); MySignals.initSensorUART(); MySignals.enableSensorUART(EEG); delay(1000); // Checks if the BT module is started answer = sendATcommand("AT", "OK", 6000); if (answer == 0) { MySignals.println("Error"); // waits for an answer from the module while (answer == 0) { // Send AT every two seconds and wait for the answer answer = sendATcommand("AT", "OK", 6000); } } else if (answer == 1) { MySignals.println("BT HC05 succesfully working!"); } //You better first try these commands via Gateway commands in a serial communication //programa like Cutecom Serial.println("Enter AT commands:"); delay(3000); sendATcommand("AT", "0K", 2000); delay(5000); sendATcommand("AT+UART=57600,0,0", "0K", 2000); delay(5000); sendATcommand("AT+ROLE=1", "0K", 2000); delay(5000); sendATcommand("AT+PSWD=0000", "0K", 2000); delay(5000); sendATcommand("AT+CMODE=0", "0K", 2000); delay(5000); sendATcommand("AT+BIND=****,**,******", "0K", 2000); // mindwave mac delay(5000); sendATcommand("AT+INIT", "0K", 2000); delay(5000); sendATcommand("AT+IAC=9E8B33", "0K", 2000); delay(5000); sendATcommand("AT+CLASS=0", "0K", 2000); delay(5000); sendATcommand("AT+INQM=1,9,48", "0K", 2000); delay(5000); sendATcommand("AT+INQ", "0K", 2000); delay(20000); sendATcommand("AT+PAIR=****,**,******,20", "0K", 2000); //mindwave mac delay(10000); sendATcommand("AT+LINK=****,**,****", "0K", 2000); //mindwave mac delay(10000); } void loop() { } int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout) { uint8_t x = 0, answer = 0; char response[500]; unsigned long previous; memset(response, '\0', 100); // Initialize the string delay(100); while ( Serial.available() > 0) Serial.read(); // Clean the input buffer delay(1000); Serial.println(ATcommand); // Send the AT command x = 0; previous = millis(); // this loop waits for the answer do { if (Serial.available() != 0) { response[x] = Serial.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer1) != NULL) { answer = 1; MySignals.println(response); } } // Waits for the asnwer with time out } while ((answer == 0) && ((millis() - previous) < timeout)); return answer; }
Upload the code to Arduino and watch the Serial monitor.
The MySignals SDK includes all the necessary functions to manage the BT 2.0 and send in real time the data sensor measures. In order to use this functions, before all, you should include the corresponding library.
BT basic connection example
Upload the next code for basic connection with the BT 2.0 module:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" int8_t answer; void setup() { //Try different baudrates, for example: //Serial.begin(57600); Serial.begin(38400); //You can use the configuration examples with the correct //AT+UART=**** command in order to change the baudrate MySignals.begin(); MySignals.expanderWrite(B00000100); MySignals.initSensorUART(); MySignals.enableSensorUART(EEG); delay(1000); // Checks if the BT module is started answer = sendATcommand("AT", "OK", 6000); if (answer == 0) { MySignals.println("Error"); // waits for an answer from the module while (answer == 0) { // Send AT every two seconds and wait for the answer answer = sendATcommand("AT", "OK", 6000); } } else if (answer == 1) { MySignals.println("BT HC05 succesfully working!"); } sendATcommand("AT+NAME?", "OK", 6000); } void loop() { } int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout) { uint8_t x = 0, answer = 0; char response[500]; unsigned long previous; memset(response, '\0', 100); // Initialize the string delay(100); while ( Serial.available() > 0) Serial.read(); // Clean the input buffer delay(1000); Serial.println(ATcommand); // Send the AT command x = 0; previous = millis(); // this loop waits for the answer do { if (Serial.available() != 0) { response[x] = Serial.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer1) != NULL) { answer = 1; MySignals.println(response); } } // Waits for the asnwer with time out } while ((answer == 0) && ((millis() - previous) < timeout)); return answer; }
Upload the code to Arduino and watch the Serial monitor. Here is the USB output using the Arduino IDE serial port terminal.
Basic mode example
Upload the next code for basic mode configuration:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include "Wire.h" #include "SPI.h" void setup() { MySignals.begin(); //Try different baudrates, for example: Serial.begin(57600); //Serial.begin(38400); //You can use the configuration examples with the correct //AT+UART=**** command in order to change the baudrate } void loop() { //Mode: communication Power: off MySignals.expanderWrite(B00001000); delay(1000); //Mode: communication Power: on MySignals.expanderWrite(B00001100); delay(5000); //Mode: AT Power: off MySignals.expanderWrite(B00000000); delay(1000); //Mode: AT Power: on MySignals.expanderWrite(B00000100); delay(5000); }
Upload the code to Arduino and watch the Serial monitor.
The Libelium expansion board allows your MySignals board to communicate wirelessly using Zigbee.
GPRS quadband for Waspmote (SIM900) offers GPRS connection to your MySignals board. You can send your data by SMS or do missed calls from your Arduino to mobile devices... or to another Waspmote connected with this module.
The 3G module for Waspmote enables the connectivity to high speed WCDMA and HSPA cellular networks in order to make possible the creation of the next level of worldwide interactivity projects inside the new "Internet of Things" era.
The new 4G for Waspmote enables the connectivity to high speed LTE, HSPA+, WCDMA cellular networks in order to make possible the creation of the next level of worldwide interactivity projects inside the new "Internet of Things" era.
Example code
This example shows the way to send a text message with the corporal temperature using the GPRS module. Upload the next code:
/* Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. http://www.libelium.com By using it you accept the MySignals Terms and Conditions. You can find them at: http://libelium.com/legal This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Version: 0.1 Design: David Gascon Implementation: Luis Martin / Victor Boria */ #include <MySignals.h> #include <Wire.h> #include "SPI.h" #define phone_number "XXXXXXX" void setup() { //Write here you correct baud rate Serial.begin(115200); MySignals.begin(); /* expanderState is initialized with B10000001 Expansor pin library names: EXP_3G_ON EXP_TOUCH_CS EXP_BT_POWER EXP_BT_KEY EXP_ADC_CS EXP_SNORE_POT EXP_RESET_BLE EXP_WIFI_ON */ //Enable 3G module power -> bit0:0 bitClear(MySignals.expanderState, EXP_3G_ON); MySignals.expanderWrite(MySignals.expanderState); MySignals.initSensorUART(); MySignals.enableSensorUART(EXPANSION); delay(2000); // checks if the module is started uint8_t answer = sendATcommand("AT", "OK", 2000); if (answer == 0) { delay(3000); // waits for an answer from the module while (answer == 0) { // Send AT every two seconds and wait for the answer answer = sendATcommand("AT", "OK", 2000); } } MySignals.println("Connecting network"); while( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 ); MySignals.print("Setting SMS mode..."); sendATcommand("AT+CMGF=1", "OK", 1000); // sets the SMS mode to text MySignals.println("Sending SMS"); char aux_string[30]; sprintf(aux_string,"AT+CMGS=\"%s\"", phone_number); answer = sendATcommand(aux_string, ">", 2000); // send the SMS number if (answer == 1) { Serial.println(F("Test-Arduino-Hello World")); Serial.write(0x1A); answer = sendATcommand("", "OK", 20000); if (answer == 1) { MySignals.println("Sent"); } else { MySignals.println("error"); } } else { MySignals.println("error"); } delay(1000); } void loop() { delay(5000); } int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout) { uint8_t x = 0, answer = 0; char response[100]; unsigned long previous; memset(response, '\0', 100); // Initialize the string delay(100); while ( Serial.available() > 0) Serial.read(); // Clean the input buffer Serial.println(ATcommand); // Send the AT command x = 0; previous = millis(); // this loop waits for the answer do { if (Serial.available() != 0) { response[x] = Serial.read(); x++; // check if the desired answer is in the response of the module if (strstr(response, expected_answer1) != NULL) { answer = 1; } } // Waits for the asnwer with time out } while ((answer == 0) && ((millis() - previous) < timeout)); return answer; }
The Expansion Board allows to connect two radios at the same time. This means a lot of different combinations are now possible using any of the ten radios available for Waspmote: 802.15.4, ZigBee, Bluetooth, RFID, RFID/NFC, WiFi, GSM/GPRS, 3G/GPRS, 868 MHz and 900 MHz.
Libelium MySignal comes with a Cloud API that allows us to read data from our account.
We can see a list our members and read the values measured for a user by MySignal.
This data available in this RESTful API can be used by the customer to create new developments.
There is no need to install anything but you can go to:
https://cloud.libelium.com/mysignals_documentation/api_web/
This is the representation of the API in Swagger format.
If you already know this tool you can skip this section and go to the next section (PHP Example).
Here you can browse all the available methods of the API and see the parameters that you need to use.LS
Is it possible to test the API from here following these steps:
Method 1: Login
Click over '/auth/login', fill the form with your email and password and click 'Try it out!'. If you provided the right data you should see something like this:
The response body contains the token that you should use to access to your data in the following steps. Click 'Authorize', write 'Bearer <your token>' and click authorize.
Method 2: Get list of your members
Click in '/members' section and then “Try it out!” button.
You should see a list with your members.
I you don't see it please make sure that your followed all the instructions of the previous step (Login)
Method 3: Get list of your members
Click '/values' section and fill the parameters as in the picture. Then click “Try it out!” button.
Available values for sensor_id are:
sensor_id | name | units |
---|---|---|
position | Body position | 1 supine, 2 left, 3right, 4 prone, 5 stand or sit, 6 non-defined |
position_x | X axis acc | g |
position_y | X axis acc | g |
position_z | X axis acc | g |
temp | Temperature | Âş C |
emg_cpm | Muscle contraction | cpm |
ecg_bpm | Heart rate | bpm |
airflow_ppm | Respiratory rate | ppm |
gsr_us | Conductance | µs |
gsr_ohms | Resistance | ohms |
blood_dias | Diastolic pressure | mmHg |
blood_syst | Systolic pressure | mmHg |
blood_bpm | Heart rate | bpm |
spo2_oxy | Oxygen saturation | % |
spo2_bpm | Heart rate | bpm |
gluco_mg | Glucose mg | mg/dl |
gluco_mol | Glucose mmol | mmol/l |
spir_pef | PEF | spir_pef |
spir_fev | FEV1 | spir_fev |
snore_spm | Snore rate | spm |
scale_ble_weight | Wheight | kg |
scale_ble_bodyfat | Bodyfat | % |
scale_ble_bonemass | Bonemass | % |
scale_ble_musclemass | Musclemass | % |
scale_ble_visceralfat | Visceralfat | % |
scale_ble_water | Water | % |
scale_ble_calories | Calories | kcal |
blood_ble_dias | Diastolic pressure | mmHg |
blood_ble_syst | Systolic pressure | mmHg |
blood_ble_bpm | Heart rate | bpm |
spo2_ble_oxy | Oxygen saturation | % |
spo2_ble_bpm | Heart rate | bpm |
gluco_ble_mg | Glucose | mg/dl |
gluco_ble_mmol | Glucose mmol | mmol/l |
eeg_ble_attention | EEG Attention | % |
eeg_ble_meditation | EEG meditation | % |
There is an example that you can download from:
http://downloads.libelium.com/mysignals/mysignals_web/api_cloud_v1.zip
This will log you in the system, get a list of your members and get the latest 5 temperature values of one of your users.
<?php /* * * Copyright (C) 2016 Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is distributed WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. * * By using it you accept the MySignals Terms and Conditions. * You can find them at: http://libelium.com/legal * * * Version: 0.1 * Design: David Gascon * Implementation: J.Berrocal */ include('includes/httpful.phar'); // Config $email = 'your@email.com'; $password = 'your_password'; // API Vars $api_base = 'https://api.libelium.com/mysignals'; $api_headers = ['Accept' => 'application/x.webapi.v1+json']; //1.- Login $parameters = json_encode([ 'email' => $email, 'password' => $password ]); $response_login = \Httpful\Request::post($api_base . '/auth/login') ->sendsJson() ->body($parameters) ->addHeaders($api_headers) ->send(); echo "1.- Login: <br><br>".$response_login->raw_body."<hr><br>"; //Save the Token in the header array. if($response_login->code == 200){ $api_headers['Authorization'] = 'Bearer '.$response_login->body->token; } //2.- Get my members $response_members = \Httpful\Request::get($api_base . '/members') ->addHeaders($api_headers) ->send(); echo "2.- Get my members: <br><br><pre>".json_encode($response_members->body, JSON_PRETTY_PRINT)."</pre><hr><br>"; //3.- Get values from the first of my members if(count($response_members->body->data) >= 1){ $member_id = $response_members->body->data[0]->id; $parameters = [ 'member_id' => $member_id, 'sensor_id' => 'temp', 'ts_start' => '2015-01-01 00:00:00', 'ts_end' => '2017-01-01 00:01:00', 'limit' => '5', 'cursor' => '0', 'order' => 'desc' ]; $response_values = \Httpful\Request::get($api_base . '/values?'.http_build_query($parameters)) ->addHeaders($api_headers) ->send(); echo "3.- Get values from one member (member_id= ".$member_id."): <br><br><pre>".json_encode($response_values->body, JSON_PRETTY_PRINT)."</pre><hr><br>"; }
There is a forum available in which you can get support for MySignals Hardware Development Platform.
MySignals Products are not medical devices or healthcare services, nor are they intended for medical diagnosis, cure, mitigation, treatment, advice or prevention of disease. MySignals Products are not finished products, so they are not intended to be purchased by End Users, but by developers, researchers and OEM Customers. Read our Terms & Conditions before buying for a complete understanding.
If you are interested in Internet of Things (IoT) or M2M projects check our open source sensor platform Waspmote which counts with more than 100 sensors available to use 'off the shelf', a complete API with hundreds of ready to use codes and a low consumption mode of just 0.7µA to ensure years of battery life.
Know more at:
Get the Starter Kits at: