ebolisa
December 11, 2015, 5:06pm
1
Hi,
I’m displaying several messages on a LCD so, to be able to read all of them, I need to add some delays.
The latter adds an overall delay to my main loop of about 7 seconds. To cut it down, I used Robin’s routine at Demonstration code for several things at the same time - Project Guidance - Arduino Forum .
Perhaps, I’m implanting it wrong, but the routine is not shorting out the overall delay. What’s the best way to accomplish it? TIA
#include <Bridge.h>
#include <Console.h>
#include <LiquidCrystal_I2C.h>
/* LCD Display */
const byte dir = 0x27; // I2C hexadecimal address
LiquidCrystal_I2C lcd(dir, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // set address and pins
/* https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay */
unsigned long currentMillis = 0;
unsigned long previousMillis = 0; // will store last time LCD was updated
unsigned long previousMillis_1 = 0;
const long interval = 1000; // display delay
void setup() {
Bridge.begin();
Console.begin();
// set up the LCD's number of columns and rows:
lcd.begin(20, 4);
lcd.print("Initializing...");
delay(1000);
lcd.clear();
}
void loop() {
currentMillis = millis();
Console.println("Start " + getTimeStamp());
// doing several tasks here
// ...
/* updating LCD display */
if (currentMillis - previousMillis >= interval) {
updateDisplay ();
previousMillis = currentMillis;
}
Console.println("End " + getTimeStamp()); // time delay of 6-7 seconds here from start loop
}
//// LCD update
void updateDisplay() {
//unsigned long currentMillis = millis();
// if (currentMillis - previousMillis >= interval) {
lcd.clear();
lcd.setCursor(0, 1); // col row
lcd.print(getTimeStamp()); // display time date
//previousMillis = currentMillis;
delay(2000);
// }
// currentMillis = millis();
// if (currentMillis - previousMillis_1 >= interval) {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("H20 Temp is 40º C"); // display water temp
//previousMillis_1 = currentMillis;
delay(2000);
//}
lcd.clear(); // clear display
lcd.setCursor(0, 0); // set curson
lcd.print("Tech Room T=" + String(34) + " C");
lcd.setCursor(0, 1);
lcd.print("Tech Room H=" + String(44) + " %");
lcd.setCursor(0, 2); // set curson
lcd.print("Main Room T=" + String(31) + " C");
lcd.setCursor(0, 3);
lcd.print("Main Room H=" + String(43) + " %");
delay(2000);
}
//// END updateDisplay
//**** Get Time Stamp ****
String getTimeStamp() {
String result;
Process time;
time.begin("date");
time.addParameter("+%d/%m/%Y-%T");
time.run();
while (time.available() > 0) {
char c = time.read();
if (c != '\n')
result += c;
}
return result;
}
//// END getTimeStamp
ebolisa
December 11, 2015, 5:49pm
3
Thanks for the reply.
I modified the code with the use of millis but the datetime, in this case, is not displayed on the LCD
currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
lcd.clear();
lcd.setCursor(0, 1); // col row
lcd.print(getTimeStamp()); // display date & time
previousMillis = currentMillis;
}
Robin2
December 11, 2015, 6:00pm
4
Post your complete code.
I wonder if you are using previousMillis() in two different places and they are getting mixed up.
...R
We can't see the rest of your code so that the context of your timing can be seen.
ebolisa
December 11, 2015, 7:12pm
6
Here's the code...
Thank you.
#include <Bridge.h>
#include <Console.h>
#include <LiquidCrystal_I2C.h>
/* LCD Display */
const byte dir = 0x27; // I2C hexadecimal address
LiquidCrystal_I2C lcd(dir, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // set address and pins
/* https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay */
unsigned long currentMillis = 0;
unsigned long previousMillis = 0; // will store last time LCD was updated
const long interval = 1000; // display delay
void setup() {
Bridge.begin();
Console.begin();
// set up the LCD's number of columns and rows:
lcd.begin(20, 4);
lcd.print("Initializing...");
delay(1000);
lcd.clear();
}
void loop() {
Console.println("Start " + getTimeStamp());
// doing several tasks here
// ...
/* updating LCD display */
updateDisplay ();
Console.println("End " + getTimeStamp()); // time delay of 6-7 seconds here from start loop
}
//// LCD update
void updateDisplay() {
currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
lcd.clear();
lcd.setCursor(0, 1); // col row
lcd.print(getTimeStamp()); // display time date
previousMillis = currentMillis;
// delay(2000);
}
// currentMillis = millis();
// if (currentMillis - previousMillis_1 >= interval) {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("H20 Temp is 40º C"); // display water temp
//previousMillis_1 = currentMillis;
delay(2000);
//}
lcd.clear(); // clear display
lcd.setCursor(0, 0); // set curson
lcd.print("Tech Room T=" + String(34) + " C");
lcd.setCursor(0, 1);
lcd.print("Tech Room H=" + String(44) + " %");
lcd.setCursor(0, 2); // set curson
lcd.print("Main Room T=" + String(31) + " C");
lcd.setCursor(0, 3);
lcd.print("Main Room H=" + String(43) + " %");
delay(2000);
}
//// END updateDisplay
//**** Get Time Stamp ****
String getTimeStamp() {
String result;
Process time;
time.begin("date");
time.addParameter("+%d/%m/%Y-%T");
time.run();
while (time.available() > 0) {
char c = time.read();
if (c != '\n')
result += c;
}
return result;
}
//// END getTimeStamp
You still have two delays in there.
void updateDisplay() {
currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
lcd.clear();
lcd.setCursor(0, 1); // col row
lcd.print(getTimeStamp()); // display time date
previousMillis = currentMillis;
// delay(2000);
}
// currentMillis = millis();
// if (currentMillis - previousMillis_1 >= interval) {
lcd.clear(); // <---------- HERE
OK, you followed the advice above. You display the time stamp, and then in the line above you immediately clear the LCD. So obviously you don't see that display for long, right?
ebolisa
December 11, 2015, 7:57pm
9
Moved the clear out the loop but no display...
#include <Bridge.h>
#include <Console.h>
#include <LiquidCrystal_I2C.h>
/* LCD Display */
const byte dir = 0x27; // I2C hexadecimal address
LiquidCrystal_I2C lcd(dir, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // set address and pins
/* https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay */
unsigned long currentMillis = 0; // will store last time LCD was updated
unsigned long currentMillis1 = 0;
unsigned long currentMillis2 = 0;
unsigned long previousMillis = 0;
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
const long interval = 4000; // display delay
void setup() {
Bridge.begin();
Console.begin();
// set up the LCD's number of columns and rows:
lcd.begin(20, 4);
lcd.print("Initializing...");
delay(1000);
lcd.clear();
}
void loop() {
Console.println("Start " + getTimeStamp());
// doing several tasks here
// ...
/* updating LCD display */
updateDisplay ();
Console.println("End " + getTimeStamp()); // time delay of 6-7 seconds here from start loop
}
//// LCD update
void updateDisplay() {
currentMillis = millis();
lcd.clear();
if (currentMillis - previousMillis >= interval) {
lcd.setCursor(0, 1); // col row
lcd.print(getTimeStamp()); // display time date
previousMillis = currentMillis;
// delay(2000);
}
currentMillis1 = millis();
lcd.clear();
if (currentMillis1 - previousMillis1 >= interval) {
lcd.setCursor(0, 1);
lcd.print("H20 Temp is 40º C"); // display water temp
previousMillis1 = currentMillis1;
//delay(2000);
}
currentMillis2 = millis();
lcd.clear();
if (currentMillis2 - previousMillis2 >= interval) {
lcd.setCursor(0, 0); // set curson
lcd.print("Tech Room T=" + String(34) + " C");
lcd.setCursor(0, 1);
lcd.print("Tech Room H=" + String(44) + " %");
lcd.setCursor(0, 2); // set curson
lcd.print("Main Room T=" + String(31) + " C");
lcd.setCursor(0, 3);
lcd.print("Main Room H=" + String(43) + " %");
previousMillis2 = currentMillis2;
//delay(2000);
}
}
//// END updateDisplay
//**** Get Time Stamp ****
String getTimeStamp() {
String result;
Process time;
time.begin("date");
time.addParameter("+%d/%m/%Y-%T");
time.run();
while (time.available() > 0) {
char c = time.read();
if (c != '\n')
result += c;
}
return result;
}
//// END getTimeStamp
Here:
if (currentMillis - previousMillis >= interval) {
lcd.setCursor(0, 1); // col row
lcd.print(getTimeStamp()); // display time date
previousMillis = currentMillis;
// delay(2000);
}
currentMillis1 = millis();
lcd.clear(); // <---------- THIS
ebolisa
December 11, 2015, 8:44pm
11
Nick, I need to clear the display otherwise, the text will overlap.
The code works fine with the function delay().
//// LCD update
void updateDisplay() {
lcd.clear();
lcd.setCursor(0, 1); // col row
lcd.print(getTimeStamp()); // display time date
delay(2000);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("H20 Temp is 40º C"); // display water temp
delay(2000);
lcd.clear();
lcd.setCursor(0, 0); // set curson
lcd.print("Tech Room T=" + String(34) + " C");
lcd.setCursor(0, 1);
lcd.print("Tech Room H=" + String(44) + " %");
lcd.setCursor(0, 2); // set curson
lcd.print("Main Room T=" + String(31) + " C");
lcd.setCursor(0, 3);
lcd.print("Main Room H=" + String(43) + " %");
delay(2000);
}
//// END updateDisplay
ebolisa
December 11, 2015, 9:39pm
13
Delta: I'm displaying
date time
clear
Temperatures from dhr sensors
Clear
Temperature from a thermister
Clear
But it's not the scope of my original question.
MorganS
December 12, 2015, 3:34am
16
ebolisa:
Delta: I'm displaying
date time
clear
Temperatures from dhr sensors
Clear
Temperature from a thermister
Clear
You really should be doing:
Clear
date time
clear
Temperatures from dhr sensors
Clear
Temperature from a thermister
ebolisa:
Nick, I need to clear the display otherwise, the text will overlap.
The code works fine with the function delay().
If would make a lot more sense if you cleared it, just before writing to it, not just after.
if (currentMillis - previousMillis >= interval) {
lcd.clear(); // <--- clear before writing something else
lcd.setCursor(0, 1); // col row
lcd.print(getTimeStamp()); // display time date
previousMillis = currentMillis;
}
ebolisa
December 12, 2015, 11:06am
18
Ok, I see the problem (said the blind man).
The code below prints 3 lines of text at different time simulating my LCD text.
The problem is that the text stays on for a cycle which is too short for a display.
So going back to my original code/question, how do I use millis in place of delay() correctly?
Thank you.
#include <Bridge.h>
#include <Console.h>
/* https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay */
unsigned long currentMillis = 0;
unsigned long currentMillis1 = 0;
unsigned long currentMillis2 = 0;
unsigned long previousMillis = 0;
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
const long interval = 6000; // 6 secs display delay
void setup() {
Bridge.begin();
Console.begin();
while (!Console);
Console.println("Hi, I'm ready!");
}
void loop() {
currentMillis = millis();
Console.println(currentMillis);
Console.println(previousMillis);
Console.println(currentMillis - previousMillis);
if (currentMillis - previousMillis >= interval) {
Console.println("Do nice things");
//previousMillis = currentMillis;
previousMillis += interval;
}
currentMillis1 = millis();
Console.println(currentMillis1);
Console.println(previousMillis1);
Console.println(currentMillis1 - previousMillis1);
if (currentMillis1 - previousMillis1 >= interval) {
Console.println("Do more nice things");
//previousMillis1 = currentMillis1;
previousMillis1 += interval;
}
currentMillis2 = millis();
Console.println(currentMillis2);
Console.println(previousMillis2);
Console.println(currentMillis2 - previousMillis2);
if (currentMillis2 - previousMillis2 >= interval) {
Console.println("Do much more nice things");
//previousMillis2 = currentMillis2;
previousMillis2 += interval;
}
}
how do I use millis in place of delay() correctly?
Save the millis() value at the time that the start action, such as display of data, happens. Then, each time through loop(), check whether the required wait period has elapsed by subtracting the start time from the millis() value now. If the period has elapsed then act accordingly, display the next data, and save the start time for the next activity. If not, then go round loop() again, perhaps taking other actions and/or reading inputs, but don't block the free running of loop().
ebolisa
December 12, 2015, 12:10pm
20
Bob, that's what I'm doing with the code shown in my prior post. Not sure there's a different way to do it.
ebolisa:
Bob, that's what I'm doing with the code shown in my prior post. Not sure there's a different way to do it.
take a look at this:
#include <Bridge.h>
#include <Console.h>
/* https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay */
unsigned long previousMillis0 = 0;
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
const long interval0 = 6000; // 6 secs display delay
const long interval1 = 12000;
const long interval2 = 18000;
void setup()
{
Bridge.begin();
Console.begin();
while (!Console);
Console.println("Hi, I'm ready!");
}
void loop()
{
unsigned long currentMillis = millis(); //catch the current value of millis()
if (currentMillis - previousMillis0 >= interval0) // compare first
{
Console.println("Do nice things");
//previousMillis = currentMillis;
previousMillis0 += interval0;
}
if (currentMillis - previousMillis1 >= interval1) // second
{
Console.println("Do more nice things");
previousMillis1 += interval1;
}
if (currentMillis - previousMillis2 >= interval2) //and third time against value of millis for the turn of loop()
{
Console.println("Do much more nice things");
previousMillis2 += interval2;
}
}
ebolisa
December 12, 2015, 12:47pm
22
Bulldog: Thank you, it worked!! I saved the 7 seconds which I was after.