/*
1) პირველი რეჟიმია "ნორმალური" მოდა. კონტროლერის ჩართვისას, ვთქვათ,
ჩართულია პირველი ანტენა (შესბამისი ნომრის ლედ ნათურა ანთია RX-TX). არცერთი
TX ნათურა არ ანთია. ამ რეჟიმში მიმღები და გადამცემი ანტენა ერთიდაიგივეა.
კლავიატურაზე 1-დან-8 მდე აკრეფვით, ჩართავთ შესაბამის ანტენას, რომელიც
მიმღებიც (RX) და გადამცემიც (TX) ერთდოულად იქნება.
2) მეორე (RX Scan Mode) რეჟიმია, სადაც ხდება მიმღები (RX) ანტენის არჩევა.
ამ რეჟიმის გააქტიურებას ვახდენთ * ღილაკით კლავიატურიდან. ამავდროულად
ინთება TX ანტენის ლედ ნათურაც. TX ანტენა იქნება ის, რომელიც იყო ბოლო
მოქმედების დროს "ნორმალურ" რეჟიხში. ამ დროს სადაც არ უნდა გადართოთ
მიმღები ანტენა კლავიატურიდან, გადამცემი ანტენა, ptt-ს დაჭერით, ირთვება
მხოლოდ არჩეული გადამცემი TX ანტენა. რჟიმიდან გამოსვლა ხდება *-ზე ხელახალი
დაკლიკებით.
3) მესამე (TX Scan Mode) რეჟიმია, სადაც ხდება გადამცემი (TX) ანტენის არჩევა.
ამ რჟიმში შესვლა შესაძლებელია # ზე დაკლიკებით. ამ რეჟიმში RX ანტენა
ფიქსირებულია და ვახდენთ მხოლოდ TX ანტენის გადართვას. რეჟიმიდან გამოსვლა
ხდება #-ზე ხელახალი დაკლიკებით. (2)-დან (3) რეჟიმში, ან (3)-დან (2)-ში
გადასვლა ხდება ეგრევე * ან # ის დაკლიკებით.
4) არსებობს ასევე, Swap რეჟიმი, როცა არჩეული TX და RX ანტენებს შეგიძლიათ
შეუცვალოთ როლები და გადამცემი ანტენა გახდეს მიმღები, ხოლო მიმღები - გადამცემი,
9-ს ღილაკით. Swap რეჟიმი ჩართვადია მხოლოდ RX Scan Mode ან TX Scan Mode რეჟიმში.
Swap რეჟიმში შეუძლებელია სხვა ანტენის არჩევა ან შეცვლა, მხოლოდ არჩეული ორი ანტენა
ცვლის როლებს. Swap ის გამორთვა ხდება ისევ 9 ღილაკით, ან (RX Scan Mode)
რეჟიმის (*-ით), ან (TX Scan Mode) რეჟიმის (#-ით) გაუქმებით).
ანუ, SWAP რეჟიმიდან 3 გზაა: ა) 9, ბ) *, გ) #.
ა) SWAP-დან 9-ით გამოსვლა დაგაბრუნებს იმ რეჟიმში რომელიდანაც გადახვედი SWAP-ში.
ბ) SWAP-დან *-ით გამოსვლა გადაგიყვანს ეგრევე RX Scan Mode-ში.
გ) SWAP-დან #-ით გამოსვლა გადაგიყვანს ეგრევე TX Scan Mode-ში.
დ) გადასვლა (RX Scan Mode) -> (TX Scan Mode): TX-RX ანტენა ხდება ის,
რომელიც იყო RX (იმიტომ, რომ RX სკანირებას ახდენდი).
ე) გადასვლა (TX Scan Mode) -> (RX Scan Mode): TX-RX ანტენა ხდება ის,
რომელიც იყო TX (იმიტომ, რომ TX სკანირებას ახდენდი).
5) ანტენების შეზღუდვა: დავუშვათ 8 ანტენის ნაცვლად გვაქვს მხოლოდ 5 ანტენა:
1 დან 5 ის ჩათვლით დაკავებულია კონექტორები სვიჩზე. ამ დროს 6, 7, 8 კონექტორი ცარიელია.
შეგვიძლია შევზღუდოთ გადართვა 6, 7, 8 ანტენებზე შემდეგნაირად: ვკრებთ 005 კომბინაციას და
სისტემა გადავა 5 ანტენიან სვიჩის რეჟიმზე. ამ დროს შეუძლებელია 6, 7, 8 ანტენის ჩართვა.
შეზღუდვიდან გამოსვლის 2 გზაა: ა) 008 კომბინაცია, და ბ) სვიჩის გადატივრთვა, გამორთვა-ჩართვა.
ასევე, კლავიატურაზე მხოლოდ 0-ის აკრეფა რეაგირებას არ ახდენს; ხოლო 00 კომბინაციის მერე
კოდი გელოდება 2 წამი. ამ 2 წამში თუ არ მოხდა ანტენების რაოდენობის არჩევა, სისტემა
გამოდის ლოდინის რეჟიმიდან და უქმდება 00 კომბინაცია (რათა არ მოხდეს სისტემის ბლოკირება).
6) როდესაც PTT აქტიურია და ტრანსივერი/სვიჩი TX ზეა, იბლოკება რელეების გადართვა.
7) ** კომბინაცია უდრის # კომბინაციას.
8) რომელიმე ანტენაზე 3 წამზე მეტი ხნით დაკლიკებისას ხდება ამ
ანტენაზე TX აკრძალვის დადება. განმეორებით 3 წამზე მეტი ხნით დაწოლა
მოხსნის აკრძალვას.
ავტორები: 4L7ZS, 4L4CR და 4L0VE.
(ბაგი: აკრძალული ანტენა TX სკანში გადასვლისას, სანამ გამოცვლი გადადის გადაცემაზე)
--------------------------------
4x3 kaypad Black pinouts:
Pin_Number = Pad_RC
NC
1 = C2
2 = R1
3 = C1
4 = R4
5 = C3
6 = R3
7 = R2
NC
-------------- ---------------
Connections:
(Arduino) = (Pad_RC) = (Pad Kay_Number)
A0 = R1 = 2
A1 = R2 = 7
A2 = R3 = 6
A3 = R4 = 4
D3 = C1 = 3
D4 = C2 = 1
D5 = C3 = 5
-----------------------------
*/
/* (unchanged header comments omitted for brevity in this snippet) */
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Shift register pins
const int latchPin1 = 6;
const int clockPin1 = 7;
const int dataPin1 = 8;
const int latchPin2 = 9;
const int clockPin2 = 10;
const int dataPin2 = 11;
const int statusLedPin = 13;
const int swapLedPin = 12;
const int pttPin = 2;
const int txScanLedPin = 0;
const int MaxAntLedPin = 1;
// State variables
int activeRelay = 0;
int txRelay = 0;
int rxRelay = 0;
bool rxScanMode = false;
bool txScanMode = false;
bool swapMode = false;
int maxAntennas = 8;
// Array to track blocked antennas (true = blocked from TX)
bool blockedAntennas[8] = {false, false, false, false, false, false, false, false};
// Tracking changes
int lastRxRelay = -1;
int lastTxRelay = -1;
bool lastPttState = false;
bool lastRxScanMode = false;
bool lastTxScanMode = false;
bool lastSwapMode = false;
// Keypad configuration
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[ROWS] = {A0, A1, A2, A3};
byte colPins[COLS] = {3, 4, 5};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Antenna names
const String antennaNames[] = {
"1-Ant", "2-Ant", "3-Ant", "4-Ant",
"5-Ant", "6-Ant", "7-Ant", "8-Ant"
};
// ------------------------
// Keypad event for long press
// ------------------------
void keypadEvent(KeypadEvent key) {
switch (keypad.getState()) {
case HOLD:
if (key >= '1' && key <= '8') {
int antenna = key - '1';
if (antenna >= 0 && antenna < 8) {
toggleAntennaBlock(antenna); // Block/unblock TX
}
}
break;
}
}
// ------------------------
// Setup
// ------------------------
void setup() {
pinMode(latchPin1, OUTPUT);
pinMode(clockPin1, OUTPUT);
pinMode(dataPin1, OUTPUT);
pinMode(latchPin2, OUTPUT);
pinMode(clockPin2, OUTPUT);
pinMode(dataPin2, OUTPUT);
pinMode(pttPin, INPUT);
pinMode(statusLedPin, OUTPUT);
pinMode(swapLedPin, OUTPUT);
digitalWrite(latchPin1, LOW);
digitalWrite(clockPin1, LOW);
digitalWrite(dataPin1, LOW);
digitalWrite(latchPin2, LOW);
digitalWrite(clockPin2, LOW);
digitalWrite(dataPin2, LOW);
pinMode(txScanLedPin, OUTPUT);
digitalWrite(txScanLedPin, LOW);
pinMode(MaxAntLedPin, OUTPUT);
digitalWrite(MaxAntLedPin, LOW);
keypad.addEventListener(keypadEvent);
keypad.setHoldTime(3000); // 3 seconds for long press
if (detectLCD()) {
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("HELLO FROM 4L7ZS");
lcd.setCursor(0, 1);
lcd.print("4L4CR AND 4L0VE");
}
// initial states
activeRelay = 0;
txRelay = activeRelay; // <<< ensure TX follows RX at startup
rxRelay = 0;
rxScanMode = false;
txScanMode = false;
swapMode = false;
updateAntennas(); // <<< Synchronize RX/TX LEDs and logic
updateLCD(); // <<< show correct info at startup
// Initialize latches (show initial RX and TX as appropriate)
digitalWrite(latchPin1, LOW);
shiftOut(dataPin1, clockPin1, MSBFIRST, 1 << activeRelay);
digitalWrite(latchPin1, HIGH);
updateLatch2();
}
// ------------------------
// Detect LCD presence
// ------------------------
bool detectLCD() {
Wire.begin();
Wire.beginTransmission(0x27);
if (Wire.endTransmission() == 0) return true;
Wire.beginTransmission(0x3F);
if (Wire.endTransmission() == 0) return true;
return false;
}
// ------------------------
// Loop
// ------------------------
void loop() {
handleKeys();
checkPTT();
updateAntennas();
bool currentPtt = digitalRead(pttPin);
int currentRx = (rxScanMode || txScanMode) ? rxRelay : activeRelay;
int currentTx = (rxScanMode || txScanMode) ? txRelay : activeRelay;
if (currentRx != lastRxRelay || currentTx != lastTxRelay ||
currentPtt != lastPttState || rxScanMode != lastRxScanMode ||
txScanMode != lastTxScanMode || swapMode != lastSwapMode) {
updateLCD();
lastRxRelay = currentRx;
lastTxRelay = currentTx;
lastPttState = currentPtt;
lastRxScanMode = rxScanMode;
lastTxScanMode = txScanMode;
lastSwapMode = swapMode;
}
}
// ------------------------
// Blink TX indicator only (second shift register)
// ------------------------
void blinkTxIndicator(int antenna) {
for (int i = 0; i < 2; i++) {
// LED ON
digitalWrite(latchPin2, LOW);
shiftOut(dataPin2, clockPin2, MSBFIRST, 1 << antenna);
digitalWrite(latchPin2, HIGH);
delay(300);
// LED OFF
digitalWrite(latchPin2, LOW);
shiftOut(dataPin2, clockPin2, MSBFIRST, 0);
digitalWrite(latchPin2, HIGH);
delay(300);
}
// Restore original TX LED
updateLatch2();
}
// ------------------------
// Handle keys
// ------------------------
// Restored inputBuffer/00 logic here to provide maxAntennas feature.
void handleKeys() {
static String inputBuffer = "";
static unsigned long zeroPressTime = 0;
static unsigned long lastStarPressTime = 0;
char key = keypad.getKey();
if (!key) {
// check timeout for 00 state
if (inputBuffer == "00" && (millis() - zeroPressTime > 2000)) {
inputBuffer = "";
updateLCD();
}
return;
}
// If in 00 wait-for-N state and a digit pressed, route it to processKey
if (inputBuffer == "00" && isDigit(key)) {
processKey(key, inputBuffer, zeroPressTime, lastStarPressTime);
return;
}
// PTT block: if PTT active, show message and block switching
if (digitalRead(pttPin) == HIGH) {
if (key && detectLCD()) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TX Active!");
lcd.setCursor(0, 1);
lcd.print("Switch Blocked");
delay(1000);
updateLCD();
}
return;
}
// Normal key handling
if (key >= '1' && key <= '8') {
int antenna = key - '1';
if (antenna >= 0 && antenna < maxAntennas) {
if (rxScanMode || txScanMode) setScanAntenna(antenna);
else setActiveAntenna(antenna);
}
// pressing a numeral resets any '00' partial buffer (defensive)
if (inputBuffer == "0") inputBuffer = "";
return;
} else {
processKey(key, inputBuffer, zeroPressTime, lastStarPressTime);
}
}
// ------------------------
// Process keys (including 00 -> maxAntennas)
// ------------------------
void processKey(char key, String &inputBuffer, unsigned long &zeroPressTime, unsigned long &lastStarPressTime) {
// Handle 0 and 00 logic for setting maxAntennas
if (key == '0') {
if (inputBuffer == "") {
inputBuffer = "0";
} else if (inputBuffer == "0") {
inputBuffer = "00";
zeroPressTime = millis();
if (detectLCD()) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("00 code entered");
lcd.setCursor(0, 1);
lcd.print("Wait for N (1-8)");
}
}
return;
}
// If waiting for antenna count after 00
if (inputBuffer == "00" && isDigit(key)) {
int newMax = key - '0';
if (newMax >= 1 && newMax <= 8) {
maxAntennas = newMax;
updateMaxAntLed();
if (detectLCD()) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Max antennas set");
lcd.setCursor(0, 1);
lcd.print("Now: ");
lcd.print(maxAntennas);
delay(1000);
}
// If active/tx/rx exceed new max adjust them
if (activeRelay >= maxAntennas) activeRelay = maxAntennas - 1;
if (rxRelay >= maxAntennas) rxRelay = maxAntennas - 1;
if (txRelay >= maxAntennas) txRelay = maxAntennas - 1;
updateAntennas();
}
inputBuffer = "";
return;
}
// Cancel 00 mode if any other key pressed
if (inputBuffer == "00" && !isDigit(key)) {
inputBuffer = "";
updateLCD();
}
// Normal special key processing
if (key == '9') toggleSwapMode();
else if (key == '*') {
unsigned long now = millis();
if (now - lastStarPressTime < 500) toggleTxScanMode();
else toggleRxScanMode();
lastStarPressTime = now;
}
else if (key == '#') toggleTxScanMode();
}
// ------------------------
// Helper: find next available unblocked TX antenna starting AFTER 'start'
// returns -1 if none found
// ------------------------
int findNextAvailableFrom(int start) {
if (maxAntennas <= 0) return -1;
int idx = (start + 1) % maxAntennas;
for (int count = 0; count < maxAntennas; count++) {
if (!blockedAntennas[idx]) return idx;
idx = (idx + 1) % maxAntennas;
}
return -1;
}
// ------------------------
// Block/unblock TX antenna
// ------------------------
void toggleAntennaBlock(int antennaNumber) {
if (antennaNumber < 0 || antennaNumber >= 8) return;
blockedAntennas[antennaNumber] = !blockedAntennas[antennaNumber];
// Blink only TX LED (second shift register)
blinkTxIndicator(antennaNumber);
// If current TX is blocked, select next available TX antenna (search forward)
if (blockedAntennas[antennaNumber] && txRelay == antennaNumber) {
int next = findNextAvailableFrom(antennaNumber);
if (next >= 0) {
txRelay = next;
} else {
// no available antenna -> keep txRelay but it will be treated as blocked (updateLatch2 handles)
txRelay = -1;
}
updateLatch2();
}
// If we unblocked and txRelay was -1, try to restore
if (!blockedAntennas[antennaNumber] && txRelay == -1) {
txRelay = antennaNumber; // preferentially restore to the unblocked one
updateLatch2();
}
updateLCD();
}
// ------------------------
// Find new TX antenna (legacy, keep for compatibility)
// Attempts to find any unblocked antenna from 0..maxAntennas-1
// ------------------------
void findNewTxAntenna() {
for (int i = 0; i < maxAntennas; i++) {
if (!blockedAntennas[i]) {
txRelay = i;
updateLatch2();
return;
}
}
txRelay = 0;
updateLatch2();
}
bool canUseAsTx(int antennaNumber) {
if (antennaNumber < 0 || antennaNumber >= 8) return false;
return !blockedAntennas[antennaNumber];
}
// ------------------------
// RX/TX scan & swap
// ------------------------
void toggleRxScanMode() {
bool cameFromTxScan = false;
if (txScanMode) { rxRelay = txRelay; txScanMode = false; cameFromTxScan = true; }
rxScanMode = !rxScanMode;
digitalWrite(statusLedPin, rxScanMode ? HIGH : LOW);
if (rxScanMode) {
if (!cameFromTxScan) txRelay = activeRelay;
rxRelay = activeRelay;
swapMode = false;
digitalWrite(swapLedPin, LOW);
updateLatch2();
} else {
activeRelay = rxRelay;
swapMode = false;
digitalWrite(swapLedPin, LOW);
digitalWrite(latchPin2, LOW);
shiftOut(dataPin2, clockPin2, MSBFIRST, 0);
digitalWrite(latchPin2, HIGH);
}
updateLCD();
}
void toggleTxScanMode() {
bool cameFromRxScan = false;
if (rxScanMode) {
txRelay = rxRelay;
rxScanMode = false;
cameFromRxScan = true;
// Turn off status LED when coming from RX Scan Mode
digitalWrite(statusLedPin, LOW);
}
txScanMode = !txScanMode;
if (txScanMode) {
if (!cameFromRxScan) rxRelay = activeRelay;
txRelay = activeRelay;
// *** NEW: if the txRelay selected is blocked, choose the next available one BEFORE PTT ***
if (txRelay >= 0 && txRelay < maxAntennas && blockedAntennas[txRelay]) {
blinkTxIndicator(txRelay);
int next = findNextAvailableFrom(txRelay);
if (next >= 0) {
txRelay = next; // automatically change to next available unblocked antenna
} else {
// no unblocked antenna found - leave txRelay as-is (UI will indicate blocked)
txRelay = -1;
}
}
swapMode = false;
digitalWrite(swapLedPin, LOW);
updateLatch2();
} else {
// Exiting TX scan, keep the chosen txRelay as active selection
if (txRelay >= 0) activeRelay = txRelay;
swapMode = false;
digitalWrite(swapLedPin, LOW);
digitalWrite(latchPin2, LOW);
shiftOut(dataPin2, clockPin2, MSBFIRST, 0);
digitalWrite(latchPin2, HIGH);
}
updateLCD();
}
void toggleSwapMode() {
if (!(rxScanMode || txScanMode)) return;
if (!swapMode) {
// Attempting to enter swap
if (canUseAsTx(rxRelay) && canUseAsTx(txRelay)) {
swapMode = true;
int temp = rxRelay;
rxRelay = txRelay;
txRelay = temp;
digitalWrite(swapLedPin, HIGH);
} else {
blinkTxIndicator(txRelay >= 0 ? txRelay : 0);
if (detectLCD()) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Swap blocked!");
lcd.setCursor(0,1);
lcd.print("TX antenna blocked");
delay(1200);
updateLCD();
}
return;
}
} else {
// Exiting Swap: reverse back
swapMode = false;
int temp = rxRelay;
rxRelay = txRelay;
txRelay = temp;
digitalWrite(swapLedPin, LOW);
}
updateLatch2();
updateLCD();
}
// ------------------------
// Set scan antenna
// ------------------------
void setScanAntenna(int antennaNumber) {
if (antennaNumber < 0 || antennaNumber >= maxAntennas) return;
if (swapMode) return;
if (rxScanMode) rxRelay = antennaNumber;
else if (txScanMode) {
if (canUseAsTx(antennaNumber)) {
txRelay = antennaNumber;
updateLatch2();
} else {
// If attempting to select a blocked TX in TX scan, blink and show message.
blinkTxIndicator(antennaNumber);
if (detectLCD()) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Ant ");
lcd.print(antennaNumber + 1);
lcd.print(" TX Blocked!");
delay(1000);
updateLCD();
}
}
}
updateLCD();
}
// ------------------------
// Set active antenna (normal mode)
// ------------------------
void setActiveAntenna(int antennaNumber) {
if (antennaNumber < 0 || antennaNumber >= maxAntennas) return;
activeRelay = antennaNumber;
// ensure txRelay follows activeRelay in Normal Mode if txRelay was previously same as active
// For startup we set txRelay = activeRelay; after that user may change txRelay in scan modes.
updateLCD();
}
// ------------------------
// Check PTT
// ------------------------
void checkPTT() {
static bool lastPttState = LOW;
bool currentPttState = digitalRead(pttPin);
if (currentPttState != lastPttState) {
lastPttState = currentPttState;
updateAntennas();
}
}
// ------------------------
// Update relays LEDs
// ------------------------
void updateAntennas() {
bool pttActive = digitalRead(pttPin);
int currentRx = (rxScanMode || txScanMode) ? rxRelay : activeRelay;
int currentTx;
if (rxScanMode || txScanMode) {
// In scan modes, check if TX antenna is blocked
if (txRelay < 0) {
currentTx = currentRx; // fallback when txRelay = -1
} else if (blockedAntennas[txRelay]) {
// If blocked, use RX antenna as TX
currentTx = currentRx;
} else {
currentTx = txRelay;
}
} else {
// Normal mode - TX is only active on TX LEDs when PTT active (updateLatch2 handles visibility)
currentTx = txRelay;
}
int displayAntenna = (rxScanMode || txScanMode) ? (pttActive ? currentTx : currentRx) : activeRelay;
// Update main shift register (RX)
digitalWrite(latchPin1, LOW);
shiftOut(dataPin1, clockPin1, MSBFIRST, 1 << displayAntenna);
digitalWrite(latchPin1, HIGH);
// Update TX LEDs
updateLatch2();
digitalWrite(txScanLedPin, txScanMode ? HIGH : LOW);
}
// ------------------------
// Update second shift register (TX LEDs)
// ------------------------
void updateLatch2() {
byte latch2Pattern = 0;
bool pttActive = digitalRead(pttPin);
int currentTx = -1;
if (rxScanMode || txScanMode) {
// In scan modes, if txRelay == -1 (no available unblocked) use rxRelay as fallback
if (txRelay < 0) currentTx = rxRelay;
else currentTx = blockedAntennas[txRelay] ? rxRelay : txRelay;
} else {
// Normal Mode
if (activeRelay >= 0 && activeRelay < maxAntennas && blockedAntennas[activeRelay]) {
if (pttActive) {
// Find next available unblocked antenna for TX starting AFTER activeRelay
int next = findNextAvailableFrom(activeRelay);
if (next >= 0) currentTx = next;
else currentTx = -1;
}
// If still none found, then no TX LED will light
} else {
// RX antenna can be used for TX
if (pttActive) currentTx = activeRelay;
}
}
if (currentTx >= 0) {
latch2Pattern = 1 << currentTx;
} else {
latch2Pattern = 0;
}
digitalWrite(latchPin2, LOW);
shiftOut(dataPin2, clockPin2, MSBFIRST, latch2Pattern);
digitalWrite(latchPin2, HIGH);
}
// ------------------------
// Update LCD
// ------------------------
void updateLCD() {
if (!detectLCD()) {
// avoid calling lcd.* if no LCD — but your earlier code assumed lcd exists; keep consistent with prior behavior
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("RX:");
lcd.print(antennaNames[(rxScanMode || txScanMode) ? rxRelay : activeRelay]);
lcd.setCursor(10, 0);
lcd.print(digitalRead(pttPin) ? "TX" : (rxScanMode ? "RXScM" : (txScanMode ? "TXScM" : "RX")));
lcd.setCursor(0, 1);
lcd.print("TX:");
if ((rxScanMode || txScanMode)) {
if (txRelay >= 0 && txRelay < 8) {
lcd.print(antennaNames[txRelay]);
if (blockedAntennas[txRelay]) lcd.print("*");
} else {
// txRelay invalid -> show fallback RX as TX
lcd.print(antennaNames[(rxScanMode || txScanMode) ? rxRelay : activeRelay]);
lcd.print("*");
}
} else {
lcd.print(antennaNames[activeRelay]);
if (blockedAntennas[activeRelay]) lcd.print("*");
}
lcd.setCursor(10, 1);
lcd.print(swapMode ? "Swap" : "NoSwaP");
}
void updateMaxAntLed() {
digitalWrite(MaxAntLedPin, maxAntennas < 8 ? HIGH : LOW);
}PTT
TX
RX-TX
RX Scan Mode (*)
SWAP
Antenna-1
Antenna-2
Antenna-3
Antenna-4
Antenna-5
Antenna-6
Antenna-7
Antenna-8
1
1
TX Scan Mode (**)
0
BLK
RTS
SWP