Random characters after using LCD during a while
georges6410 opened this issue · 14 comments
Hello,
I've tried using your library, and it works kinda well, but after using it a few minutes, the screen prints random characters.
Here I have :
http://image.noelshack.com/fichiers/2016/10/1457905151-img-20160313-223745.jpg
If I remove the wires to cut off the power, and replug it after : still the characters on the picture.
After a few tests, the characters can be removed, but I can't identify the actions to perform to achieve this.
Could you help ?
Thanks
Whenever I saw this issue in the past it was related to timing. The lcd code should have waited for the LCD to complete an operation but it wasn't waiting long enough.
To help determine whether this could be a timing issue, please replace lcd.js from your installation with the modified version of lcd.js from this gist. Perhaps the modified version which quadruples the delays will improve things.
If it still doesn't work, please post the code that is causing the error.
@georges6410 did the modified version of lcd.js with quadrupled delays resolve the issue?
It seems that the modified version doesn't resolve the issue.
I'll post here tonight the complete code, but I do this :
lcdScreen.clear(function() {
lcdScreen.print(theMessage);
});
Edit : it seems to be working finally. Don't know why the other day it wasn't working, but for now it works great.
So, I guess we can say it's closed and solved.
If the following code is executed twice in quick succession there may be issues. The clear
and print
methods are both asynchronous. If the second call to clear
occurs before the first call to print
has completed the behavior is undefined.
lcdScreen.clear(function() {
lcdScreen.print(theMessage);
});
@georges6410 I'd like to try and reproduce the issue. Can you tell me which platform (Pi, BeagleBone, ...), operating system, and version of Node.js is being used?
It's possible to reproduce the issue with the following code on a Raspberry Pi 1 Model B with Node.js v5.5 in less than a minute:
'use strict';
var Lcd = require('../lcd'),
lcd = new Lcd({rs: 23, e: 24, data: [17, 18, 22, 27], cols: 20, rows: 4});
lcd.on('ready', function () {
setInterval(function () {
lcd.clear(function () {
lcd.print(new Array(8).join('0123456789'));
});
}, 80);
});
Because both clear
and print
are asynchronous and because the program doesn't wait for print
to complete execution before calling clear
again everything can get very messed up. The lcd package doesn't have any internal mechanisms for preventing this from occurring.
I had the exact same problem, and it seems that this gist solved it. I created a fork to integrate it and to be able to use it as a dependency with npm.
@fivdi: don't you consider using it on master as the main code? It would help with reliability and using the library with proper npm versions.
Thanks
PS: The library is great btw 👍
@roland-vachter I think the gist is more of a workaround or hack than a solution. It may work in some scenarios but not in others. I think the real problems is that asynchronous operations that are run "concurrently" are interfering with each other. Do you have code that can be used to reproduce the problem?
Putting the asynchronous operations in a queue and running them sequentially rather than allowing them to run in parallel would be better.
The problem on my side appeared after running the code for a longer time, updating the display each minute. It was a simple clear -> setCursor to first line -> print -> setCursor to second line -> print.
let printLcd = (data) => {
lcd.clear(() => {
lcd.home(() => {
lcd.setCursor(0, 0);
setTimeout(() => {
lcd.print('I: '+
(" " + data.inside.temperature.toFixed(1)).slice(-5) + 'C ' +
(" " + data.inside.humidity).slice(-3) + '%',
() => {
lcd.setCursor(0, 1);
setTimeout(() => {
lcd.print('O: '+
(" " + data.outside.temperature.toFixed(1)).slice(-5) + 'C ' +
(" " + data.outside.humidity).slice(-3) + '%');
}, 50);
}
);
}, 50);
});
});
};
I have the raspberry PI 2.
Now with this gist it runs for almost a day without issue.
There are libraries which access the GPIO in another way than onoff does, synchronously (https://www.npmjs.com/package/rpio), this might be a good solution avoiding conflicting async operations.
@roland-vachter The above code will function correctly if printLcd
is really only called once per minute. However, if printLcd
called twice in quick succession it is highly likely that there will be issues. The clear
, home
, and print
methods are asynchronous. It's therefore possible to call printLcd
for a second time before a previous call to printLcd
has completed. This is very likely to happen with heating-control-rpi
. printLcd
is called here when ambientalConditions
change. The ambientalConditions
can change when the outsideConditions or insideContitions change. The outsideConditions are updated every 60 seconds and the insideConditions are updated every 60 seconds. It's highly likely that the outsideConditions
and the insideConditions
will be updated at more or less the same time an that printLcd
is called for a second time before the first call has completed.
Now with this gist it runs for almost a day without issue.
This may be the case but it's not a good solution.
There are libraries which access the GPIO in another way than onoff does, synchronously (https://www.npmjs.com/package/rpio), this might be a good solution avoiding conflicting async operations.
Internally the lcd
package only uses synchronous onoff
methods. The clear
and home
methods are asynchronous because it's essential to wait 1.52 milliseconds for a HD44780 LCD module to clear the display or move the cursor to the home position before asking the display to do anything else. The print
method is asynchronous because it was designed that way. As far as I remember, it takes approximately 30 milliseconds to write 80 characters to an LCD display synchronously with onoff on a raspberry Pi 1 Model B. Blocking the CPU for 30 milliseconds is a long time, so the print
method is asynchronous. It write the characters to the LCD one by one and returns to the Node.js event loop after writing each character.
@georges6410 @roland-vachter lcd v1.1.3 has just been published on npm. lcd now queues asynchronous operations and executes them sequentially. It should resolve the issues that you were seeing.
That's a really good news! Thank you, I will give it a try once I get home.
As mentioned above the lcd package now queues asynchronous operations and executes them sequentially. This prevents the asynchronous operations from stepping on each other and messing things up. Note that the print, clear, and home operations are still asynchronous.
Thanks for reporting this issue.