Can anyone amend my code to remove he delay function and replace it with millisDelay? I've read online that the delay function may be the cause of my problems that I'm having with the sketch taking up too much memory and possibly causing downtime on my wifi connection to the IoT cloud.
#include <BufferedInput.h>
#include <BufferedOutput.h>
#include <PinFlasher.h>
#include <SafeString.h>
#include <SafeStringNameSpace.h>
#include <SafeStringNameSpaceEnd.h>
#include <SafeStringNameSpaceStart.h>
#include <SafeStringReader.h>
#include <SafeStringStream.h>
#include <SerialComs.h>
#include <loopTimer.h>
#include <millisDelay.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>
#include "thingProperties.h" // Include Arduino IoT Cloud Thing properties
#include <Arduino_ConnectionHandler.h>
const int SENSOR_PIN = 13; // Arduino pin connected to DS18B20 sensor's DQ pin
OneWire oneWire(SENSOR_PIN); // setup a oneWire instance
DallasTemperature tempSensor(&oneWire); // pass oneWire to DallasTemperature library
LiquidCrystal_I2C lcd(0x3F, 16, 2); // I2C address 0x3F (from DIYables LCD), 16 column and 2 rows
void setup() {
Serial.begin(9600); // initialize serial
delay(1500);
// Connect to WiFi
Serial.println("Attempting to connect to WiFi...");
while (!WiFi.begin(SECRET_SSID, SECRET_OPTIONAL_PASS)) {
Serial.println("Failed to connect to WiFi. Retrying...");
delay(1000);
}
// Wait for WiFi connection to be established
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi!");
// Initialize Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
// Defined in thingProperties.h
initProperties();
tempSensor.begin(); // initialize the sensor
lcd.init(); // initialize the lcd
lcd.backlight(); // open the backlight
}
void loop() {
tempSensor.requestTemperatures(); // send the command to get temperatures
tempCelsius = tempSensor.getTempCByIndex(0); // read temperature in Celsius
Serial.print(tempCelsius); // print the temperature in Celsius
Serial.println("°C");
lcd.clear();
lcd.setCursor(0, 0); // start to print at the first row
lcd.print("CONCRETE TEMP:"); // print concrete temp wording
lcd.setCursor(0, 1); // start to print at the second row
lcd.print(tempCelsius); // print the temperature in Celsius
lcd.print((char)223); // print ° character
lcd.print("C");
ArduinoCloud.update(); // Update Arduino IoT Cloud
delay(10000); // read temperature once every 15 minutes which is 900000 ms
}
// Function called when Concrete_Temperature property changes
void on_Concrete_Temperature_change() {
// You can add custom behavior here if needed
}
I'm reading online that the delay function can actually pause your code and cause it to get "stuck" during the time that it's in the delay period whereas if you use millisDelay, the code is still running it's just one specific function that is delayed.
I want a 15 minute delay between the collection of temperature data points and I don't want this delay to cause downtime between the connection of the UNO R4 wifi and the IoT cloud.
The millisDelay function shown here years ago -does- work but it's a good bit slower than non-blocking code as I demonstrated here years ago.
It's possible to replace delays with timing code, often callled millis-code that does not resort to context shifting interrupts and their associated overhead. I have a method I used to convert delay-ridden code that uses millis/micros timing combined with a state machine that always works. Many members here know it, I believe. and the un-delay examples are in the archives.
I go to cataract surgery today and next week but after that I'd be happy to show and explain how to write functions that run as parallel tasks in void loop() with NO O/S or interrupts. Those tasks run independently but can coordinate and cooperate through shared global variables to run very fast, void loop can be kept up to 50 kHz and higher speed, there is a lean function to show that I use to check on the impact of code changes in non-blocking sketches.
Remember that delay(1) wastes 16000 cpu cycles.
Every AVR interrupt requires a minimum of 85 cycles plus whatever the interrupt service code does, they make poor work-arounds for tasking and they use up interrupts some libraries need! There are better, indispensable uses for interrupts than get around code.. save interrupts for that and your tasks will be more reusable not to mention run faster.
People used to depending on an O/S to do it for them get into ruts where they HAVE TO have work-around bail-outs.
I'm not going to worry about the setup() function, but this one is really simple...
void loop() {
static unsigned long cycleTimestamp = millis();
if (millis() - cycleTimestamp >= 1000UL) {
cycleTimestamp += 1000UL;
tempSensor.requestTemperatures(); // send the command to get temperatures
tempCelsius = tempSensor.getTempCByIndex(0); // read temperature in Celsius
Serial.print(tempCelsius); // print the temperature in Celsius
Serial.println("°C");
lcd.clear();
lcd.setCursor(0, 0); // start to print at the first row
lcd.print("CONCRETE TEMP:"); // print concrete temp wording
lcd.setCursor(0, 1); // start to print at the second row
lcd.print(tempCelsius); // print the temperature in Celsius
lcd.print((char)223); // print ° character
lcd.print("C");
ArduinoCloud.update(); // Update Arduino IoT Cloud
}
}
See the tutorial on blink without delay for more information.
Test it and see it will be true every 1000 milliseconds.
static unsigned long cycleTimestamp = millis();
As this is a static local, this line is only executed once ever to initialize the variable. If this is over your head, you can also structure it as follows:
but it isn't a drop-in replacement for delay(). It just sets up millis()-based timers with classes and you still need to re-structure your code to be non-blocking.
When you are doing one thing at a time, delay() makes no difference. The place it makes a difference is when the part that is delayed is keeping other code from running.
But now you can add other non-blocking functions to perhaps monitor ambient temperature or have buttons to decrease/increase the report period.
ALL -- I'm back from surgery on the worst eye, pupil still dilated and eye feels sort of scratched but already less blurry. The other eye gets done next week.
Is there any chance you'd be open to a video call with me to diagnose the issue I'm having? I'm a complete novice at coding and I can't for the life of me fix the arduino since I've updated the firmware. It collects two data points and then reads an error code, see the link here for the error
Do you think this would solve the error I'm seeing? See the error here. Sorry for late reply, I've been on holiday. I'm also a complete novice at this, i've pieced together the code from different blog posts and online forums and tried to put this together.
I can't repeat what you're doing since I don't have an Uno R4.
The code you show in that thread uses a library I don't have or is not complete since read temperatures function isn't in what you do show.
"fix the Arduino".... or fix the sketch?
Right now, we would be using terms differently and not understanding what the other means, leading to communication errors between us.
There are many unknowns at the same time.
Which unknown is causing which problem won't be apparent and that easily leads to fixing what isn't broken... and adding bugs as a result.
Trouble-shooting involves reducing unknowns to one then fixing that. It's done one piece at a time instead of on the whole by guessing what to change.
Where we left off, you were getting advice to make changes that I don't see any of done. Was it running good and solid before you changed the firmware? What happens when you change the firmware back? Why change what worked unless it didn't?
because the static variable only gets set the first time, when it is created. After that it stays and does not get reset.
For beginners it is more clear to make a global variable and set it to millis() in setup(). The difference is that only loop() has access to the local-to-loop() static variable.
ALL.... I can see now. Still doing eye drops but YOW what a difference! In a month I may have glasses and see 20-20 but close already and web pages that hurt my eyes before, don't!
The sketch worked fine before I updated the firmware. I updated the firmware as I was seeing downtime in the connectivity between the R4 Wifi and the IoT cloud and a possible solution to this was to update the firmware. That is when my problem first started. I didn't know it was possible to change the firmware back. I'll look into this.