/* stupid atenna matrix firmware - by DL3SD * FIXME: * - replace delay in loop by interrupt handling * - maybe implement sleep mode to avoid hf issues by arduino clock */ #include #include #include #define MODES 6 #define VERSION " v0.2" #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 struct state { char name[4]; bool K1; bool K2; bool K3; bool K4; bool K5; bool K6; }; struct identifier { char ant[3][16]; char trx[3][16]; }; struct identifier names; const struct state matrix[] = { {"123", 0, 0, 0, 0, 0, 0}, // ANT1->TRX1 ANT2->TRX2 ANT3->TRX3 {"213", 1, 0, 1, 0, 0, 0}, // ANT1->TRX2 ANT2->TRX1 ANT3->TRX3 {"312", 1 ,1, 1, 0, 1, 0}, // ANT1->TRX3 ANT2->TRX1 ANT3->TRX2 {"132", 0 ,0, 1, 1, 1, 0}, // ANT1->TRX1 ANT2->TRX3 ANT3->TRX2 {"231", 1 ,0 ,1, 1, 1, 1}, // ANT1->TRX2 ANT2->TRX3 ANT3->TRX1 {"321", 1 ,1 ,0, 0, 1, 1}, // ANT1->TRX3 ANT2->TRX2 ANT3->TRX1 }; int mode; LiquidCrystal_I2C lcd(0x27, 20, 4); void setup() { Serial.begin(9600); Serial.print(F("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("loading identifiers from EEPROM..")); EEPROM.get(0, names); Serial.println("done"); Serial.print(F("initializing display..")); lcd.init(); lcd.backlight(); Serial.println("done"); Serial.print(F("initializing relays with mode 123..")); setMode("123"); Serial.println("done"); Serial.println("setup finished"); Serial.println(); } void storeName(char *dst, char *src) { strncpy(dst, src, strlen(src)); dst[strlen(src) - 1] = '\0'; } void printMatrix() { char m[4], out[32]; int c; // get current mode string like '312' strcpy(m, matrix[mode].name); lcd.clear(); lcd.setCursor(0,0); lcd.print(" S.A.M. by DL3SD"); for(int i=0; i < 3; i++) { c = m[i]-48; lcd.setCursor(0, i+1); lcd.print(names.trx[i]); sprintf(out, "<- %s", names.ant[c-1]); lcd.setCursor(8, i+1); lcd.print(out); } } void setRelays() { digitalWrite(pin_K1, matrix[mode].K1); digitalWrite(pin_K2, matrix[mode].K2); digitalWrite(pin_K3, matrix[mode].K3); digitalWrite(pin_K4, matrix[mode].K4); digitalWrite(pin_K5, matrix[mode].K5); digitalWrite(pin_K6, matrix[mode].K6); printMatrix(); } void nextMode() { if(mode == MODES - 1) { mode = 0; } else { mode++; } Serial.print("next mode: "); Serial.println(matrix[mode].name); setRelays(); } void setMode(char *m) { char debug[32]; m[3] = '\0'; for(int i=0 ; i < MODES; i++) { //sprintf(debug, "comparing %s against %s", m, matrix[i].name); //Serial.println(debug); if(strcmp(matrix[i].name, m) == 0) { mode = i; //sprintf(debug, "found mode %s at index %d", m, i); //Serial.println(debug); setRelays(); return; } } sprintf(debug, "ERROR: cant find mode %s", m); Serial.println(debug); return; } void parseCommand() { String s; s = Serial.readString(); switch (s[0]) { case 'a': switch (s[1]) { case '1': case '2': case '3': storeName(names.ant[(int)s[1] - 49], &s[2]); break; default: Serial.println("unsupported option"); Serial.println(); break; } break; case 't': switch (s[1]) { case '1': case '2': case '3': storeName(names.trx[(int)s[1] - 49], &s[2]); break; default: Serial.println("unsupported option"); Serial.println(); break; } break; case 'm': if(s.length() == 5) { setMode(&s[1]); } else { Serial.print("getting mode:"); Serial.println(matrix[mode].name); Serial.println(); } break; case 'n': nextMode(); break; case 'h': Serial.println(F("following commands are available:")); Serial.println(F(" a1mygreatantenna1 - sets name of ANT1 to mygreatantenna1")); Serial.println(F(" a2mygreatantenna2 - sets name of ANT2 to mygreatantenna2")); Serial.println(F(" a3mygreatantenna3 - sets name of ANT3 to mygreatantenna3")); Serial.println(F(" t1mygreatrig1 - sets name of TRX1 to mygreatrig1")); Serial.println(F(" t2mygreatrig2 - sets name of TRX2 to mygreatrig2")); Serial.println(F(" t3mygreatrig3 - sets name of TRX3 to mygreatrig3")); Serial.println(F(" m312 - activate matrix 312 (I1->O3 I2->O1 I3->O2)")); Serial.println(F(" m - print current matrix")); Serial.println(F(" n - goto next matrix entry")); Serial.println(F(" r - print runtime settings")); Serial.println(F(" w - store runtime settings to EEPROM")); Serial.println(F(" h - print this help text")); Serial.print(F(" firmware version: ")); Serial.println(VERSION); Serial.println(); break; case 'w': EEPROM.put(0, names); Serial.println("runtime settings stored in EEPROM"); break; case 'r': Serial.println(F("current runtime settings:")); Serial.print(F("ANT1: ")); Serial.println(names.ant[0]); Serial.print(F("ANT2: ")); Serial.println(names.ant[1]); Serial.print(F("ANT3: ")); Serial.println(names.ant[2]); Serial.print(F("TRX1: ")); Serial.println(names.trx[0]); Serial.print(F("TRX2: ")); Serial.println(names.trx[1]); Serial.print(F("TRX3: ")); Serial.println(names.trx[2]); Serial.println(F("-> dont forget to write to EEPROM with 'w'")); Serial.println(); break; default: Serial.println(F("command not found - enter 'h' for help")); Serial.println(); break; } } void loop() { if (Serial.available() > 0) { parseCommand(); } if(digitalRead(pin_T) == HIGH) { //Serial.println("button pressed.."); nextMode(); } delay(300); }