This is the latest working sketch for the Arduino UNO. Any comments or suggestions invited.
Marty
N5KBP
/* Program to emulate a Yaesu YC-601 digital display for the old Yaesu FT401B
* Transceiver. It takes the output of the VFO. Counts it then manipulates the
* numbers to show the output on a TM1638 8 segment led display/key board from ebay.
* It uses the buttons built into the TM1638 for user input ie Band, mode and calibration
* setup. It takes a little outside hardware. You have to condition the input
* to a square wave. I use a 74hc4046 to do that then the frequency must be divided
* by 2 to get the 9 mhz output that the Yaesu outputs down to a frequency the Arduino
* Uno can handle. That is done with a 74hct4040 shift register. All the info on this can
* be found with a little help from Google. I plan on adding a power down reset circuit
* and code later to write the config data to the EEProm on power down.
* My experience is in Visual Basic. This is my first attempt at C so
* It is not as structured as I would like and is probably a memory hog. But it works.
* Thanks to all the library writers, code sharers and circuit sharers.
* I have thourally enjoyed this project and like most programs it will
* suffer from feature bloat eventually. :^)
* Code is released under the GNU GPL license
* Marty Duplissey
* N5KBP
*/
#include <FreqCount.h>
#include <TM1638.h>
#include <EEPROM.h>
struct config
{
byte initflag;
boolean displaytens;
byte lastmode ;
byte lastband ;
unsigned long bandoffset[11];
};
config configdata;
int mode ; // 0 = LSB, 1 = USB, 2 = CW/Tune 3 = AM
int currentband ;
unsigned long oldcount;
unsigned long count;
int modeoffset[] = {150,-150,-70,0}; // LSB,USB,CW,AM
byte buttons;
unsigned long buttonpressed;
char modestring[4] = {'L','U','C','A'};
String displaystring; // string to send to display
int calamount = 1; // amount to change with calibrate buttons
// define a module on data pin 8, clock pin 9, strobe pin 7
TM1638 module(8,9,7);
void setup() {
EEPROM.get(0,configdata);
if (configdata.initflag != B10111010)
{
configdata.initflag = B10111010;
configdata.displaytens = true;
configdata.lastmode = 0;
configdata.lastband = 0;
configdata.bandoffset[0] = 1270000; // 80M
configdata.bandoffset[1] = 1620000; // 40M
configdata.bandoffset[2] = 2320000; // 20M
configdata.bandoffset[3] = 3020000; // 15M
configdata.bandoffset[4] = 3720000; // 10A
configdata.bandoffset[5] = 3770000; // 10B
configdata.bandoffset[6] = 3820000; // 10C
configdata.bandoffset[7] = 3870000; // 10D
configdata.bandoffset[8] = 1920000; // WWV 10 MHZ
configdata.bandoffset[9] = 3620000; // 11M
configdata.bandoffset[10] = 0;// change to 1070000 for 160m on FT101
EEPROM.put (0,configdata);
};
mode = configdata.lastmode;
if (configdata.displaytens == false) calamount = 10;
// if not showing 10's digit change calibrate by 100 hz per button press
currentband = configdata.lastband;
//Serial.begin(57600);// for debugging
FreqCount.begin(100); // Gate time 1/10 th of a second
module.clearDisplay();
}
void loop() {
if (FreqCount.available()) {
count = FreqCount.read();
// count = 447500; //debug code comment out for real use
count = count * 2; // compensate for the / 2 before
// counting done in hardware because of the
// limitations of the ardiuno
if (count == oldcount + 1){// anti jitter code
count = oldcount ;}
if (count == oldcount - 1){
count = oldcount;} // end anti jitter code
oldcount = count;
// count = configdata.bandoffset[currentband]- count; //Use instead of following
// line if using with FT101
if (currentband != 10) count = configdata.bandoffset[currentband]- count;
count = count + modeoffset[mode];
if (configdata.displaytens == false)// drop 10's digit
{
unsigned long newcount = count / 10;
int roundtest = count % 10;// round display after integer division
if (roundtest > 4) newcount = newcount + 1;
displaystring = String(newcount);
if (displaystring.length() < 6) displaystring = " " + displaystring;
displaystring = (" " + displaystring);
displaystring = modestring[mode]+ displaystring;// add mode letter to left most digit of display
module.setDisplayToString(displaystring,0b0000010010);
}
else
{
displaystring = String(count);// show 10's digits
if (displaystring.length() < 7) {displaystring = " " + displaystring;}
displaystring = modestring[mode]+ displaystring;// add mode letter to left most digit of display
module.setDisplayToString(displaystring,0b0000100100);
};
buttons = module.getButtons();
if (buttons != 0){
switch (buttons) {
case 1:// mode button
if (buttonpressed >= millis())break;
if (mode < 3)
{
mode = mode + 1;
}
else
{
mode = 0;
}
configdata.lastmode = mode;
buttonpressed = millis()+400;
case 2:// switch between 10s digit showing
if (buttonpressed >= millis())break;
if (configdata.displaytens == true)
{
configdata.displaytens = false;
calamount = 10;// Move 100 hrz with cal button
}
else
{
configdata.displaytens = true;
calamount = 1; // Move 10 hrz with cal button
}
buttonpressed = millis()+400;
case 4: // Band up button
if (buttonpressed >= millis())break;
if (currentband < 10)
{
currentband = currentband + 1;
}
else
{
currentband = 0;
}
configdata.lastband = currentband;
buttonpressed = millis()+400;
case 8: //Band down button
if (buttonpressed >= millis())break;
if (currentband > 0)
{
currentband = currentband - 1;
}
else
{
currentband = 10;
}
configdata.lastband = currentband;
buttonpressed = millis()+400;
case 32:// Calibrate up button
if (buttonpressed >= millis())break;
configdata.bandoffset[currentband] = configdata.bandoffset[currentband] + calamount;
buttonpressed = millis()+200;
case 64:// Calibrate down button
if (buttonpressed >= millis())break;
configdata.bandoffset[currentband] = configdata.bandoffset[currentband] - calamount;
buttonpressed = millis()+200;
case 128:// write config to EEPROM
if (buttonpressed >= millis())break;
EEPROM.put (0,configdata);
buttonpressed = millis()+400;
}
}
}
}