SPI display option for 4 Line Display usermod.
This commit is contained in:
parent
445825df44
commit
5c3c8b7b8a
@ -31,6 +31,21 @@
|
|||||||
#ifndef FLD_PIN_SDA
|
#ifndef FLD_PIN_SDA
|
||||||
#define FLD_PIN_SDA 21
|
#define FLD_PIN_SDA 21
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FLD_PIN_CLOCKSPI
|
||||||
|
#define FLD_PIN_CLOCKSPI 18
|
||||||
|
#endif
|
||||||
|
#ifndef FLD_PIN_DATASPI
|
||||||
|
#define FLD_PIN_DATASPI 23
|
||||||
|
#endif
|
||||||
|
#ifndef FLD_PIN_DC
|
||||||
|
#define FLD_PIN_DC 19
|
||||||
|
#endif
|
||||||
|
#ifndef FLD_PIN_CS
|
||||||
|
#define FLD_PIN_CS 5
|
||||||
|
#endif
|
||||||
|
#ifndef FLD_PIN_RESET
|
||||||
|
#define FLD_PIN_RESET 26
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifndef FLD_PIN_SCL
|
#ifndef FLD_PIN_SCL
|
||||||
#define FLD_PIN_SCL 5
|
#define FLD_PIN_SCL 5
|
||||||
@ -38,6 +53,21 @@
|
|||||||
#ifndef FLD_PIN_SDA
|
#ifndef FLD_PIN_SDA
|
||||||
#define FLD_PIN_SDA 4
|
#define FLD_PIN_SDA 4
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FLD_PIN_CLOCKSPI
|
||||||
|
#define FLD_PIN_CLOCKSPI 14
|
||||||
|
#endif
|
||||||
|
#ifndef FLD_PIN_DATASPI
|
||||||
|
#define FLD_PIN_DATASPI 13
|
||||||
|
#endif
|
||||||
|
#ifndef FLD_PIN_DC
|
||||||
|
#define FLD_PIN_DC 12
|
||||||
|
#endif
|
||||||
|
#ifndef FLD_PIN_CS
|
||||||
|
#define FLD_PIN_CS 15
|
||||||
|
#endif
|
||||||
|
#ifndef FLD_PIN_RESET
|
||||||
|
#define FLD_PIN_RESET 16
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// When to time out to the clock or blank the screen
|
// When to time out to the clock or blank the screen
|
||||||
@ -64,11 +94,13 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
SSD1306, // U8X8_SSD1306_128X32_UNIVISION_HW_I2C
|
SSD1306, // U8X8_SSD1306_128X32_UNIVISION_HW_I2C
|
||||||
SH1106, // U8X8_SH1106_128X64_WINSTAR_HW_I2C
|
SH1106, // U8X8_SH1106_128X64_WINSTAR_HW_I2C
|
||||||
SSD1306_64, // U8X8_SSD1306_128X64_NONAME_HW_I2C
|
SSD1306_64, // U8X8_SSD1306_128X64_NONAME_HW_I2C
|
||||||
SSD1305, // U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C
|
SSD1305, // U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C
|
||||||
SSD1305_64 // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C
|
SSD1305_64, // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C
|
||||||
|
SSD1306_SPI, // U8X8_SSD1306_128X32_NONAME_HW_SPI
|
||||||
|
SSD1306_SPI64 // U8X8_SSD1306_128X64_NONAME_HW_SPI
|
||||||
} DisplayType;
|
} DisplayType;
|
||||||
|
|
||||||
class FourLineDisplayUsermod : public Usermod {
|
class FourLineDisplayUsermod : public Usermod {
|
||||||
@ -80,8 +112,13 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
|
|
||||||
// HW interface & configuration
|
// HW interface & configuration
|
||||||
U8X8 *u8x8 = nullptr; // pointer to U8X8 display object
|
U8X8 *u8x8 = nullptr; // pointer to U8X8 display object
|
||||||
int8_t sclPin=FLD_PIN_SCL, sdaPin=FLD_PIN_SDA; // I2C pins for interfacing, get initialised in readFromConfig()
|
#ifndef FLD_SPI_DEFAULT
|
||||||
|
int8_t ioPin[5] = {FLD_PIN_SCL, FLD_PIN_SDA, -1, -1, -1}; // I2C pins: SCL, SDA
|
||||||
DisplayType type = SSD1306; // display type
|
DisplayType type = SSD1306; // display type
|
||||||
|
#else
|
||||||
|
int8_t ioPin[5] = {FLD_PIN_CLOCKSPI, FLD_PIN_DATASPI, FLD_PIN_CS, FLD_PIN_DC, FLD_PIN_RESET}; // SPI pins: CLK, MOSI, CS, DC, RST
|
||||||
|
DisplayType type = SSD1306_SPI; // display type
|
||||||
|
#endif
|
||||||
bool flip = false; // flip display 180°
|
bool flip = false; // flip display 180°
|
||||||
uint8_t contrast = 10; // screen contrast
|
uint8_t contrast = 10; // screen contrast
|
||||||
uint8_t lineHeight = 1; // 1 row or 2 rows
|
uint8_t lineHeight = 1; // 1 row or 2 rows
|
||||||
@ -131,53 +168,74 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
// network here
|
// network here
|
||||||
void setup() {
|
void setup() {
|
||||||
if (type == NONE) return;
|
if (type == NONE) return;
|
||||||
if (!pinManager.allocatePin(sclPin)) { sclPin = -1; type = NONE; return;}
|
bool allocated = false;
|
||||||
if (!pinManager.allocatePin(sdaPin)) { pinManager.deallocatePin(sclPin); sclPin = sdaPin = -1; type = NONE; return; }
|
byte i;
|
||||||
|
if (type == SSD1306_SPI || type == SSD1306_SPI64) {
|
||||||
|
for (i=0; i<5; i++) if (!pinManager.allocatePin(ioPin[i])) { allocated=true; break; }
|
||||||
|
if (i<5 && allocated) { for (byte i=0; i<5; i++) pinManager.deallocatePin(ioPin[i]); type=NONE; return; }
|
||||||
|
} else {
|
||||||
|
for (i=0; i<2; i++) if (!pinManager.allocatePin(ioPin[i])) { allocated=true; break; }
|
||||||
|
if (i<2 && allocated) { for (byte i=0; i<5; i++) pinManager.deallocatePin(ioPin[i]); type=NONE; return; }
|
||||||
|
}
|
||||||
DEBUG_PRINTLN(F("Allocating display."));
|
DEBUG_PRINTLN(F("Allocating display."));
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSD1306:
|
case SSD1306:
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
if (!(sclPin==5 && sdaPin==4))
|
if (!(ioPin[0]==5 && ioPin[1]==4))
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_SW_I2C(sclPin, sdaPin); // SCL, SDA, reset
|
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA
|
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
lineHeight = 1;
|
lineHeight = 1;
|
||||||
break;
|
break;
|
||||||
case SH1106:
|
case SH1106:
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
if (!(sclPin==5 && sdaPin==4))
|
if (!(ioPin[0]==5 && ioPin[1]==4))
|
||||||
u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_SW_I2C(sclPin, sdaPin); // SCL, SDA, reset
|
u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA
|
u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
case SSD1306_64:
|
case SSD1306_64:
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
if (!(sclPin==5 && sdaPin==4))
|
if (!(ioPin[0]==5 && ioPin[1]==4))
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_SW_I2C(sclPin, sdaPin); // SCL, SDA, reset
|
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA
|
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
case SSD1305:
|
case SSD1305:
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
if (!(sclPin==5 && sdaPin==4))
|
if (!(ioPin[0]==5 && ioPin[1]==4))
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_NONAME_SW_I2C(sclPin, sdaPin); // SCL, SDA, reset
|
u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA
|
u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
lineHeight = 1;
|
lineHeight = 1;
|
||||||
break;
|
break;
|
||||||
case SSD1305_64:
|
case SSD1305_64:
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
if (!(sclPin==5 && sdaPin==4))
|
if (!(ioPin[0]==5 && ioPin[1]==4))
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_SW_I2C(sclPin, sdaPin); // SCL, SDA, reset
|
u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA
|
u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
|
lineHeight = 2;
|
||||||
|
break;
|
||||||
|
case SSD1306_SPI:
|
||||||
|
if (!(ioPin[0]==FLD_PIN_CLOCKSPI && ioPin[1]==FLD_PIN_DATASPI)) // if not overridden these sould be HW accellerated
|
||||||
|
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
|
||||||
|
else
|
||||||
|
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
||||||
|
lineHeight = 1;
|
||||||
|
break;
|
||||||
|
case SSD1306_SPI64:
|
||||||
|
if (!(ioPin[0]==FLD_PIN_CLOCKSPI && ioPin[1]==FLD_PIN_DATASPI)) // if not overridden these sould be HW accellerated
|
||||||
|
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
|
||||||
|
else
|
||||||
|
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -605,10 +663,10 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||||
*/
|
*/
|
||||||
void addToConfig(JsonObject& root) {
|
void addToConfig(JsonObject& root) {
|
||||||
JsonObject top = root.createNestedObject(FPSTR(_name));
|
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||||
JsonArray i2c_pin = top.createNestedArray("pin");
|
JsonArray io_pin = top.createNestedArray("pin");
|
||||||
i2c_pin.add(sclPin);
|
for (byte i=0; i<5; i++) io_pin.add(ioPin[i]);
|
||||||
i2c_pin.add(sdaPin);
|
top["help4PinTypes"] = F("Clk,Data,CS,DC,RST"); // help for Settings page
|
||||||
top["type"] = type;
|
top["type"] = type;
|
||||||
top[FPSTR(_flip)] = (bool) flip;
|
top[FPSTR(_flip)] = (bool) flip;
|
||||||
top[FPSTR(_contrast)] = contrast;
|
top[FPSTR(_contrast)] = contrast;
|
||||||
@ -630,8 +688,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
bool readFromConfig(JsonObject& root) {
|
bool readFromConfig(JsonObject& root) {
|
||||||
bool needsRedraw = false;
|
bool needsRedraw = false;
|
||||||
DisplayType newType = type;
|
DisplayType newType = type;
|
||||||
int8_t newScl = sclPin;
|
int8_t newPin[5]; for (byte i=0; i<5; i++) newPin[i] = ioPin[i];
|
||||||
int8_t newSda = sdaPin;
|
|
||||||
|
|
||||||
JsonObject top = root[FPSTR(_name)];
|
JsonObject top = root[FPSTR(_name)];
|
||||||
if (top.isNull()) {
|
if (top.isNull()) {
|
||||||
@ -640,9 +697,8 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
newScl = top["pin"][0] | newScl;
|
|
||||||
newSda = top["pin"][1] | newSda;
|
|
||||||
newType = top["type"] | newType;
|
newType = top["type"] | newType;
|
||||||
|
for (byte i=0; i<5; i++) newPin[i] = top["pin"][i] | ioPin[i];
|
||||||
flip = top[FPSTR(_flip)] | flip;
|
flip = top[FPSTR(_flip)] | flip;
|
||||||
contrast = top[FPSTR(_contrast)] | contrast;
|
contrast = top[FPSTR(_contrast)] | contrast;
|
||||||
refreshRate = (top[FPSTR(_refreshRate)] | refreshRate/1000) * 1000;
|
refreshRate = (top[FPSTR(_refreshRate)] | refreshRate/1000) * 1000;
|
||||||
@ -653,20 +709,21 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
DEBUG_PRINT(FPSTR(_name));
|
DEBUG_PRINT(FPSTR(_name));
|
||||||
if (!initDone) {
|
if (!initDone) {
|
||||||
// first run: reading from cfg.json
|
// first run: reading from cfg.json
|
||||||
sclPin = newScl;
|
for (byte i=0; i<5; i++) ioPin[i] = newPin[i];
|
||||||
sdaPin = newSda;
|
|
||||||
type = newType;
|
type = newType;
|
||||||
DEBUG_PRINTLN(F(" config loaded."));
|
DEBUG_PRINTLN(F(" config loaded."));
|
||||||
} else {
|
} else {
|
||||||
DEBUG_PRINTLN(F(" config (re)loaded."));
|
DEBUG_PRINTLN(F(" config (re)loaded."));
|
||||||
// changing parameters from settings page
|
// changing parameters from settings page
|
||||||
if (sclPin!=newScl || sdaPin!=newSda || type!=newType) {
|
bool pinsChanged = false;
|
||||||
|
for (byte i=0; i<5; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; }
|
||||||
|
if (pinsChanged || type!=newType) {
|
||||||
if (type != NONE) delete (static_cast<U8X8*>(u8x8));
|
if (type != NONE) delete (static_cast<U8X8*>(u8x8));
|
||||||
pinManager.deallocatePin(sclPin);
|
for (byte i=0; i<5; i++) {
|
||||||
pinManager.deallocatePin(sdaPin);
|
if (ioPin[i]>=0) pinManager.deallocatePin(ioPin[i]);
|
||||||
sclPin = newScl;
|
ioPin[i] = newPin[i];
|
||||||
sdaPin = newSda;
|
}
|
||||||
if (newScl<0 || newSda<0) {
|
if (ioPin[0]<0 || ioPin[1]<0) { // data & clock must be > -1
|
||||||
type = NONE;
|
type = NONE;
|
||||||
return true;
|
return true;
|
||||||
} else type = newType;
|
} else type = newType;
|
||||||
@ -678,7 +735,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
if (needsRedraw && !wakeDisplay()) redraw(true);
|
if (needsRedraw && !wakeDisplay()) redraw(true);
|
||||||
}
|
}
|
||||||
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
||||||
return true;
|
return !(top["pin"][2]).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user