/*
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) NEW: Long press (3 seconds) on antenna keys 1-8 blocks that antenna from TX use.
9) დაემატა გარე EEPROM
ავტორები: 4L7ZS, 4L4CR და 4L0VE.
--------------------------------
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
-----------------------------
*/
/* Full antenna switch sketch — uses external I2C EEPROM (24LCxxx on A4/A5)
Authors: 4L7ZS, 4L4CR, 4L0VE
Notes: external EEPROM address assumed 0x50 (A0/A1/A2 = GND)
*/
#include <Wire.h>
#include <AT24C02.h> // External I2C EEPROM library
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
// ---------------- I2C devices ----------------
LiquidCrystal_I2C lcd(0x27, 16, 2);
AT24C02 extEeprom(0x50); // external EEPROM at address 0x50
// Shift register pins - using constexpr
constexpr int latchPin1 = 6;
constexpr int clockPin1 = 7;
constexpr int dataPin1 = 8;
constexpr int latchPin2 = 9;
constexpr int clockPin2 = 10;
constexpr int dataPin2 = 11;
constexpr int modeLedPin = 13; // renamed
constexpr int swapLedPin = 12;
constexpr int pttPin = 2;
// Timing constants
constexpr unsigned long LONG_PRESS_TIME = 3000UL;
constexpr unsigned long BLINK_DURATION = 1200UL;
constexpr unsigned long BLINK_INTERVAL = 300UL;
// EEPROM memory map (external EEPROM addresses)
constexpr uint16_t EE_MAX_ANTENNAS = 0x0000;
constexpr uint16_t EE_BLOCKED_MASK = 0x0001; // 1 byte
constexpr uint16_t EE_ACTIVE_RELAY = 0x0002;
constexpr uint16_t EE_TX_RELAY = 0x0003;
constexpr uint16_t EE_RX_RELAY = 0x0004;
constexpr uint16_t EE_SIGNATURE = 0x000A; // mark validity
// State variables
int activeRelay = 0;
int txRelay = 0;
int rxRelay = 0;
bool rxScanMode = false;
bool txScanMode = false;
bool swapMode = false;
int maxAntennas = 8;
// blocked antennas bitmask -> use array for runtime
bool blockedAntennas[8] = {false, false, false, false, false, false, false, false};
// For tracking changes and non-blocking ops
int lastRxRelay = -1;
int lastTxRelay = -1;
bool lastPttState = false;
bool lastRxScanMode = false;
bool lastTxScanMode = false;
bool lastSwapMode = false;
// Non-blocking blink variables
bool isBlinking = false;
int blinkAntenna = -1;
unsigned long blinkStartTime = 0;
bool blinkState = false;
// LCD presence
bool lcdPresent = true;
// Antenna names
const String antennaNames[] = {
"1-Ant", "2-Ant", "3-Ant", "4-Ant",
"5-Ant", "6-Ant", "7-Ant", "8-Ant"
};
// Keypad configuration (matches your wiring)
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);
// Forward declarations
void toggleAntennaBlock(int antennaNumber);
void saveSettings();
void loadSettings();
void startBlinking(int antenna);
void handleBlinking();
void handleKeys();
void processKey(char key, String &inputBuffer, unsigned long &zeroPressTime, unsigned long &lastStarPressTime);
void updateAntennas();
void updateLatch2();
void updateLCD();
void findNewTxAntenna();
bool canUseAsTx(int antennaNumber);
void toggleRxScanMode();
void toggleTxScanMode();
void toggleSwapMode();
void setScanAntenna(int antennaNumber);
void setActiveAntenna(int antennaNumber);
bool detectLCD();
// Keypad event handler for HOLD (long press)
void keypadEvent(KeypadEvent key) {
switch (keypad.getState()) {
case HOLD:
if (key >= '1' && key <= '8') {
int antenna = key - '1'; // 0..7
if (antenna >= 0 && antenna < 8) {
toggleAntennaBlock(antenna);
}
}
break;
default:
break;
}
}
void setup() {
Serial.begin(115200);
Wire.begin(); // I2C for LCD and EEPROM
pinMode(latchPin1, OUTPUT);
pinMode(clockPin1, OUTPUT);
pinMode(dataPin1, OUTPUT);
pinMode(latchPin2, OUTPUT);
pinMode(clockPin2, OUTPUT);
pinMode(dataPin2, OUTPUT);
pinMode(pttPin, INPUT);
pinMode(modeLedPin, OUTPUT);
pinMode(swapLedPin, OUTPUT);
digitalWrite(latchPin1, LOW);
digitalWrite(clockPin1, LOW);
digitalWrite(dataPin1, LOW);
digitalWrite(latchPin2, LOW);
digitalWrite(clockPin2, LOW);
digitalWrite(dataPin2, LOW);
// configure keypad
keypad.addEventListener(keypadEvent);
keypad.setHoldTime(LONG_PRESS_TIME); // milliseconds
keypad.setDebounceTime(50);
// initialize external EEPROM object (if library needs it, already done on declaration)
// load settings from external EEPROM (if present)
loadSettings();
// detect LCD
lcdPresent = detectLCD();
if (lcdPresent) {
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("HELLO FROM 4L7ZS");
lcd.setCursor(0,1);
lcd.print("4L4CR AND 4L0VE");
}
// ensure modes reset at boot
rxScanMode = false;
txScanMode = false;
swapMode = false;
// Initialize outputs according to loaded settings
digitalWrite(latchPin1, LOW);
shiftOut(dataPin1, clockPin1, MSBFIRST, 1 << activeRelay);
digitalWrite(latchPin1, HIGH);
digitalWrite(latchPin2, LOW);
shiftOut(dataPin2, clockPin2, MSBFIRST, 1 << txRelay);
digitalWrite(latchPin2, HIGH);
digitalWrite(modeLedPin, LOW);
digitalWrite(swapLedPin, LOW);
if (lcdPresent) updateLCD();
}
// detect presence of common I2C LCD addresses
bool detectLCD() {
Wire.beginTransmission(0x27);
if (Wire.endTransmission() == 0) return true;
Wire.beginTransmission(0x3F);
if (Wire.endTransmission() == 0) return true;
return false;
}
void loop() {
handleBlinking(); // non-blocking blink state machine
handleKeys();
checkPTT:; // label protection removed (typo prevention)
// handle PTT change inside checkPTT() below
checkPTT();
updateAntennas();
// update LCD when state changes
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) {
if (lcdPresent) updateLCD();
lastRxRelay = currentRx;
lastTxRelay = currentTx;
lastPttState = currentPtt;
lastRxScanMode = rxScanMode;
lastTxScanMode = txScanMode;
lastSwapMode = swapMode;
}
}
// ---------- Non-blocking blinking ----------
void handleBlinking() {
if (!isBlinking) return;
unsigned long now = millis();
unsigned long elapsed = now - blinkStartTime;
if (elapsed >= BLINK_DURATION) {
isBlinking = false;
updateAntennas(); // restore normal display
return;
}
bool newState = ((elapsed / BLINK_INTERVAL) % 2) == 0;
if (newState != blinkState) {
blinkState = newState;
if (blinkState) {
digitalWrite(latchPin1, LOW);
shiftOut(dataPin1, clockPin1, MSBFIRST, 1 << blinkAntenna);
digitalWrite(latchPin1, HIGH);
} else {
digitalWrite(latchPin1, LOW);
shiftOut(dataPin1, clockPin1, MSBFIRST, 0);
digitalWrite(latchPin1, HIGH);
}
}
}
void startBlinking(int antenna) {
blinkAntenna = antenna;
blinkStartTime = millis();
blinkState = false;
isBlinking = true;
}
// ---------- Key handling ----------
void handleKeys() {
static String inputBuffer = "";
static unsigned long zeroPressTime = 0;
static unsigned long lastStarPressTime = 0;
char key = keypad.getKey();
// If PTT is active, block switching and show message
if (digitalRead(pttPin) == HIGH) {
if (key && lcdPresent) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("TX Active!");
lcd.setCursor(0,1);
lcd.print("Switch Blocked");
delay(700);
updateLCD();
}
return;
}
if (key) {
if (key >= '1' && key <= '8') {
int antenna = key - '1'; // 0..7
if (antenna >= 0 && antenna < maxAntennas) {
if (rxScanMode || txScanMode) {
setScanAntenna(antenna);
} else {
setActiveAntenna(antenna);
}
saveSettings(); // persist change
}
} else {
processKey(key, inputBuffer, zeroPressTime, lastStarPressTime);
}
}
// 00N timeout handling
if (inputBuffer.startsWith("00") && inputBuffer.length() == 2) {
if (millis() - zeroPressTime > 2000) {
inputBuffer = "";
if (lcdPresent) updateLCD();
}
}
}
void processKey(char key, String &inputBuffer, unsigned long &zeroPressTime, unsigned long &lastStarPressTime) {
if (key == '0') {
if (inputBuffer.length() < 2) {
inputBuffer += '0';
if (inputBuffer.length() == 2) zeroPressTime = millis();
}
return;
}
else if (inputBuffer.startsWith("00") && inputBuffer.length() == 2 && isDigit(key)) {
int newMax = key - '0';
if (newMax >= 1 && newMax <= 8) {
maxAntennas = newMax;
if (lcdPresent) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Max Antennas:");
lcd.setCursor(0,1);
lcd.print("Now set to ");
lcd.print(maxAntennas);
delay(800);
}
if (activeRelay >= maxAntennas) activeRelay = maxAntennas - 1;
if (rxRelay >= maxAntennas) rxRelay = maxAntennas - 1;
if (txRelay >= maxAntennas) txRelay = maxAntennas - 1;
updateAntennas();
saveSettings();
}
inputBuffer = "";
if (lcdPresent) updateLCD();
return;
}
else {
inputBuffer = "";
}
if (key == '9') toggleSwapMode();
else if (key == '*') {
unsigned long now = millis();
if (now - lastStarPressTime < 500) {
toggleTxScanMode();
lastStarPressTime = 0;
} else {
toggleRxScanMode();
lastStarPressTime = now;
}
}
else if (key == '#') toggleTxScanMode();
}
// ---------- Block/unblock antenna ----------
void toggleAntennaBlock(int antennaNumber) {
if (antennaNumber < 0 || antennaNumber >= 8) return;
blockedAntennas[antennaNumber] = !blockedAntennas[antennaNumber];
if (lcdPresent) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Ant ");
lcd.print(antennaNumber + 1);
lcd.print(" TX ");
lcd.print(blockedAntennas[antennaNumber] ? "BLOCKED" : "UNBLOCKED");
delay(700);
}
startBlinking(antennaNumber);
if (lcdPresent) updateLCD();
if (blockedAntennas[antennaNumber] && txRelay == antennaNumber) {
findNewTxAntenna();
}
saveSettings();
}
// ---------- Swap mode ----------
void toggleSwapMode() {
if (!(rxScanMode || txScanMode)) return;
swapMode = !swapMode;
// swap rx/tx
int temp = rxRelay;
rxRelay = txRelay;
txRelay = temp;
digitalWrite(swapLedPin, swapMode ? HIGH : LOW);
updateLatch2();
if (lcdPresent) updateLCD();
saveSettings();
}
// ---------- LCD update (optimized) ----------
void updateLCD() {
if (!lcdPresent) return;
static int lastDisplayRx = -1;
static int lastDisplayTx = -1;
static bool lastDisplayPtt = false;
static bool lastDisplaySwap = false;
int currentRx = (rxScanMode || txScanMode) ? rxRelay : activeRelay;
int currentTx = (rxScanMode || txScanMode) ? txRelay : activeRelay;
bool currentPtt = digitalRead(pttPin);
if (lastDisplayRx != currentRx || lastDisplayTx != currentTx ||
lastDisplayPtt != currentPtt || lastDisplaySwap != swapMode) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("RX:");
lcd.print(antennaNames[currentRx]);
lcd.setCursor(10,0);
if (currentPtt) {
if (rxScanMode) lcd.print("TX_Sc");
else if (txScanMode) lcd.print("TXScM");
else lcd.print("TX");
} else {
if (rxScanMode) lcd.print("RXScM");
else if (txScanMode) lcd.print("TXScM");
else lcd.print("RX");
}
lcd.setCursor(0,1);
lcd.print("TX:");
lcd.print(antennaNames[currentTx]);
if (blockedAntennas[currentTx]) lcd.print("*");
lcd.setCursor(10,1);
lcd.print(swapMode ? "Swap" : "NoSwaP");
lastDisplayRx = currentRx;
lastDisplayTx = currentTx;
lastDisplayPtt = currentPtt;
lastDisplaySwap = swapMode;
}
}
// ---------- Helpers and mode toggles ----------
void findNewTxAntenna() {
for (int i = 0; i < maxAntennas; ++i) {
if (!blockedAntennas[i]) {
txRelay = i;
updateLatch2();
saveSettings();
return;
}
}
txRelay = 0;
updateLatch2();
saveSettings();
}
bool canUseAsTx(int antennaNumber) {
return !blockedAntennas[antennaNumber];
}
void toggleRxScanMode() {
bool cameFromTxScan = false;
if (txScanMode) {
rxRelay = txRelay;
txScanMode = false;
cameFromTxScan = true;
}
rxScanMode = !rxScanMode;
digitalWrite(modeLedPin, 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);
}
if (lcdPresent) updateLCD();
saveSettings();
}
void toggleTxScanMode() {
bool cameFromRxScan = false;
if (rxScanMode) {
txRelay = rxRelay;
rxScanMode = false;
cameFromRxScan = true;
}
txScanMode = !txScanMode;
digitalWrite(modeLedPin, txScanMode ? HIGH : LOW);
if (txScanMode) {
if (!cameFromRxScan) {
rxRelay = activeRelay;
txRelay = activeRelay;
}
swapMode = false;
digitalWrite(swapLedPin, LOW);
updateLatch2();
} else {
activeRelay = txRelay;
swapMode = false;
digitalWrite(swapLedPin, LOW);
digitalWrite(latchPin2, LOW);
shiftOut(dataPin2, clockPin2, MSBFIRST, 0);
digitalWrite(latchPin2, HIGH);
}
if (lcdPresent) updateLCD();
saveSettings();
}
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 (lcdPresent) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Ant ");
lcd.print(antennaNumber + 1);
lcd.print(" TX Blocked!");
delay(800);
updateLCD();
}
}
if (lcdPresent) updateLCD();
saveSettings();
}
void setActiveAntenna(int antennaNumber) {
if (antennaNumber < 0 || antennaNumber >= maxAntennas) return;
activeRelay = antennaNumber;
if (lcdPresent) updateLCD();
saveSettings();
}
void checkPTT() {
static bool lastState = LOW;
bool current = digitalRead(pttPin);
if (current != lastState) {
lastState = current;
updateAntennas();
}
}
void updateAntennas() {
if (isBlinking) return; // don't override blinking
if (rxScanMode || txScanMode) {
bool pttActive = digitalRead(pttPin);
int activeAntenna = pttActive ? txRelay : rxRelay;
digitalWrite(latchPin1, LOW);
shiftOut(dataPin1, clockPin1, MSBFIRST, 1 << activeAntenna);
digitalWrite(latchPin1, HIGH);
updateLatch2();
} else {
digitalWrite(latchPin1, LOW);
shiftOut(dataPin1, clockPin1, MSBFIRST, 1 << activeRelay);
digitalWrite(latchPin1, HIGH);
}
}
void updateLatch2() {
digitalWrite(latchPin2, LOW);
shiftOut(dataPin2, clockPin2, MSBFIRST, 1 << txRelay);
digitalWrite(latchPin2, HIGH);
}
// ---------- External EEPROM save/load ----------
void saveSettings() {
// write bytes to ext EEPROM (AT24C02)
extEeprom.write(EE_MAX_ANTENNAS, (uint8_t)maxAntennas);
// blocked mask
uint8_t blockedMask = 0;
for (int i = 0; i < 8; ++i) if (blockedAntennas[i]) blockedMask |= (1 << i);
extEeprom.write(EE_BLOCKED_MASK, blockedMask);
extEeprom.write(EE_ACTIVE_RELAY, (uint8_t)activeRelay);
extEeprom.write(EE_TX_RELAY, (uint8_t)txRelay);
extEeprom.write(EE_RX_RELAY, (uint8_t)rxRelay);
extEeprom.write(EE_SIGNATURE, 0x55); // mark valid
}
void loadSettings() {
// check signature
uint8_t sig = extEeprom.read(EE_SIGNATURE);
if (sig == 0x55) {
maxAntennas = extEeprom.read(EE_MAX_ANTENNAS);
if (maxAntennas < 1 || maxAntennas > 8) maxAntennas = 8;
uint8_t blockedMask = extEeprom.read(EE_BLOCKED_MASK);
for (int i = 0; i < 8; ++i) blockedAntennas[i] = (blockedMask & (1 << i)) != 0;
activeRelay = extEeprom.read(EE_ACTIVE_RELAY);
txRelay = extEeprom.read(EE_TX_RELAY);
rxRelay = extEeprom.read(EE_RX_RELAY);
if (activeRelay < 0 || activeRelay >= maxAntennas) activeRelay = 0;
if (txRelay < 0 || txRelay >= maxAntennas) txRelay = 0;
if (rxRelay < 0 || rxRelay >= maxAntennas) rxRelay = 0;
} else {
// defaults
maxAntennas = 8;
activeRelay = 0;
txRelay = 0;
rxRelay = 0;
for (int i = 0; i < 8; ++i) blockedAntennas[i] = false;
}
}
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