Hello everybody.
I have a project regarding health monitoring, I used NodeMCU esp8266 device and ad8232 for ecg and also max30102 for spo2 and bpmI wanted to display these three variables on ubidots using wifi but the platform says there is no information “no found information” , please help if the error is in the code.
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "spo2_algorithm.h"
#include "heartRate.h"
#include "MAX30105.h"
/****************************************
* Define Constants
****************************************/
#define WIFISSID "W00935" // Put your WifiSSID here
#define PASSWORD "35093509" // Put your wifi password here
#define TOKEN "BBFF-xm0r17RezjcZLx2Sve8FMZvNUJduSk" // Put your Ubidots' TOKEN
#define MQTT_CLIENT_NAME "myhealthmontoring" // MQTT client Name, please enter your own 8-12 alphanumeric character ASCII string;
#define device_label "monitoring" // Assig the device label
//define variable's label
#define VARIABLE_LABEL_1 "ecgmoy" // Put the variable label
#define VARIABLE_LABEL_2 "spo2" // Put the variable label
#define VARIABLE_LABEL_3 "beatsPerMinute" // Put the variable label
char mqttBroker[] = "industrial.api.ubidots.com";
char payload[700];
char topic[500];
// Space to store values to send
char str_val_1[10];
char str_val_2[10];
char str_val_3[10];
/****************************************
* Initialize constructors for objects
****************************************/
//ecg
const int N=10; // Définition du nombre d'échantillons
int ecg[N]; // un tableau pour stocker les échantillons lus
int n= 0; // l'indice de l'échantillon courant
float ecgmoy =0 ; // la moyenne des échantillons mémorisés
float somme =0; // la somme des échantillons mémorisés
//spo2
MAX30105 particleSensor;
uint32_t irBuffer[100]; //infrared LED sensor data
uint32_t redBuffer[100]; //red LED sensor data
int32_t bufferLength; //data length
int32_t spo2; //SPO2 value
int8_t validSPO2; //indicator to show if the SPO2 calculation is valid
int32_t heartRate; //heart rate value
int8_t validHeartRate; //indicator to show if the heart rate calculation is valid
// BPM
const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
WiFiClient ubidots;
PubSubClient client(ubidots);
/****************************************
* Auxiliar Functions
****************************************/
void callback(char* topic, byte* payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
Serial.write(payload, length);
Serial.println(topic);
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
// Attemp to connect
if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) {
Serial.println("Connected");
} else {
Serial.print("Failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 2 seconds");
// Wait 2 seconds before retrying
delay(2000);
}
}
}
/****************************************
* Main Functions
*******************0*********************/
void setup() {
Serial.begin(115200);
WiFi.begin(WIFISSID, PASSWORD);
Serial.println();
Serial.print("Waiting for WiFi...");
while (WiFi.status()!= WL_CONNECTED) {
Serial.print(".");
delay(500);
Serial.println("");
Serial.println("WiFi Connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
client.setServer(mqttBroker, 1883);
client.setCallback(callback);
pinMode (LED_BUILTIN, OUTPUT);
Serial.print("Initializing pulse oximeter..");
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
{
Serial.println(F("MAX30102 was not found. Please check wiring/power."));
while (1);
}
Serial.println(F("Attach sensor to finger with rubber band. Press any key to start conversion"));
while (Serial.available() == 0) ; //wait until user presses a key
Serial.read();
byte ledBrightness = 60; //Options: 0=Off to 255=50mA
byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
byte sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
int pulseWidth = 411; //Options: 69, 118, 215, 411
int adcRange = 4096; //Options: 2048, 4096, 8192, 16384
particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings
particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
pinMode(A0, INPUT);
for (int i=0 ; i<N ; i++){ ecg [i] = 0; } }
}
void loop() {
if (!client.connected()) { reconnect(); }
// Serial.begin(115200);
somme = somme - ecg [n];
// Lecture du capteur
ecg[n] = analogRead(A0);
// Ajout du dernier echantillon
somme = somme + ecg [n];
// Incrémentation de n
n++;
if (n>= N){
// ...retour au début
n =0; }
ecgmoy = somme / N;
bufferLength = 100; //buffer length of 100 stores 4 seconds of samples running at 25sps
//read the first 100 samples, and determine the signal range
for (byte i = 0 ; i < bufferLength ; i++)
{ while (particleSensor.available() == false) //do we have new data?
particleSensor.check(); //Check the sensor for new data
redBuffer[i] = particleSensor.getRed();
irBuffer[i] = particleSensor.getIR();
particleSensor.nextSample(); //We're finished with this sample so move to next sample
}
/*calculate heart rate and SpO2 after first 100 samples (first 4 seconds of samples)*/
maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
//Continuously taking samples from MAX30102. Heart rate and SpO2 are calculated every 1 second
while (1)
{
//dumping the first 25 sets of samples in the memory and shift the last 75 sets of samples to the top
for (byte i = 25; i < 100; i++)
{
redBuffer[i - 25] = redBuffer[i];
irBuffer[i - 25] = irBuffer[i];
}
//take 25 sets of samples before calculating the heart rate.
for (byte i = 75; i < 100; i++)
{
while (particleSensor.available() == false) //do we have new data?
particleSensor.check(); //Check the sensor for new data
redBuffer[i] = particleSensor.getRed();
irBuffer[i] = particleSensor.getIR();
particleSensor.nextSample(); //We're finished with this sample so move to next sample
long irValue = particleSensor.getIR();
if (checkForBeat(irValue) == true)
{
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
if (beatsPerMinute < 255 && beatsPerMinute > 20)
{
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
//Take average of readings
beatAvg = 0;
for (byte x = 0 ; x < RATE_SIZE ; x++)
beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
}
if (irValue < 50000)
{ Serial.print(" No finger?");
Serial.println();
} else {
//send samples and calculation result to terminal program through UART
Serial.print(F("red=")); Serial.print(redBuffer[i], DEC);
Serial.print(F(", ir=")); Serial.print(irBuffer[i], DEC);
Serial.print(F(", HR=")); Serial.print(heartRate, DEC);
Serial.print(F(", HRvalid=")); Serial.print(validHeartRate, DEC);
Serial.print(F(", SPO2=")); Serial.print(spo2, DEC);
Serial.print(F(", SPO2Valid=")); Serial.println(validSPO2, DEC);
Serial.print("IR="); Serial.print(irValue);
Serial.print(", BPM="); Serial.print(beatsPerMinute);
Serial.print(", Avg BPM="); Serial.print(beatAvg);
Serial1.print("<Serial1"); Serial1.print(","); Serial1.print(spo2); Serial1.print(","); Serial1.print(heartRate); Serial1.print(">"); }
}
//After gathering 25 new samples recalculate HR and SP02
maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
}
/*transform the values of the sesors to char type..*/
/* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/
dtostrf( ecgmoy , 4, 2, str_val_1);
dtostrf(spo2, 4, 2, str_val_2);
dtostrf(beatsPerMinute, 4, 2, str_val_3);
/*builds the payload */
sprintf(topic, "%s", ""); // Cleans the topic content
sprintf(topic, "%s%s", "/v1.6/devices/", device_label);
sprintf(payload, "%s", ""); // Cleans the payload content
sprintf(payload, "{\"%s\":", VARIABLE_LABEL_1); // Adds the variable label
sprintf(payload, "%s {\"value\": %s}", payload, str_val_1); // Adds the value
sprintf(payload, "{\"%s\":", VARIABLE_LABEL_2); // Adds the variable label
sprintf(payload, "%s {\"value\": %s}", payload,str_val_2 ); // Adds the value
sprintf(payload, "%s, \"%s\":", payload,VARIABLE_LABEL_3); // Adds the variable label
sprintf(payload, "%s {\"value\": %s}", payload, str_val_3); // Adds the value
sprintf(payload, "%s}", payload); // Closes the dictionary brackets
Serial.println("Publishing data to Ubidots Cloud");
Serial.println(payload);
Serial.println(topic);
client.publish(topic, payload);
client.loop();
delay (20);
}