-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathArduinoVFOTuner.ino
224 lines (171 loc) · 5.31 KB
/
ArduinoVFOTuner.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/*
Arduino VFO Tuner for Harris RF-550
Author: d3rail0
Testers:
Keith Densmore
Bryan Kim
Completion date: Sunday the 5th of November, 2017
*/
#include "src/bconverter.h"
#include <EEPROM.h>
const double EPSILON = 0.0001;
const int encoder0PinA = 3;
const int encoder0PinB = 2;
const int SAVE_STATE_BUTTON = 11;
const int SPEED_BUTON = 12;
const int TUNE_SWITCH = 17;
// Radio Configuration
const long MAX_FREQUENCY = 30000000; // Maximum frequency limit
const long MIN_FREQUENCY = 0; // Minimum frequency limit
const double STANDARD_MULTIPLIER = 1.0;
const double FAST_MULTIPLIER = 0.5;
const char EEPROM_SIGNATURE[] = "dat1"; // Constant for EEPROM signature
struct TunerState {
char signature[5]; // A signature to check if valid data is stored
long frequency;
short tuneSpeedID;
};
//Rotary encoder
volatile int encoder0Pos = 0;
//Button for selecting tune speed
int buttonSaveState = LOW;
int oldButtonSaveState = LOW;
int speedButtonState = 0;
int tuneSwitchPrevState = LOW;
int state = HIGH;
int tuneSwitchReading;
//Tune speeds
TunerState tunerState;
bool FAST_MODE = false;
unsigned long tuneAmount = 100;
const unsigned long tuneSpeeds[4] = {100, 1000, 10000, 100000};
long bcdNum;
unsigned long timer;
const short diff = 200;
void readEncoder();
void tuneFrequency(bool up);
bool debounceButton(int buttonPin, bool oldState);
// Initialize the tuner state
void initState() {
strcpy(tunerState.signature, EEPROM_SIGNATURE);
tunerState.frequency = 7000000;
tunerState.tuneSpeedID = 0;
}
// Save current tuner state to EEPROM
void saveState() {
EEPROM.put(0, tunerState);
Serial.println("State saved!");
}
// Load last tuner state from EEPROM
void loadState() {
EEPROM.get(0, tunerState);
if (strcmp(tunerState.signature, EEPROM_SIGNATURE) == 0) {
// Check if the tuneSpeedID is within a valid range
if (tunerState.tuneSpeedID < 0 || tunerState.tuneSpeedID > 3) {
Serial.println("Incorrect tuneSpeedID reading from EEPROM.");
initState(); // Reset to initial state
}
tuneAmount = tuneSpeeds[tunerState.tuneSpeedID];
Serial.println("Tuner state loaded from EEPROM:");
Serial.print("frequency = ");
Serial.println(tunerState.frequency);
Serial.print("tuneAmount = ");
Serial.println(tuneAmount);
} else {
// Set default values and save them
initState();
saveState();
Serial.println("Default tuner state saved to EEPROM.");
}
}
void setup() {
// Configure input pins
pinMode(encoder0PinA, INPUT);
pinMode(encoder0PinB, INPUT);
pinMode(SAVE_STATE_BUTTON, INPUT);
pinMode(SPEED_BUTON, INPUT);
pinMode(TUNE_SWITCH, INPUT);
// turn on pull-up resistor
digitalWrite(encoder0PinA, HIGH);
digitalWrite(encoder0PinB, HIGH);
// BCD requires 22 lines for tuning
for (int i = 0; i < 22; i++)
pinMode(22 + i, OUTPUT);
// encoder pin on interrupt 0 - pin 2
attachInterrupt(0, readEncoder, CHANGE);
Serial.begin(115200);
Serial.println("start");
loadState();
}
void loop() {
// Update state if button is active
buttonSaveState = debounceButton(SAVE_STATE_BUTTON, oldButtonSaveState);
if (buttonSaveState == HIGH && oldButtonSaveState == LOW) {
saveState();
}
oldButtonSaveState = buttonSaveState;
//interrupts will take care of themselves
speedButtonState = digitalRead(SPEED_BUTON);
FAST_MODE = !(speedButtonState == HIGH);
tuneSwitchReading = digitalRead(TUNE_SWITCH);
if (tuneSwitchReading == LOW && tuneSwitchPrevState == HIGH && millis() - timer > diff)
{
state = !state;
if (state == LOW) {
tunerState.tuneSpeedID = (tunerState.tuneSpeedID + 1) % 4;
tuneAmount = tuneSpeeds[tunerState.tuneSpeedID];
}
tuneSwitchReading = !state;
timer = millis();
}
tuneSwitchPrevState = tuneSwitchReading;
}
bool debounceButton(int buttonPin, bool oldState) {
bool stateNow = digitalRead(buttonPin);
if(oldState!=stateNow) {
delay(10);
stateNow = digitalRead(buttonPin);
}
return stateNow;
}
void updateFrequency() {
bcdNum = bcv::mConvertToBCD(tunerState.frequency / 100);
//DEBUGGING ---------------|
//Serial.println("");
//Serial.print(frequency);
//Serial.print(" >> ");
//Serial.println(bcdNum);
//-------------------------|
for (int i = 21; i >= 0; i--)
digitalWrite(43 - i, (bcdNum >> i) & 1);
}
void tuneFrequency(bool up) {
double multiplier = (FAST_MODE) ? FAST_MULTIPLIER : STANDARD_MULTIPLIER;
long frequencyChange = static_cast<long>(tuneAmount * multiplier) * (up ? 1 : -1);
tunerState.frequency += frequencyChange;
if (tuneAmount == 1000) {
tunerState.frequency -= (tunerState.frequency % 1000);
} else if (tuneAmount == 10000) {
tunerState.frequency -= (tunerState.frequency % 10000) - (tunerState.frequency % 1000);
}
// Handle edge frequencies
if (tunerState.frequency < MIN_FREQUENCY) {
/*
Change to frequency=MAX_FREQUENCY if you want
the frequency to go from MIN_FREQUENCY to MAX_FREQUENCY when
RF goes below MIN_FREQUENCY
*/
tunerState.frequency = MIN_FREQUENCY;
} else if (tunerState.frequency > MAX_FREQUENCY) {
tunerState.frequency = MIN_FREQUENCY;
}
}
void readEncoder() {
if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
tuneFrequency(false);
}
else {
tuneFrequency(true);
}
updateFrequency();
}