Skip to content

Commit

Permalink
Direct frequency entry (resolves #2)
Browse files Browse the repository at this point in the history
  • Loading branch information
camilstaps committed Apr 11, 2017
1 parent 7a59637 commit 12eda7d
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 15 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ Use the rotary encoder to tune. Tuning can be done in steps of 50Hz, 200Hz,
1kHz and 10kHz. Rotate through these steps by pressing the rotary encoder. For
all steps except 50Hz, the corresponding digit on the display will blink.

Direct Frequency Entry (DFE) can be used by holding the encoder button for 1s.
It is only available when a paddle is connected. The display will read `DFE`.
Key in the desired frequency. The current digit blinks. Save with the keyer
switch or cancel with the RIT switch. When all four digits are entered, the
new frequency is saved automatically. Abbreviations can be used for 0 (T) and 9
(N) and for all numbers when enabled (see under 'Optional features').

### RIT
Pressing the RIT button turns RIT on. The display will show the RIT offset.

Expand Down Expand Up @@ -110,6 +117,20 @@ done by adding and removing `#define` lines to `settings.h`.

- `OPT_BAND_SELECT`: change the band by pressing RIT for 2s.
- `OPT_ERASE_EEPROM`: erase the EEPROM by holding RIT for 8s.
- `OPT_DFE`: direct frequency entry by holding the encoder button for 1s.
- `OPT_DFE_OBSCURE_ABBREVIATIONS`: adds number abbreviations to DFE according
to the table below. Abbreviations for 0 (T) and 9 (N) are always enabled.

| Letter | Number
---|---
| A | 1
| U | 2
| W | 3
| V | 4
| S | 5
| B | 6
| G | 7
| D | 8

## How to flash the firmware

Expand Down Expand Up @@ -155,6 +176,7 @@ Some images of the connections:
- Minor changes to the display
- Made several things settings (see `settings.h`)
- Big steps tuning (issue [#3](/../../issues/3))
- Direct frequency entry (issue [#2](/../../issues/2))
- 2017-04-04:
- Added bands up to 10m and enabled run-time band switching
- Fixed rotary encoder issues
Expand Down
7 changes: 6 additions & 1 deletion README/states.dot
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
digraph {
startup[label="Startup"];
default[label="Default", width=1.5, height=1];
default[label="Default", width=1.5, height=1.5];
keying[label="Keying"];
adjust_cs[label="Adjust CS"];
change_band[label="Change Band"];
dfe[label="DFE"];
mem_send_wait[label="Mem Send Wait"];
mem_send_tx[label="Mem Send TX"];
mem_enter_wait[label="Mem Enter Wait"];
Expand All @@ -29,6 +30,10 @@ digraph {
change_band:s -> change_band:s [label="Up/down"];
change_band -> default [label="Keyer"];

default -> dfe [label="Encoder (1s)"];
dfe:s -> dfe:s [label="Paddle"];
dfe -> default [label="RIT/Keyer"];

default -> mem_send_wait [label="Keyer", constraint=false];
mem_send_wait -> default [label="Keyer"];
mem_send_wait -> mem_send_tx [label="Paddle"];
Expand Down
Binary file modified README/states.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions SODA_POP/SODA_POP.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ enum state : unsigned char {
S_DEFAULT,
S_KEYING,
S_ADJUST_CS,
#ifdef OPT_BAND_SELECT
S_CHANGE_BAND,
#endif
#ifdef OPT_DFE
S_DFE,
#endif
S_MEM_SEND_WAIT,
S_MEM_SEND_TX,
S_MEM_ENTER_WAIT,
Expand Down Expand Up @@ -56,4 +61,10 @@ const byte tuning_blinks[] = {BLINK_NONE, BLINK_0, BLINK_1, BLINK_2};
#define SIDETONE_ENABLE() {tone(A2, SIDETONE_FREQ);}
#define SIDETONE_DISABLE() {noTone(A2);}

#ifdef OPT_DFE
byte dfe_character;
byte dfe_position;
unsigned int dfe_freq;
#endif

#endif
113 changes: 103 additions & 10 deletions SODA_POP/SODA_POP.ino
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ void setup()

if (digitalRead(DASHin) == LOW)
state.key.mode = KEY_STRAIGHT;

state.display.blinking = BLINK_1;
}

void loop()
Expand All @@ -147,7 +145,12 @@ void loop()
case S_DEFAULT: loop_default(); break;
case S_KEYING: loop_keying(); break;
case S_ADJUST_CS: loop_adjust_cs(); break;
#ifdef OPT_BAND_SELECT
case S_CHANGE_BAND: loop_change_band(); break;
#endif
#ifdef OPT_DFE
case S_DFE: loop_dfe(); break;
#endif
case S_MEM_ENTER_WAIT: loop_mem_enter_wait(); break;
case S_MEM_ENTER: loop_mem_enter(); break;
case S_MEM_ENTER_REVIEW: loop_mem_enter_review(); break;
Expand Down Expand Up @@ -175,8 +178,23 @@ void loop_default()
} else if (rotated_down()) {
freq_adjust(-tuning_steps[state.tuning_step]);
} else if (state.inputs.encoder_button) {
nextFstep();
debounce_encoder_button();
duration = time_encoder_button();
#ifdef OPT_DFE
if (duration > 1000) {
if (state.key.mode == KEY_IAMBIC) {
state.state = S_DFE;
dfe_character = 0xff;
dfe_position = 3;
dfe_freq = 0;
invalidate_display();
} else {
morse(MX);
}
} else
#endif
if (duration > 50) {
rotate_tuning_steps();
}
// Keyer switch for memory and code speed
} else if (state.inputs.keyer) {
duration = time_keyer();
Expand Down Expand Up @@ -280,6 +298,74 @@ void loop_change_band()
}
}

#ifdef OPT_DFE
void loop_dfe()
{
if (dfe_character != 0xff) {
unsigned int add;
switch (dfe_character) {
case M0: case MT: add = 0; break;
#ifdef OPT_DFE_OBSCURE_ABBREVIATIONS
case M1: case MA: add = 1; break;
case M2: case MU: add = 2; break;
case M3: case MW: add = 3; break;
case M4: case MV: add = 4; break;
case M5: case MS: add = 5; break;
case M6: case MB: add = 6; break;
case M7: case MG: add = 7; break;
case M8: case MD: add = 8; break;
#else
case M1: add = 1; break;
case M2: add = 2; break;
case M3: add = 3; break;
case M4: add = 4; break;
case M5: add = 5; break;
case M6: add = 6; break;
case M7: add = 7; break;
case M8: add = 8; break;
#endif
case M9: case MN: add = 9; break;
default:
morse(Mquestion);
dfe_character = 0xff;
return;
}
dfe_character = 0xff;

for (byte i = 0; i < dfe_position; i++)
add *= 10;
dfe_freq += add;

if (dfe_position-- == 0) {
set_dfe();
morse(MR);
}

invalidate_display();
} else if (state.inputs.keyer) {
set_dfe();
invalidate_display();
morse(MR);
debounce_keyer();
} else if (state.inputs.rit) {
state.state = S_DEFAULT;
invalidate_display();
morse(MX);
debounce_rit();
} else if (key_active()) {
iambic_key();
}
}

void set_dfe()
{
state.op_freq = (BAND_LIMITS_LOW[state.band] / 10000000) * 10000000;
state.op_freq += ((unsigned long) dfe_freq) * 10000;
fix_op_freq();
state.state = S_DEFAULT;
}
#endif

void loop_mem_enter_wait()
{
memory_pointer = 0;
Expand Down Expand Up @@ -426,20 +512,23 @@ void loop_calibration_peak_rx()
}
}

// adjust the operating frequency
void freq_adjust(long step)
{
state.op_freq += step;
fix_op_freq();
invalidate_display();
invalidate_frequencies();
}

void fix_op_freq()
{
if (state.op_freq > BAND_LIMITS_HIGH[state.band])
state.op_freq = BAND_LIMITS_HIGH[state.band];
if (state.op_freq < BAND_LIMITS_LOW[state.band])
state.op_freq = BAND_LIMITS_LOW[state.band];
invalidate_display();
invalidate_frequencies();
}

//toggle tuning step rate
void nextFstep()
void rotate_tuning_steps()
{
state.tuning_step++;
if (state.tuning_step >= sizeof(tuning_steps))
Expand All @@ -448,7 +537,6 @@ void nextFstep()
}

/*
*
* timer outside of the normal Ardinu timers
* does keyer timing and port D mulitplexing for display and
* switch inputs.
Expand Down Expand Up @@ -491,6 +579,11 @@ void key_handle_end()
buffer[memory_pointer] = 0xff;
toggle_display();
}
#ifdef OPT_DFE
else if (state.state == S_DFE) {
dfe_character = morse_char;
}
#endif
}

void key_handle_dash()
Expand Down
25 changes: 25 additions & 0 deletions SODA_POP/buttons.ino
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ unsigned int time_rit()
#endif
delay(1);
} while (state.inputs.rit);
debounce_rit();

return duration;
}
Expand Down Expand Up @@ -87,6 +88,30 @@ unsigned int time_keyer()
delay(1); //for some reason a delay call has to be done when doing bit read flag tests or it locks up
//this doesn't seem to be a problem when doing digital reads of a port pin instead.
} while (state.inputs.keyer); // wait until the bit goes high.
debounce_keyer();

return duration;
}

unsigned int time_encoder_button()
{
unsigned int duration = 0;
unsigned long start_time = tcount;

do {
duration = tcount - start_time;
#ifdef OPT_DFE
if (duration > 1000) {
state.display.digits[3] = LED_D;
state.display.digits[2] = LED_F;
state.display.digits[1] = LED_E;
state.display.digits[0] = 0x00;
state.display.dots = 0x0;
}
#endif
delay(1);
} while (state.inputs.encoder_button);
debounce_encoder_button();

return duration;
}
Expand Down
33 changes: 31 additions & 2 deletions SODA_POP/display.ino
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ void display_isr()
break;

case 3:
if (state.display.digits[3] == LED_N_0)
state.display.digits[3] = 0x00; //blank MSD if 0
if (state.display.blinking != BLINK_3 || BLINKED_ON)
PORTD = state.display.digits[3];
digitalWrite(SLED4, LOW);
Expand Down Expand Up @@ -65,10 +63,17 @@ void invalidate_display()
display_cs();
break;
case S_STARTUP:
#ifdef OPT_BAND_SELECT
case S_CHANGE_BAND:
#endif
case S_CALIBRATION_CHANGE_BAND:
display_band();
break;
#ifdef OPT_DFE
case S_DFE:
display_dfe();
break;
#endif
case S_MEM_ENTER_WAIT:
case S_MEM_ENTER:
state.display.digits[3] = LED_E;
Expand Down Expand Up @@ -186,13 +191,37 @@ void display_freq()
unsigned long frequency = state.op_freq/100;
// Then display the digits one by one
state.display.digits[3] = LED_DIGITS[(frequency % 1000000) / 100000];
if (state.display.digits[3] == LED_N_0)
state.display.digits[3] = 0x00; //blank MSD if 0
state.display.digits[2] = LED_DIGITS[(frequency % 100000) / 10000];
state.display.digits[1] = LED_DIGITS[(frequency % 10000) / 1000];
state.display.digits[0] = LED_DIGITS[(frequency % 1000) / 100];
state.display.dots = 0x2;
state.display.blinking = tuning_blinks[state.tuning_step];
}

#ifdef OPT_DFE
void display_dfe()
{
if (dfe_position == 3) {
state.display.digits[3] = LED_D;
state.display.digits[2] = LED_F;
state.display.digits[1] = LED_E;
state.display.digits[0] = 0x00;
state.display.dots = 0x0;
} else {
state.display.digits[3] = LED_DIGITS[(dfe_freq % 10000) / 1000];
if (state.display.digits[3] == LED_N_0)
state.display.digits[3] = 0x00; //blank MSD if 0
state.display.digits[2] = LED_DIGITS[(dfe_freq % 1000) / 100];
state.display.digits[1] = LED_DIGITS[(dfe_freq % 100) / 10];
state.display.digits[0] = LED_DIGITS[dfe_freq % 10];
state.display.dots = 0x2;
state.display.blinking = dfe_position + 1;
}
}
#endif

void display_band()
{
state.display.digits[3] = LED_N_6;
Expand Down
3 changes: 1 addition & 2 deletions SODA_POP/key.ino
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ void straight_key()

void key_isr()
{
if (state.key.timer > 0) {
if (state.key.timer > 0)
if (--state.key.timer == 0)
state.key.timeout = 1;
}
}

void iambic_key()
Expand Down
2 changes: 2 additions & 0 deletions SODA_POP/morse.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@
#define M8 0b111100 // 8
#define M9 0b111110 // 9

#define Mquestion 0b1001100 // ?

#endif
1 change: 1 addition & 0 deletions SODA_POP/segments.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#define LED_A 0xf9
#define LED_C 0xe2
#define LED_D LED_N_0
#define LED_E 0xf2
#define LED_F 0xf0
#define LED_I LED_N_1
Expand Down
Loading

0 comments on commit 12eda7d

Please sign in to comment.