Thanks @PeteKnight
This code returns the reading with no problems
#include "DS18.h"
DS18 sensor(D5);
void setup() {
Serial.begin(115200);
}
void loop() {
if (sensor.read()) {
// Do something cool with the temperature
Serial.printf("Temperature " );
Serial.println(sensor.fahrenheit());
}
}
As soon as I add the stepWidget, I start seeing the errors
// This #include statement was automatically added by the Particle IDE.
#include <OneWire.h>
// This #include statement was automatically added by the Particle IDE.
#include <blynk.h>
#include "DS18.h"
DS18 sensors(D5);
float stepWidget;
char auth[] = "char auth";
BLYNK_CONNECTED() {
Blynk.syncAll();
Blynk.notify("CONNECTED");
//Blynk.syncVirtual(V1);
}
BLYNK_WRITE(V25) {
//if (sensors.read())
stepWidget = param.asInt();
Blynk.virtualWrite(V26, stepWidget);
Serial.printf("Step ");
Serial.println(stepWidget);
Serial.printf("Temp ");
Serial.println(sensors.fahrenheit());
Serial.printf("(int) Temp ");
Serial.println((int) sensors.fahrenheit());
}
void setup() {
Serial.begin(115200);
Blynk.begin(auth);
}
void loop() {
Blynk.run();
// Read the next available 1-Wire temperature sensor
if (sensors.read()) {
// Do something cool with the temperature
Serial.printf("Temperature F ");
Serial.println(sensors.fahrenheit());
}
}
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Step 60.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Temperature F 68.45
Step 61.00
Temp 32.00
(int) Temp 32
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Step 62.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Step 63.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Temperature F 68.45
Step 64.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Temperature F 68.45
Step 65.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Step 66.00
Temp 68.45
(int) Temp 68
Step 67.00
Temp 68.45
(int) Temp 68
Step 68.00
Temp 68.45
(int) Temp 68
Step 69.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Temperature F 68.45
Step 70.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Step 71.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Step 70.00
Temp 68.45
(int) Temp 68
Step 69.00
Temp 68.45
(int) Temp 68
Step 68.00
Temp 68.45
(int) Temp 68
Step 67.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Step 66.00
Temp 32.00
(int) Temp 32
Step 65.00
Temp 32.00
(int) Temp 32
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Step 64.00
Temp 68.45
(int) Temp 68
Step 63.00
Temp 68.45
(int) Temp 68
Step 62.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Step 61.00
Temp 68.45
(int) Temp 68
Step 60.00
Temp 68.45
(int) Temp 68
Step 60.00
Temp 68.45
(int) Temp 68
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Temperature F 68.45
Iâve tried moving it everywhere possible. The result is the same. This was just my last attempt If I add it to the variable section and use a timer, same result. If I put it in the setup section it reads it once and you already know what happens in the loop.
I believe this is the code. I apologize but I have tried many different variations.
// This #include statement was automatically added by the Particle IDE.
#include <OneWire.h>
// This #include statement was automatically added by the Particle IDE.
#include <blynk.h>
#include "DS18.h"
DS18 sensors(D5);
float stepWidget;
float temp;
char auth[] = "auth token";
BlynkTimer timer;
BLYNK_CONNECTED() {
Blynk.syncAll();
Blynk.notify("CONNECTED");
//Blynk.syncVirtual(V1);
}
void sendSensorsHigh() {
if (sensors.read()) {
Serial.printf("Temperature F ");
Serial.println(sensors.fahrenheit());
}
}
BLYNK_WRITE(V26) {
stepWidget = param.asInt();
Blynk.virtualWrite(V25, stepWidget); //
Serial.printf("Step");
Serial.println(stepWidget);
if(stepWidget >= sensors.fahrenheit()){
digitalWrite(D7, HIGH);
digitalWrite(D0, HIGH);
Serial.println ("ON");
}
else if (stepWidget < sensors.fahrenheit()){
digitalWrite(D7, LOW);
digitalWrite(D0, LOW);
Serial.println("OFF");
}
}
void setup() {
Serial.begin(115200);
Blynk.begin(auth);
pinMode(D0, OUTPUT);
pinMode(D7, OUTPUT);
timer.setInterval(100L, sendSensorsHigh);
}
void loop() {
Blynk.run();
timer.run();
}
this is the result
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Step60.00
ON
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Step60.00
OFF
Temperature F 70.25
Temperature F 70.25
Step61.00
OFF
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Step62.00
OFF
Step63.00
OFF
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Step64.00
OFF
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Step65.00
OFF
Temperature F 70.25
Temperature F 70.36
Temperature F 70.25
Temperature F 70.25
Temperature F 70.36
Temperature F 70.25
Temperature F 70.36
Temperature F 70.25
Step66.00
OFF
Temperature F 70.36
Temperature F 70.36
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
Step67.00
OFF
Temperature F 70.25
Temperature F 70.25
Step68.00
ON
Temperature F 70.36
Temperature F 70.25
Temperature F 70.25
Temperature F 70.25
You can see the random ON when it should be OFF
Thanks
This line of code is making your device read the temperature every time the step widget is pressed.
You should be taking the temperature reading at the start of the sendSensorsHigh function and saving the result to a variable.
You should then be doing the comparison between this temperature variable and the value from the step widget in that sendSensorsHigh routine.
But, Iâm sure you donât needs to be taking these readings and doing that comparison 10 times every second, which is what your timer is currently doing. Iâm sure that running this timed loop every 5 or 10 seconds would be more than sufficient.
Okay, I still dont think youâve grasped what I was saying, and there are some issues with the way that youâve implemented the suggestions so far, so Iâve taken your code and changed it for you.
I really want you to understand what Iâve changed and why, so that you can tweak the code to get it working the way you want it to. Please read through the revised code and my comments below, so that you understand what Iâve done and why. The code is untested, uncompiled and the logic for the temperature comparison and evaluation may be wrong - but I donât have your hardware or have your libraries installed.
// This #include statement was automatically added by the Particle IDE.
#include <OneWire.h>
// This #include statement was automatically added by the Particle IDE.
#include <blynk.h>
#include "DS18.h"
DS18 sensors(D5);
float targetTemp;
float temp;
char auth[] = "auth token";
BlynkTimer timer;
void takeTempReading()
{
if (sensors.read())
{
temp = sensors.fahrenheit() // Take a temperature reading and save it to the variable temp
Serial.printf("Temperature F ");
Serial.println(temp); // Print the saved temperature value without having to re-read the sensor
Blynk.virtualWrite(V1, targetTemp); // Write the saved temperature out to the Blynk widget on pin V1
}
if(temp >= targetTemp)
{
digitalWrite(D7, HIGH);
digitalWrite(D0, HIGH);
Serial.println ("Temperature is at or above target");
}
else
{
digitalWrite(D7, LOW);
digitalWrite(D0, LOW);
Serial.println("Temperature is below target");
}
}
BLYNK_CONNECTED()
{
Blynk.syncVirtual(V26); // Ask the Blynk server for the current Target Temperature
Blynk.notify("CONNECTED");
}
BLYNK_WRITE(V26) // Step widget used to set the Target Temperature
{
targetTemp = param.asFloat();
Blynk.virtualWrite(V25, targetTemp); //
Serial.printf("Step");
Serial.println(targetTemp);
}
void setup()
{
Serial.begin(115200);
Blynk.begin(auth);
pinMode(D0, OUTPUT);
pinMode(D7, OUTPUT);
timer.setInterval(5000, takeTempReading);
}
void loop()
{
Blynk.run();
timer.run();
}
The comments in the code should be self explanatory, but you need to read through it to understand them. Key points to note:
Your function that was called sendSensorsHigh() is now called takeTempReading() as it better describes what the function actually does.
The variable called stepWidget is now called targetTemp as it better describes what it is used for. This is still a float type variable, but the value coming from the step widget is now being read as a float as well, rather than an integer. This will allow you to set the step level to 0.5 if you want to have half degree control of the target temperature (not so much of an issue when you work in Farenheit, but for those of us in the civilised world who work in Celcius it is necessary to have finer control )
Iâve assumed that you will want to see the actual temperature from the sensor in your Blynk app. Iâve added a line in the takeTempReading() which writes the temperature to a widget attached to virtual pin V1. If this pin is currently in use then youâll need to change that line of code. The widget can be any display type, maybe a labelled value or gauge widget would work well.
Iâve made a change to the way that the if comparisons are done. Iâm now comparing the temperature to the temperature to the target temperature, whereas before you were doing the comparison the other way around. Iâve kept the comparison operators the same way around (>=) and Iâve changed the serial print message from On/Off to something that makes more sense. Youâd previously commented on the D7 and D0 states being incorrect, and when you test this if itâs not working the way you want then change the HIGH and LOW commands around.
Please read through the code and the se notes, then test the code on your device with your sensor and let me now if its working the way you want it to. Iâm hoping that youâll be able to fix any issues yourself now but if not then please explain what the issue is and what youâve tried, and weâll help you to fix it.
Thank you very much for your continued help, I appreciate your time. I have read through the code and noted the changes you made as well as your comments.
In response to the comments
1-agreed
2- partially agree
3-Yes, I did. After clearing up a minor editing issue, works fine (both V1 and V25 were writing targetTemp)
4- Explain the change when you have time, please. Is there a difference in making the comparison this way?
The end result is that it is working as I had expected. I look forward to your reply.
What you were doing before was saying âif the target temperature is greater than or equal to the actual temperature then do some stuffâ
What it now says is âIf the actual temperature is greater than or equal to the target temperature then do some stuffâ which is obviously the exact opposite of what it did before.
Iâve also deleted the âelse ifâ and replaced it with a simple âifâ. This is simply because thatâs really what you want to do - you donât need to specify the alternate criteria, you just need to acknowledge that it it isnât greater than or equal to then it has to be lower than.
As far as which variable you put first in an if statement, there is no hard and fast rule, but the approach that most programmers tend to take is to put the thing that changes most frequently first and the thing thatâs more constant second. As the measured temperature is going to be fluctuating frequently and the target temperature is more static then doing it the way I have is the âpreferredâ format.
Sorry, my mistake. I copied and pasted and changed the virtual PIN number, but not what was being written to that virtual pin.
I think youâll agree that giving your variables and functions meaningful names makes it easier to work out whatâs happening, and in this case it was easier to see that targetTemp needed to be changed to Temp for the V1 pin.
One thing that you may want to consider for the future is introducing some hysteresis into the thermostat process.
At the moment, if the target is 70°F and the actual temperature fluctuates between 69.999° and 70.0° the thermostat will turn the heater on and off in rapid succession. Depending on the type of heater, this may be undesirable.
Hysteresis adds a degree of insensitivity or latency to the process, maybe waiting until the temperature is 0.2° above target before turning the heater off, and 0.2° below target before turning the heater on. This means youâll get intentional fluctuations of 0.4°F, but thatâs probably much better than you get with most mechanical thermostats.
Just a bit of food for thought, and something to look out for when doing your testing.
Thanks for the explanation. I will make it a practice from this point forward.
No need for an apology. I was sure to read every line of code, several times along with the comments prior to even trying to compile it in my attempt to understand everything you passed along. I also agree with your comment about naming the variables and functions with something more appropriate.
Thanks also for the heads up on the Hysteresis, I will begin researching that. Lastly, thanks for your time, patience and knowledge.