I have a CharacterDisplay module that displays a message for a few seconds whenever a particular event is triggered. The message contains an embedded newline (\n) character, so that part of the message appears on the first line, and the rest appears on the second line. Every time I output the message, I execute the following sequence of code:
Nothing else is done to the characterDisplay object elsewhere in the application.
The first time this sequence executes, the display shows exactly what I expect it to show:
The next time the exact same sequence executes, the display shows a single line (top line of the display):
It appears that the second round doesn’t treat the \n as a newline, but instead just prints the second line overlayed onto the first line. What’s really interesting (to me) about this is that the behavior toggles on every execution of that code sequence. In other words, if we were to assign a sequence number to each execution of that code (Clear followed by Print), all the odd-numbered executions display the expected two lines of output, and all the even-numbered executions display the single-line overlayed output.
Any thoughts on what might be causing this toggling behavior?
get the source code for the module, and it should explain what is happening.
@ Mike -
You make an excellent suggestion. I had actually looked for the source code (I should have said so) in the Gadgeteer project on Codeplex, but the closest I could find was the Display_HD44780, which presents a completely different API.
Where would I find the module source code for the GHI CHARD-GM-395 Character Display Module?
@ iamin -
Thanks for the pointer to the driver source code. I found the bug that is causing this behavior.
The driver has a variable called currentRow, which keeps track of the current output row (0, 1, wrapping back to 0). It correctly increments (mod 2) whenever a newline character is encountered in the Print methods. But currentRow is not set back to 0 in either the Clear or CursorHome methods. The underlying device commands cause the device to set the cursor’s row back to 0 (internally) in both of these methods, but if the currentRow variable happened to be 1 when either Clear or CursorHome was called, the currentRow variable becomes out of sync with the device’s idea of the current row.
After printing the two lines, currentRow is 1 (the second line), and the device internally agrees it’s on that row. On the second go-round, the first output line is printed on the first display line (using the device’s idea of the current row), the embedded newline causes currentRow to wrap to 0, the device’s cursor position is set to row zero (based on the now-incorrect currentRow value), and the second line of output overwrites the text already displayed on the first row. Once this happens, currentRow and the device’s idea of the current row are back in sync. This is why the problem occurs on every other execution of the Clear/Print sequence.
The fix to the driver is to set currentRow to 0 in both the Clear and CursorHome methods. This would keep currentRow and the device’s idea of the current row in sync at all times.
The workaround in application code, in this case, is to add a newline to the end of the second line of output, which will cause currentRow to wrap around to 0 before the next call to Clear, causing the variable and the device to be in sync about which row the cursor is on.
characterDisplay.Print("Welcome\nFred\n"); // newline added at the end
I would be happy to fix and test the driver, or file a bug report against the driver with the details of the fix. But I don’t yet know the official procedure for either.
@ iamin -
Thanks for the pointer. I have filed the bug report.
And thanks for the kind words.