Uploading Data on Thingspeak

Hello fellow programmers ,
I am trying to upload the findings of my max30100 sensor to thingspeak.
While i have a working example who is not connected on thingspeak , when i try and connect it to thing speak i get 0 readings for both Bpm and Spo2 .
My code is here and i believe it has to do something with me trying to pass a float value to thingspeak,

/*
  Arduino-MAX30100 oximetry / heart rate integrated sensor library
  Copyright (C) 2016  OXullo Intersecans <x@brainrapers.org>

  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/>.
*/

#include <Wire.h>
#include "ThingSpeak.h"
#include "MAX30100_PulseOximeter.h"
#include <WiFiNINA.h>  /* wifi libaries to connect our device with BLYNK */
#include <BlynkSimpleWiFiNINA.h> /* libaries to connect our device with BLYNK */
#define BLYNK_PRINT Serial
#define REPORTING_PERIOD_MS     1000
#define BLYNK_MAX_SENDBYTES 256 // Default is 128

// PulseOximeter is the higher level interface to the sensor
// it offers:
//  * beat detection reporting
//  * heart rate calculation
//  * SpO2 (oxidation level) calculation
PulseOximeter pox;
BlynkTimer timer;
WiFiClient  client;
float spo2 = pox.getSpO2();



unsigned long myChannelNumber = 1151277;
const char * myWriteAPIKey = "";
char auth[] = "";
// DONT STEAL THEM PLEASE
// xD
char ssid[] = "";
char pass[] = "";
uint32_t tsLastReport = 0;


//simple and smart function to ignore first readings which are false and then check if Heart rate or Spo2 levels are abnormal , we ll call it outside of the loop because the IoT server gonna get overflooded with DATA , so we ll call with interval Time
void sendMsg()
{
  float h = pox.getHeartRate();
  float o = pox.getSpO2();

  if ( h >= 140)
  {
    Blynk.notify("Your BpM is Quite High,I am Sending Data To you Doctor ");
  }
  else if ( o<90 & o>80)
  {
    Blynk.notify("Your Spo2 is Quite Low,I am Sending Data To your Doctor ");
  }
  else if (h < 40)
  {
    Blynk.notify("Your BpM is Quite Low,I am Sending Data To you Doctor ");
  }
  else if (h==0 & o==0)
  {
    Blynk.notify("Place your finger to the sensor");
  }

}

void  wifi_connect(){
  
  if(WiFi.status() != WL_CONNECTED)
  {
    Serial.print("Attempting to connect to SSID: ");
    while(WiFi.status() != WL_CONNECTED){
      WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network
      Serial.print(".");
      delay(5000);     
    } 
    Serial.println("\nConnected.");
  }
}



// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
  Serial.println("Beat!");
}

void setup()
{
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  ThingSpeak.begin(client);  //Initialize ThingSpeak


  Serial.print("Initializing pulse oximeter..");

  // Initialize the PulseOximeter instance
  // Failures are generally due to an improper I2C wiring, missing power supply
  // or wrong target chip
  if (!pox.begin()) {
    Serial.println("FAILED");
    for (;;);
  } else {
    Serial.println("SUCCESS");
  }

  // The default current for the IR LED is 50mA and it could be changed
  //   by uncommenting the following line. Check MAX30100_Registers.h for all the
  //   available options.
  // pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);

  // Register a callback for the beat detection
  pox.setOnBeatDetectedCallback(onBeatDetected);

  timer.setInterval(30000, sendMsg); //runs every half a min
  timer.setInterval(1000, wifi_connect);


}

void loop()
{


  Blynk.run();
  timer.run();

  float x= ThingSpeak.writeField(myChannelNumber, 1, spo2, myWriteAPIKey);

  
  // Make sure to call update as fast as possible
  pox.update();

  // Asynchronously dump heart rate and oxidation levels to the serial
  // For both, a value of 0 means "invalid"
  if (millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    Serial.print("Heart rate:");
    Serial.print(pox.getHeartRate());
    Serial.print("bpm / SpO2:");
    Serial.print(pox.getSpO2());
    Serial.println("%");

    {
      // here what i did , is i am converting DIgital and ANALOG outputs to VIRTUAL so i can display them
      Blynk.virtualWrite(5, pox.getHeartRate());
      Blynk.virtualWrite(4, pox.getSpO2());

    }
    tsLastReport = millis();
  }
}

As i ve been writing alot of Python lately , i am kinda bad with C++ on type casting , how can i convert a float or moreover seems like an unsigned char to a String ?
Python logic says a=5 so u do astring=str(a) but its not the same in arduino environment.

P.S obviously i deleted from the posted code my Api key , ssid ,pass etc .

