From d5025f1150866069aa2b7c82ea00ca1d17ed8ff4 Mon Sep 17 00:00:00 2001 From: benoitm Date: Sun, 21 Jun 2020 21:55:14 +0200 Subject: [PATCH 1/7] Add 2nd HW I2C support --- src/SSD1306Wire.h | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/SSD1306Wire.h b/src/SSD1306Wire.h index 9f30b4b6..b2d7e1d5 100644 --- a/src/SSD1306Wire.h +++ b/src/SSD1306Wire.h @@ -40,33 +40,40 @@ #define _max max #endif +enum HW_I2C { + I2C_ONE, + I2C_TWO +}; + class SSD1306Wire : public OLEDDisplay { private: uint8_t _address; int _sda; int _scl; bool _doI2cAutoInit = false; + TwoWire* _wire = NULL; public: - SSD1306Wire(uint8_t _address, int _sda = -1, int _scl = -1, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) { + SSD1306Wire(uint8_t _address, int _sda = -1, int _scl = -1, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64, HW_I2C _i2cBus = I2C_ONE) { setGeometry(g); this->_address = _address; this->_sda = _sda; this->_scl = _scl; + this->_wire = (_i2cBus==I2C_ONE)?&Wire:&Wire1; } bool connect() { #if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH8266) - Wire.begin(); + _wire->begin(); #else // On ESP32 arduino, -1 means 'don't change pins', someone else has called begin for us. if(this->_sda != -1) - Wire.begin(this->_sda, this->_scl); + _wire->begin(this->_sda, this->_scl); #endif // Let's use ~700khz if ESP8266 is in 160Mhz mode // this will be limited to ~400khz if the ESP8266 in 80Mhz mode. - Wire.setClock(700000); + _wire->setClock(700000); return true; } @@ -115,14 +122,14 @@ class SSD1306Wire : public OLEDDisplay { for (y = minBoundY; y <= maxBoundY; y++) { for (x = minBoundX; x <= maxBoundX; x++) { if (k == 0) { - Wire.beginTransmission(_address); - Wire.write(0x40); + _wire->beginTransmission(_address); + _wire->write(0x40); } - Wire.write(buffer[x + y * this->width()]); + _wire->write(buffer[x + y * this->width()]); k++; if (k == 16) { - Wire.endTransmission(); + _wire->endTransmission(); k = 0; } } @@ -130,7 +137,7 @@ class SSD1306Wire : public OLEDDisplay { } if (k != 0) { - Wire.endTransmission(); + _wire->endTransmission(); } #else @@ -148,14 +155,14 @@ class SSD1306Wire : public OLEDDisplay { } for (uint16_t i=0; i < displayBufferSize; i++) { - Wire.beginTransmission(this->_address); - Wire.write(0x40); + _wire->beginTransmission(this->_address); + _wire->write(0x40); for (uint8_t x = 0; x < 16; x++) { - Wire.write(buffer[i]); + _wire->write(buffer[i]); i++; } i--; - Wire.endTransmission(); + _wire->endTransmission(); } #endif } @@ -170,18 +177,18 @@ class SSD1306Wire : public OLEDDisplay { } inline void sendCommand(uint8_t command) __attribute__((always_inline)){ initI2cIfNeccesary(); - Wire.beginTransmission(_address); - Wire.write(0x80); - Wire.write(command); - Wire.endTransmission(); + _wire->beginTransmission(_address); + _wire->write(0x80); + _wire->write(command); + _wire->endTransmission(); } void initI2cIfNeccesary() { if (_doI2cAutoInit) { #if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH8266) - Wire.begin(); + _wire->begin(); #else - Wire.begin(this->_sda, this->_scl); + _wire->begin(this->_sda, this->_scl); #endif } } From 52e2bc95fc99b1dca0f21ff96120db49d4a8ae0e Mon Sep 17 00:00:00 2001 From: Benoit Masson Date: Mon, 27 Jul 2020 21:39:42 +0200 Subject: [PATCH 2/7] Update README.md Add 2nd HW I2C support --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 04944b83..57c1bc48 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,8 @@ The library supports different protocols to access the OLED display. Currently t SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL // for 128x32 displays: // SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32); // ADDRESS, SDA, SCL, GEOMETRY_128_32 (or 128_64) +// for using 2nd Hardware I2C (if availbale) +// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_32, I2C_TWO); //default value is I2C_ONE ``` for a SH1106: From 24bc289c5aed68404bf185f65753ec1de1339a6f Mon Sep 17 00:00:00 2001 From: Benoit Masson Date: Tue, 28 Jul 2020 19:08:55 +0200 Subject: [PATCH 3/7] Add 2nd HW I2C support Add 2nd HW I2C support --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 57c1bc48..3910e101 100644 --- a/README.md +++ b/README.md @@ -76,8 +76,8 @@ The library supports different protocols to access the OLED display. Currently t SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL // for 128x32 displays: // SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32); // ADDRESS, SDA, SCL, GEOMETRY_128_32 (or 128_64) -// for using 2nd Hardware I2C (if availbale) -// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_32, I2C_TWO); //default value is I2C_ONE +// for using 2nd Hardware I2C (if available) +// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_32, I2C_TWO); //default value is I2C_ONE if not mentioned ``` for a SH1106: From 8ad42fbd1f4e83ffcb8b3982a5a6efad12b28e53 Mon Sep 17 00:00:00 2001 From: benoitm Date: Sat, 1 Aug 2020 20:33:59 +0200 Subject: [PATCH 4/7] Add frequency option for WIre config. --- src/SSD1306Wire.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/SSD1306Wire.h b/src/SSD1306Wire.h index b2d7e1d5..d3855c05 100644 --- a/src/SSD1306Wire.h +++ b/src/SSD1306Wire.h @@ -52,15 +52,33 @@ class SSD1306Wire : public OLEDDisplay { int _scl; bool _doI2cAutoInit = false; TwoWire* _wire = NULL; + int _frequency; public: - SSD1306Wire(uint8_t _address, int _sda = -1, int _scl = -1, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64, HW_I2C _i2cBus = I2C_ONE) { + + /** + * Create and initialize the Display using Wire library + * + * Beware for retro-compatibility default values are provided for all parameters see below. + * Please note that if you don't wan't SD1306Wire to initialize and change frequency speed ot need to + * ensure -1 value are specified for all 3 parameters. This can be usefull to control TwoWire with multiple + * device on the same bus. + * + * @param _address I2C Display address + * @param _sda I2C SDA pin number, default to -1 to skip Wire begin call + * @param _scl I2C SCL pin number, default to -1 (only SDA = -1 is considered to skip Wire begin call) + * @param g display geometry dafault to generic GEOMETRY_128_64, see OLEDDISPLAY_GEOMETRY definition for other options + * @param _i2cBus on ESP32 with 2 I2C HW buses, I2C_ONE for 1st Bus, I2C_TWO fot 2nd bus, default I2C_ONE + * @param _frequency for Frequency by default Let's use ~700khz if ESP8266 is in 160Mhz mode, this will be limited to ~400khz if the ESP8266 in 80Mhz mode + */ + SSD1306Wire(uint8_t _address, int _sda = -1, int _scl = -1, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64, HW_I2C _i2cBus = I2C_ONE, int _frequency = 700000) { setGeometry(g); this->_address = _address; this->_sda = _sda; this->_scl = _scl; this->_wire = (_i2cBus==I2C_ONE)?&Wire:&Wire1; + this->_frequency = _frequency; } bool connect() { @@ -73,7 +91,8 @@ class SSD1306Wire : public OLEDDisplay { #endif // Let's use ~700khz if ESP8266 is in 160Mhz mode // this will be limited to ~400khz if the ESP8266 in 80Mhz mode. - _wire->setClock(700000); + if(this->_frequency != -1) + _wire->setClock(this->_frequency); return true; } From 75dc9e92ce3cc16443350d81393e5089dab91ff7 Mon Sep 17 00:00:00 2001 From: benoitm Date: Sat, 1 Aug 2020 20:40:15 +0200 Subject: [PATCH 5/7] I2C frequency README --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3910e101..34ba99b8 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,9 @@ SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL // SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32); // ADDRESS, SDA, SCL, GEOMETRY_128_32 (or 128_64) // for using 2nd Hardware I2C (if available) // SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_32, I2C_TWO); //default value is I2C_ONE if not mentioned +// By default SD1306Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value +// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_32, I2C_ONE, 400000); //set I2C frequency to 400kHz +// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_32, I2C_ONE, -1); //skip setting the I2C bus frequency ``` for a SH1106: From e819455c7c51f380a88c93d1b82a60b062aea749 Mon Sep 17 00:00:00 2001 From: benoitm Date: Mon, 3 Aug 2020 22:00:14 +0200 Subject: [PATCH 6/7] replicate for SH1106 --- README.md | 9 ++++--- src/OLEDDisplay.h | 5 ++++ src/SH1106Wire.h | 64 +++++++++++++++++++++++++++++++++-------------- src/SSD1306Wire.h | 6 +---- 4 files changed, 57 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 34ba99b8..785d8063 100644 --- a/README.md +++ b/README.md @@ -77,10 +77,10 @@ SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL // for 128x32 displays: // SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32); // ADDRESS, SDA, SCL, GEOMETRY_128_32 (or 128_64) // for using 2nd Hardware I2C (if available) -// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_32, I2C_TWO); //default value is I2C_ONE if not mentioned +// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_TWO); //default value is I2C_ONE if not mentioned // By default SD1306Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value -// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_32, I2C_ONE, 400000); //set I2C frequency to 400kHz -// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_32, I2C_ONE, -1); //skip setting the I2C bus frequency +// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, 400000); //set I2C frequency to 400kHz +// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, -1); //skip setting the I2C bus frequency ``` for a SH1106: @@ -89,6 +89,9 @@ for a SH1106: #include "SH1106Wire.h" SH1106Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL +// By default SD1306Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value +// SH1106Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, 400000); //set I2C frequency to 400kHz +// SH1106Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, -1); //skip setting the I2C bus frequency ``` ### I2C with brzo_i2c diff --git a/src/OLEDDisplay.h b/src/OLEDDisplay.h index 205dffc3..ca351be2 100644 --- a/src/OLEDDisplay.h +++ b/src/OLEDDisplay.h @@ -141,6 +141,11 @@ enum OLEDDISPLAY_GEOMETRY { GEOMETRY_RAWMODE, }; +enum HW_I2C { + I2C_ONE, + I2C_TWO +}; + typedef char (*FontTableLookupFunction)(const uint8_t ch); char DefaultFontTableLookup(const uint8_t ch); diff --git a/src/SH1106Wire.h b/src/SH1106Wire.h index 58f1c94f..fd9085ff 100644 --- a/src/SH1106Wire.h +++ b/src/SH1106Wire.h @@ -46,21 +46,47 @@ class SH1106Wire : public OLEDDisplay { uint8_t _sda; uint8_t _scl; bool _doI2cAutoInit = false; + TwoWire* _wire = NULL; + int _frequency; public: - SH1106Wire(uint8_t _address, uint8_t _sda, uint8_t _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) { + /** + * Create and initialize the Display using Wire library + * + * Beware for retro-compatibility default values are provided for all parameters see below. + * Please note that if you don't wan't SD1306Wire to initialize and change frequency speed ot need to + * ensure -1 value are specified for all 3 parameters. This can be usefull to control TwoWire with multiple + * device on the same bus. + * + * @param _address I2C Display address + * @param _sda I2C SDA pin number, default to -1 to skip Wire begin call + * @param _scl I2C SCL pin number, default to -1 (only SDA = -1 is considered to skip Wire begin call) + * @param g display geometry dafault to generic GEOMETRY_128_64, see OLEDDISPLAY_GEOMETRY definition for other options + * @param _i2cBus on ESP32 with 2 I2C HW buses, I2C_ONE for 1st Bus, I2C_TWO fot 2nd bus, default I2C_ONE + * @param _frequency for Frequency by default Let's use ~700khz if ESP8266 is in 160Mhz mode, this will be limited to ~400khz if the ESP8266 in 80Mhz mode + */ + SH1106Wire(uint8_t _address, uint8_t _sda, uint8_t _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64, HW_I2C _i2cBus = I2C_ONE, int _frequency = 700000) { setGeometry(g); this->_address = _address; this->_sda = _sda; this->_scl = _scl; + this->_wire = (_i2cBus==I2C_ONE)?&Wire:&Wire1; + this->_frequency = _frequency; } bool connect() { - Wire.begin(this->_sda, this->_scl); +#if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH8266) + _wire->begin(); +#else + // On ESP32 arduino, -1 means 'don't change pins', someone else has called begin for us. + if(this->_sda != -1) + _wire->begin(this->_sda, this->_scl); +#endif // Let's use ~700khz if ESP8266 is in 160Mhz mode // this will be limited to ~400khz if the ESP8266 in 80Mhz mode. - Wire.setClock(700000); + if(this->_frequency != -1) + _wire->setClock(this->_frequency); return true; } @@ -107,25 +133,25 @@ class SH1106Wire : public OLEDDisplay { sendCommand(minBoundXp2L); for (x = minBoundX; x <= maxBoundX; x++) { if (k == 0) { - Wire.beginTransmission(_address); - Wire.write(0x40); + _wire->beginTransmission(_address); + _wire->write(0x40); } - Wire.write(buffer[x + y * displayWidth]); + _wire->write(buffer[x + y * displayWidth]); k++; if (k == 16) { - Wire.endTransmission(); + _wire->endTransmission(); k = 0; } } if (k != 0) { - Wire.endTransmission(); + _wire->endTransmission(); k = 0; } yield(); } if (k != 0) { - Wire.endTransmission(); + _wire->endTransmission(); } #else uint8_t * p = &buffer[0]; @@ -134,12 +160,12 @@ class SH1106Wire : public OLEDDisplay { sendCommand(0x02); sendCommand(0x10); for( uint8_t x=0; x<8; x++) { - Wire.beginTransmission(_address); - Wire.write(0x40); + _wire->beginTransmission(_address); + _wire->write(0x40); for (uint8_t k = 0; k < 16; k++) { - Wire.write(*p++); + _wire->write(*p++); } - Wire.endTransmission(); + _wire->endTransmission(); } } #endif @@ -154,18 +180,18 @@ class SH1106Wire : public OLEDDisplay { return 0; } inline void sendCommand(uint8_t command) __attribute__((always_inline)){ - Wire.beginTransmission(_address); - Wire.write(0x80); - Wire.write(command); - Wire.endTransmission(); + _wire->beginTransmission(_address); + _wire->write(0x80); + _wire->write(command); + _wire->endTransmission(); } void initI2cIfNeccesary() { if (_doI2cAutoInit) { #ifdef ARDUINO_ARCH_AVR - Wire.begin(); + _wire->begin(); #else - Wire.begin(this->_sda, this->_scl); + _wire->begin(this->_sda, this->_scl); #endif } } diff --git a/src/SSD1306Wire.h b/src/SSD1306Wire.h index d3855c05..730d9008 100644 --- a/src/SSD1306Wire.h +++ b/src/SSD1306Wire.h @@ -39,11 +39,7 @@ #define _min min #define _max max #endif - -enum HW_I2C { - I2C_ONE, - I2C_TWO -}; +//-------------------------------------- class SSD1306Wire : public OLEDDisplay { private: From 3f0ca803b82935dd9a275de23b1b76b927d66b6a Mon Sep 17 00:00:00 2001 From: Benoit Masson Date: Tue, 4 Aug 2020 13:25:34 +0200 Subject: [PATCH 7/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 785d8063..52a8be93 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ for a SH1106: #include "SH1106Wire.h" SH1106Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL -// By default SD1306Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value +// By default SH1106Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value // SH1106Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, 400000); //set I2C frequency to 400kHz // SH1106Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, -1); //skip setting the I2C bus frequency ```