Display 3 variables in the Ubidots platform using esp8266 device

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” , If you have only one variable, ecg for example, the platform responds and displays the chart. But it does not respond if I want to work with the three variables. please help if the error is in the code.
this is 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
 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
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);
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, "")) {
    } else {
      Serial.print("Failed, rc=");
      Serial.println(" try again in 2 seconds");
      // Wait 2 seconds before retrying
* Main Functions
void setup() {
  Serial.print("Waiting for WiFi..."); 
  while (WiFi.status()!= WL_CONNECTED) {
  Serial.println("WiFi Connected");
  Serial.println("IP address: ");
  client.setServer(mqttBroker, 1883);
 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

  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
     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?");
 } 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");
    client.publish(topic, payload);
    delay (20);

Topics merged

Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

1 Like

Hello @sirinerahmani

I believe the issue could be in the loop() frequency. Since it's close to 20ms (coming from the delay() ), it means that it will definitely be exceeding the 4 requests/second limit for paid accounts at Ubidots, or the 1 request/second limit for STEM accounts at Ubidots.

I'd recommend you maybe use the esp8266 as data logger and then send the data to Ubidots, however, this might not be the best approach for your project as applications such as EGC monitoring require an infrastructure for very high frequency data and Ubidots wasn't built with that sort of applications in mind.

I'm curious to know if the loop had the same delay for when you sent only one variable, because this should have rendered the same result as if sending the 3 variables.

Best regards,

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.