I'm not very familiar with the thingspeak-API I used a code found on random nerd tutorials successfully to send data to thingspeak.
it has the following basic structure

  // set the fields with the values
  ThingSpeak.setField(1, number1);
  ThingSpeak.setField(2, number2);
  ThingSpeak.setField(3, number3);
  ThingSpeak.setField(4, number4);

  // figure out the status message
  if(number1 > number2){
    myStatus = String("field1 is greater than field2"); 
  }
  else if(number1 < number2){
    myStatus = String("field1 is less than field2");
  }
  else{
    myStatus = String("field1 equals field2");
  }
  
  // set the status
  ThingSpeak.setStatus(myStatus);
  
  // write to the ThingSpeak channel
  int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
  if(x == 200){
    Serial.println("Channel update successful.");
  }
  else{
    Serial.println("Problem updating channel. HTTP error code " + String(x));

So there is a command setField() that is used which your code is missing.

best regards Stefan

Thing is , my data is already being sent on field 1 , so thats not the problem .
I think the problem lies when i transfer a value like 96% as a float , when i need to convert it to a String.
dtostrf gives me compiler error btw.

I have a code running

just the important parts not the whole code

float SHT31_Temp = -9.87;
float SHT31_Hum  = -12.34;

    ThingSpeak.setField(1, SHT31_Temp);
    ThingSpeak.setField(2, SHT31_Hum);    // write to the ThingSpeak channel


    int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
    if(x == 200){
      Serial.println("Channel update successful.");
    }
    else {
      Serial.println("Problem updating channel. HTTP error code " + String(x));
    }

that works just fine.

did you do error-checking by evaluating the result of the command

ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

ThingSpeak allows adding data only once every 20 seconds

my recommendation writing a tiny testcode that does nothing more than sending a float-value to thingsspeak every 30 seconds

best regards Stefan

will do that and let you know Stefan. Thank you.

P.S i also think its 15seconds and if you have writefields after writefields etc

Update :

I manage to get it working by making TS write a function and call it from void setup() with time interval 15000.
Everything works but for 15sec , when my Setup uses the TS write function , everything freezes at the exact numbers they had at that time .

Still cant do much if the program freezes every 15 sec.

I'm not sure if I understand what you have tried and what you mean by describing the results.

The setup-function runs through only once after reset or power-on. And then never again until next reset.
If you weren't aware of this fact I recomend learning more about the basics how to program with arduinos.
with this tutorial

Arduino Programming Course

It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.

In the code you posted in the thread-opening post

loop runs through at high speed sending much to much data to thingspeak.

It is the same with Blynk you do a virtualwrite once every second. This overloads your blynk-connection.
Imagine millions of users sending 10 commands per second to the Blynk-server. This is almost like a denial of service attack

Best thing is to post your actual code and give a detailed description what is happening.
For analysing what your program does add serial debug output

best regards Stefan

I understand what happens to setup and Loop , thats why i use 30sec intervals for blynk write and thats why i have a clear void loop.
After alot of testing , now i am here:

/*
  Arduino-MAX30100 oximetry / heart rate integrated sensor library
  Copyright (C) 2016  OXullo Intersecans <x@brainrapers.org>

  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/>.
*/

#include <Wire.h>
#include "ThingSpeak.h"
#include "MAX30100_PulseOximeter.h"
#include <WiFiNINA.h>  /* wifi libaries to connect our device with BLYNK */
#include <BlynkSimpleWiFiNINA.h> /* libaries to connect our device with BLYNK */
#define BLYNK_PRINT Serial
#define REPORTING_PERIOD_MS     1000
#define BLYNK_MAX_SENDBYTES 256 // Default is 128

// PulseOximeter is the higher level interface to the sensor
// it offers:
//  * beat detection reporting
//  * heart rate calculation
//  * SpO2 (oxidation level) calculation
PulseOximeter pox;
BlynkTimer timer;
WiFiClient  client;


unsigned long myChannelNumber = ;
const char * myWriteAPIKey = "";
char auth[] = "";
// DONT STEAL THEM PLEASE
// xD
char ssid[] = "";
char pass[] = "";
uint32_t tsLastReport = 0;


//simple and smart function to ignore first readings which are false and then check if Heart rate or Spo2 levels are abnormal , we ll call it outside of the loop because the IoT server gonna get overflooded with DATA , so we ll call with interval Time
void sendMsg()
{
  float h = pox.getHeartRate();
  float o = pox.getSpO2();

  if ( h >= 140 || h < 40  & h != 0)
  {
    Blynk.notify("Your BpM are in dangeours levels");
  }
  else if ( o<90 & o>80)
  {
    Blynk.notify("Your Spo2 is Quite Low .");
  }
  else if (h == 0 || o == 0)
  {
    Blynk.notify("Place your finger to the sensor");
  }

}

 void getRatings()
 {
   // Asynchronously dump heart rate and oxidation levels to the serial
  // For both, a value of 0 means "invalid"
  if (millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    Serial.print("Heart rate:");
    Serial.print(pox.getHeartRate());
    Serial.print("bpm / SpO2:");
    Serial.print(pox.getSpO2());
    Serial.println("%");


    {
      // here what i did , is i am converting DIgital and ANALOG outputs to VIRTUAL so i can display them
      Blynk.virtualWrite(5, pox.getHeartRate());
      Blynk.virtualWrite(4, pox.getSpO2());

    }
    tsLastReport = millis();
  }
 }




void  wifi_connect() {

  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.print("Attempting to connect to SSID: ");
    while (WiFi.status() != WL_CONNECTED) {
      WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network
      Serial.print(".");
      delay(5000);
    }
    Serial.println("\nConnected.");
  }
}

