#include <Wire.h>
#include <LiquidCrystal.h>
#include "Rotary.h"
#include <si5351.h>
#include <EEPROM.h>
// Регистры управления 595
//#define BPF_CLK 13
//#define BPF_DATA 11
//#define BPF_LATCH 10
// Подключение модуля синтезатора
//#define W_CLK 13
//#define FQ_UD 12
//#define DATA 11
// Раскомментарить для настройки кейпада
//#define Keypad_ADC
// Раскомментарить для включения CAT
#define CAT_SPEED 19200
//Раскомментировать если требуется сброс EEPROM
#define INIT_EEPROM
// Подключение дешифратора диапазонов К561ИД1 ( CD4028 )
#define BPF_D0 A2
#define BPF_D1 A1
#define BPF_D2 A0
#define BPF_D3 13
//Управление ATT / Preamp
#define ATT 11
#define PRE 12
// Коррекция расчета частоты si5351 для записи в EEPROM при инициализации
#define SI5351_INITIAL_CORR 0
// Подберите емкость из 0PF 6PF 8PF при коррекции = 0 для получения
// частоты синтезатора равной или чуть больше, чем на экране.
// Затем коррекцией подгоните до нужной (при увеличении коррекции уменьшается частота на выходе)
#define SI5351_CRYSTAL_LOAD0 SI5351_CRYSTAL_LOAD_6PF
// Здесь введите частоту вашего кварца на si5351
#define SI5351_CRYSTAL_FREQ 27000000
// Ток выходов si5351
// основной
#define SI5351_DRIVE_CLK0 SI5351_DRIVE_8MA
// опорник 1й ПЧ
#define SI5351_DRIVE_CLK2 SI5351_DRIVE_2MA
// Показание на ЖКИ плюс(минус) на значение ПЧ (базовая при инициализации)
#define IFFreq 10700000
// Вторая ПЧ (оставить 0 если не нужна, определяет вместе с IFFreq частоту опорника 1й ПЧ, можно - и +)
#define IFFreq2 455000
// Вкл/выкл генерации опорного гетеродина 1й ПЧ на втором выходе si5351 (закомментарить если не нужено)
#define IFFreqSIOut
// Общая частота изменения преобразования вверх/вниз (внутри диапазонов индивидуальные настройки)
// Логика работы с ПЧ описана в функции sendFrequency()
#define IFUpDn 13880000
// Блокировка выхода за границы диапазонов, не работает вроде :)
//#define LockInBand
// Управление TX/RX (активный LOW - TX)
#define TXRX 4
// Клавиатура, S- метр, P- метр.
#define KEYPAD A3
#define SMETER A6
#define PMETER A7
#define MAXFREQ 1590000000
#define MINFREQ 1000000
#define MAXIFFREQ 11000000
#define MINIFFREQ 8000000
#define TIME_DISPLAY_RATE 1500
#define SMETER_1 80
#define SMETER_2 120
#define SMETER_3 160
#define SMETER_4 200
#define SMETER_5 240
#define SMETER_6 280
#define SMETER_7 320
#define SMETER_8 360
#define SMETER_9 400
#define SMETER_9_10 440
#define SMETER_9_20 480
#define SMETER_9_30 520
#define PMETER_1 80
#define PMETER_2 120
#define PMETER_3 160
#define PMETER_4 200
#define PMETER_5 240
#define PMETER_6 280
#define PMETER_7 320
#define PMETER_8 360
#define PMETER_9 400
#define PMETER_10 440
#define PMETER_11 480
#define PMETER_12 520
#define BAND_MAX 9 //Число диапазонов для обработки
// Границы диапазонов
// 160-метровый (1,81 - 2 МГц)
#define BAND_01_LOW 144000000 //Нижняя граница диапазона
#define BAND_01_HIGH 145000000 //Верхняя граница диапазона
#define BAND_01_NUM 1 //Номер диапазона (для вычисления ячеек EEPROM)
#define BAND_01_EN true //Диапазон включен (если false - будет игнорироваться)
#define BAND_01_DSSB 0 //Верхняя / нижняя боковая по умолчанию (пока не используется)
#define BAND_01_INV -1 //-1 (онимает ПЧ) 1 (прибавляет)Инверсия боковой (пока не используется)
#define BAND_01_NAME "2 m" //Название диапазона
// 80-метровый (3,5 - 3,8 МГц)
#define BAND_02_LOW 145000001
#define BAND_02_HIGH 146000000
#define BAND_02_NUM 2
#define BAND_02_EN true
#define BAND_02_DSSB 0
#define BAND_02_INV -1
#define BAND_02_NAME "2 m" //Название диапазона
// 40-метровый (7 - 7,2 МГц)
#define BAND_03_LOW 146005000
#define BAND_03_HIGH 147000000
#define BAND_03_NUM 3
#define BAND_03_EN true
#define BAND_03_DSSB 0
#define BAND_03_INV -1
#define BAND_03_NAME "2 m" //Название диапазона
// 30-метровый (только телеграф 10,1 - 10,15 МГц)
#define BAND_04_LOW 147005000
#define BAND_04_HIGH 148000000
#define BAND_04_NUM 4
#define BAND_04_EN true
#define BAND_04_DSSB 0
#define BAND_04_INV -1
#define BAND_04_NAME "2 m" //Название диапазона
// 20-метровый (14 - 14,35 МГц)
#define BAND_05_LOW 148005000
#define BAND_05_HIGH 148050000
#define BAND_05_NUM 5
#define BAND_05_EN true
#define BAND_05_DSSB 0
#define BAND_05_INV -1
#define BAND_05_NAME "MVD" //Название диапазона
// 16-метровый (18,068 - 18,168 МГц)
#define BAND_06_LOW 148051000
#define BAND_06_HIGH 148175000
#define BAND_06_NUM 6
#define BAND_06_EN true
#define BAND_06_DSSB 0
#define BAND_06_INV -1
#define BAND_06_NAME "MVD" //Название диапазона
// 15-метровый (21 - 21,45 МГц)
#define BAND_07_LOW 148185000
#define BAND_07_HIGH 148375000
#define BAND_07_NUM 7
#define BAND_07_EN true
#define BAND_07_DSSB 0
#define BAND_07_INV -1
#define BAND_07_NAME "ITK" //Название диапазона
// 12-метровый (24,89 - 25,14 МГц)
#define BAND_08_LOW 148376000
#define BAND_08_HIGH 148875000
#define BAND_08_NUM 8
#define BAND_08_EN true
#define BAND_08_DSSB 0
#define BAND_08_INV -1
#define BAND_08_NAME "MCS" //Название диапазона
// 10-метровый (28 - 29,7 МГц)
#define BAND_09_LOW 148876000
#define BAND_09_HIGH 174000000
#define BAND_09_NUM 9
#define BAND_09_EN true
#define BAND_09_DSSB 0
#define BAND_09_INV -1
#define BAND_09_NAME "RZD" //Название диапазона
// Границы диапазонов для коммутации ДПФ
#define BAND_BPF_01_LOW 144000000 //Нижняя граница диапазона
#define BAND_BPF_01_HIGH 145000000 //Верхняя граница диапазона
#define BAND_BPF_01_CODE 0b000000000 //Код для управления ДПФ
#define BAND_BPF_02_LOW 145000001
#define BAND_BPF_02_HIGH 146000000
#define BAND_BPF_02_CODE 0b00001000
#define BAND_BPF_03_LOW 146000001
#define BAND_BPF_03_HIGH 148000000
#define BAND_BPF_03_CODE 0b00000100
#define BAND_BPF_04_LOW 148000001
#define BAND_BPF_04_HIGH 151000000
#define BAND_BPF_04_CODE 0b000001100
#define BAND_BPF_05_LOW 151000001
#define BAND_BPF_05_HIGH 155000000
#define BAND_BPF_05_CODE 0b000000010
#define BAND_BPF_06_LOW 155000001
#define BAND_BPF_06_HIGH 164000000
#define BAND_BPF_06_CODE 0b000001010
#define BAND_BPF_07_LOW 164000001
#define BAND_BPF_07_HIGH 170000000
#define BAND_BPF_07_CODE 0b000000110
#define BAND_BPF_08_LOW 170000001
#define BAND_BPF_08_HIGH 171000000
#define BAND_BPF_08_CODE 0b000001110
#define BAND_BPF_09_LOW 171000001
#define BAND_BPF_09_HIGH 174000000
#define BAND_BPF_09_CODE 0b000000001
// Значения уровня с АЦП для кнопок на делителе _1 нижнее _2 верхнее
// 1я кнопка
#define BUTTON1_1 700
#define BUTTON1_2 950
// 2я кнопка
#define BUTTON2_1 500
#define BUTTON2_2 690
// 3я кнопка
#define BUTTON3_1 310
#define BUTTON3_2 490
// 4я кнопка
#define BUTTON4_1 160
#define BUTTON4_2 240
// 5я кнопка
#define BUTTON5_1 80
#define BUTTON5_2 140
// 6я кнопка
#define BUTTON6_1 0
#define BUTTON6_2 30
#define pulseHigh(pin) { digitalWrite(pin, HIGH); delay(1); digitalWrite(pin, LOW); delay(1); }
struct Band {
int_fast8_t num;
int_fast8_t xnum;
int_fast8_t dssb;
int_fast8_t inv;
int_fast8_t nd;
int_fast8_t ld;
int_fast16_t bpf;
int_fast16_t xbpf;
int_fast32_t fhigh;
int_fast32_t flow;
char bname[4];
};
Band band = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, " "};
struct Mode {
// int_fast8_t mode;
// int_fast8_t cw_dir_freq;
// int_fast8_t inv;
unsigned int code;
String modename;
};
//Биты управления режимами через внешний регистр
Mode mode_m[4] = {0xFF, "", 0b0000000000000000, "USB", 0b1000000000000000, "LSB", 0xFF, ""};
Rotary r = Rotary(2,3); // sets the pins the rotary encoder uses. Must be interrupt pins.
//Подключаем энкодер к 2 и 3 ножкам
LiquidCrystal lcd(5, 6, 7, 8, 9, 10); // I used an odd pin combination because I need pin 2 and 3 for the interrupts.
//Подключаем 1602 дисплей к соответствующим пинам, указываем номера портов в порядке RS, E, DB4, DB5, DB6, DB7
int_fast32_t rx = 10000000; // Base (starting) frequency of VFO. This only loads once. To force load again see ForceFreq variable below.
int_fast32_t si5351_corr = SI5351_INITIAL_CORR; // Base correction for si5351 chip.
int_fast32_t xsi5351_corr = 1;
int_fast32_t rx2 = 1; // variable to hold the updated frequency
// Переменная для хранения новой частоты
int_fast32_t increment = 1000; // starting VFO update increment in HZ.
// Установка шага на один щелчек энкодера при запуске.
int_fast32_t iffreq = IFFreq; // variable to hold the updated frequency
int_fast32_t xiffreq = 1;
int_fast16_t buttonstate = 0; // Значение АЦП кейпада
int_fast16_t obuttonstate = 0; // Предыдущее значение АЦП кейпада
int_fast16_t smeter = 0; // Значение АЦП S-метра
int_fast16_t pmeter = 0; // Значение АЦП P-метра
int_fast16_t xbuttonstate[7] = { 0,0,0,0,0,0,0 }; //Массив предыдущих стостояний кнопок
int_fast8_t mode = 1; // Текущий режим
int_fast8_t xmode = 0; // Предыдущий режим
int_fast8_t tx_mode = 0; // Текущий режим TX/RX
int_fast8_t xtx_mode = 0; // Предыдущий режим TX/RX
int_fast8_t att_preamp = 0; // Att / Preamp побитно
int_fast8_t com_mode = 0; // Общий режим работы устройства
// 0 - управление основной частотой
// 1 - управление ПЧ
// 2 - управление коррекцией si5351
//int_fast16_t GoIF = 1; // Состояние вычета ПЧ
//int_fast16_t xGoIF = 0; // Старое состояние вычета ПЧ
String hertz = "100 Hz"; //Нужно для установки шага энкодера, при необходимости раскомментировать.
int hertzPosition = 5;
byte ones,tens,hundreds,thousands,tenthousands,hundredthousands,millions ; //Десятичные разряды представления частоты (для EEPROM)
String freq; // string to hold the frequency
//Строка для хранения частоты
String smtr; // string to hold the s-meter value
//Строка для хранения значения S-метра
String xsmtr; // string to hold the s-meter old value
//Строка для хранения предыдущего значения S-метра
unsigned long timepassed = millis(); // int to hold the arduino miilis since startup
// Для хранения числа миллисекунд, прошедших с момента запуска
unsigned long rate_timepassed = millis(); // Для хранения числа миллисекунд идникации шага частоты
int memstatus = 0; // value to notify if memory is current or old. 0=old, 1=current.
// Смотрим, в памяти значение старое или новое. 0 - Старое 1 -Новое
Si5351 si5351; // Синтезатор
byte lcd_sym_01[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111 };
byte lcd_sym_02[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111 };
byte lcd_sym_03[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111 };
byte lcd_sym_04[8] = { 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 };
byte lcd_sym_05[8] = { 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 };
byte lcd_sym_06[8] = { 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 };
byte lcd_sym_07[8] = { 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 };
// Для CAT
boolean CATTXState=0;
boolean xCATTXState=1;
#ifdef CAT_SPEED
int buffget[11];
int incoming;
byte sendDMHz=0;
byte sendMHz=0;
byte sendkHz=0;
byte sendHz=0;
int DMHZ = 0;
int MHZ = 0;
int KHZ = 0;
int HZ = 0;
//int slowo=0;
int CTi=0;
int bandCAT=0;
long QRG;
#endif
// быстрое деление для преобразования числа в строку
void divmodu10(uint32_t n, uint32_t ", uint8_t &rem) {
quot = n >> 1;
quot += quot >> 1;
quot += quot >> 4;
quot += quot >> 8;
quot += quot >> 16;
uint32_t qq = quot;
quot >>= 3;
rem = uint8_t(n - ((quot << 1) + (qq & ~7ul)));
if(rem > 9)
{
rem -= 10;
quot++;
}
}
// быстрое преобразования числа в строку с разделителем разрядов
// , uint8_t tcnt
char * utoa_fast_div(uint32_t value, char *buffer, uint8_t tcnt) {
uint8_t dcnt = 0;
uint32_t quot;
uint8_t rem;
uint8_t ocnt = tcnt;
buffer[--tcnt] = 0;
if (com_mode < 2) {
buffer[--tcnt] = 'z';
buffer[--tcnt] = 'H';
buffer[--tcnt] = 'k';
buffer[--tcnt] = ' ';
divmodu10(value, quot, rem);
value = quot;
} else {
buffer[--tcnt] = ' ';
buffer[--tcnt] = ' ';
buffer[--tcnt] = ' ';
buffer[--tcnt] = ' ';
}
do
{
divmodu10(value, quot, rem);
buffer[--tcnt] = rem + '0';
if ((tcnt == (ocnt - 7)) && (com_mode < 2)) buffer[--tcnt] = '.';
value = quot;
}
while ((value != 0) && (tcnt > 1));
while (tcnt > 0) {
buffer[--tcnt] = ' ';
};
tcnt = ocnt - 9;
while (tcnt > 0) {
buffer[tcnt + 3] = buffer[tcnt];
buffer[tcnt] = ' ';
tcnt--;
}
return buffer;
}
void setup() {
//Для I2C LCD
//lcd.init();
//lcd.backlight();
lcd.begin(16, 2); //Указываем сколько у нас символов и строк на дисплее.
// Спецсимволы для S/P метра
lcd.createChar(1, lcd_sym_01);
lcd.createChar(2, lcd_sym_02);
lcd.createChar(3, lcd_sym_03);
lcd.createChar(4, lcd_sym_04);
lcd.createChar(5, lcd_sym_05);
lcd.createChar(6, lcd_sym_06);
lcd.createChar(7, lcd_sym_07);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
//pinMode(FQ_UD, OUTPUT); //Выставляем вывод как цифровой выход
//pinMode(W_CLK, OUTPUT); //Выставляем вывод как цифровой выход
//pinMode(DATA, OUTPUT); //Выставляем вывод как цифровой выход
//pinMode(BPF_CLK, OUTPUT);
//pinMode(BPF_DATA, OUTPUT);
//pinMode(BPF_LATCH, OUTPUT);
pinMode(BPF_D0, OUTPUT);
pinMode(BPF_D1, OUTPUT);
pinMode(BPF_D2, OUTPUT);
pinMode(BPF_D3, OUTPUT);
pinMode(ATT, OUTPUT);
pinMode(PRE, OUTPUT);
pinMode(TXRX, INPUT);
digitalWrite(TXRX, HIGH);
Wire.begin();
// **mine. There is a calibration sketch in File/Examples/si5351Arduino
// where you can determine the correction by using the serial monitor.
// ввести калибровочное знечение в строчке si5351.set_correction(хххххххх).
// Нужно вычислить запустив "si5351calibration" в папке с примерами библиотеки si5351.
// initialize the Si5351
si5351.init(SI5351_CRYSTAL_LOAD0, SI5351_CRYSTAL_FREQ, 0);
// If you're using a 27Mhz crystal, put in 27000000 instead of 0
// 0 is the default crystal frequency of 25Mhz.
si5351.output_enable(SI5351_CLK0, 1);
si5351.output_enable(SI5351_CLK1, 0);
si5351.output_enable(SI5351_CLK2, 0);
// 2MA ~ 7dbm, 8MA ~ 14dbm
si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_CLK0);
#ifdef INIT_EEPROM
initMem();
#endif
// Load the stored frequency
//Загружаем сохраненную частоту
if (keypooler() == 6) {
initMem();
} else {
restoreMem();
decodeband(rx);
};
memstatus = 1;
si5351.set_correction(si5351_corr, SI5351_PLL_INPUT_XO);
xsi5351_corr = si5351_corr;
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
#ifdef IFFreqSIOut
si5351.drive_strength(SI5351_CLK2, SI5351_DRIVE_CLK2);
si5351.output_enable(SI5351_CLK2, 1);
//si5351.set_freq((iffreq + IFFreq2) * SI5351_FREQ_MULT, SI5351_PLL_FIXED, SI5351_CLK2);
si5351.set_freq((iffreq + ((mode_m[mode].modename=='LSB')?-1:1)*IFFreq2) * SI5351_FREQ_MULT, SI5351_PLL_FIXED, SI5351_CLK2);
xiffreq = iffreq;
#endif
#ifdef CAT_SPEED
Serial.begin(CAT_SPEED);
#endif
//pinMode(RESET, OUTPUT); //Выставляем вывод как цифровой выход
//pulseHigh(RESET);
//pulseHigh(W_CLK);
//pulseHigh(FQ_UD); // this pulse enables serial mode on the AD9850 - Datasheet page 12.
// Этот импульс необходим для последовательной шины, Datasheet страница 12.
//pinMode(KEYPAD,INPUT); // Конфигурируем порт кейпада
//pinMode(SMETER,INPUT); // Конфигурируем порт S-метра
//pinMode(PINGOIF,INPUT); // Конфигурируем вход вычета ПЧ
//digitalWrite(PINGOIF,HIGH); // Подтягиваем вход вычета ПЧ к плюсу питания
//Serial.begin(115200);
//lcd.setCursor(hertzPosition,1);
//lcd.print(hertz); // Начало настроек для выбора кнопки переключения шага энкодера----------------
};
void loop() {
int keypressed;
#ifdef LockInBand
// Если используется блокировка выхода за пределы диапазонов
if ((rx != rx2) && ((rx < band.flow) || (rx > band.fhigh)) && (band.nd == 0)) rx = rx2;
#endif
#ifdef CAT_SPEED
if (Serial.available() > 0){
catread();
}
#endif
// Обновляем информацию на дисплее и частоту синтезатора если она (частота) изменилась
if ((rx != rx2)||(iffreq != xiffreq)||(si5351_corr != xsi5351_corr)) {
if (si5351_corr != xsi5351_corr) {
si5351.set_correction(si5351_corr, SI5351_PLL_INPUT_XO);
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
#ifdef IFFreqSIOut
//si5351.set_freq((iffreq + IFFreq2) * SI5351_FREQ_MULT, SI5351_PLL_FIXED, SI5351_CLK2);
si5351.set_freq((iffreq + ((mode_m[mode].modename=='LSB')?-1:1) * IFFreq2) * SI5351_FREQ_MULT, SI5351_CLK2);
#endif
sendFrequency(rx);
}
//mode_m[mode].modename
#ifdef IFFreqSIOut
if (iffreq != xiffreq) {
//si5351.set_freq(iffreq + IFFreq2 * SI5351_FREQ_MULT, SI5351_PLL_FIXED, SI5351_CLK2);
si5351.set_freq(iffreq + ((mode_m[mode].modename=='LSB')?-1:1) * IFFreq2 * SI5351_FREQ_MULT, SI5351_CLK2);
sendFrequency(rx);
}
#endif
if (rx != rx2) {
decodeband(rx);
if (band.bpf != band.xbpf) {
sendReg(mode_m[mode].code + band.bpf);
band.xbpf = band.bpf;
if (band.num != band.xnum) { band.xnum = band.num; }
}
if (band.num != band.xnum) {
sendReg(mode_m[mode].code + band.bpf);
band.xnum = band.num;
}
sendFrequency(rx);
}
if (com_mode == 0) { showFrequency(rx); }
if (com_mode == 1) { showFrequency(iffreq); }
if (com_mode == 2) { showFrequency(si5351_corr); }
if ((rx2 != 1)&&(xiffreq != 1)&&(xsi5351_corr != 1)) {
memstatus = 0;
timepassed = millis() + 5000;
}
rx2 = rx;
xiffreq = iffreq;
xsi5351_corr = si5351_corr;
};
if (mode != xmode) {
sendReg(mode_m[mode].code + band.bpf);
showMode(mode);
}
#ifdef CAT_SPEED
if (CATTXState != xCATTXState) {
// lcd.setCursor(1,1);
// lcd.print(" TM1 ");
// lcd.setCursor(6,1);
// lcd.print(tx_mode, DEC); //28
// delay(1000);
if ((CATTXState == 1)&&(xCATTXState == 0)) {
tx_mode = HIGH;
showOptions();
}
// lcd.setCursor(1,1);
// lcd.print(" TM2 ");
// lcd.setCursor(6,1);
// lcd.print(tx_mode, DEC); //28
// delay(1000);
if ((CATTXState == 0)&&(xCATTXState == 1)&(xtx_mode == LOW)) {
tx_mode = LOW;
showOptions();
}
xCATTXState = CATTXState;
} else if ((CATTXState == 0)&&(xCATTXState == 0)) {
// Считываем TX / RX
// На всякий случай антидребезг
tx_mode = !digitalRead(TXRX);
if (tx_mode != xtx_mode) {
delay(10);
tx_mode = !digitalRead(TXRX);
if (tx_mode != xtx_mode) {
xtx_mode = tx_mode;
showOptions();
} else {
tx_mode = xtx_mode;
}
}
}
#else
if (tx_mode != xtx_mode) {
delay(10);
tx_mode = !digitalRead(TXRX);
if (tx_mode != xtx_mode) {
xtx_mode = tx_mode;
showOptions();
} else {
tx_mode = xtx_mode;
}
}
#endif
#ifdef Keypad_ADC
buttonstate = analogRead(KEYPAD);
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(5,1);
lcd.print(buttonstate);
delay(1000);
#endif
//Проверяем не нажата ли кнопка кейпада
keypressed = keypooler();
// Функции кнопок
switch (keypressed) {
case 0:
break;
case 1:
setAttPre();
break;
case 2:
setBand(-1);
break;
case 3:
setBand(1);
break;
case 4:
setMode();
break;
case 5:
setComMode();
break;
case 6:
setIncrement();
break;
default:
break;
}
//Преобразуем значение уровня S-метра в строку
smtr = " ";
if (tx_mode) {
pmeter = analogRead(PMETER); // Считываем значение АЦП P-метра
} else {
smeter = analogRead(SMETER); // Считываем значение АЦП S-метра
}
if (!tx_mode) {
if (smeter > SMETER_9_30)
{ smtr += "\02\02\03\03\04\04\05\06\07+30"; } else
if (smeter > SMETER_9_20)
{ smtr += "\02\02\03\03\04\04\05\06\07+20"; } else
if (smeter > SMETER_9_10)
{ smtr += "\02\02\03\03\04\04\05\06\07+10"; } else
if (smeter > SMETER_9)
{ smtr += "\02\02\03\03\04\04\05\06\07 "; } else
if (smeter > SMETER_8)
{ smtr += "\02\02\03\03\04\04\05\06 "; } else
if (smeter > SMETER_7)
{ smtr += "\02\02\03\03\04\04\05 "; } else
if (smeter > SMETER_6)
{ smtr += "\02\02\03\03\04\04 "; } else
if (smeter > SMETER_5)
{ smtr += "\02\02\03\03\04 "; } else
if (smeter > SMETER_4)
{ smtr += "\02\02\03\03 "; } else
if (smeter > SMETER_3)
{ smtr += "\02\02\03 "; } else
if (smeter > SMETER_2)
{ smtr += "\02\02 "; } else
if (smeter > SMETER_1)
{ smtr += "\02 "; } else
{ };
} else {
if (pmeter > PMETER_12)
{ smtr += "\02\02\03\03\04\04\05\05\06\06\07\07"; } else
if (pmeter > PMETER_11)
{ smtr += "\02\02\03\03\04\04\05\05\06\06\07 "; } else
if (pmeter > PMETER_10)
{ smtr += "\02\02\03\03\04\04\05\05\06\06 "; } else
if (pmeter > PMETER_9)
{ smtr += "\02\02\03\03\04\04\05\05\06 "; } else
if (pmeter > PMETER_8)
{ smtr += "\02\02\03\03\04\04\05\05 "; } else
if (pmeter > PMETER_7)
{ smtr += "\02\02\03\03\04\04\05 "; } else
if (pmeter > PMETER_6)
{ smtr += "\02\02\03\03\04\04 "; } else
if (pmeter > PMETER_5)
{ smtr += "\02\02\03\03\04 "; } else
if (pmeter > PMETER_4)
{ smtr += "\02\02\03\03 "; } else
if (pmeter > PMETER_3)
{ smtr += "\02\02\03 "; } else
if (pmeter > PMETER_2)
{ smtr += "\02\02 "; } else
if (pmeter > PMETER_1)
{ smtr += "\02 "; } else
{ };
}
while (smtr.length() < 16) { smtr += " "; };
// Показываем S/P-метр если время индикации шага перестройки вышло
if ((millis() > rate_timepassed) && (xsmtr != smtr)) { showSmeter(); };
// Записываем частоту и другие параметры в постоянную память если они не изменялись поседние 2-3 секунды
if ((memstatus == 0) && ( timepassed < millis() )) {
if (band.nd == 0) { storeMemBand(band.num); }
storeMem();
};
}
// ********************** поддержка CAT (IC 756) ********************** <
#ifdef CAT_SPEED
void catread(){
incoming = Serial.read(); delay(3);
//lcd.setCursor(1,1);
//lcd.print("CAT ");
//lcd.setCursor(5,1);
//lcd.print(incoming, DEC);
//delay(1000);
//display.print (incoming); display.display();
if (incoming == 254) {
Serial.write(incoming);
Serial.flush();
incoming=Serial.read(); //delay(3);
if (incoming == 254){
Serial.write(incoming);
Serial.flush();
//display.print(incoming); display.display();
//delay(3);
buffget[0] = 0;
CTi=0;
do{
incoming=Serial.read();
//delay(3);
Serial.write(incoming);
Serial.flush();
buffget[CTi]=incoming;
//display.print (buffget[CTi]); display.print(" ");
CTi++;
} while(incoming!=253); //dopóki nie przyjdzie FD
Serial.flush();
delay (1);
}
}
switch (CTi){
case 4:
CATpoll_in();
break;
case 5:
CATsetmode();
break;
case 6:
CATsetmode();
break;
case 9:
CATsetfreq();
break;
default:
FA();
break;
}
}
void CATpoll_in(){
if (buffget[2]==3){freq_to_send();}
if (buffget[2]==4){mode_to_send();}
}
void CATsetmode()
{
if (buffget[2]==6) poll_in_mode(); else
{
if (buffget[2]==0x1C) {
if ((CTi=6)&&(buffget[4]==0x01)) CATTXState = 1;
if ((CTi=6)&&(buffget[4]==0x00)) CATTXState = 0;
if ((CTi=5)&&(buffget[3]==0x01)) CATTXState = 1;
if ((CTi=5)&&(buffget[3]==0x00)) CATTXState = 0;
if ((CTi=5)&&(buffget[3]==0x00)&&(buffget[4]==0x01)) CATTXState = 1;
if ((CTi=5)&&(buffget[3]==0x00)&&(buffget[4]==0x00)) CATTXState = 0;
Serial.write (0xFE);
Serial.write (0xFE);
Serial.write (0x50);
Serial.write (0xE0);
Serial.write (buffget[2]);
Serial.write (0xFD);
Serial.flush();
} else {
FA();
}
}
// lcd.setCursor(1,1);
// lcd.print("CAT ");
// lcd.setCursor(6,1);
// lcd.print(CATTXState, DEC); //28
// delay(1000);
// lcd.setCursor(1,1);
// lcd.print("CAT1 ");
// lcd.setCursor(6,1);
// lcd.print(buffget[2], DEC); //28
// delay(1000);
// lcd.setCursor(1,1);
// lcd.print("CAT2 ");
// lcd.setCursor(6,1);
// lcd.print(CTi, DEC); //5
// delay(1000);
// lcd.setCursor(1,1);
// lcd.print("CAT3 ");
// lcd.setCursor(6,1);
// lcd.print(buffget[3], DEC); //0
// delay(1000);
// lcd.setCursor(1,1);
// lcd.print("CAT4 ");
// lcd.setCursor(6,1);
// lcd.print(buffget[4], DEC); //
// delay(1000);
// lcd.setCursor(1,1);
// lcd.print(" ");
}
void CATsetfreq()
{
// Установка частоты с компа
if ((buffget[2]==5)||(buffget[2]==0))
poll_in_frequency();
}
void poll_in_mode()
{
// Установка режима с компа, пока нет
}
void poll_in_frequency(){
// Формируем частоту для установки с компа
DMHZ = (buffget[6]); // Десятки МГц
DMHZ = DMHZ - (((DMHZ/16) * 6));
MHZ = buffget[5]; // МГц
MHZ = MHZ - (((MHZ/16) * 6)); // Трансформируем в формат ICOM CAT
KHZ = buffget[4];
KHZ = KHZ - (((KHZ/16) * 6)); // Трансформируем в формат ICOM CAT
HZ = buffget[3];
HZ = HZ - (((HZ/16) * 6)); // Трансформируем в формат ICOM CAT
QRG = (((long(DMHZ)*1000000)+(long(MHZ) * 10000) + (long(KHZ) * 100) + (long(HZ) * 1))); // Собираем частоту из формата MMkkkH
bandCAT=99;
if ((DMHZ >= 1)&&(DMHZ < 3)) bandCAT=0;
if ((DMHZ >= 3)&&(DMHZ < 7)) bandCAT=1;
if ((DMHZ >= 7)&&(DMHZ < 10)) bandCAT=2;
if ((DMHZ >= 10)&&(DMHZ < 14)) bandCAT=2;
if ((DMHZ >= 14)&&(DMHZ < 18)) bandCAT=3;
if ((DMHZ >= 18)&&(DMHZ < 21)) bandCAT=3;
if ((DMHZ >= 21)&&(DMHZ < 24)) bandCAT=3;
if ((DMHZ >= 24)&&(DMHZ < 27)) bandCAT=3;
if ((DMHZ >= 27)&&(DMHZ < 30)) bandCAT=3;
if (bandCAT!=99) {
Serial.write (0xFE);
Serial.write (0xFE);
Serial.write (0x50);
Serial.write (0xE0);
Serial.write (buffget[2]);
Serial.write (0xFD);
Serial.flush();
rx=QRG;
} else {
FA();
}
}
void freq_to_send()
{
int_fast32_t lrx = rx / 10;
// Формируем частоту для отправки в комп
sendDMHz = lrx/100000;
sendDMHz = sendDMHz + (((sendDMHz/10) * 6));
sendMHz = (lrx % 100000)/1000;
sendMHz = sendMHz + (((sendMHz/10) * 6));
sendkHz = (lrx % 1000)/10;
sendkHz = sendkHz + (((sendkHz/10) * 6));
sendHz = (lrx % 10)*10;
sendHz = sendHz + (((sendHz/10) * 6));
Serial.write (0xFE);
Serial.write (0xFE);
Serial.write (0xE0);
Serial.write (0x50);
Serial.write (0x03);
Serial.write (sendHz);
Serial.write (sendkHz);
Serial.write (sendMHz);
Serial.write (sendDMHz);
Serial.write (0x0);
Serial.write (0xFD);
Serial.flush();
}
void mode_to_send(){
Serial.write (0xFE);
Serial.write (0xFE);
Serial.write (0xE0);
Serial.write (0x50);
Serial.write (0x04);
// 0 - LSB, 1 - USB, 2 - CW ?
// Декодируем режим просто по частоте
if (IFUpDn < rx) {
// пусть будет USB
Serial.write (0x01);
} else {
// пусть будет LSB
Serial.write (0x00);
}
Serial.write (0x02);
Serial.write (0xFD);
Serial.flush();
}
void FA(){
Serial.write (0xFE);
Serial.write (0xFE);
Serial.write (0xE0);
Serial.write (0x50);
Serial.write (0xFA);
Serial.write (0xFD);
Serial.flush();
}
#endif
// ********************** поддержка CAT (IC 756) ********************** >
int keypooler() {
int xbtnstate = buttonstate;
int keypressed = 0;
buttonstate = analogRead(KEYPAD); // Считываем значение АЦП кейпада
if (buttonstate > BUTTON1_2) {
//все кнопки отпущены, но были нажаты
if ((xbuttonstate[1] + xbuttonstate[2] + xbuttonstate[3] + xbuttonstate[4] + xbuttonstate[5] + xbuttonstate[6]) != 0) {
//на предыдущем шаге была нажатая кнопка, делаем паузу на дребезг и проверяем еще раз
delay(10);
buttonstate = analogRead(KEYPAD); // Считываем значение АЦП кейпада
if (buttonstate > BUTTON1_2) {
//кнопки действительно отпущены
for (int i=1;i<7;i++) xbuttonstate[i] = 0;
}
}
} else {
//кнопки были отпущены, но теперь что то нажали
if ((xbuttonstate[1] + xbuttonstate[2] + xbuttonstate[3] + xbuttonstate[4] + xbuttonstate[5] + xbuttonstate[6]) == 0) {
//после паузы считываем еще раз
xbtnstate = buttonstate;
delay(10);
buttonstate = analogRead(KEYPAD); // Считываем значение АЦП кейпада
if ((buttonstate > (xbtnstate - 5 - (buttonstate/10))) && (buttonstate < (xbtnstate + 5 + (buttonstate/10)))) {
//определенно что то нажато
if ((buttonstate >= BUTTON1_1)&&(buttonstate <= BUTTON1_2)) { keypressed = 1; } else
if ((buttonstate >= BUTTON2_1)&&(buttonstate <= BUTTON2_2)) { keypressed = 2; } else
if ((buttonstate >= BUTTON3_1)&&(buttonstate <= BUTTON3_2)) { keypressed = 3; } else
if ((buttonstate >= BUTTON4_1)&&(buttonstate <= BUTTON4_2)) { keypressed = 4; } else
if ((buttonstate >= BUTTON5_1)&&(buttonstate <= BUTTON5_2)) { keypressed = 5; } else
if ((buttonstate >= BUTTON6_1)&&(buttonstate <= BUTTON6_2)) { keypressed = 6; };
}
xbuttonstate[keypressed] = 1;
}
}
return(keypressed);
}
void setAttPre() {
att_preamp += 1;
if (att_preamp > 2) att_preamp = 0;
digitalWrite(ATT, att_preamp & 0B01);
digitalWrite(PRE, att_preamp & 0B10);
showOptions();
}
//Вывод частоты в верхнюю строку LCD
void showFrequency(int_fast32_t lrx) {
char buffer[15];
utoa_fast_div(lrx, buffer, sizeof(buffer));
lcd.setCursor(2,0);
lcd.print(buffer);
// добавить
lcd.setCursor(0,1);
if (com_mode == 0) {
// if (IFUpDn < rx) {
// частота выше границы,гетеродин ниже частоты
band.bname[3] = 0;
lcd.print(band.bname);
//} else {
//lcd.print("LSB");
//}
}
if (com_mode == 1) { lcd.print("IF "); }
if (com_mode == 2) { lcd.print("COR"); }
};
//Выводим вкл/выкл ATT / Preamp
void showOptions() {
lcd.setCursor(0,0);
if (tx_mode == 0) {
if (att_preamp & 0B01) lcd.print("ATT");
else
if (att_preamp & 0B10) lcd.print("PRE");
else lcd.print(" ");
} else {
lcd.print("TX ");
}
}
//Выводим значение S/P-метра на LCD
void showSmeter() {
if (xsmtr != smtr) {
lcd.setCursor(3,1);
lcd.print(smtr);
xsmtr = smtr;
}
}
//Выводим режим
void showMode(int_fast8_t mode) {
//if (xmode != mode) {
//lcd.setCursor(0,1);
//lcd.print(mode_m[mode].modename);
//xmode = mode;
//}
}
void decodeband(int_fast32_t rx) {
//Декодируем диапазон и заполняем band
band.nd = 0;
band.num = 0;
//lcd.setCursor(1,1);
//lcd.print(" IN ");
//lcd.setCursor(5,1);
//lcd.print(rx);
//delay(2000);
if ((rx >= BAND_01_LOW)&&(rx <= BAND_01_HIGH)&&(BAND_01_EN)) { band.num = BAND_01_NUM; band.dssb = BAND_01_DSSB; band.inv = BAND_01_INV; band.fhigh = BAND_01_HIGH; band.flow = BAND_01_LOW; strcpy(band.bname, BAND_01_NAME); }
else if ((rx >= BAND_02_LOW)&&(rx <= BAND_02_HIGH)&&(BAND_02_EN)) { band.num = BAND_02_NUM; band.dssb = BAND_02_DSSB; band.inv = BAND_02_INV; band.fhigh = BAND_02_HIGH; band.flow = BAND_02_LOW; strcpy(band.bname, BAND_02_NAME); }
else if ((rx >= BAND_03_LOW)&&(rx <= BAND_03_HIGH)&&(BAND_03_EN)) { band.num = BAND_03_NUM; band.dssb = BAND_03_DSSB; band.inv = BAND_03_INV; band.fhigh = BAND_03_HIGH; band.flow = BAND_03_LOW; strcpy(band.bname, BAND_03_NAME); }
else if ((rx >= BAND_04_LOW)&&(rx <= BAND_04_HIGH)&&(BAND_04_EN)) { band.num = BAND_04_NUM; band.dssb = BAND_04_DSSB; band.inv = BAND_04_INV; band.fhigh = BAND_04_HIGH; band.flow = BAND_04_LOW; strcpy(band.bname, BAND_04_NAME); }
else if ((rx >= BAND_05_LOW)&&(rx <= BAND_05_HIGH)&&(BAND_05_EN)) { band.num = BAND_05_NUM; band.dssb = BAND_05_DSSB; band.inv = BAND_05_INV; band.fhigh = BAND_05_HIGH; band.flow = BAND_05_LOW; strcpy(band.bname, BAND_05_NAME); }
else if ((rx >= BAND_06_LOW)&&(rx <= BAND_06_HIGH)&&(BAND_06_EN)) { band.num = BAND_06_NUM; band.dssb = BAND_06_DSSB; band.inv = BAND_06_INV; band.fhigh = BAND_06_HIGH; band.flow = BAND_06_LOW; strcpy(band.bname, BAND_06_NAME); }
else if ((rx >= BAND_07_LOW)&&(rx <= BAND_07_HIGH)&&(BAND_07_EN)) { band.num = BAND_07_NUM; band.dssb = BAND_07_DSSB; band.inv = BAND_07_INV; band.fhigh = BAND_07_HIGH; band.flow = BAND_07_LOW; strcpy(band.bname, BAND_07_NAME); }
else if ((rx >= BAND_08_LOW)&&(rx <= BAND_08_HIGH)&&(BAND_08_EN)) { band.num = BAND_08_NUM; band.dssb = BAND_08_DSSB; band.inv = BAND_08_INV; band.fhigh = BAND_08_HIGH; band.flow = BAND_08_LOW; strcpy(band.bname, BAND_08_NAME); }
else if ((rx >= BAND_09_LOW)&&(rx <= BAND_09_HIGH)&&(BAND_09_EN)) { band.num = BAND_09_NUM; band.dssb = BAND_09_DSSB; band.inv = BAND_09_INV; band.fhigh = BAND_09_HIGH; band.flow = BAND_09_LOW; strcpy(band.bname, BAND_09_NAME); }
else { band.nd = 1; };
if (band.num != 0) band.ld = band.num;
if ((rx >= BAND_BPF_01_LOW)&&(rx <= BAND_BPF_01_HIGH)) { band.bpf = BAND_BPF_01_CODE; }
else if ((rx >= BAND_BPF_02_LOW)&&(rx <= BAND_BPF_02_HIGH)) { band.bpf = BAND_BPF_02_CODE; }
else if ((rx >= BAND_BPF_03_LOW)&&(rx <= BAND_BPF_03_HIGH)) { band.bpf = BAND_BPF_03_CODE; }
else if ((rx >= BAND_BPF_04_LOW)&&(rx <= BAND_BPF_04_HIGH)) { band.bpf = BAND_BPF_04_CODE; }
else if ((rx >= BAND_BPF_05_LOW)&&(rx <= BAND_BPF_05_HIGH)) { band.bpf = BAND_BPF_05_CODE; }
else if ((rx >= BAND_BPF_06_LOW)&&(rx <= BAND_BPF_06_HIGH)) { band.bpf = BAND_BPF_06_CODE; }
else if ((rx >= BAND_BPF_07_LOW)&&(rx <= BAND_BPF_07_HIGH)) { band.bpf = BAND_BPF_07_CODE; }
else if ((rx >= BAND_BPF_08_LOW)&&(rx <= BAND_BPF_08_HIGH)) { band.bpf = BAND_BPF_08_CODE; }
else if ((rx >= BAND_BPF_09_LOW)&&(rx <= BAND_BPF_09_HIGH)) { band.bpf = BAND_BPF_09_CODE; }
else { band.bpf = 0; }
}
void setIncrement() {
//Здесь закомментированы шаги переключения энкодера, необходимое раскомментировать
//if(increment == 10){increment = 50; hertz = "50 Hz"; hertzPosition=5;}
//else if (increment == 50){increment = 100; hertz = "100 Hz"; hertzPosition=4;}
//else if (increment == 100){increment = 500; hertz="500 Hz"; hertzPosition=4;}
//else if (increment == 500){increment = 1000; hertz="1 KHz"; hertzPosition=6;}
//else if (increment == 1000){increment = 2500; hertz="2.5 KHz"; hertzPosition=4;}
//else if (increment == 2500){increment = 5000; hertz="5 KHz"; hertzPosition=6;}
//else if (increment == 5000){increment = 10000; hertz="10 KHz"; hertzPosition=5;}
//else if (increment == 10000){increment = 100000; hertz="100 KHz"; hertzPosition=4;}
//else if (increment == 100000){increment = 1000000; hertz="1 MHz"; hertzPosition=6;}
//else{increment = 10; hertz = "10 Hz"; hertzPosition=5;};
//Другой вариант шага переключения частоты
//if(increment == 10){increment = 100; hertz = "100 Hz"; hertzPosition=4;}
//else if (increment == 100){increment = 1000; hertz = "1 KHz"; hertzPosition=6;}
//else if (increment == 1000){increment = 10000; hertz="10 KHz"; hertzPosition=5;}
//else if (increment == 10000){increment = 100000; hertz="100 KHz"; hertzPosition=4;}
//else {increment = 10; hertz = "10 Hz"; hertzPosition=5;};
//Другой вариант шага переключения частоты
//if(increment == 100){increment = 1000; hertz = " 1 kHz"; hertzPosition=5;}
if (increment == 100){increment = 5000; hertz=" 5 kHz"; hertzPosition=6;}
else if (increment == 5000){increment = 25000; hertz="25 KHz"; hertzPosition=5;}
//else if (increment == 25000){increment = 100000; hertz="100 kHz"; hertzPosition=5;}
else if (increment == 25000){increment = 1000000; hertz="1 MHz"; hertzPosition=6;}
else {increment = 100; hertz = "100 Hz"; hertzPosition=5;};
lcd.setCursor(3,1);
lcd.print(" ");
lcd.setCursor(hertzPosition,1);
lcd.print(hertz);
xsmtr = "";
rate_timepassed = millis() + TIME_DISPLAY_RATE; // До этого времени S-метр не будет отображаться
}
//---------------------------------------------Окончание участка кода для управления шагом щелчка энкодером.
// Процедура прерывания по событию изменение состояния энкодера
ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result) {
if (com_mode == 0) {
if (result == DIR_CW) { rx=rx+increment; }
else { rx=rx-increment; };
if (rx >=MAXFREQ) {rx=rx2;}; // Верхний предел частоты
if (rx <=MINFREQ) {rx=rx2;}; // Нижний предел частоты
}
if (com_mode == 1) {
if (result == DIR_CW) { iffreq=iffreq+increment/10; }
else { iffreq=iffreq-increment/10; };
if (iffreq >=MAXIFFREQ) {iffreq=xiffreq;}; // Верхний предел ПЧ
if (iffreq <=MINIFFREQ) {iffreq=xiffreq;}; // Нижний предел ПЧ
}
if (com_mode == 2) {
if (result == DIR_CW) { si5351_corr=si5351_corr+increment; }
else { si5351_corr=si5351_corr-increment; };
if (si5351_corr >=MAXIFFREQ) {si5351_corr=xsi5351_corr;}; // Верхний предел коррекции
if (si5351_corr <=0) {si5351_corr=xsi5351_corr;}; // Нижний предел коррекции
}
};
}
void sendReg(int_fast16_t bpf) {
// Отправляем код диапазона и/или режим работы на дешифратор или сдвиговые регистры
// HC595
// digitalWrite(BPF_LATCH, LOW);
// delay(1);
// tfr_byte(dpf & 0xFF);
// tfr_byte((dpf >> 8) & 0xFF);
// digitalWrite(BPF_LATCH, HIGH);
// Дешифратор
digitalWrite(BPF_D0, bpf & 0B0001);
digitalWrite(BPF_D1, bpf & 0B0010);
digitalWrite(BPF_D2, bpf & 0B0100);
digitalWrite(BPF_D3, bpf & 0B1000);
}
// Расчитываем и отправляем новую частоту в синтезатор
void sendFrequency(double frequency) {
// Si5351
double l_frequency_to_synth = frequency;
// Логика расчета частоты для синтезатора
#ifdef IFFreq
// Если используем ПЧ
if (band.nd == 1) {
// Частота вне заданных диапазонов
if (IFUpDn < rx) {
// Частота выше границы, гетеродин ниже частоты
l_frequency_to_synth = rx - iffreq;
} else {
// Частота ниже границы, гетеродин выше частоты
l_frequency_to_synth = rx + iffreq;
}
} else {
// Частота в одном из диапазонов, делаем как в настройке диапазона
l_frequency_to_synth = (rx + (iffreq * band.inv));
}
#endif
// Отправляем частоту в si5351
//si5351.set_freq( l_frequency_to_synth * SI5351_FREQ_MULT, SI5351_PLL_FIXED, SI5351_CLK0 );
si5351.set_freq( l_frequency_to_synth * SI5351_FREQ_MULT, SI5351_CLK0 );
//timepassed = millis() + 5000;
//memstatus = 0; // Сигнализируем об изменении частоты и потенциальной необходимости ее записи в постоянную память
}
void setBand(int dir) {
if (band.num == 0) band.num = band.ld;
band.num += dir;
if (band.num < 1) { band.num = BAND_MAX; }
else if (band.num > BAND_MAX) { band.num = 1; }
if (dir > 0) {
if ((!BAND_01_EN) && (band.num == 1)) { band.num++; }
if ((!BAND_02_EN) && (band.num == 2)) { band.num++; }
if ((!BAND_03_EN) && (band.num == 3)) { band.num++; }
if ((!BAND_04_EN) && (band.num == 4)) { band.num++; }
if ((!BAND_05_EN) && (band.num == 5)) { band.num++; }
if ((!BAND_06_EN) && (band.num == 6)) { band.num++; }
if ((!BAND_07_EN) && (band.num == 7)) { band.num++; }
if ((!BAND_08_EN) && (band.num == 8)) { band.num++; }
} else if (dir < 0) {
if ((!BAND_09_EN) && (band.num == 9)) { band.num--; }
if ((!BAND_08_EN) && (band.num == 8)) { band.num--; }
if ((!BAND_07_EN) && (band.num == 7)) { band.num--; }
if ((!BAND_06_EN) && (band.num == 6)) { band.num--; }
if ((!BAND_05_EN) && (band.num == 5)) { band.num--; }
if ((!BAND_04_EN) && (band.num == 4)) { band.num--; }
if ((!BAND_03_EN) && (band.num == 3)) { band.num--; }
if ((!BAND_02_EN) && (band.num == 2)) { band.num--; }
}
if (band.num != band.xnum) {
storeMemBand(band.xnum);
restoreMemBand(band.num);
}
}
void setMode() {
mode++;
if ((mode < 0) || (mode_m[mode].code == 0xFF)) { mode = 1; }
timepassed = millis() + 5000;
memstatus = 0; // Сигнализируем об изменении режима и потенциальной необходимости его записи в постоянную память
}
void setComMode() {
com_mode++;
if (com_mode > 2) { com_mode = 0; }
if (com_mode == 0) { rx2 = 1; }
if (com_mode == 1) { xiffreq = 1; }
if (com_mode == 2) { xsi5351_corr = 1; }
}
void restoreMem() {
mode = EEPROM.read(9);
xmode = 0;
freq = String(EEPROM.read(0))+String(EEPROM.read(1))+String(EEPROM.read(2))+String(EEPROM.read(3))+String(EEPROM.read(4))+String(EEPROM.read(5))+String(EEPROM.read(6));
rx = freq.toInt();
rx2 = 1;
freq = String(EEPROM.read(110))+String(EEPROM.read(111))+String(EEPROM.read(112))+String(EEPROM.read(113))+String(EEPROM.read(114))+String(EEPROM.read(115))+String(EEPROM.read(116));
iffreq = freq.toInt();
xiffreq = 1;
freq = String(EEPROM.read(120))+String(EEPROM.read(121))+String(EEPROM.read(122))+String(EEPROM.read(123))+String(EEPROM.read(124))+String(EEPROM.read(125))+String(EEPROM.read(126));
si5351_corr = freq.toInt();
xsi5351_corr= 1;
if (rx >= MAXFREQ) { rx = MAXFREQ; }; // Верхний предел частоты
if (rx <= MINFREQ) { rx = MINFREQ; }; // Нижний предел частоты
if ((mode < 0) || (mode_m[mode].code == 0xFF)) { mode = 1; } // Если считали кривой режим
}
void restoreMemBand(int num) {
freq = String(EEPROM.read(0 + (num * 10)))+String(EEPROM.read(1 + (num * 10)))+String(EEPROM.read(2 + (num * 10)))+String(EEPROM.read(3 + (num * 10)))+String(EEPROM.read(4 + (num * 10)))+String(EEPROM.read(5 + (num * 10)))+String(EEPROM.read(6 + (num * 10)));
mode = EEPROM.read(9 + (num * 10));
xmode = 0;
rx2 = rx;
rx = freq.toInt();
if (rx >= MAXFREQ) { rx = rx2; }; // Верхний предел частоты
if (rx <= MINFREQ) { rx = rx2; }; // Нижний предел частоты
if ((mode < 0) || (mode_m[mode].code == 0xFF)) { mode = 1; } // Если считали кривой режим
}
void initMem() {
lcd.setCursor(0,0);
lcd.print(" INITIALIZING ");
lcd.setCursor(0,1);
lcd.print(" EEPROM ");
delay(1000);
memstatus = 0;
mode = 1;
iffreq = IFFreq;
si5351_corr = 12345;
rx = BAND_01_LOW; decodeband(rx); storeMemBand(1);
if (BAND_01_EN && (memstatus == 0)) { storeMem(); }
rx = BAND_02_LOW; decodeband(rx); storeMemBand(2);
if (BAND_02_EN && (memstatus == 0)) { storeMem(); }
rx = BAND_03_LOW; decodeband(rx); storeMemBand(3);
if (BAND_03_EN && (memstatus == 0)) { storeMem(); }
rx = BAND_04_LOW; decodeband(rx); storeMemBand(4);
if (BAND_04_EN && (memstatus == 0)) { storeMem(); }
rx = BAND_05_LOW; decodeband(rx); storeMemBand(5);
if (BAND_05_EN && (memstatus == 0)) { storeMem(); }
rx = BAND_06_LOW; decodeband(rx); storeMemBand(6);
if (BAND_06_EN && (memstatus == 0)) { storeMem(); }
rx = BAND_07_LOW; decodeband(rx); storeMemBand(7);
if (BAND_07_EN && (memstatus == 0)) { storeMem(); }
rx = BAND_08_LOW; decodeband(rx); storeMemBand(8);
if (BAND_08_EN && (memstatus == 0)) { storeMem(); }
rx = BAND_09_LOW; decodeband(rx); storeMemBand(9);
if (BAND_09_EN && (memstatus == 0)) { storeMem(); }
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" ");
}
void splitRx(int_fast32_t rx) {
millions = byte(rx/1000000);
hundredthousands = byte((rx/100000)%10);
tenthousands = byte((rx/10000)%10);
thousands = byte((rx/1000)%10);
hundreds = byte((rx/100)%10);
tens = byte((rx/10)%10);
ones = byte((rx/1)%10);
}
void storeMemBand(int num){
//Записываем частоту текущего диапазона в постоянную память (EEPROM) поразрядно
//Но только если попадает в границы диапазона
if ((num > 0)&&(rx >= band.flow)&&(rx <= band.fhigh)) {
splitRx(rx);
EEPROM.update(0 + (num * 10),millions);
EEPROM.update(1 + (num * 10),hundredthousands);
EEPROM.update(2 + (num * 10),tenthousands);
EEPROM.update(3 + (num * 10),thousands);
EEPROM.update(4 + (num * 10),hundreds);
EEPROM.update(5 + (num * 10),tens);
EEPROM.update(6 + (num * 10),ones);
EEPROM.update(9 + (num * 10),mode);
}
};
void storeMem(){
//Записываем текущую частоту в постоянную память (EEPROM) поразрядно
//lcd.setCursor(4,1);
//lcd.print("-=STORING=- ");
splitRx(rx);
EEPROM.update(0,millions);
EEPROM.update(1,hundredthousands);
EEPROM.update(2,tenthousands);
EEPROM.update(3,thousands);
EEPROM.update(4,hundreds);
EEPROM.update(5,tens);
EEPROM.update(6,ones);
EEPROM.update(9,mode);
splitRx(iffreq);
EEPROM.update(110,millions);
EEPROM.update(111,hundredthousands);
EEPROM.update(112,tenthousands);
EEPROM.update(113,thousands);
EEPROM.update(114,hundreds);
EEPROM.update(115,tens);
EEPROM.update(116,ones);
splitRx(si5351_corr);
EEPROM.update(120,millions);
EEPROM.update(121,hundredthousands);
EEPROM.update(122,tenthousands);
EEPROM.update(123,thousands);
EEPROM.update(124,hundreds);
EEPROM.update(125,tens);
EEPROM.update(126,ones);
memstatus = 1; // Сигнализируем программе, что последние изменения частоты записаны в постоянную память (EEPROM)
//delay(100);
//lcd.setCursor(4,1);
//lcd.print(" ");
//xsmtr = "";
};