Skip to content

Commit

Permalink
Merge pull request #22 from camilstaps/Auto-band-v2
Browse files Browse the repository at this point in the history
Auto band functionality
  • Loading branch information
camilstaps authored May 16, 2017
2 parents e7270cf + 775e0df commit 0c1ce56
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 9 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ There are several features that can be added to the rig if you want to. This is
done by adding and removing `#define` lines to `settings.h`.

- `OPT_BAND_SELECT`: change the band by pressing RIT for 2s.
- `OPT_AUTO_BAND`: auto-select bands using a PCA9536 PIO (thanks VK3IL).
- `OPT_ERASE_EEPROM`: erase the EEPROM by holding RIT for 8s.
- `OPT_STORE_CW_SPEED`: store the CW speed in EEPROM.
- `OPT_DFE`: direct frequency entry by holding the encoder button for 1s.
Expand Down Expand Up @@ -209,6 +210,8 @@ Some images of the connections:

## Changelog

- 2017-05-16:
- `OPT_AUTO_BAND` (PR [#22](/../../pull/22) by VK3IL)
- 2017-05-12:
- VK band plans (PR [#21](/../../pull/21) by VK3IL)
- 2017-05-04:
Expand Down
5 changes: 5 additions & 0 deletions SODA_POP/SODA_POP.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ byte memory_index_character;
#define EEPROM_CW_SPEED 7 // 1 byte
#endif

#ifdef OPT_AUTO_BAND
#define PCA9536_BUS_ADDR 0x41 // I2C address for PCA9536
#undef OPT_BAND_SELECT
#endif

#endif

// vim: tabstop=2 shiftwidth=2 expandtab:
94 changes: 89 additions & 5 deletions SODA_POP/SODA_POP.ino
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ Si5351 si5351;
#define IF_DEFAULT 491480000

byte memory_pointer;
byte errno; // Global error number for S_ERROR

const int MUTE = A3;
const int TXEN = 13; // production A0
Expand Down Expand Up @@ -142,11 +143,18 @@ void setup()
TIMSK1 |= 1 << OCIE1A;
interrupts();

#ifdef OPT_AUTO_BAND
state.state = EEPROM.read(6) == 0xff ? S_CALIBRATION_CORRECTION : S_DEFAULT;
read_module_band();
#else
state.band = (enum band) EEPROM.read(6); // check for operating band
if (state.band == BAND_UNKNOWN) {
state.band = (enum band) 0;
state.state = S_CALIBRATION_CORRECTION;
} else {
state.state = S_DEFAULT;
}
#endif

fetch_calibration_data(); //load calibration data
si5351.set_correction(cal_value); //correct the clock chip error
Expand All @@ -155,7 +163,6 @@ void setup()
invalidate_display();
delay(1000);

state.state = S_DEFAULT;
invalidate_display();
digitalWrite(MUTE, LOW);

Expand Down Expand Up @@ -194,7 +201,7 @@ void loop()
case S_CALIBRATION_PEAK_RX: loop_calibration_peak_rx(); break;
case S_ERROR: loop_error(); break;
default:
error();
error(1);
break;
}

Expand Down Expand Up @@ -237,6 +244,11 @@ void loop_default()
state.idle_for = DISABLE_DISPLAY_AFTER - 500;
#endif

#ifdef OPT_AUTO_BAND
if (tcount % 5000 == 0) // Check the band module for changes every 5s
read_module_band();
#endif

if (key_active()) {
state.state = S_KEYING;
// Tuning with the rotary encoder
Expand Down Expand Up @@ -795,8 +807,12 @@ void loop_calibration_peak_if()
EEPROM.write(EEPROM_IF_FREQ + 1, state.op_freq >> 8);
EEPROM.write(EEPROM_IF_FREQ + 2, state.op_freq >> 16);
EEPROM.write(EEPROM_IF_FREQ + 3, state.op_freq >> 24);

#ifdef OPT_AUTO_BAND
EEPROM.write(6, 0); // Reset the "not calibrated" flag now that we've written the cal values
state.state = S_CALIBRATION_PEAK_RX;
#else
state.state = S_CALIBRATION_CHANGE_BAND;
#endif
invalidate_frequencies();
invalidate_display();

Expand Down Expand Up @@ -865,7 +881,7 @@ void key_handle_end()
state.state = S_DEFAULT;
} else if (state.state == S_MEM_ENTER) {
if (memory_pointer == MEMORY_LENGTH) {
error();
error(2);
return;
}
buffer[memory_pointer++] = morse_char;
Expand Down Expand Up @@ -1089,10 +1105,78 @@ void ee_erase()
* Enter the error state. This error is non-recoverable and should only be used
* in very rare cases.
*/
void error()
void error(byte er)
{
errno = er;
state.state = S_ERROR;
}

#ifdef OPT_AUTO_BAND
/*
* Read the input latch of the PCA9536 and return a 4-bit value
* If the band module can't be read or the value is out of range, display an error and wait for a valid band module
*/
byte PCA9536_read()
{
for (boolean err = true; err; err = false) {
Wire.beginTransmission(PCA9536_BUS_ADDR);
Wire.write(byte(0x00)); // We read only from register 0, the input latch
Wire.endTransmission(false); // Transmit repeated start rather than stop at end of transmission
Wire.requestFrom(PCA9536_BUS_ADDR, 1);
if (Wire.available() != 1) { // Unable to read the band module ID (most
// likely it's not plugged in properly, or being changed!)
err = true;
} else {
byte reg_val = Wire.read() & 0x0f;
if(reg_val < 2 || reg_val > 11) // Module has an un-supported configuration
err = true;
}
if (err) {
state.display.digits[3] = LED_N_6;
state.display.digits[2] = LED_n;
state.display.digits[1] = LED_E;
state.display.digits[0] = LED_r;
state.display.dots = 0x0;
delay(500);
}
}
invalidate_display();
return reg_val;
}

/*
* Check if the band module has changed and if it has, reset bandlimits and operating frequency
*/
void read_module_band()
{
enum band new_band;

switch (PCA9536_read()) { // Map returned value to current band table range
case 2: new_band = BAND_160; break;
case 3: new_band = BAND_80; break;
#ifdef BAND_60
case 4: new_band = BAND_60; break;
#endif
case 5: new_band = BAND_40; break;
case 6: new_band = BAND_30; break;
case 7: new_band = BAND_20; break;
case 8: new_band = BAND_17; break;
case 9: new_band = BAND_15; break;
case 10: new_band = BAND_12; break;
case 11: new_band = BAND_10; break;
default: new_band = BAND_UNKNOWN; error(3); break;
}

if (new_band != state.band) {
digitalWrite(MUTE, LOW); // Make sure we are in receive mode
state.band = new_band;
setup_band(); // Set the band limits and default
// operating frequency for the selected band
display_band();
delay(2000); // Allow time to view the band on the display
invalidate_display();
}
}
#endif

// vim: tabstop=2 shiftwidth=2 expandtab:
2 changes: 1 addition & 1 deletion SODA_POP/buttons.ino
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ unsigned int time_encoder_button()
}

/**
* Debounche the keyer button.
* Debounce the keyer button.
*/
void debounce_keyer()
{
Expand Down
4 changes: 2 additions & 2 deletions SODA_POP/display.ino
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ void invalidate_display()
case S_ERROR:
state.display.digits[3] = LED_E;
state.display.digits[2] = LED_r;
state.display.digits[1] = LED_r;
state.display.digits[0] = 0x00;
state.display.digits[0] = LED_DIGITS[errno / 10];
state.display.digits[0] = LED_DIGITS[errno % 10];
state.display.dots = 0x2;
break;
}
Expand Down
5 changes: 4 additions & 1 deletion SODA_POP/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
/* Band selection by pressing RIT for 2s */
#define OPT_BAND_SELECT

/* Autoband selection based on plugged in module with PCA9536 PIO */
//#define OPT_AUTO_BAND

/* Erase EEPROM by pressing RIT for 8s */
#define OPT_ERASE_EEPROM

Expand All @@ -48,7 +51,7 @@
#define OPT_DFE

/* Disable display when idle */
#define OPT_DISABLE_DISPLAY
//#define OPT_DISABLE_DISPLAY
#define DISABLE_DISPLAY_AFTER 2500 /* Time to disable display after, in ms */

/* More message memories. Select using the rotary encoder. */
Expand Down

0 comments on commit 0c1ce56

Please sign in to comment.