I have some simple code that reads a temp and publishes its value every 10 seconds. I’d like it to only send the data when theres a change in temp greater than 3 degrees. Im unsure of the code and also wondering if that saved value is retained when the device loses power. Any suggestions?
If your device really loses power and you haven't got a backup power connected (e.g. coin cell on VBAT for Photons) then the last values won't be retained, unless you store them in EEPROM (or any other non-volatile medium).
And for the other part, you'd need two variables (should be float or double instead of int) - one to hold the new reading and one to keep the old one - and then compare the absolute value of both like this
float newTemp = dht.getTempFarenheit(); // although there is a spelling error in the library
// as it should be Fahrenheit
if (fabs(newTemp - temperature) > 3) {
temperature = newTemp;
...
}
BTW, I'd rather only publish one event that features both values like this
void loop() {
static uint32_t ms = 0;
if (millis() - ms < 10000) return; // if the last visit was less than 10 sec ago bail out
ms = millis();
char data[32];
float newTemp = dht.getTempFarenheit();
if (fabs(newTemp - temperature) > 3.0) {
temperature = newTemp;
humidity = dht.getHumidity();
snprintf(data, sizeof(data), "%.1f °F, %.1f %%", temperature, humidity);
Particle.publish("Temp, Humidity", data, PRIVATE);
}
}
I'm sure you know this, but lest anyone be confused, when you use battery backup you need to declare a variable as 'retained'. Variables are not automatically saved when you have VBAT.
Ok, got it! That all works. How would that work with something like GPS coordinates (ie - 12.345678) If I only want to publish changes in position? I can’t convert a char to float, correct?
TinyGPS gps;
char szInfo[64];
// Every 15 minutes
int sleep = 1 * 60 * 1000;
void setup(){
Serial1.begin(9600);
}
void loop(){
bool isValidGPS = false;
for (unsigned long start = millis(); millis() - start < 1000;){
// Check GPS data is available
while (Serial1.available()){
char c = Serial1.read();
// parse GPS data
if (gps.encode(c))
isValidGPS = true;
}
}
// If we have a valid GPS location then publish it
if (isValidGPS){
float lat, lon;
unsigned long age;
gps.f_get_position(&lat, &lon, &age);
sprintf(szInfo, "%.6f,%.6f", (lat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : lat), (lon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : lon));
}
else{
// Not a vlid GPS location, jsut pass 0.0,0.0
// This is not correct because 0.0,0.0 is a valid GPS location, we have to pass a invalid GPS location
// and check it at the client side
sprintf(szInfo, "0.0,0.0");
}
Particle.publish("gpsloc", szInfo);
}
You can convert char to float, but you don’t need to since the GPS library should provide you with the latitude and longitude values as floats and if you are using TinyGPS++ library you should also get a distanceBetween() function that you can use to calculate the distance between your last and current position and compare that against a threshold.