|
@ -5,20 +5,21 @@ |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
#include <EEPROM.h> |
|
|
#include <EEPROM.h> |
|
|
#include <Wire.h> |
|
|
|
|
|
#include <LiquidCrystal_I2C.h> |
|
|
|
|
|
|
|
|
|
|
|
#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 VERSION "v0.2" |
|
|
#define pin_K2 7 |
|
|
#define MODES 6 |
|
|
#define pin_K3 6 |
|
|
|
|
|
#define pin_K4 5 |
|
|
|
|
|
#define pin_K5 4 |
|
|
|
|
|
#define pin_K6 3 |
|
|
|
|
|
#define pin_T 12 |
|
|
|
|
|
|
|
|
|
|
|
struct state { |
|
|
struct state { |
|
|
char name[4]; |
|
|
char name[4]; |
|
@ -31,11 +32,12 @@ struct state { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
struct identifier { |
|
|
struct identifier { |
|
|
|
|
|
char signature[16]; |
|
|
char ant[3][16]; |
|
|
char ant[3][16]; |
|
|
char trx[3][16]; |
|
|
char trx[3][16]; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
struct identifier names; |
|
|
struct identifier names; // = { "samcfg", "ant1", "ant2", "ant3", "trx1", "trx2", "trx3" };
|
|
|
|
|
|
|
|
|
const struct state matrix[] = { |
|
|
const struct state matrix[] = { |
|
|
{"123", 0, 0, 0, 0, 0, 0}, // ANT1->TRX1 ANT2->TRX2 ANT3->TRX3
|
|
|
{"123", 0, 0, 0, 0, 0, 0}, // ANT1->TRX1 ANT2->TRX2 ANT3->TRX3
|
|
@ -48,43 +50,18 @@ const struct state matrix[] = { |
|
|
|
|
|
|
|
|
int mode; |
|
|
int mode; |
|
|
|
|
|
|
|
|
LiquidCrystal_I2C lcd(0x27, 20, 4); |
|
|
/*###########################################*/ |
|
|
|
|
|
#if defined(USE_I2C_LCD) |
|
|
|
|
|
/*###########################################*/ |
|
|
|
|
|
|
|
|
void setup() { |
|
|
#include <Wire.h> |
|
|
Serial.begin(9600); |
|
|
#include <LiquidCrystal_I2C.h> |
|
|
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"); |
|
|
|
|
|
|
|
|
|
|
|
Serial.print(F("[S] loading identifiers from EEPROM..")); |
|
|
LiquidCrystal_I2C lcd(0x27, 20, 4); |
|
|
EEPROM.get(0, names); |
|
|
|
|
|
Serial.println("done"); |
|
|
|
|
|
|
|
|
|
|
|
Serial.print(F("[S] initializing display..")); |
|
|
void initDisplay() { |
|
|
lcd.init(); |
|
|
lcd.init(); |
|
|
lcd.backlight(); |
|
|
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.setCursor(8,0); |
|
|
lcd.print(F("stupid")); |
|
|
lcd.print(F("stupid")); |
|
|
delay(350); |
|
|
delay(350); |
|
@ -100,7 +77,7 @@ void bootSplash() { |
|
|
delay(3000); |
|
|
delay(3000); |
|
|
lcd.clear(); |
|
|
lcd.clear(); |
|
|
lcd.setCursor(8,0); |
|
|
lcd.setCursor(8,0); |
|
|
lcd.print(F("see")); |
|
|
lcd.print(F("visit")); |
|
|
lcd.setCursor(0,1); |
|
|
lcd.setCursor(0,1); |
|
|
lcd.print(F("github.com/denzs/sam")); |
|
|
lcd.print(F("github.com/denzs/sam")); |
|
|
lcd.setCursor(0,2); |
|
|
lcd.setCursor(0,2); |
|
@ -108,12 +85,7 @@ void bootSplash() { |
|
|
delay(5000); |
|
|
delay(5000); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void storeName(char *dst, char *src) { |
|
|
void updateDisplay() { |
|
|
strncpy(dst, src, strlen(src)); |
|
|
|
|
|
dst[strlen(src) - 1] = '\0'; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void printMatrix() { |
|
|
|
|
|
char m[4], out[32]; |
|
|
char m[4], out[32]; |
|
|
int c; |
|
|
int c; |
|
|
|
|
|
|
|
@ -122,16 +94,181 @@ void printMatrix() { |
|
|
lcd.clear(); |
|
|
lcd.clear(); |
|
|
lcd.setCursor(3,0); |
|
|
lcd.setCursor(3,0); |
|
|
lcd.print(F("S.A.M. by DL3SD")); |
|
|
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; |
|
|
c = m[i]-48; |
|
|
lcd.setCursor(0, i+1); |
|
|
lcd.setCursor(0, i+1); |
|
|
lcd.print(names.trx[i]); |
|
|
lcd.print(names.trx[i]); |
|
|
lcd.setCursor(9, i+1); |
|
|
lcd.setCursor(10, i+1); |
|
|
sprintf(out, "<- %s", names.ant[c-1]); |
|
|
sprintf(out, "%s", names.ant[c-1]); |
|
|
lcd.print(out); |
|
|
lcd.print(out); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*###########################################*/ |
|
|
|
|
|
#endif |
|
|
|
|
|
/*###########################################*/ |
|
|
|
|
|
|
|
|
|
|
|
/*###########################################*/ |
|
|
|
|
|
#if defined(USE_I2C_OLED) |
|
|
|
|
|
/*###########################################*/ |
|
|
|
|
|
|
|
|
|
|
|
#include <Adafruit_GFX.h> |
|
|
|
|
|
#include <Adafruit_SSD1306.h> |
|
|
|
|
|
#include <Fonts/FreeSans9pt7b.h> |
|
|
|
|
|
#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 <GxEPD2_BW.h> // including both doesn't hurt |
|
|
|
|
|
#include <GxEPD2_3C.h> // including both doesn't hurt FIXME remove??? |
|
|
|
|
|
#include <Fonts/FreeMonoBold9pt7b.h> |
|
|
|
|
|
|
|
|
|
|
|
#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<GxEPD2_290, MAX_HEIGHT(GxEPD2_290)> 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) { |
|
|
void setRelays(bool display) { |
|
|
digitalWrite(pin_K1, matrix[mode].K1); |
|
|
digitalWrite(pin_K1, matrix[mode].K1); |
|
|
digitalWrite(pin_K2, matrix[mode].K2); |
|
|
digitalWrite(pin_K2, matrix[mode].K2); |
|
@ -140,7 +277,7 @@ void setRelays(bool display) { |
|
|
digitalWrite(pin_K5, matrix[mode].K5); |
|
|
digitalWrite(pin_K5, matrix[mode].K5); |
|
|
digitalWrite(pin_K6, matrix[mode].K6); |
|
|
digitalWrite(pin_K6, matrix[mode].K6); |
|
|
if (display) { |
|
|
if (display) { |
|
|
printMatrix(); |
|
|
updateDisplay(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -181,7 +318,7 @@ void parseCommand(String s) { |
|
|
case '2': |
|
|
case '2': |
|
|
case '3': |
|
|
case '3': |
|
|
storeName(names.ant[(int)s[1] - 49], &s[2]); |
|
|
storeName(names.ant[(int)s[1] - 49], &s[2]); |
|
|
printMatrix(); |
|
|
updateDisplay(); |
|
|
break; |
|
|
break; |
|
|
default: |
|
|
default: |
|
|
Serial.println("unsupported option"); |
|
|
Serial.println("unsupported option"); |
|
@ -195,7 +332,7 @@ void parseCommand(String s) { |
|
|
case '2': |
|
|
case '2': |
|
|
case '3': |
|
|
case '3': |
|
|
storeName(names.trx[(int)s[1] - 49], &s[2]); |
|
|
storeName(names.trx[(int)s[1] - 49], &s[2]); |
|
|
printMatrix(); |
|
|
updateDisplay(); |
|
|
break; |
|
|
break; |
|
|
default: |
|
|
default: |
|
|
Serial.println("unsupported option"); |
|
|
Serial.println("unsupported option"); |
|
|