Help with particle.publish temperature sensor

Hello,

I'm using a 10K thermistor and calculating the temperature in a voltage divider circuit using the thermistor Beta value. I'm having success with the temperature reading as well as the particle.variable. I wanted to try to experiment with particle.publish and I'm having some issues. I was able to get the code to compile, but i'm not getting any publishing. A few things I wasn't sure of like the "int temp" and setting temp = Tf. Also I was not sure of the "String(temp))" at the end of my particle.publish

 * Project Read 10k Thermistor
 * Author: Aaron Smith  
 * Date: 
 * Reads 10k thermistor in voltage divider circuit on A0
 * 
 */


#include "Particle.h"
#define TEMP_CHECK_INTERVAL 30000


SYSTEM_MODE(AUTOMATIC);

SYSTEM_THREAD(ENABLED);

SerialLogHandler logHandler(LOG_LEVEL_INFO);

#define RT0 10000
#define B 3947.57
#define R 9880
float RT;
float VR;
float ln;
float Tx;
float Tc;
float T0;
double Tf;
float VRT;
float Vin = A0;
int temp;
unsigned long lastTempCheck = 0;

void checkTemp(){ 
    //Read the voltage across the thermistor
  VRT = (3.3/4095) * analogRead(Vin);

//Calculate the voltage across the thermistor
  VR = 3.3 - VRT;
//Calculate resistance of the thermistor
  RT = VRT / (VR/R);
//Calculate temperature from thermistor resistance
  ln = log(RT/RT0);
  Tx = (1 / ((ln / B) + (1 / T0)));
//Convert to Celsius
  Tc = Tx - 273.15;
//Convert and display in Fahrenheit
  Tf = round(((Tc * 1.8) + 32)*10)/10;
  temp = Tf;}

void setup() {
  Serial.begin(9600);
  pinMode(Vin, INPUT);
  T0 = 25 + 273.15;
  Particle.variable("Temperaturef", Tf);
  Particle.publish("Temperaturef", String(temp));
}
void loop() {
//Read the voltage across the thermistor
  VRT = (3.3/4095) * analogRead(Vin);

//Calculate the voltage across the thermistor
  VR = 3.3 - VRT;
//Calculate resistance of the thermistor
  RT = VRT / (VR/R);
//Calculate temperature from thermistor resistance
  ln = log(RT/RT0);
  Tx = (1 / ((ln / B) + (1 / T0)));
//Convert to Celsius
  Tc = Tx - 273.15;
//Convert and display in Fahrenheit
  Tf = round(((Tc * 1.8) + 32)*10)/10;
  Serial.print (Tf);
  Serial.println ("F");
 if (lastTempCheck + TEMP_CHECK_INTERVAL > millis()){
     lastTempCheck = millis();
     checkTemp();
 }
  delay (500);
}

Hi,

The problem is the publish being in setup().
If you place it in loop() it will do what you want:

void setup() {
  Serial.begin(9600);
  pinMode(Vin, INPUT);
  T0 = 25 + 273.15;
  Particle.variable("Temperaturef", Tf);
}
void loop() {
(...your current code...)

    static unsigned long publishTime = 0;
    if ((millis() - publishTime) > 30000)
    {
        Log.info("publishTime...");
        publishTime = millis();
        Particle.publish("Temperaturef", String(temp));
    }

Best,

2 Likes

What exactly is this doing?

This prints to the serial console, so when you have your Particle device connected via usb cable, you can run:

particle serial monitor

Then you will see when the command is executed every 30 seconds. At that time, the online Particle console at https://console.particle.io/ will show you the publish if the device in online and connected to the cloud.

What is the difference with Serial.print?

Why the ... after publishTime?

Also,

on the Particle.publish("TemperatureF", String(temp));

what is the reason for String? Can I not just publish my double Tf, which would include decimal places?

i

Hi,

all your answers and more are in the docs :muscle:

I invite you to read those links, please. Thanks!

3 Likes

Thank you, I appreciate the lead. So far, i've only been able to learn by example. Reading the documents is unfortunately goes over my head, yet I persist...

 * Project Read 10k Thermistor
 * Author: Aaron Smith  
 * Date: 
 * Reads 10k thermistor in voltage divider circuit on A0
 * 
 */


#include "Particle.h"


SYSTEM_MODE(AUTOMATIC);

SYSTEM_THREAD(ENABLED);

SerialLogHandler logHandler(LOG_LEVEL_INFO);

#define RT0 10000
#define B 3947.57
#define R 9880
float RT;
float VR;
float ln;
float Tx;
float Tc;
float T0;
double Tf;
int temp;
float VRT;
float Vin = A0;
unsigned long publishDelay = 60000;
unsigned long previousTimePub = 0;

void checkTemp(){ 
    //Read the voltage across the thermistor
  VRT = (3.3/4095) * analogRead(Vin);

//Calculate the voltage across the thermistor
  VR = 3.3 - VRT;
//Calculate resistance of the thermistor
  RT = VRT / (VR/R);
//Calculate temperature from thermistor resistance
  ln = log(RT/RT0);
  T0 = 25 + 273.15;
  Tx = (1 / ((ln / B) + (1 / T0)));
//Convert to Celsius
  Tc = Tx - 273.15;
//Convert and display in Fahrenheit
  Tf = round(((Tc * 1.8) + 32)*10)/10;
  temp = Tf;
  }

void setup() {
  Serial.begin(9600);
  pinMode(Vin, INPUT);
  Particle.variable("Temperaturef", Tf);

}
void loop() {
  unsigned long timeNow = millis();
  checkTemp();
    Serial.print (Tf);
    Serial.println ("F");
  
 if (timeNow - previousTimePub > publishDelay){
     checkTemp();
     Particle.publish("Temperaturef", String(temp));
     Log.info("previousTimePub...");
     previousTimePub += publishDelay;
 }
  delay (500);
}

I've managed to get this bit of code working. I would prefer that it published the decimal places set by my definition of Tf but I have seem to get that to work. Is there some type of data conversion that would work?

What if you publish Tf then? temp is declared as int, which means losing the decimals.

I understand that, I tried setting it as a double and/or removing "temp" and just using Tf (which is a rounded double), and I got the proper number but all the digits after my round were zero eg. 74.2000000. My thought is it should not have displayed the zeros

@Aarons64, you can define the number of decimal places for a float without rounding (unless you need for something else) using String(Tf, 1) where 1 is the number of decimal places you want to include. You can look at the Arduino String reference here:

2 Likes

thanks, that did it. I'm tying to learn about the different data types. So now that it is a "string" technically its not really a number?

That's correct. It is a character "string" representation of the number being converted. You could look at this Arduino guide for variable types:

The Particle platform uses a 32bit processor so integers, for example, are stored as 32bit (4 byte) values. Float variables also use 32bits whereas double (double precision) type variables use 64bits.

Strings come from the Arduino world and both good and bad depending on how they are used. You will find lots of posts on this subject.

2 Likes