Это старая версия документа!
CODE
#include <SPI.h> #include <Ethernet.h> #include <EthernetUdp.h> #include <Wire.h> #include <LiquidCrystal_I2C.h>
/* ================= НАСТРОЙКИ ================= */
LiquidCrystal_I2C lcd(0x27, 16, 2);
Ethernet byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 0, 240); IP декодера unsigned int localPort = 12060;
CAT timeout const unsigned long CAT_TIMEOUT = 7000; Энкодер (проверенные пины) const int ENC_A = 10; const int ENC_B = 3; const int ENC_BTN = 2;
Реле const int RELAYS[] = {4, 5, 6, 7, 8, 9}; const int RELAY_COUNT = sizeof(RELAYS) / sizeof(int); /* ================= СОСТОЯНИЯ ================= */ enum Mode { AUTO, MANUAL }; Mode mode = AUTO; Причины MANUAL bool manualForced = false; пользователь bool autoFallback = false; потеря CAT
EthernetUDP Udp;
unsigned long lastCatTime = 0; bool catActive = false;
long lastFreq = 0; int currentBand = -1; int manualBandIndex = 0;
/* ================= ДИАПАЗОНЫ ================= */
struct Band {
const char* name; long from; long to;
};
Band bands[] = {
{"160M", 1800000, 2000000},
{"80M", 3500000, 3800000},
{"40M", 7000000, 7350000},
{"20M", 14000000, 14350000},
{"15M", 21000000, 21450000},
{"10M", 28000000, 29700000}
};
const int BAND_COUNT = sizeof(bands) / sizeof(Band);
/* ================= СЛУЖЕБНЫЕ ================= */
int detectBand(long freq) {
for (int i = 0; i < BAND_COUNT; i++) {
if (freq >= bands[i].from && freq <= bands[i].to)
return i;
}
return -1;
}
void setRelays(int bandIndex) {
for (int i = 0; i < RELAY_COUNT; i++) digitalWrite(RELAYS[i], (i == bandIndex) ? HIGH : LOW);
if (bandIndex < 0)
for (int i = 0; i < RELAY_COUNT; i++)
digitalWrite(RELAYS[i], LOW);
}
Формат: 7.165.7 void printFreqCompact(long f) { int MHz = f / 1000000; int kHz = (f / 1000) % 1000; int hundred = (f / 100) % 10; lcd.print(MHz); lcd.print(«.»); if (kHz < 100) lcd.print(«0»); if (kHz < 10) lcd.print(«0»); lcd.print(kHz); lcd.print(«.»); lcd.print(hundred); } /* ================= ЭКРАН ================= */ void drawScreen() { lcd.clear(); lcd.setCursor(0, 0); lcd.print(«IP:»); lcd.print(ip); lcd.setCursor(0, 1); if (mode == AUTO) { lcd.print(«AUTO:»); if (currentBand >= 0) lcd.print(bands[currentBand].name); else lcd.print(«–»); lcd.print(« »); if (catActive) printFreqCompact(lastFreq); else lcd.print(«NO CAT»); } else { lcd.print(«MANUAL:»); lcd.print(bands[manualBandIndex].name); } } /* ================= СТАРТ ================= */ void splashScreen() { lcd.clear(); lcd.setCursor(0, 0); lcd.print(«EW8ZO ver 0.33»); lcd.setCursor(0, 1); lcd.print(«Band Decoder»); delay(2000); } /* ================= UDP ================= */ void readUDP() { int packetSize = Udp.parsePacket(); if (!packetSize) return; char buf[400]; int len = Udp.read(buf, sizeof(buf) - 1); if (len ⇐ 0) return; buf[len] = 0; char* f = strstr(buf, «<Freq>»); if (!f) return; f += 6; lastFreq = atol(f) * 10; int b = detectBand(lastFreq); if (b >= 0) currentBand = b; catActive = true; lastCatTime = millis(); 🔁 возврат из auto-fallback
if (mode == MANUAL && autoFallback) {
mode = AUTO;
autoFallback = false;
manualForced = false;
}
if (mode == AUTO) setRelays(currentBand); drawScreen();
}
/* ================= КНОПКА ================= */
void handleButton() {
static unsigned long pressTime = 0; static bool pressed = false;
if (!digitalRead(ENC_BTN)) {
if (!pressed) {
pressed = true;
pressTime = millis();
}
} else {
if (pressed && millis() - pressTime > 800) {
if (mode == AUTO) {
mode = MANUAL;
manualForced = true;
autoFallback = false;
setRelays(-1);
} else {
mode = AUTO;
manualForced = false;
autoFallback = false;
setRelays(currentBand);
}
drawScreen();
}
pressed = false;
}
}
/* ================= ЭНКОДЕР ================= */
void handleEncoder() {
static int lastA = HIGH; int A = digitalRead(ENC_A);
if (A != lastA && A == LOW && mode == MANUAL) {
if (digitalRead(ENC_B))
manualBandIndex = (manualBandIndex + 1) % BAND_COUNT;
else
manualBandIndex = (manualBandIndex - 1 + BAND_COUNT) % BAND_COUNT;
drawScreen(); } lastA = A;
}
/* ================= TIMEOUT ================= */
void checkCatTimeout() {
if (mode != AUTO) return;
if (catActive && millis() - lastCatTime > CAT_TIMEOUT) {
catActive = false;
mode = MANUAL;
autoFallback = true;
manualForced = false;
manualBandIndex = (currentBand >= 0) ? currentBand : 0;
setRelays(-1);
drawScreen();
}
}
/* ================= SETUP ================= */
void setup() {
pinMode(ENC_A, INPUT_PULLUP); pinMode(ENC_B, INPUT_PULLUP); pinMode(ENC_BTN, INPUT_PULLUP);
for (int i = 0; i < RELAY_COUNT; i++) pinMode(RELAYS[i], OUTPUT);
setRelays(-1);
lcd.begin(); lcd.backlight(); splashScreen();
Ethernet.begin(mac, ip); Udp.begin(localPort);
drawScreen();
}
/* ================= LOOP ================= */
void loop() {
readUDP(); handleEncoder(); handleButton(); checkCatTimeout();
}
