kopia lustrzana https://github.com/threeme3/usdx
Fixed an overflow issue in Hilbert transform filter. Increased SSB bandwidth to 2.4 kHz.
rodzic
963eb4a323
commit
e5c3197c53
23
QCX-SSB.ino
23
QCX-SSB.ino
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// https://github.com/threeme3/QCX-SSB
|
||||
|
||||
#define VERSION "1.01a"
|
||||
#define VERSION "1.01b"
|
||||
|
||||
// QCX pin defintion
|
||||
#define LCD_D4 0
|
||||
|
@ -33,7 +33,7 @@ LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
|
|||
#include <avr/wdt.h>
|
||||
#define F_CPU 20000000 // Crystal frequency of XTAL1
|
||||
|
||||
#define I2C_DELAY 6 // Determines I2C Speed (2=939kb/s (too fast!!); 3=822kb/s; 4=731kb/s; 5=658kb/s; 6=598kb/s [default]). Increase this value when you get I2C tx errors (E05); decrease this value when you get a CPU overload (E01). An increment eats ~3.5% CPU load; minimum value is 3 on my QCX, resulting in 84.5% CPU load
|
||||
#define I2C_DELAY 4 // Determines I2C Speed (2=939kb/s (too fast!!); 3=822kb/s; 4=731kb/s; 5=658kb/s; 6=598kb/s). Increase this value when you get I2C tx errors (E05); decrease this value when you get a CPU overload (E01). An increment eats ~3.5% CPU load; minimum value is 3 on my QCX, resulting in 84.5% CPU load
|
||||
#define I2C_DDR DDRC // Pins for the I2C bit banging
|
||||
#define I2C_PIN PINC
|
||||
#define I2C_PORT PORTC
|
||||
|
@ -373,9 +373,9 @@ inline void vox(bool trigger)
|
|||
}
|
||||
|
||||
volatile uint8_t drive = 4;
|
||||
#define F_SAMP 4401 //4400 // ADC sample-rate; is best a multiple _UA and fits exactly in OCR0A = ((F_CPU / 64) / F_SAMP) - 1 , should not exceed CPU utilization (validate with test_samplerate)
|
||||
#define _UA (4401) //360 // unit angle; integer representation of one full circle turn or 2pi radials or 360 degrees, should be a integer divider of F_SAMP and maximized to have higest precision
|
||||
#define MAX_DP (_UA/1) //(_UA/2) // the occupied SSB bandwidth can be further reduced by restricting the maximum phase change (set MAX_DP to _UA/2).
|
||||
#define F_SAMP 4807 // 4807 4401 // ADC sample-rate; is best a multiple _UA and fits exactly in OCR0A = ((F_CPU / 64) / F_SAMP) - 1 , should not exceed CPU utilization (validate with test_samplerate)
|
||||
#define _UA (F_SAMP) //360 // unit angle; integer representation of one full circle turn or 2pi radials or 360 degrees, should be a integer divider of F_SAMP and maximized to have higest precision
|
||||
//#define MAX_DP (_UA/1) //(_UA/2) // the occupied SSB bandwidth can be further reduced by restricting the maximum phase change (set MAX_DP to _UA/2).
|
||||
|
||||
inline int16_t arctan3(int16_t q, int16_t i) // error ~ 0.8 degree
|
||||
{ // source: [1] http://www-labs.iro.umontreal.ca/~mignotte/IFT2425/Documents/EfficientApproximationArctgFunction.pdf
|
||||
|
@ -406,28 +406,29 @@ inline int16_t ssb(int16_t in)
|
|||
v[15] = in - prev_in; // DC decoupling
|
||||
|
||||
i = v[7];
|
||||
q = ((v[0] - v[14]) * 2 + (v[2] - v[12]) * 8 + (v[4] - v[10]) * 21 + v[6] * 79 - v[8] * 79) / 128; // Hilbert transform, 40dB side-band rejection in 400..1900Hz (4402 SPS) when used in image-rejection scenario
|
||||
q = ((v[0] - v[14]) * 2 + (v[2] - v[12]) * 8 + (v[4] - v[10]) * 21 + (v[6] - v[8]) * 15) / 128 + (v[6] - v[8]) / 2; // Hilbert transform, 40dB side-band rejection in 400..1900Hz (@4kSPS) when used in image-rejection scenario; (Hilbert transform require 5 additional bits)
|
||||
|
||||
uint16_t _amp = abs(i) > abs(q) ? abs(i) + abs(q) / 4 : abs(q) + abs(i) / 4; // approximation of: amp = sqrt(i*i + q*q); error 0.95dB
|
||||
|
||||
#define VOX_THRESHOLD (1 << 1) // 1*6=6dB above ADC noise level
|
||||
#define VOX_THRESHOLD (1 << 1) // 1*6dB above ADC noise level
|
||||
if(vox_enable) vox((_amp > VOX_THRESHOLD));
|
||||
|
||||
_amp = _amp << drive;
|
||||
_amp = ((_amp > 255) || (drive == 8)) ? 255 : _amp; // clip or when drive=8 use max output
|
||||
OCR1BL = (tx) ? lut[_amp] : 0; // submit amplitude to PWM register
|
||||
OCR1BL = (tx) ? lut[_amp] : 0; // submit amplitude to PWM register; can be done best as soon as possible to make sure that the new envelope setting is stabalized when the phase change occurs
|
||||
|
||||
static int16_t prev_phase;
|
||||
int16_t phase = arctan3(q, i);
|
||||
int16_t dp = phase - prev_phase; // phase difference and restriction
|
||||
prev_phase = phase;
|
||||
|
||||
if(dp < 0) dp = dp + _UA; // prevent negative frequencies to reduce spur on other sideband
|
||||
if(dp < 0) dp = dp + _UA; // make negative phase shifts positive: prevents negative frequencies and will reduce spurs on other sideband
|
||||
#ifdef MAX_DP
|
||||
if(dp > MAX_DP){ // dp should be less than half unit-angle in order to keep frequencies below F_SAMP/2
|
||||
prev_phase = phase - (dp - MAX_DP); // substract restdp
|
||||
dp = MAX_DP;
|
||||
}
|
||||
|
||||
#endif
|
||||
if(usb)
|
||||
return dp * ( F_SAMP / _UA); // calculate frequency-difference based on phase-difference
|
||||
else
|
||||
|
@ -435,7 +436,7 @@ inline int16_t ssb(int16_t in)
|
|||
}
|
||||
|
||||
volatile uint16_t numSamples = 0;
|
||||
#define MIC_ATTEN 1 // 6dB attenuation/step, since LSB bits anyway are quite noisy
|
||||
#define MIC_ATTEN 1 // 1*6dB attenuation (note that the LSB bits are quite noisy)
|
||||
|
||||
// This is the ADC ISR, issued with sample-rate via timer1 compb interrupt.
|
||||
// It performs in real-time the ADC sampling, calculation of SSB phase-differences, calculation of SI5351 frequency registers and send the registers to SI5351 over I2C.
|
||||
|
|
13
README.md
13
README.md
|
@ -1,7 +1,7 @@
|
|||
# **ⓆⒸⓍ-ⓈⓈⒷ**
|
||||
|
||||
# QCX-SSB: SSB with your QCX transceiver (modification)
|
||||
This is a simple and experimental modification that transforms a [QCX] into a (Class-E driven) SSB transceiver. It can be used to make QRP SSB contacts, or (in combination with a PC) used for the digital modes such as FT8. It can be fully-continuous tuned through bands 160m-10m in the LSB/USB-modes with a 2200Hz bandwidth has up to 5W PEP SSB output and features a software-based full Break-In VOX for fast RX/TX switching in voice and digital operations.
|
||||
This is a simple and experimental modification that transforms a [QCX] into a (Class-E driven) SSB transceiver. It can be used to make QRP SSB contacts, or (in combination with a PC) used for the digital modes such as FT8. It can be fully-continuous tuned through bands 160m-10m in the LSB/USB-modes with a 2400Hz bandwidth has up to 5W PEP SSB output and features a software-based full Break-In VOX for fast RX/TX switching in voice and digital operations.
|
||||
|
||||
The SSB transmit-stage is implemented completely in a digital and software-based manner: at the heart the
|
||||
ATMEGA328P is sampling the input-audio and reconstructing a SSB-signal by controlling the SI5351 PLL phase (through tiny frequency changes over 800kbit/s I2C) and controlling the PA Power (through PWM on the key-shaping circuit). In this way a highly power-efficient class-E driven SSB-signal can be realized; a PWM driven class-E design keeps the SSB transceiver simple, tiny, cool, power-efficient and low-cost (ie. no need for power-inefficient and complex linear amplifier with bulky heat-sink as often is seen in SSB transceivers).
|
||||
|
@ -18,7 +18,7 @@ pe1nnz@amsat.org
|
|||
## List of features:
|
||||
- **[EER]/[Polar-transmitter] Class-E** driven SSB transmit-stage
|
||||
- Approximately **5W PEP SSB output** (depending on supply voltage, PA voltage regulated through PWM with **48dB dynamic range**)
|
||||
- Supports **USB and LSB** modes up to **2200 Hz bandwidth** (receiver and transmitter)
|
||||
- Supports **USB and LSB** modes up to **2400 Hz bandwidth** (receiver and transmitter)
|
||||
- Two-tone third-order intermodulation distortion **(IMD3) of -33dBc** and **carrier/side-band rejection better than -45dBc** (two-tone)
|
||||
- Receiver unwanted side-band **rejection up to -20dB**
|
||||
- Continuously tunable through bands **80m-10m** (anything between 20kHz-99MHz is tunable but with degraded or loss in performance)
|
||||
|
@ -108,7 +108,7 @@ For SSB reception the QCX CW filter is too small, therefore the first modificati
|
|||
|
||||
For SSB transmission the QCX DVM-circuitry is changed and used as an audio-input circuit (installation steps 2-5). An electret-microphone (with PTT switch) is added to the Paddle jack connecting the DVM-circuitry, whereby the DOT input acts as the PTT and the DASH input acts as the audio-input (installation step 7). The electret microphone is biased with 5V through a 10K resistor. A 10nF blocking capacitor prevents RF leakage into the circuit. The audio is fed into ADC2 input of the ATMEGA328P microprocessor through a 220nF decoupling capacitor. The ADC2 input is biased at 0.55V via a divider network of 10K to a 1.1V analog reference voltage, with 10-bits ADC resolution this means the microphone-input sensitivity is about 1mV (1.1V/1024) which is just sufficient to process unamplified speech.
|
||||
|
||||
A new QCX-SSB firmware is uploaded to the ATMEGA328P (installation step 8), and facilitates a [digital SSB generation technique] in a completely software-based manner. A DSP algorithm samples the ADC2 audio-input at a rate of 4400 samples/s, performs a Hilbert transformation and determines the phase and amplitude of the complex-signal; the phase-changes are restricted<sup>[4](#note4)</sup> and transformed into either positive (for USB) or negative (for LSB) phase changes which in turn transformed into temporary frequency changes which are sent 4400 times per second over 800kbit/s I2C towards the SI5351 PLL. This result in phase changes on the SSB carrier signal and delivers a SSB-signal with a bandwidth of 2200 Hz whereby spurious in the opposite side-band components is attenuated.
|
||||
A new QCX-SSB firmware is uploaded to the ATMEGA328P (installation step 8), and facilitates a [digital SSB generation technique] in a completely software-based manner. A DSP algorithm samples the ADC2 audio-input at a rate of 4400 samples/s, performs a Hilbert transformation and determines the phase and amplitude of the complex-signal; the phase-changes are restricted<sup>[4](#note4)</sup> and transformed into either positive (for USB) or negative (for LSB) phase changes which in turn transformed into temporary frequency changes which are sent 4400 times per second over 800kbit/s I2C towards the SI5351 PLL. This result in phase changes on the SSB carrier signal and delivers a SSB-signal with a bandwidth of 2400 Hz whereby spurious in the opposite side-band components is attenuated.
|
||||
|
||||
The amplitude of the complex-signal controls the supply-voltage of the PA, and thus the envelope of the SSB-signal. The key-shaping circuit is controlled with a 32kHz PWM signal, which can control the PA voltage from 0 to about 12V in 256 steps, providing a dynamic range of (log2(256) * 6 =) 48dB in the SSB signal. C31 is removed (installation step 6) to ensure that Q6 is operating as a digital switch, this improves the efficiency, thermal stability, linearity, dynamic range and response-time. Though the amplitude information is not mandatory to make a SSB signal intelligable, adding amplitude information improves quality. The complex-amplitude is also used in VOX-mode to determine when RX and TX transitions are supposed to be made.
|
||||
|
||||
|
@ -116,7 +116,7 @@ The IMD performance is related dependent on the quality of the system: the linea
|
|||
|
||||
|
||||
## Results
|
||||
Here is a [sample1] and [sample2] me calling CQ on 40m with my QCX-SSB at 5W and received back by the Hack Green websdr about 400km away.
|
||||
Here is a [sample] me calling CQ on 40m with my QCX-SSB at 5W and received back by the Hack Green websdr about 400km away.
|
||||
|
||||
Several OMs reported a successful QCX-SSB modification and were able to make SSB QRP DX contacts over thousands of kilometers on the 20m and 40m bands. During CQ WW contest I was able to make 34 random QSOs on 40m with 5W and an inverted-V over the house in just a few hours with CN3A as my furthest contact, I could observe the benefits of using SSB with constant-envelope in cases where my signal was weak; for FT8 a Raspberry Pi 3B+ with JTDX was used to make FT8 contacts all the way up to NA.
|
||||
|
||||
|
@ -127,7 +127,7 @@ The following performance measurements were made with QCX-SSB R1.01, a modified
|
|||
- Opposite side-band rejection (two-tone): better than -45dBc
|
||||
- Carrier rejection (two-tone): better than -45dBc
|
||||
- Wide-band spurious (two-tone): better than -45dBc
|
||||
- 3dB bandwidth (sweep): 400..2130Hz
|
||||
- 3dB bandwidth (sweep): 400..2330Hz
|
||||
![twotone](https://raw.githubusercontent.com/threeme3/QCX-SSB/master/twotone.png)
|
||||
|
||||
Known issues:
|
||||
|
@ -198,7 +198,6 @@ Known issues:
|
|||
|
||||
[HD44780]: https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
|
||||
|
||||
[sample1]: https://youtu.be/lna4xQDhK20
|
||||
[sample]: https://youtu.be/Q6_BCqBZjZU
|
||||
|
||||
[sample2]: https://youtu.be/DrUMMQo8Fb0
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue