I have much of the solution done. I used this test code:
// cursor tests--see if cursor correctly turned off as we leave second chip, mainly
lcd.clear();
lcd.noCursor();
int i=0;
while (i<nRows*2) {
lcd(0,i%4)<<"no cursor"<<i;
i++;
delay(500);
}
delay(4000);
lcd.clear();
lcd.cursor();
i=0;
while (i<nRows*2) {
lcd(0,i%4)<<"cursor"<<i;
i++;
delay(500);
}
delay(4000);
lcd.noCursor();
lcd.clear();
lcd.blink();
i=0;
while (i<nRows*2) {
lcd(0,i%4)<<"blink"<<i;
i++;
delay(500);
}
delay(4000);
lcd.noBlink();
lcd.clear();
lcd.cursor();
lcd.blink();
i=0;
while (i<nRows*2) {
lcd(0,i%4)<<"c+b"<<i;
i++;
delay(500);
}
delay(4000);
lcd.noCursor();
lcd.noBlink();
//end cursor test 1
(I'm using Streaming)
As Don said, I'd never really used cursors and had not thought carefully about them. So the spot where I turned the underline cursor off really should have turned the cursor on on the other chip and I ignored the blinking cursor altogether.
The command to turn the display on or off also resets the cursor flags.
here are the changes to LiquidCrystal.cpp that I've made:
void LiquidCrystal::display() {
_displaycontrol |= LCD_DISPLAYON;
commandBoth(LCD_DISPLAYCONTROL | _displaycontrol & 0xfc); //both chips on, both cursors off
command(LCD_DISPLAYCONTROL | _displaycontrol); //selected chip gets cursor on
}
and
void LiquidCrystal::setCursor(uint8_t col, uint8_t row) // this can be called by the user but is also called before writing some characters.
{
if ( row > _numlines ) {
row = _numlines-1; // we count rows starting w/0
}
_y = row;
_x = col;
_setCursFlag = 0; //user did a setCursor--clear the flag that may have been set in write()
int8_t high_bit = row_offsets[row] & 0x40; // this keeps coordinates pegged to a spot on the LCD screen even if the user scrolls right or
int8_t offset = col + (row_offsets[row] &0x3f) + _scroll_count; //left under program control. Previously setCursor was pegged to a location in DDRAM
//the 3 quantities we add are each <40
if (offset > 39) offset -= 40; // if the display is autoscrolled this method does not work, however.
if (offset < 0) offset += 40;
offset |= high_bit;
if (_chip != (row & 0b10)) command(LCD_DISPLAYCONTROL | _displaycontrol & 0xfc);; //turn off cursors on chip we are leaving
_chip = row & 0b10; //if it is row 0 or 1 this is 0; if it is row 2 or 3 this is 2
command(LCD_DISPLAYCONTROL | _displaycontrol); //turn on cursor on chip we moved to
command(LCD_SETDDRAMADDR | (byte) offset );
}
Stylistically 0xfc should get changed; the underline and blink cursor are in bits 0x01 and 0x02 and are defined symbolically in LiquidCrystal.h
so far I have just run the 40x4 through the test code. The one thing I see is that the underline cursor now is left on at the end of the first time through the loop of tests. That may be the desired behavior, I'm inclined to think that it is.
the nice surprise as I actually coded this is that I did not need another RAM location to keep track of cursor flags.
I will get the full test done on all the LCDs over the next few days; I doubt there will be surprises. then I can zip and post the code. It would be nice to know that this solves your problem.