diff --git a/OLEDDisplay.cpp b/OLEDDisplay.cpp index e55683f3b19345add7bb7f93822adc882bac4b62..f895dddaee3d33ffe7f5c5b7456871f5bff478ee 100644 --- a/OLEDDisplay.cpp +++ b/OLEDDisplay.cpp @@ -32,14 +32,14 @@ bool OLEDDisplay::init() { DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Can't establish connection to display\n"); return false; } - this->buffer = (uint8_t*) malloc(sizeof(uint8_t) * DISPLAY_BUFFER_SIZE); + this->buffer = (uint8_t*) malloc(sizeof(uint8_t) * displayBufferSize); if(!this->buffer) { DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Not enough memory to create display\n"); return false; } #ifdef OLEDDISPLAY_DOUBLE_BUFFER - this->buffer_back = (uint8_t*) malloc(sizeof(uint8_t) * DISPLAY_BUFFER_SIZE); + this->buffer_back = (uint8_t*) malloc(sizeof(uint8_t) * displayBufferSize); if(!this->buffer_back) { DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Not enough memory to create back buffer\n"); free(this->buffer); @@ -63,7 +63,7 @@ void OLEDDisplay::end() { void OLEDDisplay::resetDisplay(void) { clear(); #ifdef OLEDDISPLAY_DOUBLE_BUFFER - memset(buffer_back, 1, DISPLAY_BUFFER_SIZE); + memset(buffer_back, 1, displayBufferSize); #endif display(); } @@ -73,11 +73,11 @@ void OLEDDisplay::setColor(OLEDDISPLAY_COLOR color) { } void OLEDDisplay::setPixel(int16_t x, int16_t y) { - if (x >= 0 && x < 128 && y >= 0 && y < 64) { + if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) { switch (color) { - case WHITE: buffer[x + (y / 8) * DISPLAY_WIDTH] |= (1 << (y & 7)); break; - case BLACK: buffer[x + (y / 8) * DISPLAY_WIDTH] &= ~(1 << (y & 7)); break; - case INVERSE: buffer[x + (y / 8) * DISPLAY_WIDTH] ^= (1 << (y & 7)); break; + case WHITE: buffer[x + (y / 8) * displayWidth] |= (1 << (y & 7)); break; + case BLACK: buffer[x + (y / 8) * displayWidth] &= ~(1 << (y & 7)); break; + case INVERSE: buffer[x + (y / 8) * displayWidth] ^= (1 << (y & 7)); break; } } } @@ -222,21 +222,21 @@ void OLEDDisplay::fillCircle(int16_t x0, int16_t y0, int16_t radius) { } void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) { - if (y < 0 || y >= DISPLAY_HEIGHT) { return; } + if (y < 0 || y >= displayHeight) { return; } if (x < 0) { length += x; x = 0; } - if ( (x + length) > DISPLAY_WIDTH) { - length = (DISPLAY_WIDTH - x); + if ( (x + length) > displayWidth) { + length = (displayWidth - x); } if (length <= 0) { return; } uint8_t * bufferPtr = buffer; - bufferPtr += (y >> 3) * DISPLAY_WIDTH; + bufferPtr += (y >> 3) * displayWidth; bufferPtr += x; uint8_t drawBit = 1 << (y & 7); @@ -255,15 +255,15 @@ void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) { } void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) { - if (x < 0 || x >= DISPLAY_WIDTH) return; + if (x < 0 || x > displayWidth) return; if (y < 0) { length += y; y = 0; } - if ( (y + length) > DISPLAY_HEIGHT) { - length = (DISPLAY_HEIGHT - y); + if ( (y + length) > displayHeight) { + length = (displayHeight - y); } if (length <= 0) return; @@ -273,7 +273,7 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) { uint8_t drawBit; uint8_t *bufferPtr = buffer; - bufferPtr += (y >> 3) * DISPLAY_WIDTH; + bufferPtr += (y >> 3) * displayWidth; bufferPtr += x; if (yOffset) { @@ -293,7 +293,7 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) { if (length < yOffset) return; length -= yOffset; - bufferPtr += DISPLAY_WIDTH; + bufferPtr += displayWidth; } if (length >= 8) { @@ -303,14 +303,14 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) { drawBit = (color == WHITE) ? 0xFF : 0x00; do { *bufferPtr = drawBit; - bufferPtr += DISPLAY_WIDTH; + bufferPtr += displayWidth; length -= 8; } while (length >= 8); break; case INVERSE: do { *bufferPtr = ~(*bufferPtr); - bufferPtr += DISPLAY_WIDTH; + bufferPtr += displayWidth; length -= 8; } while (length >= 8); break; @@ -391,8 +391,8 @@ void OLEDDisplay::drawStringInternal(int16_t xMove, int16_t yMove, char* text, u } // Don't draw anything if it is not on the screen. - if (xMove + textWidth < 0 || xMove > DISPLAY_WIDTH ) {return;} - if (yMove + textHeight < 0 || yMove > DISPLAY_HEIGHT) {return;} + if (xMove + textWidth < 0 || xMove > displayWidth ) {return;} + if (yMove + textHeight < 0 || yMove > displayHeight) {return;} for (uint16_t j = 0; j < textLength; j++) { int16_t xPos = xMove + cursorX; @@ -556,7 +556,7 @@ void OLEDDisplay::flipScreenVertically() { } void OLEDDisplay::clear(void) { - memset(buffer, 0, DISPLAY_BUFFER_SIZE); + memset(buffer, 0, displayBufferSize); } void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) { @@ -591,6 +591,14 @@ void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) { } } +uint16_t OLEDDisplay::getWidth(void) { + return displayWidth; +} + +uint16_t OLEDDisplay::getHeight(void) { + return displayHeight; +} + bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars){ if (logBuffer != NULL) free(logBuffer); uint16_t size = lines * chars; @@ -675,7 +683,8 @@ void OLEDDisplay::sendInitCommands(void) { sendCommand(SETDISPLAYCLOCKDIV); sendCommand(0xF0); // Increase speed of the display max ~96Hz sendCommand(SETMULTIPLEX); - sendCommand(0x3F); + //sendCommand(0x3F); + sendCommand(displayHeight - 1); sendCommand(SETDISPLAYOFFSET); sendCommand(0x00); sendCommand(SETSTARTLINE); @@ -686,9 +695,21 @@ void OLEDDisplay::sendInitCommands(void) { sendCommand(SEGREMAP); sendCommand(COMSCANINC); sendCommand(SETCOMPINS); - sendCommand(0x12); + + if (geometry == GEOMETRY_128_64) { + sendCommand(0x12); + } else if (geometry == GEOMETRY_128_32) { + sendCommand(0x02); + } + sendCommand(SETCONTRAST); - sendCommand(0xCF); + + if (geometry == GEOMETRY_128_64) { + sendCommand(0xCF); + } else if (geometry == GEOMETRY_128_32) { + sendCommand(0x8F); + } + sendCommand(SETPRECHARGE); sendCommand(0xF1); sendCommand(DISPLAYALLON_RESUME); @@ -699,8 +720,8 @@ void OLEDDisplay::sendInitCommands(void) { void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *data, uint16_t offset, uint16_t bytesInData) { if (width < 0 || height < 0) return; - if (yMove + height < 0 || yMove > DISPLAY_HEIGHT) return; - if (xMove + width < 0 || xMove > DISPLAY_WIDTH) return; + if (yMove + height < 0 || yMove > displayHeight) return; + if (xMove + width < 0 || xMove > displayWidth) return; uint8_t rasterHeight = 1 + ((height - 1) >> 3); // fast ceil(height / 8.0) int8_t yOffset = yMove & 7; @@ -722,13 +743,13 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt byte currentByte = pgm_read_byte(data + offset + i); int16_t xPos = xMove + (i / rasterHeight); - int16_t yPos = ((yMove >> 3) + (i % rasterHeight)) * DISPLAY_WIDTH; + int16_t yPos = ((yMove >> 3) + (i % rasterHeight)) * displayWidth; int16_t yScreenPos = yMove + yOffset; int16_t dataPos = xPos + yPos; - if (dataPos >= 0 && dataPos < DISPLAY_BUFFER_SIZE && - xPos >= 0 && xPos < DISPLAY_WIDTH ) { + if (dataPos >= 0 && dataPos < displayBufferSize && + xPos >= 0 && xPos < displayWidth ) { if (yOffset >= 0) { switch (this->color) { @@ -736,11 +757,11 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt case BLACK: buffer[dataPos] &= ~(currentByte << yOffset); break; case INVERSE: buffer[dataPos] ^= currentByte << yOffset; break; } - if (dataPos < (DISPLAY_BUFFER_SIZE - DISPLAY_WIDTH)) { + if (dataPos < (displayBufferSize - displayWidth)) { switch (this->color) { - case WHITE: buffer[dataPos + DISPLAY_WIDTH] |= currentByte >> (8 - yOffset); break; - case BLACK: buffer[dataPos + DISPLAY_WIDTH] &= ~(currentByte >> (8 - yOffset)); break; - case INVERSE: buffer[dataPos + DISPLAY_WIDTH] ^= currentByte >> (8 - yOffset); break; + case WHITE: buffer[dataPos + displayWidth] |= currentByte >> (8 - yOffset); break; + case BLACK: buffer[dataPos + displayWidth] &= ~(currentByte >> (8 - yOffset)); break; + case INVERSE: buffer[dataPos + displayWidth] ^= currentByte >> (8 - yOffset); break; } } } else { diff --git a/OLEDDisplay.h b/OLEDDisplay.h index b46e7edcc828156d3ff28a24f2c4828a19cb1cd1..6e9d0fcef908c2db948fb97ecced0c8e127d7977 100644 --- a/OLEDDisplay.h +++ b/OLEDDisplay.h @@ -42,12 +42,6 @@ #define OLEDDISPLAY_DOUBLE_BUFFER #endif - -// Display settings -#define DISPLAY_WIDTH 128 -#define DISPLAY_HEIGHT 64 -#define DISPLAY_BUFFER_SIZE 1024 - // Header Values #define JUMPTABLE_BYTES 4 @@ -107,10 +101,18 @@ enum OLEDDISPLAY_TEXT_ALIGNMENT { TEXT_ALIGN_CENTER_BOTH = 3 }; + +enum OLEDDISPLAY_GEOMETRY { + GEOMETRY_128_64 = 0, + GEOMETRY_128_32 = 1 +}; + typedef byte (*FontTableLookupFunction)(const byte ch); + class OLEDDisplay : public Print { public: + // Initialize the display bool init(); @@ -226,7 +228,11 @@ class OLEDDisplay : public Print { // Draw the log buffer at position (x, y) void drawLogBuffer(uint16_t x, uint16_t y); - // Implementent needed function to be compatible with Print class + // Get screen geometry + uint16_t getWidth(void); + uint16_t getHeight(void); + + // Implement needed function to be compatible with Print class size_t write(uint8_t c); size_t write(const char* s); @@ -238,6 +244,12 @@ class OLEDDisplay : public Print { protected: + OLEDDISPLAY_GEOMETRY geometry = GEOMETRY_128_64; + + uint16_t displayWidth = 128; + uint16_t displayHeight = 64; + uint16_t displayBufferSize = 1024; + OLEDDISPLAY_TEXT_ALIGNMENT textAlignment = TEXT_ALIGN_LEFT; OLEDDISPLAY_COLOR color = WHITE; diff --git a/OLEDDisplayUi.cpp b/OLEDDisplayUi.cpp index 3fb4326a4d6ead0584b61e2d6187b1e8b3241575..51e026290174882f0293ee342eca9eb8753e6041 100644 --- a/OLEDDisplayUi.cpp +++ b/OLEDDisplayUi.cpp @@ -254,28 +254,28 @@ void OLEDDisplayUi::drawFrame(){ int16_t x, y, x1, y1; switch(this->frameAnimationDirection){ case SLIDE_LEFT: - x = -128 * progress; + x = -(this->display->getWidth()) * progress; y = 0; - x1 = x + 128; + x1 = x + this->display->getWidth(); y1 = 0; break; case SLIDE_RIGHT: - x = 128 * progress; + x = this->display->getWidth() * progress; y = 0; - x1 = x - 128; + x1 = x - this->display->getWidth(); y1 = 0; break; case SLIDE_UP: x = 0; - y = -64 * progress; + y = -(this->display->getHeight()) * progress; x1 = 0; - y1 = y + 64; + y1 = y + (this->display->getHeight()); break; case SLIDE_DOWN: x = 0; - y = 64 * progress; + y = (this->display->getHeight()) * progress; x1 = 0; - y1 = y - 64; + y1 = y - (this->display->getHeight()); break; } @@ -360,7 +360,13 @@ void OLEDDisplayUi::drawIndicator() { break; } - uint16_t frameStartPos = (12 * frameCount / 2); + //Space between indicators - reduce for small screen sizes + uint16_t indicatorSpacing = 12; + if (this->display->getHeight() < 64 && (this->indicatorPosition == RIGHT || this->indicatorPosition == LEFT)) { + indicatorSpacing = 6; + } + + uint16_t frameStartPos = (indicatorSpacing * frameCount / 2); const char *image; uint16_t x,y; for (byte i = 0; i < this->frameCount; i++) { @@ -368,19 +374,19 @@ void OLEDDisplayUi::drawIndicator() { switch (this->indicatorPosition){ case TOP: y = 0 - (8 * indicatorFadeProgress); - x = 64 - frameStartPos + 12 * i; + x = (this->display->getWidth() / 2) - frameStartPos + indicatorSpacing * i; break; case BOTTOM: - y = 56 + (8 * indicatorFadeProgress); - x = 64 - frameStartPos + 12 * i; + y = (this->display->getHeight() - 8) + (8 * indicatorFadeProgress); + x = (this->display->getWidth() / 2) - frameStartPos + indicatorSpacing * i; break; case RIGHT: - x = 120 + (8 * indicatorFadeProgress); - y = 32 - frameStartPos + 2 + 12 * i; + x = (this->display->getWidth() - 8) + (8 * indicatorFadeProgress); + y = (this->display->getHeight() / 2) - frameStartPos + indicatorSpacing * i; break; case LEFT: x = 0 - (8 * indicatorFadeProgress); - y = 32 - frameStartPos + 2 + 12 * i; + y = (this->display->getHeight() / 2) - frameStartPos + indicatorSpacing * i; break; } diff --git a/SH1106Brzo.h b/SH1106Brzo.h index 385630b3267a7191fe0c81a21fe34d4b5de0a2e4..a747cb68ebe2994cc1ad2a13eedf58335db765ba 100644 --- a/SH1106Brzo.h +++ b/SH1106Brzo.h @@ -44,7 +44,18 @@ class SH1106Brzo : public OLEDDisplay { uint8_t _scl; public: - SH1106Brzo(uint8_t _address, uint8_t _sda, uint8_t _scl) { + SH1106Brzo(OLEDDISPLAY_GEOMETRY g, uint8_t _address, uint8_t _sda, uint8_t _scl) { + this->geometry = g; + if (g == GEOMETRY_128_64) { + this->displayWidth = 128; + this->displayHeight = 64; + this->displayBufferSize = 1024; + } else if (g == GEOMETRY_128_32) { + this->displayWidth = 128; + this->displayHeight = 32; + this->displayBufferSize = 512; + } + this->_address = _address; this->_sda = _sda; this->_scl = _scl; @@ -66,9 +77,9 @@ class SH1106Brzo : public OLEDDisplay { // Calculate the Y bounding box of changes // and copy buffer[pos] to buffer_back[pos]; - for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) { - for (x = 0; x < DISPLAY_WIDTH; x++) { - uint16_t pos = x + y * DISPLAY_WIDTH; + for (y = 0; y < (displayHeight / 8); y++) { + for (x = 0; x < displayWidth; x++) { + uint16_t pos = x + y * displayWidth; if (buffer[pos] != buffer_back[pos]) { minBoundY = _min(minBoundY, y); maxBoundY = _max(maxBoundY, y); @@ -101,7 +112,7 @@ class SH1106Brzo : public OLEDDisplay { sendCommand(minBoundXp2L); for (x = minBoundX; x <= maxBoundX; x++) { k++; - sendBuffer[k] = buffer[x + y * DISPLAY_WIDTH]; + sendBuffer[k] = buffer[x + y * displayWidth]; if (k == 16) { brzo_i2c_write(sendBuffer, 17, true); k = 0; diff --git a/SH1106Spi.h b/SH1106Spi.h index 0a64e27568ff9fc1270e13ec0eec221ac9337a67..d81d90d38a2a4668ecca1329256d9f0bf22df788 100644 --- a/SH1106Spi.h +++ b/SH1106Spi.h @@ -38,7 +38,18 @@ class SH1106Spi : public OLEDDisplay { public: - SH1106Spi(uint8_t _rst, uint8_t _dc) { + SH1106Spi(OLEDDISPLAY_GEOMETRY g, uint8_t _rst, uint8_t _dc) { + this->geometry = g; + if (g == GEOMETRY_128_64) { + this->displayWidth = 128; + this->displayHeight = 64; + this->displayBufferSize = 1024; + } else if (g == GEOMETRY_128_32) { + this->displayWidth = 128; + this->displayHeight = 32; + this->displayBufferSize = 512; + } + this->_rst = _rst; this->_dc = _dc; } @@ -71,9 +82,9 @@ class SH1106Spi : public OLEDDisplay { // Calculate the Y bounding box of changes // and copy buffer[pos] to buffer_back[pos]; - for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) { - for (x = 0; x < DISPLAY_WIDTH; x++) { - uint16_t pos = x + y * DISPLAY_WIDTH; + for (y = 0; y < (displayHeight / 8); y++) { + for (x = 0; x < displayWidth; x++) { + uint16_t pos = x + y * displayWidth; if (buffer[pos] != buffer_back[pos]) { minBoundY = _min(minBoundY, y); maxBoundY = _max(maxBoundY, y); @@ -100,18 +111,18 @@ class SH1106Spi : public OLEDDisplay { sendCommand(minBoundXp2L); digitalWrite(_dc, HIGH); // data mode for (x = minBoundX; x <= maxBoundX; x++) { - SPI.transfer(buffer[x + y * DISPLAY_WIDTH]); + SPI.transfer(buffer[x + y * displayWidth]); } yield(); } #else - for (uint8_t y=0; y<DISPLAY_HEIGHT/8; y++) { + for (uint8_t y=0; y<displayHeight/8; y++) { sendCommand(0xB0 + y); sendCommand(0x02); sendCommand(0x10); digitalWrite(_dc, HIGH); // data mode - for( uint8_t x=0; x < DISPLAY_WIDTH; x++) { - SPI.transfer(buffer[x + y * DISPLAY_WIDTH]); + for( uint8_t x=0; x < displayWidth; x++) { + SPI.transfer(buffer[x + y * displayWidth]); } yield(); } diff --git a/SH1106Wire.h b/SH1106Wire.h index f0784b9423051a4e91bf2e237b38347a2f6b6ede..3205ac06ad09ecdff37c63d4564c7a2022786e09 100644 --- a/SH1106Wire.h +++ b/SH1106Wire.h @@ -44,7 +44,18 @@ class SH1106Wire : public OLEDDisplay { uint8_t _scl; public: - SH1106Wire(uint8_t _address, uint8_t _sda, uint8_t _scl) { + SH1106Wire(OLEDDISPLAY_GEOMETRY g, uint8_t _address, uint8_t _sda, uint8_t _scl) { + this->geometry = g; + if (g == GEOMETRY_128_64) { + this->displayWidth = 128; + this->displayHeight = 64; + this->displayBufferSize = 1024; + } else if (g == GEOMETRY_128_32) { + this->displayWidth = 128; + this->displayHeight = 32; + this->displayBufferSize = 512; + } + this->_address = _address; this->_sda = _sda; this->_scl = _scl; @@ -70,9 +81,9 @@ class SH1106Wire : public OLEDDisplay { // Calculate the Y bounding box of changes // and copy buffer[pos] to buffer_back[pos]; - for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) { - for (x = 0; x < DISPLAY_WIDTH; x++) { - uint16_t pos = x + y * DISPLAY_WIDTH; + for (y = 0; y < (displayHeight / 8); y++) { + for (x = 0; x < displayWidth; x++) { + uint16_t pos = x + y * displayWidth; if (buffer[pos] != buffer_back[pos]) { minBoundY = _min(minBoundY, y); maxBoundY = _max(maxBoundY, y); @@ -103,7 +114,7 @@ class SH1106Wire : public OLEDDisplay { Wire.beginTransmission(_address); Wire.write(0x40); } - Wire.write(buffer[x + y * DISPLAY_WIDTH]); + Wire.write(buffer[x + y * displayWidth]); k++; if (k == 16) { Wire.endTransmission(); diff --git a/SSD1306Brzo.h b/SSD1306Brzo.h index 3b99d82d2a196dbc0836b8e4ad13d7fa46b60813..a9a2aa0cccb0079b727a312c3be97171d88d7e84 100644 --- a/SSD1306Brzo.h +++ b/SSD1306Brzo.h @@ -44,7 +44,18 @@ class SSD1306Brzo : public OLEDDisplay { uint8_t _scl; public: - SSD1306Brzo(uint8_t _address, uint8_t _sda, uint8_t _scl) { + SSD1306Brzo(OLEDDISPLAY_GEOMETRY g, uint8_t _address, uint8_t _sda, uint8_t _scl) { + this->geometry = g; + if (g == GEOMETRY_128_64) { + this->displayWidth = 128; + this->displayHeight = 64; + this->displayBufferSize = 1024; + } else if (g == GEOMETRY_128_32) { + this->displayWidth = 128; + this->displayHeight = 32; + this->displayBufferSize = 512; + } + this->_address = _address; this->_sda = _sda; this->_scl = _scl; @@ -67,9 +78,9 @@ class SSD1306Brzo : public OLEDDisplay { // Calculate the Y bounding box of changes // and copy buffer[pos] to buffer_back[pos]; - for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) { - for (x = 0; x < DISPLAY_WIDTH; x++) { - uint16_t pos = x + y * DISPLAY_WIDTH; + for (y = 0; y < (displayHeight / 8); y++) { + for (x = 0; x < displayWidth; x++) { + uint16_t pos = x + y * displayWidth; if (buffer[pos] != buffer_back[pos]) { minBoundY = _min(minBoundY, y); maxBoundY = _max(maxBoundY, y); @@ -101,7 +112,7 @@ class SSD1306Brzo : public OLEDDisplay { for (y = minBoundY; y <= maxBoundY; y++) { for (x = minBoundX; x <= maxBoundX; x++) { k++; - sendBuffer[k] = buffer[x + y * DISPLAY_WIDTH]; + sendBuffer[k] = buffer[x + y * displayWidth]; if (k == 16) { brzo_i2c_write(sendBuffer, 17, true); k = 0; @@ -119,12 +130,17 @@ class SSD1306Brzo : public OLEDDisplay { sendCommand(PAGEADDR); sendCommand(0x0); - sendCommand(0x7); + + if (geometry == GEOMETRY_128_64) { + sendCommand(0x7); + } else if (geometry == GEOMETRY_128_32) { + sendCommand(0x3); + } uint8_t sendBuffer[17]; sendBuffer[0] = 0x40; brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED); - for (uint16_t i=0; i<DISPLAY_BUFFER_SIZE; i++) { + for (uint16_t i=0; i<displayBufferSize; i++) { for (uint8_t x=1; x<17; x++) { sendBuffer[x] = buffer[i]; i++; diff --git a/SSD1306Spi.h b/SSD1306Spi.h index 21794587ac612cb951706546dadb2d2bb0c23593..9a41a0a264dbb1bca4a01d4dcf6fb28eb6e28fe4 100644 --- a/SSD1306Spi.h +++ b/SSD1306Spi.h @@ -44,7 +44,18 @@ class SSD1306Spi : public OLEDDisplay { uint8_t _cs; public: - SSD1306Spi(uint8_t _rst, uint8_t _dc, uint8_t _cs) { + SSD1306Spi(OLEDDISPLAY_GEOMETRY g, uint8_t _rst, uint8_t _dc, uint8_t _cs) { + this->geometry = g; + if (g == GEOMETRY_128_64) { + this->displayWidth = 128; + this->displayHeight = 64; + this->displayBufferSize = 1024; + } else if (g == GEOMETRY_128_32) { + this->displayWidth = 128; + this->displayHeight = 32; + this->displayBufferSize = 512; + } + this->_rst = _rst; this->_dc = _dc; this->_cs = _cs; @@ -79,9 +90,9 @@ class SSD1306Spi : public OLEDDisplay { // Calculate the Y bounding box of changes // and copy buffer[pos] to buffer_back[pos]; - for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) { - for (x = 0; x < DISPLAY_WIDTH; x++) { - uint16_t pos = x + y * DISPLAY_WIDTH; + for (y = 0; y < (displayHeight / 8); y++) { + for (x = 0; x < displayWidth; x++) { + uint16_t pos = x + y * displayWidth; if (buffer[pos] != buffer_back[pos]) { minBoundY = _min(minBoundY, y); maxBoundY = _max(maxBoundY, y); @@ -111,7 +122,7 @@ class SSD1306Spi : public OLEDDisplay { digitalWrite(_cs, LOW); for (y = minBoundY; y <= maxBoundY; y++) { for (x = minBoundX; x <= maxBoundX; x++) { - SPI.transfer(buffer[x + y * DISPLAY_WIDTH]); + SPI.transfer(buffer[x + y * displayWidth]); } yield(); } @@ -124,12 +135,17 @@ class SSD1306Spi : public OLEDDisplay { sendCommand(PAGEADDR); sendCommand(0x0); - sendCommand(0x7); + + if (geometry == GEOMETRY_128_64) { + sendCommand(0x7); + } else if (geometry == GEOMETRY_128_32) { + sendCommand(0x3); + } digitalWrite(_cs, HIGH); digitalWrite(_dc, HIGH); // data mode digitalWrite(_cs, LOW); - for (uint16_t i=0; i<DISPLAY_BUFFER_SIZE; i++) { + for (uint16_t i=0; i<displayBufferSize; i++) { SPI.transfer(buffer[i]); yield(); } diff --git a/SSD1306Wire.h b/SSD1306Wire.h index ac12becd0964a7d93b20e3e8a42a5db9ab9c253e..e82d9b54d374f3558a348e3da314a7d9b7099952 100644 --- a/SSD1306Wire.h +++ b/SSD1306Wire.h @@ -38,7 +38,18 @@ class SSD1306Wire : public OLEDDisplay { uint8_t _scl; public: - SSD1306Wire(uint8_t _address, uint8_t _sda, uint8_t _scl) { + SSD1306Wire(OLEDDISPLAY_GEOMETRY g, uint8_t _address, uint8_t _sda, uint8_t _scl) { + this->geometry = g; + if (g == GEOMETRY_128_64) { + this->displayWidth = 128; + this->displayHeight = 64; + this->displayBufferSize = 1024; + } else if (g == GEOMETRY_128_32) { + this->displayWidth = 128; + this->displayHeight = 32; + this->displayBufferSize = 512; + } + this->_address = _address; this->_sda = _sda; this->_scl = _scl; @@ -63,9 +74,9 @@ class SSD1306Wire : public OLEDDisplay { // Calculate the Y bounding box of changes // and copy buffer[pos] to buffer_back[pos]; - for (y = 0; y < (DISPLAY_HEIGHT / 8); y++) { - for (x = 0; x < DISPLAY_WIDTH; x++) { - uint16_t pos = x + y * DISPLAY_WIDTH; + for (y = 0; y < (displayHeight / 8); y++) { + for (x = 0; x < displayWidth; x++) { + uint16_t pos = x + y * displayWidth; if (buffer[pos] != buffer_back[pos]) { minBoundY = _min(minBoundY, y); maxBoundY = _max(maxBoundY, y); @@ -97,7 +108,7 @@ class SSD1306Wire : public OLEDDisplay { Wire.beginTransmission(_address); Wire.write(0x40); } - Wire.write(buffer[x + y * DISPLAY_WIDTH]); + Wire.write(buffer[x + y * displayWidth]); k++; if (k == 16) { Wire.endTransmission(); @@ -118,9 +129,14 @@ class SSD1306Wire : public OLEDDisplay { sendCommand(PAGEADDR); sendCommand(0x0); - sendCommand(0x7); + + if (geometry == GEOMETRY_128_64) { + sendCommand(0x7); + } else if (geometry == GEOMETRY_128_32) { + sendCommand(0x3); + } - for (uint16_t i=0; i < DISPLAY_BUFFER_SIZE; i++) { + for (uint16_t i=0; i < displayBufferSize; i++) { Wire.beginTransmission(this->_address); Wire.write(0x40); for (uint8_t x = 0; x < 16; x++) { diff --git a/examples/SSD1306ClockDemo/SSD1306ClockDemo.ino b/examples/SSD1306ClockDemo/SSD1306ClockDemo.ino index e9db7d645a610f8c42d857ba20a774b2fe9cd89e..1f1a8c968575c8c5b9ee7e2a8e6aa6afe7dca68b 100644 --- a/examples/SSD1306ClockDemo/SSD1306ClockDemo.ino +++ b/examples/SSD1306ClockDemo/SSD1306ClockDemo.ino @@ -66,7 +66,7 @@ // SH1106Brzo display(0x3c, D3, D5); // Initialize the OLED display using Wire library -SSD1306 display(0x3c, D3, D5); +SSD1306 display(GEOMETRY_128_64, 0x3c, D3, D5); // SH1106 display(0x3c, D3, D5); OLEDDisplayUi ui ( &display ); diff --git a/examples/SSD1306DrawingDemo/SSD1306DrawingDemo.ino b/examples/SSD1306DrawingDemo/SSD1306DrawingDemo.ino index cf37fb0412002492388ed3d71fbb1ec58866c233..3f6e0a4f1c90ee597abf6faf213980e29a088368 100644 --- a/examples/SSD1306DrawingDemo/SSD1306DrawingDemo.ino +++ b/examples/SSD1306DrawingDemo/SSD1306DrawingDemo.ino @@ -58,56 +58,56 @@ // SH1106Brzo display(0x3c, D3, D5); // Initialize the OLED display using Wire library - SSD1306 display(0x3c, D3, D5); + SSD1306 display(GEOMETRY_128_64, 0x3c, D3, D5); // SH1106 display(0x3c, D3, D5); // Adapted from Adafruit_SSD1306 void drawLines() { - for (int16_t i=0; i<DISPLAY_WIDTH; i+=4) { - display.drawLine(0, 0, i, DISPLAY_HEIGHT-1); + for (int16_t i=0; i<display.getWidth(); i+=4) { + display.drawLine(0, 0, i, display.getHeight()-1); display.display(); delay(10); } - for (int16_t i=0; i<DISPLAY_HEIGHT; i+=4) { - display.drawLine(0, 0, DISPLAY_WIDTH-1, i); + for (int16_t i=0; i<display.getHeight(); i+=4) { + display.drawLine(0, 0, display.getWidth()-1, i); display.display(); delay(10); } delay(250); display.clear(); - for (int16_t i=0; i<DISPLAY_WIDTH; i+=4) { - display.drawLine(0, DISPLAY_HEIGHT-1, i, 0); + for (int16_t i=0; i<display.getWidth(); i+=4) { + display.drawLine(0, display.getHeight()-1, i, 0); display.display(); delay(10); } - for (int16_t i=DISPLAY_HEIGHT-1; i>=0; i-=4) { - display.drawLine(0, DISPLAY_HEIGHT-1, DISPLAY_WIDTH-1, i); + for (int16_t i=display.getHeight()-1; i>=0; i-=4) { + display.drawLine(0, display.getHeight()-1, display.getWidth()-1, i); display.display(); delay(10); } delay(250); display.clear(); - for (int16_t i=DISPLAY_WIDTH-1; i>=0; i-=4) { - display.drawLine(DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, i, 0); + for (int16_t i=display.getWidth()-1; i>=0; i-=4) { + display.drawLine(display.getWidth()-1, display.getHeight()-1, i, 0); display.display(); delay(10); } - for (int16_t i=DISPLAY_HEIGHT-1; i>=0; i-=4) { - display.drawLine(DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, 0, i); + for (int16_t i=display.getHeight()-1; i>=0; i-=4) { + display.drawLine(display.getWidth()-1, display.getHeight()-1, 0, i); display.display(); delay(10); } delay(250); display.clear(); - for (int16_t i=0; i<DISPLAY_HEIGHT; i+=4) { - display.drawLine(DISPLAY_WIDTH-1, 0, 0, i); + for (int16_t i=0; i<display.getHeight(); i+=4) { + display.drawLine(display.getWidth()-1, 0, 0, i); display.display(); delay(10); } - for (int16_t i=0; i<DISPLAY_WIDTH; i+=4) { - display.drawLine(DISPLAY_WIDTH-1, 0, i, DISPLAY_HEIGHT-1); + for (int16_t i=0; i<display.getWidth(); i+=4) { + display.drawLine(display.getWidth()-1, 0, i, display.getHeight()-1); display.display(); delay(10); } @@ -116,8 +116,8 @@ void drawLines() { // Adapted from Adafruit_SSD1306 void drawRect(void) { - for (int16_t i=0; i<DISPLAY_HEIGHT/2; i+=2) { - display.drawRect(i, i, DISPLAY_WIDTH-2*i, DISPLAY_HEIGHT-2*i); + for (int16_t i=0; i<display.getHeight()/2; i+=2) { + display.drawRect(i, i, display.getWidth()-2*i, display.getHeight()-2*i); display.display(); delay(10); } @@ -126,9 +126,9 @@ void drawRect(void) { // Adapted from Adafruit_SSD1306 void fillRect(void) { uint8_t color = 1; - for (int16_t i=0; i<DISPLAY_HEIGHT/2; i+=3) { + for (int16_t i=0; i<display.getHeight()/2; i+=3) { display.setColor((color % 2 == 0) ? BLACK : WHITE); // alternate colors - display.fillRect(i, i, DISPLAY_WIDTH - i*2, DISPLAY_HEIGHT - i*2); + display.fillRect(i, i, display.getWidth() - i*2, display.getHeight() - i*2); display.display(); delay(10); color++; @@ -139,8 +139,8 @@ void fillRect(void) { // Adapted from Adafruit_SSD1306 void drawCircle(void) { - for (int16_t i=0; i<DISPLAY_HEIGHT; i+=2) { - display.drawCircle(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, i); + for (int16_t i=0; i<display.getHeight(); i+=2) { + display.drawCircle(display.getWidth()/2, display.getHeight()/2, i); display.display(); delay(10); } @@ -153,16 +153,16 @@ void drawCircle(void) { // ------|----- // 0100 | 1000 // - display.drawCircleQuads(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, DISPLAY_HEIGHT/4, 0b00000001); + display.drawCircleQuads(display.getWidth()/2, display.getHeight()/2, display.getHeight()/4, 0b00000001); display.display(); delay(200); - display.drawCircleQuads(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, DISPLAY_HEIGHT/4, 0b00000011); + display.drawCircleQuads(display.getWidth()/2, display.getHeight()/2, display.getHeight()/4, 0b00000011); display.display(); delay(200); - display.drawCircleQuads(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, DISPLAY_HEIGHT/4, 0b00000111); + display.drawCircleQuads(display.getWidth()/2, display.getHeight()/2, display.getHeight()/4, 0b00000111); display.display(); delay(200); - display.drawCircleQuads(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, DISPLAY_HEIGHT/4, 0b00001111); + display.drawCircleQuads(display.getWidth()/2, display.getHeight()/2, display.getHeight()/4, 0b00001111); display.display(); } diff --git a/examples/SSD1306OTADemo/SSD1306OTADemo.ino b/examples/SSD1306OTADemo/SSD1306OTADemo.ino index 6460ff9e4a308dffa396d0db473c6708e0c14f34..856917a958d22b8fc5f2ee1e8a5286b40a8fe95e 100644 --- a/examples/SSD1306OTADemo/SSD1306OTADemo.ino +++ b/examples/SSD1306OTADemo/SSD1306OTADemo.ino @@ -69,7 +69,7 @@ // SH1106Brzo display(0x3c, D3, D5); // Initialize the OLED display using Wire library -SSD1306 display(0x3c, D3, D5); +SSD1306 display(GEOMETRY_128_64, 0x3c, D3, D5); // SH1106 display(0x3c, D3, D5); @@ -90,7 +90,7 @@ void setup() { display.clear(); display.setFont(ArialMT_Plain_10); display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH); - display.drawString(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2 - 10, "OTA Update"); + display.drawString(display.getWidth()/2, display.getHeight()/2 - 10, "OTA Update"); display.display(); }); @@ -103,14 +103,14 @@ void setup() { display.clear(); display.setFont(ArialMT_Plain_10); display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH); - display.drawString(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, "Restart"); + display.drawString(display.getWidth()/2, display.getHeight()/2, "Restart"); display.display(); }); // Align text vertical/horizontal center display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH); display.setFont(ArialMT_Plain_10); - display.drawString(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, "Ready for OTA:\n" + WiFi.localIP().toString()); + display.drawString(display.getWidth()/2, display.getHeight()/2, "Ready for OTA:\n" + WiFi.localIP().toString()); display.display(); } diff --git a/examples/SSD1306SimpleDemo/SSD1306SimpleDemo.ino b/examples/SSD1306SimpleDemo/SSD1306SimpleDemo.ino index ed7401915861f89d9a1f4dd6f697bc82b44f3069..12ad6b111c57830117422b76bc9e28d86141cebd 100644 --- a/examples/SSD1306SimpleDemo/SSD1306SimpleDemo.ino +++ b/examples/SSD1306SimpleDemo/SSD1306SimpleDemo.ino @@ -58,7 +58,7 @@ // SH1106Brzo display(0x3c, D3, D5); // Initialize the OLED display using Wire library -SSD1306 display(0x3c, D3, D5); +SSD1306 display(GEOMETRY_128_64, 0x3c, D3, D5); // SH1106 display(0x3c, D3, D5); diff --git a/examples/SSD1306UiDemo/SSD1306UiDemo.ino b/examples/SSD1306UiDemo/SSD1306UiDemo.ino index 31357569ff3849b6c1098165aa96f9880129327f..f19617af86301391786b15bbc80b23080556d865 100644 --- a/examples/SSD1306UiDemo/SSD1306UiDemo.ino +++ b/examples/SSD1306UiDemo/SSD1306UiDemo.ino @@ -64,7 +64,7 @@ // SH1106Brzo display(0x3c, D3, D5); // Initialize the OLED display using Wire library -SSD1306 display(0x3c, D3, D5); +SSD1306 display(GEOMETRY_128_64, 0x3c, D3, D5); // SH1106 display(0x3c, D3, D5); OLEDDisplayUi ui ( &display );