Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| public:radio:topics:arduino:60m_transceiver [11/07/26 10:09 BST] – created john | public:radio:topics:arduino:60m_transceiver [11/07/26 10:44 BST] (current) – [Further Information] john | ||
|---|---|---|---|
| Line 4: | Line 4: | ||
| ====== 60m Transceiver ====== | ====== 60m Transceiver ====== | ||
| + | |||
| + | The 60m transceiver has the following features, which vary according to the loaded firmware | ||
| + | |||
| + | * Channelized operation | ||
| + | * LCD display | ||
| + | * Frequency | ||
| + | * Mode (SSB / CW) | ||
| + | * Modulation Source (Mic/ | ||
| + | * RX / TX status | ||
| + | * 9MHz IF with Xtal filter | ||
| + | * SSB & CW set via mode switch | ||
| + | * Approx 3W PEP | ||
| + | * Digital mode input/ | ||
| + | * SSB Mic input via 8-pin round " | ||
| + | * Modulation Source (Mic or Data) can chosen via select switch | ||
| + | * Scan start switch - scan a preset group of channels - cycles continuously, | ||
| + | * Use of Jenal SC2 CCIR493 Selcal microphone can be supported - including scanning | ||
| + | |||
| + | ===== Arduino Versions ===== | ||
| + | |||
| + | There are several different firmware versions....this is just a sample... | ||
| + | |||
| + | ==== RX Only, with SSB, CW & scan ==== | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | ++++ Firmware (Click to view) | | ||
| + | |||
| + | <code c> | ||
| + | |||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | char version[] = " | ||
| + | |||
| + | const long channel_array[] = | ||
| + | { | ||
| + | 5258500, | ||
| + | 5278500, | ||
| + | 5301000, | ||
| + | 5334000, | ||
| + | 5363000, | ||
| + | 5379000, | ||
| + | 5345000, | ||
| + | 5195000, | ||
| + | } ; | ||
| + | |||
| + | const long scan_array[] = | ||
| + | { | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } ; | ||
| + | |||
| + | |||
| + | const int mems = sizeof(channel_array)/ | ||
| + | |||
| + | const int scan_mems = sizeof(scan_array)/ | ||
| + | |||
| + | // the last " | ||
| + | // channel_array are not to be scanned. | ||
| + | // Put the channels not to be scanned last | ||
| + | // in the array and update no_scan to reflect. | ||
| + | |||
| + | const int no_scan = 0; | ||
| + | |||
| + | const long bandStart = 5000000; | ||
| + | const long bandEnd = 6000000; | ||
| + | const long txcio = 9001200; | ||
| + | |||
| + | const long cwoffset = 600; | ||
| + | const long filteroffset = 500; | ||
| + | |||
| + | volatile int channel = 01; | ||
| + | |||
| + | volatile long freq = channel_array[channel]; | ||
| + | volatile long oldfreq = 0; | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | volatile long currentfreq = 0; | ||
| + | volatile int updatedisplay = 0; | ||
| + | |||
| + | // Rotary encoder pins and other inputs | ||
| + | static const int rotAPin = 2; | ||
| + | static const int rotBPin = 3; | ||
| + | static const int pushSwPin = 4; | ||
| + | static const int mictxrxPin = 5; | ||
| + | static const int txRLA1Pin = 7; | ||
| + | static const int txRLA2Pin = 6; | ||
| + | static const int datatxrxPin = 8; | ||
| + | static const int modRLAPin = 9; | ||
| + | static const int modeSWPin = 11; | ||
| + | static const int scanSWPin = 10; | ||
| + | |||
| + | volatile int scanning = 0; | ||
| + | volatile int old_scanning = 0; | ||
| + | |||
| + | volatile int tx = 0; | ||
| + | volatile int oldtxrx = 0; | ||
| + | |||
| + | volatile int mod = 0; | ||
| + | volatile int oldmod = 0; | ||
| + | |||
| + | volatile int channel_freq = 0; // push-button to toggle tune method | ||
| + | volatile int old_channel_freq = 0; | ||
| + | |||
| + | volatile long scan_freq = scan_array[channel]; | ||
| + | volatile long old_scan_freq = 0; | ||
| + | |||
| + | volatile int mode = 1; // 1 = USB/LSB, 0 = CW | ||
| + | volatile int oldmode = 0; | ||
| + | |||
| + | // Rotary encoder variables, used by interrupt routines | ||
| + | volatile int rotState = 0; | ||
| + | volatile int rotAval = 1; | ||
| + | volatile int rotBval = 1; | ||
| + | |||
| + | |||
| + | int digit1 = 0; | ||
| + | int digit2 = 0; | ||
| + | int digit3 = 0; | ||
| + | int digit4 = 0; | ||
| + | int digit5 = 0; | ||
| + | int digit6 = 0; | ||
| + | int digit7 = 0; | ||
| + | |||
| + | // Instantiate the Objects | ||
| + | rgb_lcd lcd; | ||
| + | Si5351 si5351; | ||
| + | |||
| + | |||
| + | |||
| + | byte customChar[8] = { | ||
| + | 0b11111, | ||
| + | 0b11011, | ||
| + | 0b11001, | ||
| + | 0b00000, | ||
| + | 0b11001, | ||
| + | 0b11011, | ||
| + | 0b11111, | ||
| + | 0b11111 | ||
| + | }; | ||
| + | |||
| + | |||
| + | |||
| + | void setup() | ||
| + | { | ||
| + | |||
| + | |||
| + | // Set up frequency and radix switches | ||
| + | pinMode(rotAPin, | ||
| + | pinMode(rotBPin, | ||
| + | pinMode(pushSwPin, | ||
| + | | ||
| + | pinMode(mictxrxPin, | ||
| + | pinMode(datatxrxPin, | ||
| + | | ||
| + | pinMode(modeSWPin, | ||
| + | pinMode(scanSWPin, | ||
| + | pinMode(txRLA1Pin, | ||
| + | pinMode(txRLA2Pin, | ||
| + | pinMode(modRLAPin, | ||
| + | |||
| + | digitalWrite(txRLA1Pin, | ||
| + | digitalWrite(txRLA2Pin, | ||
| + | digitalWrite(modRLAPin, | ||
| + | |||
| + | // Set up interrupt pins | ||
| + | attachInterrupt(digitalPinToInterrupt(rotAPin), | ||
| + | attachInterrupt(digitalPinToInterrupt(rotBPin), | ||
| + | |||
| + | // Initialize the display | ||
| + | lcd.begin(16, | ||
| + | |||
| + | lcd.createChar(0, | ||
| + | |||
| + | lcd.cursor(); | ||
| + | |||
| + | // Initialize the Si5351 | ||
| + | |||
| + | // | ||
| + | // | ||
| + | // | ||
| + | | ||
| + | si5351.init(SI5351_CRYSTAL_LOAD_8PF, | ||
| + | si5351.set_correction(-34976, | ||
| + | si5351.set_pll(SI5351_PLL_FIXED, | ||
| + | si5351.drive_strength(SI5351_CLK0, | ||
| + | si5351.drive_strength(SI5351_CLK2, | ||
| + | |||
| + | | ||
| + | // Update display and send start frequency | ||
| + | UpdateDisplay(); | ||
| + | SendFrequency(); | ||
| + | } | ||
| + | |||
| + | |||
| + | void loop() | ||
| + | { | ||
| + | |||
| + | CheckScanSwitch(); | ||
| + | | ||
| + | // | ||
| + | | ||
| + | // | ||
| + | |||
| + | CheckModeSwitch(); | ||
| + | | ||
| + | // Check to see if the freq has changed | ||
| + | currentfreq = getfreq(); | ||
| + | | ||
| + | if (currentfreq != oldfreq) | ||
| + | { | ||
| + | |||
| + | oldfreq = currentfreq; | ||
| + | |||
| + | UpdateDisplay(); | ||
| + | SendFrequency(); | ||
| + | |||
| + | } | ||
| + | |||
| + | // Check the rotary encoder (radix) swith | ||
| + | if (digitalRead(pushSwPin) == LOW) // Read the rotary encoder switch | ||
| + | { | ||
| + | delay(500); | ||
| + | if (digitalRead(pushSwPin) == LOW) | ||
| + | { | ||
| + | | ||
| + | if (channel_freq == 1) | ||
| + | { | ||
| + | channel_freq = 0; | ||
| + | } | ||
| + | else if (channel_freq == 0) | ||
| + | { | ||
| + | channel_freq = 1; | ||
| + | } | ||
| + | // | ||
| + | | ||
| + | UpdateDisplay(); | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | } // end of main loop | ||
| + | |||
| + | |||
| + | long getfreq() | ||
| + | { | ||
| + | long temp_freq; | ||
| + | cli(); | ||
| + | temp_freq = freq; | ||
| + | sei(); | ||
| + | return temp_freq; | ||
| + | } | ||
| + | |||
| + | void CheckScanSwitch() | ||
| + | { | ||
| + | if (digitalRead(scanSWPin) == 0) | ||
| + | |||
| + | { | ||
| + | | ||
| + | scanning | ||
| + | scan_freq = 0; | ||
| + | channel = channel + 1; | ||
| + | |||
| + | if (channel > scan_mems - (no_scan + 1)) | ||
| + | { | ||
| + | channel = 0; | ||
| + | } | ||
| + | | ||
| + | freq = scan_array[channel]; | ||
| + | | ||
| + | UpdateDisplay(); | ||
| + | SendFrequency(); | ||
| + | delay(500); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | |||
| + | | ||
| + | if (scanning != old_scanning) | ||
| + | { | ||
| + | scanning = 0; | ||
| + | UpdateDisplay(); | ||
| + | } | ||
| + | old_scanning = scanning; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | //void CheckModSwitch() | ||
| + | //{ | ||
| + | // if (digitalRead(modSWPin) == 0) | ||
| + | // mod = 0; // 0 = Phone | ||
| + | // else if (digitalRead(modSWPin) == 1) | ||
| + | // mod = 1; // 1=Data | ||
| + | | ||
| + | | ||
| + | // if (mod != oldmod) | ||
| + | // { | ||
| + | // if ( mod == 0) | ||
| + | // { | ||
| + | // digitalWrite(modRLAPin, | ||
| + | // } | ||
| + | // else | ||
| + | // { | ||
| + | // digitalWrite(modRLAPin, | ||
| + | // } | ||
| + | // UpdateDisplay(); | ||
| + | // SendFrequency(); | ||
| + | // oldmod = mod; | ||
| + | // } | ||
| + | //} | ||
| + | |||
| + | |||
| + | void CheckModeSwitch() | ||
| + | { | ||
| + | if (digitalRead(modeSWPin) == 0) | ||
| + | mode = 0; // 0 = CW | ||
| + | else if (digitalRead(modeSWPin) == 1) | ||
| + | mode = 1; // 1=SSB | ||
| + | | ||
| + | | ||
| + | if (mode != oldmode) | ||
| + | { | ||
| + | if ( mode == 0) | ||
| + | { | ||
| + | | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | |||
| + | } | ||
| + | UpdateDisplay(); | ||
| + | SendFrequency(); | ||
| + | oldmode = mode; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | void CheckTXSwitch() | ||
| + | { | ||
| + | if (scanning == 0) | ||
| + | { | ||
| + | if (digitalRead(mictxrxPin) == 0) | ||
| + | |||
| + | { | ||
| + | tx = 1; // 1=TX | ||
| + | mod = 0; | ||
| + | | ||
| + | | ||
| + | |||
| + | { tx = 1; | ||
| + | mod = 1; | ||
| + | |||
| + | } else if (digitalRead(mictxrxPin) == 1) | ||
| + | | ||
| + | { tx = 0; // 0=Phone | ||
| + | | ||
| + | } else if (digitalRead(datatxrxPin) == 1) | ||
| + | |||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | if (tx != oldtxrx) | ||
| + | { | ||
| + | if ( tx == 1) | ||
| + | { | ||
| + | if ( mod == 0 ) | ||
| + | { | ||
| + | digitalWrite(modRLAPin, | ||
| + | } | ||
| + | else if ( mod == 1 ) | ||
| + | { | ||
| + | digitalWrite(modRLAPin, | ||
| + | } | ||
| + | digitalWrite(txRLA1Pin, | ||
| + | digitalWrite(txRLA2Pin, | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | digitalWrite(txRLA1Pin, | ||
| + | digitalWrite(txRLA2Pin, | ||
| + | } | ||
| + | UpdateDisplay(); | ||
| + | SendFrequency(); | ||
| + | oldtxrx = tx; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Interrupt routines | ||
| + | void ISRrotAChange() | ||
| + | { | ||
| + | if (digitalRead(rotAPin)) | ||
| + | { | ||
| + | rotAval = 1; | ||
| + | UpdateRot(); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | rotAval = 0; | ||
| + | UpdateRot(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | void ISRrotBChange() | ||
| + | { | ||
| + | if (digitalRead(rotBPin)) | ||
| + | { | ||
| + | rotBval = 1; | ||
| + | UpdateRot(); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | rotBval = 0; | ||
| + | UpdateRot(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | // Determine which way the rotary encoder is rotating and action as required | ||
| + | void UpdateRot() | ||
| + | { | ||
| + | switch (rotState) | ||
| + | { | ||
| + | case 0: // Idle state, look for direction | ||
| + | if (!rotBval) | ||
| + | rotState = 1; // CW 1 | ||
| + | if (!rotAval) | ||
| + | rotState = 11; // CCW 1 | ||
| + | break; | ||
| + | |||
| + | case 1: // CW, wait for A low while B is low | ||
| + | if (!rotBval) | ||
| + | { | ||
| + | if (!rotAval) | ||
| + | { | ||
| + | // either increment the radix or freq | ||
| + | if (channel_freq == 1) | ||
| + | { | ||
| + | updatedisplay = 1; | ||
| + | if (mode == 1) | ||
| + | { | ||
| + | freq = freq + 500; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | freq = freq + 100; | ||
| + | } | ||
| + | if (freq > bandEnd) | ||
| + | { | ||
| + | freq = bandEnd; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | else | ||
| + | { | ||
| + | channel = channel + 1; | ||
| + | | ||
| + | if (channel > mems -1) | ||
| + | { | ||
| + | channel = 0; | ||
| + | } | ||
| + | freq = channel_array[channel]; | ||
| + | } | ||
| + | rotState = 2; // CW 2 | ||
| + | } | ||
| + | } | ||
| + | else if (rotAval) | ||
| + | rotState = 0; // It was just a glitch on B, go back to start | ||
| + | break; | ||
| + | |||
| + | case 2: // CW, wait for B high | ||
| + | if (rotBval) | ||
| + | rotState = 3; // CW 3 | ||
| + | break; | ||
| + | |||
| + | case 3: // CW, wait for A high | ||
| + | if (rotAval) | ||
| + | rotState = 0; // back to idle (detent) state | ||
| + | break; | ||
| + | |||
| + | case 11: // CCW, wait for B low while A is low | ||
| + | if (!rotAval) | ||
| + | { | ||
| + | if (!rotBval) | ||
| + | { | ||
| + | if ( channel_freq == 1 ) | ||
| + | { | ||
| + | updatedisplay = 1; | ||
| + | |||
| + | if (mode == 1) | ||
| + | { | ||
| + | freq = freq - 500; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | freq = freq - 100; | ||
| + | } | ||
| + | | ||
| + | if (freq < bandStart) | ||
| + | { | ||
| + | freq = bandStart; | ||
| + | } | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | channel = channel - 1; | ||
| + | | ||
| + | if (channel < 0) | ||
| + | { | ||
| + | channel = mems - 1; | ||
| + | } | ||
| + | freq = channel_array[channel]; | ||
| + | |||
| + | } | ||
| + | rotState = 12; // CCW 2 | ||
| + | } | ||
| + | } | ||
| + | else if (rotBval) | ||
| + | rotState = 0; // It was just a glitch on A, go back to start | ||
| + | break; | ||
| + | |||
| + | case 12: // CCW, wait for A high | ||
| + | if (rotAval) | ||
| + | rotState = 13; // CCW 3 | ||
| + | break; | ||
| + | |||
| + | case 13: // CCW, wait for B high | ||
| + | if (rotBval) | ||
| + | rotState = 0; // back to idle (detent) state | ||
| + | break; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | void UpdateDisplay() | ||
| + | { | ||
| + | |||
| + | |||
| + | digit1 = (freq%10); | ||
| + | digit2 = ((freq/ | ||
| + | digit3 = ((freq/ | ||
| + | digit4 = ((freq/ | ||
| + | digit5 = ((freq/ | ||
| + | digit6 = ((freq/ | ||
| + | digit7 = ((freq/ | ||
| + | |||
| + | | ||
| + | lcd.setCursor(0, | ||
| + | lcd.print(digit7); | ||
| + | lcd.setCursor(1, | ||
| + | lcd.print("," | ||
| + | lcd.setCursor(2, | ||
| + | lcd.print(digit6); | ||
| + | lcd.setCursor(3, | ||
| + | lcd.print(digit5); | ||
| + | lcd.setCursor(4, | ||
| + | lcd.print(digit4); | ||
| + | lcd.setCursor(5, | ||
| + | lcd.print(" | ||
| + | lcd.setCursor(6, | ||
| + | lcd.print(digit3); | ||
| + | lcd.setCursor(7, | ||
| + | lcd.print(digit2); | ||
| + | | ||
| + | lcd.setCursor(8, | ||
| + | lcd.print(" | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | lcd.setCursor(0, | ||
| + | lcd.print(" | ||
| + | | ||
| + | | ||
| + | | ||
| + | lcd.setCursor(channel, | ||
| + | | ||
| + | |||
| + | if (scanning == 1) | ||
| + | { | ||
| + | // lcd.print(" | ||
| + | |||
| + | lcd.write((byte)0); | ||
| + | } | ||
| + | | ||
| + | /* | ||
| + | //if (channel < 10) | ||
| + | //{ | ||
| + | // | ||
| + | //} | ||
| + | // | ||
| + | |||
| + | | ||
| + | if (freq == 5287200 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5290000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5364700 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5450000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5505000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5317000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5366500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5258500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5278500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5288500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5371500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5398500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5403500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5195000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5262000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | | ||
| + | |||
| + | if ((freq >= 5259000) && (freq < 5262000) ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | |||
| + | | ||
| + | */ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | | ||
| + | |||
| + | if (tx == 0) | ||
| + | { lcd.print(" | ||
| + | | ||
| + | } else if (tx == 1) | ||
| + | { | ||
| + | lcd.print(" | ||
| + | } | ||
| + | | ||
| + | lcd.setCursor(8, | ||
| + | if (mode == 1) | ||
| + | { | ||
| + | lcd.print(" | ||
| + | } | ||
| + | if (mode == 0) | ||
| + | { | ||
| + | lcd.print(" | ||
| + | } | ||
| + | | ||
| + | lcd.setCursor(12, | ||
| + | if ( mode == 0 ) | ||
| + | { | ||
| + | lcd.print(" | ||
| + | // | ||
| + | } | ||
| + | else | ||
| + | | ||
| + | { | ||
| + | if (mod == 0) | ||
| + | { | ||
| + | lcd.print(" | ||
| + | // | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | | ||
| + | // | ||
| + | } | ||
| + | } | ||
| + | if (channel_freq == 1) | ||
| + | { | ||
| + | if (mode == 1) | ||
| + | { | ||
| + | lcd.setCursor(6, | ||
| + | } | ||
| + | else if ( mode == 0 ) | ||
| + | { | ||
| + | lcd.setCursor(7, | ||
| + | } | ||
| + | lcd.blink(); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | lcd.noBlink(); | ||
| + | } | ||
| + | } // end of updatedisplay() | ||
| + | |||
| + | |||
| + | void SendFrequency() | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | { | ||
| + | |||
| + | if (mode == 1 ) // SSB | ||
| + | |||
| + | { | ||
| + | si5351.set_freq(((txcio + freq) * 100ULL), SI5351_CLK0); | ||
| + | si5351.set_freq((txcio * 100ULL), SI5351_CLK2); | ||
| + | |||
| + | } | ||
| + | |||
| + | else if (mode == 0) // CW | ||
| + | |||
| + | if ( tx == 0 ) | ||
| + | |||
| + | { | ||
| + | |||
| + | si5351.set_freq(((txcio + freq - cwoffset - filteroffset) * 100ULL), SI5351_CLK0); | ||
| + | si5351.set_freq(((txcio | ||
| + | | ||
| + | } | ||
| + | |||
| + | else if (tx == 1 ) | ||
| + | |||
| + | { | ||
| + | |||
| + | si5351.set_freq(((txcio + freq - cwoffset - filteroffset) * 100ULL), SI5351_CLK0); | ||
| + | si5351.set_freq(((txcio - cwoffset - filteroffset) * 100ULL), SI5351_CLK2); | ||
| + | |||
| + | } | ||
| + | |||
| + | } // end of sendfrequency() | ||
| + | |||
| + | </ | ||
| + | |||
| + | ++++ | ||
| + | |||
| + | ==== Full TX/RX - with SSB, CW & Scan ==== | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | ++++ Firmware (Click to view) | | ||
| + | |||
| + | <code c> | ||
| + | |||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | char version[] = " | ||
| + | |||
| + | const long channel_array[] = | ||
| + | { | ||
| + | 5258500, | ||
| + | 5278500, | ||
| + | 5301000, | ||
| + | 5334000, | ||
| + | 5363000, | ||
| + | 5379000, | ||
| + | 5345000, | ||
| + | 5195000, | ||
| + | } ; | ||
| + | |||
| + | const long scan_array[] = | ||
| + | { | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } ; | ||
| + | |||
| + | |||
| + | const int mems = sizeof(channel_array)/ | ||
| + | |||
| + | const int scan_mems = sizeof(scan_array)/ | ||
| + | |||
| + | // the last " | ||
| + | // channel_array are not to be scanned. | ||
| + | // Put the channels not to be scanned last | ||
| + | // in the array and update no_scan to reflect. | ||
| + | |||
| + | const int no_scan = 0; | ||
| + | |||
| + | const long bandStart = 5000000; | ||
| + | const long bandEnd = 6000000; | ||
| + | const long txcio = 9001200; | ||
| + | |||
| + | const long cwoffset = 600; | ||
| + | const long filteroffset = 500; | ||
| + | |||
| + | volatile int channel = 01; | ||
| + | |||
| + | volatile long freq = channel_array[channel]; | ||
| + | volatile long oldfreq = 0; | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | volatile long currentfreq = 0; | ||
| + | volatile int updatedisplay = 0; | ||
| + | |||
| + | // Rotary encoder pins and other inputs | ||
| + | static const int rotAPin = 2; | ||
| + | static const int rotBPin = 3; | ||
| + | static const int pushSwPin = 4; | ||
| + | static const int mictxrxPin = 5; | ||
| + | static const int txRLA1Pin = 7; | ||
| + | static const int txRLA2Pin = 6; | ||
| + | static const int datatxrxPin = 8; | ||
| + | static const int modRLAPin = 9; | ||
| + | static const int modeSWPin = 11; | ||
| + | static const int scanSWPin = 10; | ||
| + | |||
| + | volatile int scanning = 0; | ||
| + | volatile int old_scanning = 0; | ||
| + | |||
| + | volatile int tx = 0; | ||
| + | volatile int oldtxrx = 0; | ||
| + | |||
| + | volatile int mod = 0; | ||
| + | volatile int oldmod = 0; | ||
| + | |||
| + | volatile int channel_freq = 0; // push-button to toggle tune method | ||
| + | volatile int old_channel_freq = 0; | ||
| + | |||
| + | volatile long scan_freq = scan_array[channel]; | ||
| + | volatile long old_scan_freq = 0; | ||
| + | |||
| + | volatile int mode = 1; // 1 = USB/LSB, 0 = CW | ||
| + | volatile int oldmode = 0; | ||
| + | |||
| + | // Rotary encoder variables, used by interrupt routines | ||
| + | volatile int rotState = 0; | ||
| + | volatile int rotAval = 1; | ||
| + | volatile int rotBval = 1; | ||
| + | |||
| + | |||
| + | int digit1 = 0; | ||
| + | int digit2 = 0; | ||
| + | int digit3 = 0; | ||
| + | int digit4 = 0; | ||
| + | int digit5 = 0; | ||
| + | int digit6 = 0; | ||
| + | int digit7 = 0; | ||
| + | |||
| + | // Instantiate the Objects | ||
| + | rgb_lcd lcd; | ||
| + | Si5351 si5351; | ||
| + | |||
| + | |||
| + | |||
| + | byte customChar[8] = { | ||
| + | 0b11111, | ||
| + | 0b11011, | ||
| + | 0b11001, | ||
| + | 0b00000, | ||
| + | 0b11001, | ||
| + | 0b11011, | ||
| + | 0b11111, | ||
| + | 0b11111 | ||
| + | }; | ||
| + | |||
| + | |||
| + | |||
| + | void setup() | ||
| + | { | ||
| + | |||
| + | |||
| + | // Set up frequency and radix switches | ||
| + | pinMode(rotAPin, | ||
| + | pinMode(rotBPin, | ||
| + | pinMode(pushSwPin, | ||
| + | | ||
| + | pinMode(mictxrxPin, | ||
| + | pinMode(datatxrxPin, | ||
| + | | ||
| + | pinMode(modeSWPin, | ||
| + | pinMode(scanSWPin, | ||
| + | pinMode(txRLA1Pin, | ||
| + | pinMode(txRLA2Pin, | ||
| + | pinMode(modRLAPin, | ||
| + | |||
| + | digitalWrite(txRLA1Pin, | ||
| + | digitalWrite(txRLA2Pin, | ||
| + | digitalWrite(modRLAPin, | ||
| + | |||
| + | // Set up interrupt pins | ||
| + | attachInterrupt(digitalPinToInterrupt(rotAPin), | ||
| + | attachInterrupt(digitalPinToInterrupt(rotBPin), | ||
| + | |||
| + | // Initialize the display | ||
| + | lcd.begin(16, | ||
| + | |||
| + | lcd.createChar(0, | ||
| + | |||
| + | lcd.cursor(); | ||
| + | |||
| + | // Initialize the Si5351 | ||
| + | |||
| + | // | ||
| + | // | ||
| + | // | ||
| + | | ||
| + | si5351.init(SI5351_CRYSTAL_LOAD_8PF, | ||
| + | si5351.set_correction(-34976, | ||
| + | si5351.set_pll(SI5351_PLL_FIXED, | ||
| + | si5351.drive_strength(SI5351_CLK0, | ||
| + | si5351.drive_strength(SI5351_CLK2, | ||
| + | |||
| + | | ||
| + | // Update display and send start frequency | ||
| + | UpdateDisplay(); | ||
| + | SendFrequency(); | ||
| + | } | ||
| + | |||
| + | |||
| + | void loop() | ||
| + | { | ||
| + | |||
| + | CheckScanSwitch(); | ||
| + | | ||
| + | CheckTXSwitch(); | ||
| + | | ||
| + | // | ||
| + | |||
| + | CheckModeSwitch(); | ||
| + | | ||
| + | // Check to see if the freq has changed | ||
| + | currentfreq = getfreq(); | ||
| + | | ||
| + | if (currentfreq != oldfreq) | ||
| + | { | ||
| + | |||
| + | oldfreq = currentfreq; | ||
| + | |||
| + | UpdateDisplay(); | ||
| + | SendFrequency(); | ||
| + | |||
| + | } | ||
| + | |||
| + | // Check the rotary encoder (radix) swith | ||
| + | if (digitalRead(pushSwPin) == LOW) // Read the rotary encoder switch | ||
| + | { | ||
| + | delay(500); | ||
| + | if (digitalRead(pushSwPin) == LOW) | ||
| + | { | ||
| + | | ||
| + | if (channel_freq == 1) | ||
| + | { | ||
| + | channel_freq = 0; | ||
| + | } | ||
| + | else if (channel_freq == 0) | ||
| + | { | ||
| + | channel_freq = 1; | ||
| + | } | ||
| + | // | ||
| + | | ||
| + | UpdateDisplay(); | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | } // end of main loop | ||
| + | |||
| + | |||
| + | long getfreq() | ||
| + | { | ||
| + | long temp_freq; | ||
| + | cli(); | ||
| + | temp_freq = freq; | ||
| + | sei(); | ||
| + | return temp_freq; | ||
| + | } | ||
| + | |||
| + | void CheckScanSwitch() | ||
| + | { | ||
| + | if (digitalRead(scanSWPin) == 0) | ||
| + | |||
| + | { | ||
| + | | ||
| + | scanning | ||
| + | scan_freq = 0; | ||
| + | channel = channel + 1; | ||
| + | |||
| + | if (channel > scan_mems - (no_scan + 1)) | ||
| + | { | ||
| + | channel = 0; | ||
| + | } | ||
| + | | ||
| + | freq = scan_array[channel]; | ||
| + | | ||
| + | UpdateDisplay(); | ||
| + | SendFrequency(); | ||
| + | delay(500); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | |||
| + | | ||
| + | if (scanning != old_scanning) | ||
| + | { | ||
| + | scanning = 0; | ||
| + | UpdateDisplay(); | ||
| + | } | ||
| + | old_scanning = scanning; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | //void CheckModSwitch() | ||
| + | //{ | ||
| + | // if (digitalRead(modSWPin) == 0) | ||
| + | // mod = 0; // 0 = Phone | ||
| + | // else if (digitalRead(modSWPin) == 1) | ||
| + | // mod = 1; // 1=Data | ||
| + | | ||
| + | | ||
| + | // if (mod != oldmod) | ||
| + | // { | ||
| + | // if ( mod == 0) | ||
| + | // { | ||
| + | // digitalWrite(modRLAPin, | ||
| + | // } | ||
| + | // else | ||
| + | // { | ||
| + | // digitalWrite(modRLAPin, | ||
| + | // } | ||
| + | // UpdateDisplay(); | ||
| + | // SendFrequency(); | ||
| + | // oldmod = mod; | ||
| + | // } | ||
| + | //} | ||
| + | |||
| + | |||
| + | void CheckModeSwitch() | ||
| + | { | ||
| + | if (digitalRead(modeSWPin) == 0) | ||
| + | mode = 0; // 0 = CW | ||
| + | else if (digitalRead(modeSWPin) == 1) | ||
| + | mode = 1; // 1=SSB | ||
| + | | ||
| + | | ||
| + | if (mode != oldmode) | ||
| + | { | ||
| + | if ( mode == 0) | ||
| + | { | ||
| + | | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | |||
| + | } | ||
| + | UpdateDisplay(); | ||
| + | SendFrequency(); | ||
| + | oldmode = mode; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | void CheckTXSwitch() | ||
| + | { | ||
| + | if (scanning == 0) | ||
| + | { | ||
| + | if (digitalRead(mictxrxPin) == 0) | ||
| + | |||
| + | { | ||
| + | tx = 1; // 1=TX | ||
| + | mod = 0; | ||
| + | | ||
| + | | ||
| + | |||
| + | { tx = 1; | ||
| + | mod = 1; | ||
| + | |||
| + | } else if (digitalRead(mictxrxPin) == 1) | ||
| + | | ||
| + | { tx = 0; // 0=Phone | ||
| + | | ||
| + | } else if (digitalRead(datatxrxPin) == 1) | ||
| + | |||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | if (tx != oldtxrx) | ||
| + | { | ||
| + | if ( tx == 1) | ||
| + | { | ||
| + | if ( mod == 0 ) | ||
| + | { | ||
| + | digitalWrite(modRLAPin, | ||
| + | } | ||
| + | else if ( mod == 1 ) | ||
| + | { | ||
| + | digitalWrite(modRLAPin, | ||
| + | } | ||
| + | digitalWrite(txRLA1Pin, | ||
| + | digitalWrite(txRLA2Pin, | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | digitalWrite(txRLA1Pin, | ||
| + | digitalWrite(txRLA2Pin, | ||
| + | } | ||
| + | UpdateDisplay(); | ||
| + | SendFrequency(); | ||
| + | oldtxrx = tx; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Interrupt routines | ||
| + | void ISRrotAChange() | ||
| + | { | ||
| + | if (digitalRead(rotAPin)) | ||
| + | { | ||
| + | rotAval = 1; | ||
| + | UpdateRot(); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | rotAval = 0; | ||
| + | UpdateRot(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | void ISRrotBChange() | ||
| + | { | ||
| + | if (digitalRead(rotBPin)) | ||
| + | { | ||
| + | rotBval = 1; | ||
| + | UpdateRot(); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | rotBval = 0; | ||
| + | UpdateRot(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | // Determine which way the rotary encoder is rotating and action as required | ||
| + | void UpdateRot() | ||
| + | { | ||
| + | switch (rotState) | ||
| + | { | ||
| + | case 0: // Idle state, look for direction | ||
| + | if (!rotBval) | ||
| + | rotState = 1; // CW 1 | ||
| + | if (!rotAval) | ||
| + | rotState = 11; // CCW 1 | ||
| + | break; | ||
| + | |||
| + | case 1: // CW, wait for A low while B is low | ||
| + | if (!rotBval) | ||
| + | { | ||
| + | if (!rotAval) | ||
| + | { | ||
| + | // either increment the radix or freq | ||
| + | if (channel_freq == 1) | ||
| + | { | ||
| + | updatedisplay = 1; | ||
| + | if (mode == 1) | ||
| + | { | ||
| + | freq = freq + 500; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | freq = freq + 100; | ||
| + | } | ||
| + | if (freq > bandEnd) | ||
| + | { | ||
| + | freq = bandEnd; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | else | ||
| + | { | ||
| + | channel = channel + 1; | ||
| + | | ||
| + | if (channel > mems -1) | ||
| + | { | ||
| + | channel = 0; | ||
| + | } | ||
| + | freq = channel_array[channel]; | ||
| + | } | ||
| + | rotState = 2; // CW 2 | ||
| + | } | ||
| + | } | ||
| + | else if (rotAval) | ||
| + | rotState = 0; // It was just a glitch on B, go back to start | ||
| + | break; | ||
| + | |||
| + | case 2: // CW, wait for B high | ||
| + | if (rotBval) | ||
| + | rotState = 3; // CW 3 | ||
| + | break; | ||
| + | |||
| + | case 3: // CW, wait for A high | ||
| + | if (rotAval) | ||
| + | rotState = 0; // back to idle (detent) state | ||
| + | break; | ||
| + | |||
| + | case 11: // CCW, wait for B low while A is low | ||
| + | if (!rotAval) | ||
| + | { | ||
| + | if (!rotBval) | ||
| + | { | ||
| + | if ( channel_freq == 1 ) | ||
| + | { | ||
| + | updatedisplay = 1; | ||
| + | |||
| + | if (mode == 1) | ||
| + | { | ||
| + | freq = freq - 500; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | freq = freq - 100; | ||
| + | } | ||
| + | | ||
| + | if (freq < bandStart) | ||
| + | { | ||
| + | freq = bandStart; | ||
| + | } | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | channel = channel - 1; | ||
| + | | ||
| + | if (channel < 0) | ||
| + | { | ||
| + | channel = mems - 1; | ||
| + | } | ||
| + | freq = channel_array[channel]; | ||
| + | |||
| + | } | ||
| + | rotState = 12; // CCW 2 | ||
| + | } | ||
| + | } | ||
| + | else if (rotBval) | ||
| + | rotState = 0; // It was just a glitch on A, go back to start | ||
| + | break; | ||
| + | |||
| + | case 12: // CCW, wait for A high | ||
| + | if (rotAval) | ||
| + | rotState = 13; // CCW 3 | ||
| + | break; | ||
| + | |||
| + | case 13: // CCW, wait for B high | ||
| + | if (rotBval) | ||
| + | rotState = 0; // back to idle (detent) state | ||
| + | break; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | void UpdateDisplay() | ||
| + | { | ||
| + | |||
| + | |||
| + | digit1 = (freq%10); | ||
| + | digit2 = ((freq/ | ||
| + | digit3 = ((freq/ | ||
| + | digit4 = ((freq/ | ||
| + | digit5 = ((freq/ | ||
| + | digit6 = ((freq/ | ||
| + | digit7 = ((freq/ | ||
| + | |||
| + | | ||
| + | lcd.setCursor(0, | ||
| + | lcd.print(digit7); | ||
| + | lcd.setCursor(1, | ||
| + | lcd.print("," | ||
| + | lcd.setCursor(2, | ||
| + | lcd.print(digit6); | ||
| + | lcd.setCursor(3, | ||
| + | lcd.print(digit5); | ||
| + | lcd.setCursor(4, | ||
| + | lcd.print(digit4); | ||
| + | lcd.setCursor(5, | ||
| + | lcd.print(" | ||
| + | lcd.setCursor(6, | ||
| + | lcd.print(digit3); | ||
| + | lcd.setCursor(7, | ||
| + | lcd.print(digit2); | ||
| + | | ||
| + | lcd.setCursor(8, | ||
| + | lcd.print(" | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | lcd.setCursor(0, | ||
| + | lcd.print(" | ||
| + | | ||
| + | | ||
| + | | ||
| + | lcd.setCursor(channel, | ||
| + | | ||
| + | |||
| + | if (scanning == 1) | ||
| + | { | ||
| + | // lcd.print(" | ||
| + | |||
| + | lcd.write((byte)0); | ||
| + | } | ||
| + | | ||
| + | /* | ||
| + | //if (channel < 10) | ||
| + | //{ | ||
| + | // | ||
| + | //} | ||
| + | // | ||
| + | |||
| + | | ||
| + | if (freq == 5287200 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5290000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5364700 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5450000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5505000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5317000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5366500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5258500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5278500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5288500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5371500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5398500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5403500 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5195000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | if (freq == 5262000 ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | | ||
| + | |||
| + | if ((freq >= 5259000) && (freq < 5262000) ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | lcd.print(" | ||
| + | } | ||
| + | |||
| + | |||
| + | | ||
| + | */ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | | ||
| + | |||
| + | if (tx == 0) | ||
| + | { lcd.print(" | ||
| + | | ||
| + | } else if (tx == 1) | ||
| + | { | ||
| + | lcd.print(" | ||
| + | } | ||
| + | | ||
| + | lcd.setCursor(8, | ||
| + | if (mode == 1) | ||
| + | { | ||
| + | lcd.print(" | ||
| + | } | ||
| + | if (mode == 0) | ||
| + | { | ||
| + | lcd.print(" | ||
| + | } | ||
| + | | ||
| + | lcd.setCursor(12, | ||
| + | if ( mode == 0 ) | ||
| + | { | ||
| + | lcd.print(" | ||
| + | // | ||
| + | } | ||
| + | else | ||
| + | | ||
| + | { | ||
| + | if (mod == 0) | ||
| + | { | ||
| + | lcd.print(" | ||
| + | // | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | | ||
| + | // | ||
| + | } | ||
| + | } | ||
| + | if (channel_freq == 1) | ||
| + | { | ||
| + | if (mode == 1) | ||
| + | { | ||
| + | lcd.setCursor(6, | ||
| + | } | ||
| + | else if ( mode == 0 ) | ||
| + | { | ||
| + | lcd.setCursor(7, | ||
| + | } | ||
| + | lcd.blink(); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | lcd.noBlink(); | ||
| + | } | ||
| + | } // end of updatedisplay() | ||
| + | |||
| + | |||
| + | void SendFrequency() | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | { | ||
| + | |||
| + | if (mode == 1 ) // SSB | ||
| + | |||
| + | { | ||
| + | si5351.set_freq(((txcio + freq) * 100ULL), SI5351_CLK0); | ||
| + | si5351.set_freq((txcio * 100ULL), SI5351_CLK2); | ||
| + | |||
| + | } | ||
| + | |||
| + | else if (mode == 0) // CW | ||
| + | |||
| + | if ( tx == 0 ) | ||
| + | |||
| + | { | ||
| + | |||
| + | si5351.set_freq(((txcio + freq - cwoffset - filteroffset) * 100ULL), SI5351_CLK0); | ||
| + | si5351.set_freq(((txcio | ||
| + | | ||
| + | } | ||
| + | |||
| + | else if (tx == 1 ) | ||
| + | |||
| + | { | ||
| + | |||
| + | si5351.set_freq(((txcio + freq - cwoffset - filteroffset) * 100ULL), SI5351_CLK0); | ||
| + | si5351.set_freq(((txcio - cwoffset - filteroffset) * 100ULL), SI5351_CLK2); | ||
| + | |||
| + | } | ||
| + | |||
| + | } // end of sendfrequency() | ||
| + | |||
| + | </ | ||
| + | ++++ | ||
| Line 14: | Line 1668: | ||
| Page updated : ~~LASTMOD~~ | Page updated : ~~LASTMOD~~ | ||
| - | {{tag>}} | + | {{tag>radio arduino |