void TSwrite()
{
  int  x = ThingSpeak.writeField(myChannelNumber, 1, pox.getSpO2(), myWriteAPIKey);
}



// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
  Serial.println("Beat!");
}

void setup()
{
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  ThingSpeak.begin(client);  //Initialize ThingSpeak

  Serial.print("Initializing pulse oximeter..");

  // Initialize the PulseOximeter instance
  // Failures are generally due to an improper I2C wiring, missing power supply
  // or wrong target chip
  if (!pox.begin()) {
    Serial.println("FAILED");
    for (;;);
  } else {
    Serial.println("SUCCESS");
  }

  // The default current for the IR LED is 50mA and it could be changed
  //   by uncommenting the following line. Check MAX30100_Registers.h for all the
  //   available options.
  // pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);

  // Register a callback for the beat detection
  pox.setOnBeatDetectedCallback(onBeatDetected);

  timer.setInterval(30000, sendMsg); //runs every half a min
 // timer.setInterval(1000, wifi_connect);
  //timer.setInterval(15000, TSwrite);
  timer.setInterval(1000, getRatings);



}

void loop()
{


  Blynk.run();
  timer.run();
  
  // Make sure to call update as fast as possible
  pox.update();
  
   if (millis() - tsLastReport > REPORTING_PERIOD_MS+(14000))
  {
      int  x = ThingSpeak.writeField(myChannelNumber, 1, pox.getSpO2(), myWriteAPIKey);

    tsLastReport = millis();
  }

}

Obviously i dont need the wifi connect since blynk connects me to wifi so i removed it with comments .
The problem i had previously was that whenever i was calling the TSwrite functionmy program was freezing.
In this Code it doesnt freeze but it only reports to thingspeak the very first reading and then stops .
that has to do maybe with this   if (millis() - tsLastReport > REPORTING_PERIOD_MS+(14000)).
I want to leave period_ms the same so i can use it for my Get Rating function but i want also to add another 14seconds to it only when i want it for my thingspeak loop

How about checking the result of the TS-write?

  int  x = ThingSpeak.writeField(myChannelNumber, 1, pox.getSpO2(), myWriteAPIKey);
  Serial.print("x = ThingSpeak.writeField  x=");
  Serial.print(x);

and do a look up at TS to see which value means what.

best regards Stefan

23:37:47.442 -> x = ThingSpeak.writeField  x=200Heart rate:92.23bpm / SpO2:96%
23:37:48.544 -> Heart rate:92.23bpm / SpO2:96%
23:37:49.610 -> Heart rate:92.23bpm / SpO2:96%
23:37:50.682 -> Heart rate:92.23bpm / SpO2:96%
23:37:51.754 -> Heart rate:92.23bpm / SpO2:96%
23:37:52.820 -> Heart rate:92.23bpm / SpO2:96%
23:37:53.888 -> Heart rate:92.23bpm / SpO2:96%
23:37:54.959 -> Heart rate:92.23bpm / SpO2:96%
23:37:56.033 -> Heart rate:92.23bpm / SpO2:96%
23:37:57.103 -> Heart rate:92.23bpm / SpO2:96%
23:37:58.200 -> Heart rate:92.23bpm / SpO2:96%
23:37:59.265 -> Heart rate:92.23bpm / SpO2:96%
23:38:00.329 -> Heart rate:92.23bpm / SpO2:96%
23:38:01.399 -> Heart rate:92.23bpm / SpO2:96%
23:38:02.299 -> x = ThingSpeak.writeField  x=-401Heart rate:92.23bpm / SpO2:96%

This is what i am talking bout , as u see my program freezes but the weird thing is that i both my heart rate and my spo2 while i only use pox.getSpO2() .hmmm

hello

i'm have similar problem when i add the code for thingspeak or blynk i can't get reading for oth my heart rate and my spo2 i don't get why ?

did it work with you ?

blynk uses its own servers. I don't know it but it might be that trying to have a connection to blynk and thingspeak does interfere. Most libraries offer result-values you should add serial print to see what results you get when you call all the thingspeak-functions

best regards Stefan

there no problem with the connection to blynk and thingspeak but the problem is max30100 stop detection my heartrate when i put my finger in the sensor and i add serial print to see what results but still no heartbear or SpO2 only give me zero

just mentioning "measuring stops" means other users would have to rebuild your system
with all hardware trying to reproduce your bugs. That is way off too much effort.

So add some more serial output to almost any place you find useful and then
post the serial output you get as a code-section
and comment at which serial output you are doing what with your sensors.

Without this details the short anser to "measuring stops" is
"find your bug" which of course is not helpful at all.

best regards Stefan

ok thank you your help i will try it

i try it but no lock this is my post here:
https://forum.arduino.cc/?topic=718374#msg4826269
if you can help i be very grateful