mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-24 21:21:24 +01:00
Enhance OLED/LCD speed
Write one character or position command per loop entry so as not to hold up the loop. Add support for SH1106 OLED as 132x64 size option.
This commit is contained in:
parent
01c3e7487f
commit
ec1d674da7
@ -44,36 +44,78 @@ size_t LCDDisplay::write(uint8_t b) {
|
||||
lcdDisplay->loop2(false);
|
||||
}
|
||||
|
||||
LCDDisplay* LCDDisplay::loop2(bool force) {
|
||||
if ((!force) && (millis() - lastScrollTime)< LCD_SCROLL_TIME) return NULL;
|
||||
lastScrollTime=millis();
|
||||
clearNative();
|
||||
int rowFirst=nextFilledRow();
|
||||
if (rowFirst<0)return NULL; // No filled rows
|
||||
setRowNative(0);
|
||||
writeNative(rowBuffer[rowFirst]);
|
||||
for (int slot=1;slot<lcdRows;slot++) {
|
||||
int rowNext=nextFilledRow();
|
||||
LCDDisplay *LCDDisplay::loop2(bool force)
|
||||
{
|
||||
static int rowFirst = -1;
|
||||
static int rowNext = 0;
|
||||
static int charIndex = 0;
|
||||
static char buffer[MAX_LCD_COLS+1];
|
||||
static char *bptr = 0;
|
||||
static bool done = false;
|
||||
|
||||
unsigned long currentMillis = millis();
|
||||
|
||||
if ((!force) && (currentMillis - lastScrollTime) < LCD_SCROLL_TIME)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
if (bptr == 0) {
|
||||
// No pending write, so go and look for one.
|
||||
if (!done) {
|
||||
if (rowFirst < 0) rowFirst = rowNext;
|
||||
// Skip blank rows
|
||||
while (rowBuffer[rowNext][0] == 0) {
|
||||
rowNext = (rowNext + 1) % MAX_LCD_ROWS;
|
||||
if (rowNext == rowFirst) {
|
||||
// we have wrapped around and not filled the screen
|
||||
topRow=-1; // start again at first row next time.
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
setRowNative(slot);
|
||||
writeNative(rowBuffer[rowNext]);
|
||||
}
|
||||
displayNative();
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
// Non-blank line found, so copy it.
|
||||
strncpy(buffer, rowBuffer[rowNext], MAX_LCD_COLS);
|
||||
} else
|
||||
buffer[0] = '\0'; // Empty line
|
||||
|
||||
setRowNative(slot); // Set position for display
|
||||
charIndex = 0;
|
||||
bptr = &buffer[0];
|
||||
|
||||
} else {
|
||||
|
||||
// Write one character, which will be a space if the string is exhausted.
|
||||
char ch = *bptr;
|
||||
if (ch) {
|
||||
writeNative(ch);
|
||||
bptr++;
|
||||
} else
|
||||
writeNative(' ');
|
||||
|
||||
if (++charIndex >= MAX_LCD_COLS) {
|
||||
// Screen slot completed, move to next one
|
||||
slot++;
|
||||
bptr = 0;
|
||||
if (!done) {
|
||||
rowNext = (rowNext + 1) % MAX_LCD_ROWS;
|
||||
if (rowNext == rowFirst) done = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (slot >= lcdRows) {
|
||||
// Last slot done, reset ready for next update.
|
||||
slot = 0;
|
||||
done = false;
|
||||
rowFirst = -1;
|
||||
lastScrollTime = currentMillis;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} while (force);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int LCDDisplay::nextFilledRow() {
|
||||
for (int rx=1;rx<=MAX_LCD_ROWS;rx++) {
|
||||
topRow++;
|
||||
topRow %= MAX_LCD_ROWS;
|
||||
if (rowBuffer[topRow][0]) return topRow;
|
||||
}
|
||||
return -1; // No slots filled
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -49,13 +49,15 @@ class LCDDisplay : public Print {
|
||||
void clearNative();
|
||||
void displayNative();
|
||||
void setRowNative(byte line);
|
||||
void writeNative(char * b);
|
||||
void writeNative(char b);
|
||||
|
||||
unsigned long lastScrollTime=0;
|
||||
int hotRow=0;
|
||||
int hotCol=0;
|
||||
int topRow=0;
|
||||
int lcdRows;
|
||||
int lcdCols;
|
||||
int slot=0;
|
||||
void renderRow(byte row);
|
||||
char rowBuffer[MAX_LCD_ROWS][MAX_LCD_COLS+1];
|
||||
};
|
||||
|
@ -22,6 +22,6 @@
|
||||
void LCDDisplay::interfake(int p1, int p2, int p3) {(void)p1; (void)p2; (void)p3;}
|
||||
void LCDDisplay::setRowNative(byte row) { (void)row;}
|
||||
void LCDDisplay::clearNative() {}
|
||||
void LCDDisplay::writeNative(char * b){ (void)b;} //
|
||||
void LCDDisplay::writeNative(char b){ (void)b;} //
|
||||
void LCDDisplay::displayNative(){}
|
||||
|
||||
|
21
LCD_OLED.h
21
LCD_OLED.h
@ -32,14 +32,21 @@ SSD1306AsciiWire LCDDriver;
|
||||
Wire.begin();
|
||||
for (byte address=0x3c; address<=0x3d; address++) {
|
||||
Wire.beginTransmission(address);
|
||||
byte error = Wire.endTransmission();
|
||||
byte error = Wire.endTransmission(true);
|
||||
if (!error) {
|
||||
// Device found
|
||||
DIAG(F("\nOLED display found at 0x%x"), address);
|
||||
interfake(OLED_DRIVER,0);
|
||||
LCDDriver.begin(lcdRows==32 ? &Adafruit128x32 : &Adafruit128x64, address);
|
||||
const DevType *devType;
|
||||
if (lcdCols == 132)
|
||||
devType = &SH1106_128x64; // Actually 132x64 but treated as 128x64
|
||||
else if (lcdCols == 128 && lcdRows == 8)
|
||||
devType = &Adafruit128x64;
|
||||
else
|
||||
devType = &Adafruit128x32;
|
||||
LCDDriver.begin(devType, address);
|
||||
lcdDisplay=this;
|
||||
LCDDriver.setFont(System5x7); // Normal 1:1 pixel scale
|
||||
LCDDriver.setFont(System5x7); // Normal 1:1 pixel scale, 8 bits high
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
@ -47,7 +54,7 @@ SSD1306AsciiWire LCDDriver;
|
||||
DIAG(F("\nOLED display not found\n"));
|
||||
}
|
||||
|
||||
void LCDDisplay::interfake(int p1, int p2, int p3) {(void)p1; lcdRows=p2/8; (void)p3;}
|
||||
void LCDDisplay::interfake(int p1, int p2, int p3) {lcdCols=p1; lcdRows=p2/8; (void)p3;}
|
||||
|
||||
void LCDDisplay::clearNative() {LCDDriver.clear();}
|
||||
|
||||
@ -55,10 +62,12 @@ SSD1306AsciiWire LCDDriver;
|
||||
// Positions text write to start of row 1..n and clears previous text
|
||||
int y=row;
|
||||
LCDDriver.setCursor(0, y);
|
||||
LCDDriver.clearToEOL();
|
||||
//LCDDriver.clearToEOL();
|
||||
}
|
||||
|
||||
void LCDDisplay::writeNative(char * b){ LCDDriver.write(b); }
|
||||
void LCDDisplay::writeNative(char b) {
|
||||
LCDDriver.write(b);
|
||||
}
|
||||
|
||||
void LCDDisplay::displayNative() { }
|
||||
|
||||
|
@ -102,6 +102,7 @@ The configuration file for DCC-EX Command Station
|
||||
|
||||
//OR define OLED_DRIVER width,height in pixels (address auto detected)
|
||||
// 128x32 or 128x64 I2C SSD1306-based devices are supported.
|
||||
// Also 132x64 I2C SH1106 devices.
|
||||
// This will not work on a UNO due to memory constraints
|
||||
// #define OLED_DRIVER 128,32
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user