Closed mooballs closed 2 years ago
/!\ there is a big difference between delay and millis. Delay is a blocking function where millis is not so your code has a problem. You need to block your execution until the good amount of time has passed.
To just block, you can do a while loop like this:
for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
// scroll one position left:
While ( (millis() - times) >= 350) {} //Has one second passed?
lcd.scrollDisplayLeft();
times = millis(); //and reset time.
}
Another thing, the comment say 1 second but you wait 350ms 😉
Thanks for having a look. I should have said, but it needs to be unblocking as there's other stuff going on in my main sketch. I tried the while () method and it still didn't work. Either way, the point is the code I've posted should work and it doesn't. It works in v1.0.6, but not 2.x.x, which is why I've raised it as an issue. It works if I use delay() but not millis() (or micros, or esp_timer_get_time). If somebody had five minutes to hook up an LCD1602 and try it I'd be most grateful. Or point me in the direction of what could possibly be messing it up (I'll try yet another board, but I keep coming back to fact that it used to work and now I've updated the arduino-esp32 version it doesn't).
I am closing this because it's a coding issue. Feel free to continue the discussion though :)
void loop(){
static int positionCounter = -1;
if(positionCounter < 0){
lcd.setCursor(0, 0);
lcd.print("Hello");
lcd.setCursor(0, 1);
lcd.print("Mate");
positionCounter = 0;
times = millis();
} else if((positionCounter >= 0) && ((millis() - times) >= 350)){
lcd.scrollDisplayLeft();
times = millis();
positionCounter++;
if(positionCounter == 16){
positionCounter = -1;
}
}
}
Have you actually tried it with an LCD? Because your code does exactly the same as mine, which is to say, doesn't work. As I say, it works in 1.0.6, but not in 2.x.x, so if its a coding issue, how could this be? (I'm not being rude, I genuinely want to know).
your code does the following thing:
prints Hello Mate
loops 16 times to check if time limit has been reached, which would never be, because they happen fast
repeat
Thanks for that mate, that makes sense and I had wondered about that bit of code. BUT ; why would it work in an earlier version of arduino-esp32 (making me think the code was sound)? plus I've tried your code and I'm getting the same result as mine.
the issue is probably i the library you are using. We require that Wire API is properly used. If you link me to the library, I can probably tell you what is wrong and how to fix it
That would be amazing, I have tried a few different libraries as I'd read about that (and I've just re-tried them now with your code), but for arguments sake lets say this one:
https://github.com/marcoschwartz/LiquidCrystal_I2C/archive/master.zip
library worked fine :) are you sure you have powered the I2C expander with 5V? it will not work on 3.3 unless you adjust the contrast
Yeah man, its all set up correctly. Its so bizarre that it works in the earlier version but not in the later ones (both your code and, weirdly, mine). Thanks for helping anyway, I don't know what I'm going to do now but I'll keep digging.
it must be contrast issue. Library and code (my code) worked out of the box here. First I connected the LCD to 3.3V which was too low (later adjusting contrast made it show the text) and it worked out of the box on 5V. No changes to the library or anything.
Very weird. Many thanks for trying it with an LCD though, at least I know its definitely something specific to my setup. It can't be the contrast though, as I can get it to display nicely either statically or with delay(). Also, this works that I found online
#include <LiquidCrystal_I2C.h>
#include <string.h>
// initialize the library with the numbers of the interface pins
int lcdColumns = 16;
int lcdRows = 2;
int scrolltime = 350;
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
char message[] = "This is some long message that will end up scrolling";
int previous = 0;
int pos = 0;
void setup() {
// set up the LCD's number of columns and rows:
lcd.init();
Serial.begin(115200);
lcd.backlight();
// Print a message to the LCD.
//lcd.print(message);
}
void printLine(int refreshSeconds){
//Check if the current second since restart is a mod of refresh seconds ,
//if it is then update the display , it must also not equal the previously
//stored value to prevent duplicate refreshes
if((millis()) % refreshSeconds == 0 && previous != (millis())){
previous = (millis());//Store the current time we entered for comparison on the next cycle
lcd.setCursor(0, 1);//Set our draw position , set second param to 0 to use the top line
char lcdTop[16];//Create a char array to store the text for the line
int copySize = 16; // What is the size of our screen , this could probably be moved outside the loop but its more dynamic like this
if(strlen(message) < 16)
{
//if the message is bigger than the current buffer use its length instead;
copySize = strlen(message);
}
//Store the current position temporarily and invert its sign if its negative since we are going in reverse
int tempPos = pos;
if(tempPos < 0)
{
tempPos = -(tempPos);
}
//Build the lcd text by copying the required text out of our template message variable
memcpy(&lcdTop[0],&message[tempPos],copySize);
lcd.print(lcdTop);//Print it from position 0
//Increase the current position and check if the position + 16 (screen size) would be larger than the message length , if it is go in reverse by inverting the sign.
pos += 1;
if(pos +16 == strlen(message))
{
pos = -(pos);
}
}
}
void loop() {
printLine(350);
}
But I'm having trouble integrating it into my sketch so I think the only thing I haven't tried is a completely new board (I realised both of mine were from the same ebayer, could both be dodgy). Having just uninstalled and reinstalled arduino and it still doing the same thing, I'm going to wait for the new board to come and if it still does it then I'm going to throw it all in the bin and drink lots of beer. Thanks again mate.
Wish you luck!
Board
ESP32 Dev Module
Device Description
Standard 1602 LCD display with standard I2C convertor.
Hardware Configuration
I2C SDA=GPIO21, SCL=GPIO22
Version
v2.0.2
IDE Name
Arduino IDE
Operating System
Windows 10
Flash frequency
40Mhz
PSRAM enabled
no
Upload speed
921600
Description
The text in the attached code will scroll across the screen if I use delay() but if I try millis() it just flickers as if its flying past very quickly (regardless of the value of milliseconds I use).
Sketch
Debug Message
Other Steps to Reproduce
It compiles fine, but will not display properly on the LCD (I've tried I2c and connecting the LCD directly to the esp32 with the same results). millis() works fine in v1.0.6 but I need to use 2.0.2 as some of the features in the project I'm working on are dependant on the latest version. I've also tried several different Liquid Crystal libraries and another esp32 board with no luck. I can't find any mention of the issue online at all.
I have checked existing issues, online documentation and the Troubleshooting Guide