@mkokes huh, Is there some how a variable type mismatch on what your second screenshot is expecting? Cause it looks like what ever interface you have in your second screen shot is expecting an Int, but it may be getting sent over as a string instead. what happens if you change the expected type on what ever interface you are using in the Second screen shot of the initial post?
I believe particle.publish() only supports strings so I’m converting the value to a string there, but from what I can tell particle.variable() should support int and bool so I’m not doing any sort of conversion there.
@mkokes your right in the fact that particle.variable supports int and bool, try changing it so the particle.variables look like this.
Particle.variable("temperature", temperature, INT);
Particle.variable("targettemp", targettemp, INT);
Particle.variable("humidity", humidity, INT);
Particle.variable("furnaceheat", furnaceHeat, INT); //this one will have to convert from bool to int and that should fix the weird issue with the number... I think
I am wondering if it is not sending right as the variable types are not defined in the right way… it shouldn’t be needed to make it work, but i have seen weirder things happen.
thanks for sticking with me as we troubleshoot this.
I have noticed that the two parameter overloads didn’t work for intand double at some point, but I’m not sure why and if this is meant to be, but @mdma might have a word to add
Hmm, I’m pretty sure of that.
I had used the two param overload for other types and one INT and while the others worked the INT didn’t so I used the three param overload without any alterations to my code and then it worked.
But since I had a solution I didn’t bother to further investigate, but I can try it out now.
Update
I tried again and it does work. Sorry for the confusion
I’m able to retrieve integers now via curl, but the boolean value I’m using for the furnaceheat variable, returned as a odd looking integer. Is this normal or am I doing something wrong there as well?
That is a little weird. It could be reading 4 bytes while the bool is 1 byte, and you’re getting memory after it. A bool is 0 / -1 so if it converts to unsigned long or something it might turn into -127 in 4 bytes somewhere, or who knows? This is safer:
return (bool_value == true) ? 1 : 0;
That will convert the bool condition to an int. Just return bool_value ? 1 : 0; would work as well, but may not be proper syntax.
No problem, not the ideal solution, but I ended up just using an int for furnaceHeat. Would’ve preffered to use a bool value, but this works.
// This #include statement was automatically added by the Particle IDE.
#include "PietteTech_DHT/PietteTech_DHT.h"
// DHT parameters
#define DHTTYPE DHT22 // Sensor type DHT11/21/22/AM2301/AM2302
#define DHTPIN D1 // Digital pin for communications
#define DHT_SAMPLE_INTERVAL 2000 // Sample every two seconds
// Use uFL External Antenna
STARTUP(WiFi.selectAntenna(ANT_EXTERNAL));
// Variables
int sampInt = 5000; //sample interval in milliseconds
int tempf;
int temperature;
int humidity;
int targettemp = 70;
int blue = D7;
int garageDoorRelay = D5;
int furnaceRelay = D6;
// furnaceHeat shows whether the furnace is running or not and furnaceActive enables the furnace to run
int furnaceHeat = 0;
bool furnaceActive = false;
//Post Function Declarations
int garageDoor(String command);
int furnOnOff(String command);
int setFurTemp(String command);
// Declaration
void dht_wrapper();
// Lib Initialize
PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);
// globals
unsigned int DHTnextSampleTime; // Next time we want to start sample
bool bDHTstarted; // flag to indicate we started acquisition
int n; // counter
void setup() {
//Hardware pin assignments
pinMode(blue, OUTPUT);
pinMode(garageDoorRelay, OUTPUT);
pinMode(furnaceRelay, OUTPUT);
// Variables Exposed to Cloud
Particle.variable("temperature", temperature);
Particle.variable("targettemp", targettemp);
Particle.variable("humidity", humidity);
Particle.variable("furnaceheat", furnaceHeat);
// Functions exposed to Cloud
Particle.function("garagedoor", garageDoor);
Particle.function("furnonoff", furnOnOff);
Particle.function("setfurtemp", setFurTemp);
//DHT
DHTnextSampleTime = 0;
//Start out with our relays turned on
digitalWrite(garageDoorRelay, HIGH);
digitalWrite(furnaceRelay, HIGH);
}
void dht_wrapper() {
DHT.isrCallback();
}
void loop()
{
//Wait a bit between loops then grab the temperature
delay(sampInt);
temperature = tempf;
// Turn the furnace on or off if necessary
heatGarage();
// Check if we need to start the next sample
if (millis() > DHTnextSampleTime) {
if (!bDHTstarted) { // start the sample
DHT.acquire();
bDHTstarted = true;
}
if (!DHT.acquiring()) { // has sample completed?
// get DHT status
//int result = DHT.getStatus();
humidity = DHT.getHumidity();
tempf = DHT.getFahrenheit();
//int tempc = DHT.getCelsius();
//int tempk = DHT.getKelvin();
//int dp = DHT.getDewPoint();
//int dpslow = DHT.getDewPointSlow();
//Turn the built in LED on to indicate publishing
digitalWrite(blue, HIGH);
//* Publish readings - uncomment/comment the values you'd like to publish
Particle.publish("Humidity", String(humidity) + "%");
Particle.publish("Temperature", String(tempf) + " °F");
//Particle.publish("Temperature", String(tempc) + " °C");
//Particle.publish("Temperature", String(tempk) + " °K");
//Particle.publish("Dew Point", String(dp) + " %");
//Particle.publish("Dew Point", String(dpslow) + " %");
//Turn the built in LED off indicate publishing finished
delay(250);
digitalWrite(blue, LOW);
n++; // increment counter
bDHTstarted = false; // reset the sample flag so we can take another
DHTnextSampleTime = millis() + DHT_SAMPLE_INTERVAL; // set the time for next sample
}
}
}
// After Loop - POST functions
// These function automagically get called upon a matching POST request
int garageDoor(String command)
{
if(command == "activate")
{
activateGarageDoor();
return 1;
}
else return -1;
}
int furnOnOff(String command)
{
if (command == "on") {
//furnaceOn();
return 1;
}
if(command == "off") {
//furnaceOff();
return 1;
}
return -1;
}
int setFurTemp(String command)
{
if (command == "on") {
setFurnaceTemp();
return 1;
} else {
return -1;
}
}
// POST helper functions
int activateGarageDoor() {
digitalWrite(garageDoorRelay, LOW);
delay(250);
digitalWrite(garageDoorRelay, HIGH);
return 1;
}
int heatGarage() {
if (targettemp >= temperature) {
if (furnaceActive = true) {
digitalWrite(furnaceRelay, LOW);
furnaceHeat = 1;
return 1;
} else {
digitalWrite(furnaceRelay, HIGH);
furnaceHeat = 0;
return -1;
}
} else {
digitalWrite(furnaceRelay, HIGH);
furnaceHeat = 0;
return -1;
}
}
int setFurnaceTemp() {
targettemp = 70;
return 1;
}
int furnaceOn() {
furnaceActive = true;
return 1;
}
int furnaceOff() {
furnaceActive = false;
return 1;
}
delay(sampInt) is 5 seconds, while DHT_SAMPLE_INTERVAL is 2 seconds. It’s not good to put long delays in your main loop because it’s stopping everything else from running, but that will cause it to check the 2 second timeout every 5 seconds.
Try getting code to run in and out of the loop as fast as possible with few delays, and you’ll notice it’s more responsive. Also for timing, this method will work better when millis() rolls over.
Thanks, that makes sense. I went through and cleaned things up a bit. Everything is working great now.
#include "PietteTech_DHT/PietteTech_DHT.h"
// DHT parameters
#define DHTTYPE DHT22 // Sensor type DHT11/21/22/AM2301/AM2302
#define DHTPIN D1 // Digital pin for communications
#define DHT_SAMPLE_INTERVAL 2000 // How often to sample in milliseconds
// Use uFL External Antenna
STARTUP(WiFi.selectAntenna(ANT_EXTERNAL));
// Variables
int lastPub;
int pubDelay = 5000; // How often to publish in milliseconds
int tempf;
int humidity;
int targettemp = 60;
int blue = D7;
int garageDoorRelay = D5;
int furnaceRelay = D6;
// furnaceHeat shows whether the furnace is running or not
int furnaceHeat = 0;
// furnaceActive enables the furnace to run
bool furnaceActive = false;
// Post Function Declarations
int garageDoor(String command);
int furnOnOff(String command);
int setFurTemp(String command);
// Declaration
void dht_wrapper();
// Lib Initialize
PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);
// globals
unsigned int DHTnextSampleTime; // Next time we want to start sample
bool bDHTstarted; // flag to indicate we started acquisition
int n; // counter
void setup() {
// Hardware pin assignments
pinMode(blue, OUTPUT);
pinMode(garageDoorRelay, OUTPUT);
pinMode(furnaceRelay, OUTPUT);
// Variables Exposed to Cloud
Particle.variable("temperature", tempf);
Particle.variable("targettemp", targettemp);
Particle.variable("humidity", humidity);
Particle.variable("furnaceheat", furnaceHeat);
// Functions exposed to Cloud
Particle.function("garagedoor", garageDoor);
Particle.function("furnonoff", furnOnOff);
Particle.function("setfurtemp", setFurTemp);
// DHT
DHTnextSampleTime = 0;
// Start out with our relays turned on
digitalWrite(garageDoorRelay, HIGH);
digitalWrite(furnaceRelay, HIGH);
}
void dht_wrapper() {
DHT.isrCallback();
}
void loop() {
// Check if we need to start the next sample
if (millis() > DHTnextSampleTime) {
if ( !bDHTstarted ) { // start the sample
DHT.acquire();
bDHTstarted = true;
digitalWrite(blue, HIGH);
}
if ( !DHT.acquiring() ) { // has sample completed?
humidity = DHT.getHumidity();
tempf = DHT.getFahrenheit();
// Turn the furnace on or off if necessary
heatGarage();
n++; // increment counter
bDHTstarted = false; // reset the sample flag so we can take another
DHTnextSampleTime = millis() + DHT_SAMPLE_INTERVAL;
}
}
if ( (millis() - lastPub) > pubDelay ) {
blinkPub();
lastPub = millis();
}
}
int blinkPub() {
// Turn the built in LED on to indicate publishing
digitalWrite(blue, HIGH);
// Publish readings - uncomment/comment the values you'd like to publish
Particle.publish("Humidity", String(humidity) + "%");
Particle.publish("Temperature", String(tempf) + " °F");
// Turn the built in LED off indicate publishing finished
digitalWrite(blue, LOW);
}
// POST functions
// These function automagically get called upon a matching POST request
int garageDoor(String command) {
if ( command == "activate" ) {
activateGarageDoor();
return 1;
}
return -1;
}
int furnOnOff(String command) {
if ( command == "on" ) {
furnaceOn();
return 1;
}
if ( command == "off" ) {
furnaceOff();
return 1;
}
return -1;
}
int setFurTemp(String command) {
if (command.length() > 0) {
setFurnaceTemp(command);
return 1;
} else {
return -1;
}
}
// POST helper functions
int activateGarageDoor() {
digitalWrite(garageDoorRelay, LOW);
delay(250);
digitalWrite(garageDoorRelay, HIGH);
Particle.publish("Garage Door", "Active");
return 1;
}
int heatGarage() {
if (furnaceActive) {
if (targettemp >= tempf) {
digitalWrite(furnaceRelay, LOW);
furnaceHeat = 1;
Particle.publish("Furnace", "On");
return 1;
} else {
digitalWrite(furnaceRelay, HIGH);
furnaceHeat = 0;
Particle.publish("Furnace", "Off");
return -1;
}
} else {
digitalWrite(furnaceRelay, HIGH);
furnaceHeat = 0;
Particle.publish("Furnace", "Off");
return -1;
}
}
int setFurnaceTemp(String command) {
targettemp = command.toInt();
return 1;
}
int furnaceOn() {
furnaceActive = true;
return 1;
}
int furnaceOff() {
furnaceActive = false;
return 1;
}
I’m having a similar if not exact same problem not being able to read variables. I’m a noob and am struggling to understand how to apply the solution to my situation.
I have two DHT22 sensors reading temps from my refridgerator and interior space. Everything is working as expected except I’m not able to query the particle variables. (and I’m getting odd spikes in the readings, but that’s for another post)
Can anyone help me apply the solution above to my code? Much appreciated;
// This #include statement was automatically added by the Particle IDE.
#include "Ubidots/Ubidots.h"
// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_DHT/Adafruit_DHT.h"
//token for ubidots
#define TOKEN "abc123abc123abc123abc123"
#define DHT1PIN 2 // fridge temp
#define DHT2PIN 4 // internal temp
#define DHTTYPE DHT22 // DHT 22 (AM2302)
Ubidots ubidots(TOKEN);
DHT dhtFridge(DHT1PIN, DHTTYPE);
DHT dhtInternal(DHT2PIN, DHTTYPE);
// Define variables
double fridgeTemp = 0;
double internalTemp = 0;
void setup()
{
Particle.variable("fridgeT", &fridgeTemp, DOUBLE); //make fridge temps avail via var
Particle.variable("internalT", &internalTemp, DOUBLE); //make internal temps avail via var
dhtFridge.begin();
dhtInternal.begin();
Serial.begin(9600);
delay(10000);
}
void loop()
{
//Read humidity into humidity vars
float fridgHumid = dhtFridge.getHumidity();
float internalHumid= dhtInternal.getHumidity();
//Read Farenheit into Temp vars
float fridgeTemp = dhtFridge.getTempFarenheit();
float internalTemp = dhtInternal.getTempFarenheit();
ubidots.add("fridgeTemp", fridgeTemp); //define fridgeTemp as ubidot var
ubidots.add("internalTemp", internalTemp); //define interalTemp as ubidot var
ubidots.sendAll(); //send vars to ubidot
delay(60000); //delay sixty sec
// Publish temp var for reading remotely
Particle.publish("fridgeTemp", String(fridgeTemp) + " °F");
Particle.publish("internalTemp", String(internalTemp) + " °F");
}
Particle.variable("fridgeT", fridgeTemp); //make fridge temps avail via var
Particle.variable("internalT", internalTemp); //make internal temps avail via var
And don't redeclare the used variables locally, that just hides the global variable that you exposed and hence they won't be updated. Only the local ones will receive the value, but will vanish once loop() finishes.
void loop() {
...
//Read Farenheit into Temp vars
float fridgeTemp = dhtFridge.getTempFarenheit();
float internalTemp = dhtInternal.getTempFarenheit();
...
}
Just remove float - BTW, your global vars are double, so why are the locals float anyway?
Perfect! that did the trick. Learn something everyday. I appreciate the help. As for the formatting of the variables, that was a leftover from some comments I saw earlier in the thread about “overloading” the variables. Obviously didn’t work. I’m not sure why I left the local var’s as float. Must have been another remnant of testing…