From 66c6a10ab6f74f30dfd49f8e4ee45d769928d2b7 Mon Sep 17 00:00:00 2001 From: Sebastian Denz Date: Tue, 26 Jan 2021 00:20:25 +0100 Subject: [PATCH] firmware: add support for e-ink, lcd and oled --- firmware/firmware.ino | 253 ++++++++++++++++++++++++++++++++---------- 1 file changed, 195 insertions(+), 58 deletions(-) diff --git a/firmware/firmware.ino b/firmware/firmware.ino index 14d1b9a..64c74c9 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -5,20 +5,21 @@ */ #include -#include -#include -#define MODES 6 +#define USE_I2C_LCD +//#define USE_I2C_OLED +//#define USE_SPI_EINK -#define VERSION "v0.2" +#define pin_K1 8 //2 +#define pin_K2 7//3 +#define pin_K3 6//4 +#define pin_K4 5//5 +#define pin_K5 4//6 +#define pin_K6 3//12 +#define pin_T 2//14 -#define pin_K1 8 -#define pin_K2 7 -#define pin_K3 6 -#define pin_K4 5 -#define pin_K5 4 -#define pin_K6 3 -#define pin_T 12 +#define VERSION "v0.2" +#define MODES 6 struct state { char name[4]; @@ -31,11 +32,12 @@ struct state { }; struct identifier { + char signature[16]; char ant[3][16]; char trx[3][16]; }; -struct identifier names; +struct identifier names; // = { "samcfg", "ant1", "ant2", "ant3", "trx1", "trx2", "trx3" }; const struct state matrix[] = { {"123", 0, 0, 0, 0, 0, 0}, // ANT1->TRX1 ANT2->TRX2 ANT3->TRX3 @@ -48,43 +50,18 @@ const struct state matrix[] = { int mode; -LiquidCrystal_I2C lcd(0x27, 20, 4); +/*###########################################*/ +#if defined(USE_I2C_LCD) +/*###########################################*/ -void setup() { - Serial.begin(9600); - Serial.print(F("[S] configuring pins..")); - pinMode(pin_K1, OUTPUT); - pinMode(pin_K2, OUTPUT); - pinMode(pin_K3, OUTPUT); - pinMode(pin_K4, OUTPUT); - pinMode(pin_K5, OUTPUT); - pinMode(pin_K6, OUTPUT); - pinMode(pin_T, INPUT); - Serial.println("done"); +#include +#include - Serial.print(F("[S] loading identifiers from EEPROM..")); - EEPROM.get(0, names); - Serial.println("done"); +LiquidCrystal_I2C lcd(0x27, 20, 4); - Serial.print(F("[S] initializing display..")); +void initDisplay() { lcd.init(); lcd.backlight(); - Serial.println("done"); - - Serial.print(F("[S] initializing relays with mode 123..")); - setMode("123"); - setRelays(0); - Serial.println("done"); - - Serial.print(F("[S] showing bootsplash..")); - bootSplash(); - Serial.println("done"); - printMatrix(); - - Serial.println("[S] setup finished"); -} - -void bootSplash() { lcd.setCursor(8,0); lcd.print(F("stupid")); delay(350); @@ -100,7 +77,7 @@ void bootSplash() { delay(3000); lcd.clear(); lcd.setCursor(8,0); - lcd.print(F("see")); + lcd.print(F("visit")); lcd.setCursor(0,1); lcd.print(F("github.com/denzs/sam")); lcd.setCursor(0,2); @@ -108,30 +85,190 @@ void bootSplash() { delay(5000); } -void storeName(char *dst, char *src) { - strncpy(dst, src, strlen(src)); - dst[strlen(src) - 1] = '\0'; -} - -void printMatrix() { +void updateDisplay() { char m[4], out[32]; int c; strcpy(m, matrix[mode].name); - + lcd.clear(); lcd.setCursor(3,0); lcd.print(F("S.A.M. by DL3SD")); - for(int i=0; i < 3; i++) { + for(int i=0; i < MODES/2; i++) { c = m[i]-48; lcd.setCursor(0, i+1); lcd.print(names.trx[i]); - lcd.setCursor(9, i+1); - sprintf(out, "<- %s", names.ant[c-1]); + lcd.setCursor(10, i+1); + sprintf(out, "%s", names.ant[c-1]); lcd.print(out); } } +/*###########################################*/ +#endif +/*###########################################*/ + +/*###########################################*/ +#if defined(USE_I2C_OLED) +/*###########################################*/ + +#include +#include +#include +#include "DejaVuSansMono5pt7b.h" + +#define OLED_RESET 4 +Adafruit_SSD1306 display(OLED_RESET); + +void updateDisplay() { + char m[4], out[32]; + int c; + + strcpy(m, matrix[mode].name); + + display.clearDisplay(); + //lcd.setCursor(3,0); + //lcd.print(F("S.A.M. by DL3SD")); + for(int i=0; i < MODES/2; i++) { + c = m[i]-48; + display.setCursor(0, (i+1)*10); + display.print(names.trx[i]); + display.setCursor(64, (i+1)*10); + sprintf(out, "%s", names.ant[c-1]); + display.print(out); + } + display.display(); +} + +void initDisplay() { + display.begin(SSD1306_SWITCHCAPVCC, 0x3C); + display.display(); + //display.setFont(&FreeSans9pt7b); + display.setFont(&DejaVuSansMono5pt7b); + //display.setTextSize(1); + delay(1000); + display.clearDisplay(); + display.setTextColor(WHITE); +} + +/*###########################################*/ +#endif +/*###########################################*/ + + +/*###########################################*/ +#if defined(USE_SPI_EINK) +/*###########################################*/ + +#define ENABLE_GxEPD2_GFX 0 +#include // including both doesn't hurt +#include // including both doesn't hurt FIXME remove??? +#include + +#define MAX_DISPLAY_BUFFER_SIZE 600 +#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8)) + +GxEPD2_BW display(GxEPD2_290(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); + +void updateDisplay() { + char out[256]; + sprintf(out, " s.a.m. by DL3SD\n github.com/denzs/sam\n\n %s %s\n %s %s\n %s %s", names.trx[0], names.ant[matrix[mode].name[0]-49], names.trx[1], names.ant[matrix[mode].name[1]-49], names.trx[2], names.ant[matrix[mode].name[2]-49]); + Serial.println(out); + display.setRotation(1); + display.setFont(&FreeMonoBold9pt7b); + display.setTextColor(GxEPD_BLACK); + int16_t tbx, tby; uint16_t tbw, tbh; + display.getTextBounds(out , 0, 0, &tbx, &tby, &tbw, &tbh); + // center the bounding box by transposition of the origin: + uint16_t x = ((display.width() - tbw) / 2) - tbx; + uint16_t y = ((display.height() - tbh) / 2) - tby; + display.setFullWindow(); + display.firstPage(); + do + { + Serial.println("[I] refresh eink screen.."); + display.fillScreen(GxEPD_WHITE); + display.setCursor(x, y); + display.print(out); + } + while (display.nextPage()); + display.hibernate(); +} + +void initDisplay() { + display.init(); + char out[] = " s.a.m. by DL3SD\n github.com/denzs/sam\n\n"; + display.setRotation(1); + display.setFont(&FreeMonoBold9pt7b); + display.setTextColor(GxEPD_BLACK); + int16_t tbx, tby; uint16_t tbw, tbh; + display.getTextBounds(out , 0, 0, &tbx, &tby, &tbw, &tbh); + // center the bounding box by transposition of the origin: + uint16_t x = ((display.width() - tbw) / 2) - tbx; + uint16_t y = ((display.height() - tbh) / 2); // - tby; + display.setFullWindow(); + display.firstPage(); + do + { + display.fillScreen(GxEPD_WHITE); + display.setCursor(x, y); + display.print(out); + } + while (display.nextPage()); + display.hibernate(); +} + +/*###########################################*/ +#endif +/*###########################################*/ + +void setup() { + Serial.begin(9600); + Serial.print(F("[S] configuring pins..")); + pinMode(pin_K1, OUTPUT); + pinMode(pin_K2, OUTPUT); + pinMode(pin_K3, OUTPUT); + pinMode(pin_K4, OUTPUT); + pinMode(pin_K5, OUTPUT); + pinMode(pin_K6, OUTPUT); + pinMode(pin_T, INPUT); + Serial.println(F("done")); + + Serial.print(F("[S] trying to read identifiers from EEPROM..")); + EEPROM.get(0, names); + Serial.println(F("done")); + if(strcmp(names.signature, "samcfg") == 0) { + Serial.println(F("[S] configuration found")); + } else { + Serial.println(F("[S] configuration not found.. using defaults")); + strcpy(names.signature, "samcfg"); + strcpy(names.ant[0], "ant1"); + strcpy(names.ant[1], "ant2"); + strcpy(names.ant[2], "ant3"); + strcpy(names.trx[0], "trx1"); + strcpy(names.trx[1], "trx2"); + strcpy(names.trx[2], "trx3"); + } + + Serial.print(F("[S] init relays with mode 123..")); + setMode("123"); + setRelays(0); + Serial.println(F("done")); + + Serial.print(F("[S] initializing display..")); + initDisplay(); + Serial.println(F("done")); + + updateDisplay(); + + Serial.println(F("[S] setup finished")); +} + +void storeName(char *dst, char *src) { + strncpy(dst, src, strlen(src)); + dst[strlen(src) - 1] = '\0'; +} + void setRelays(bool display) { digitalWrite(pin_K1, matrix[mode].K1); digitalWrite(pin_K2, matrix[mode].K2); @@ -140,7 +277,7 @@ void setRelays(bool display) { digitalWrite(pin_K5, matrix[mode].K5); digitalWrite(pin_K6, matrix[mode].K6); if (display) { - printMatrix(); + updateDisplay(); } } @@ -181,7 +318,7 @@ void parseCommand(String s) { case '2': case '3': storeName(names.ant[(int)s[1] - 49], &s[2]); - printMatrix(); + updateDisplay(); break; default: Serial.println("unsupported option"); @@ -195,7 +332,7 @@ void parseCommand(String s) { case '2': case '3': storeName(names.trx[(int)s[1] - 49], &s[2]); - printMatrix(); + updateDisplay(); break; default: Serial.println("unsupported option");