quadrature amplitude modulation (qam) in c++ · we discuss the c++ part of a transmitter/receiver...
TRANSCRIPT
Abstract
Quadrature Amplitude Modulation (QAM) is used for wireless and cable datatransmissions. While QAM is notoriously straightforward mathematically, it is inpermanent need of amendments and trade-offs to work properly in the physicalworld.We discuss the C++ part of a transmitter/receiver (TX/RX) pair that is fed withbinary data from a pipe, encodes into a QAM signal, performs DA and ADconversions on microcontrollers, and recovers the original data. It can be used withdifferent analog channels, including fiber optic and long wave radio.The implementation goes a long way to cope with distortions, discretizationartifacts, out-of-band noise (literally), in-band noise, out-of sync clocks, varyingsignal strength, and blocking input. It is vital to control error propagation duringsignal processing and apply forward error correction.Electromagnetic compatibility requirements restrain signal generation in softwareand call for low pass filters in hardware. As timing and speed are critical, timedDirect Memory Access (DMA) is mandatory for data transport to and from theDigital to Analog Conversion (DAC) and ADC units.Indeed, timing is so critical that when you put a finger on one of the quartz crystalsthat drive the DMA channels, observable program behavior changes. Cope with itin software!
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 1 / 35
Quadrature Amplitude Modulation (QAM) in C++
Heiko Frederik Bloch
November 21, 2017
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 1 / 35
Band-limited Signals
-11
-10
-9
-8
-7
-6
-5
-4
-3
-2
-1
0
1
2
3
4
5
6
7
8
9
10
11
-19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
'/tmp/adcrecord.monitor'using2:3''using4:5
'/tmp/adcrecord.monitor2'using2:3
The red dots (”symbols”) are complex amplitudes of a 137kHz sine wave
They change at a fixed rate, the symbol rate.
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 2 / 35
µCs, Amplifiers & Antenna
2x (TX&RX) µC boards with 12 bitADC and DAC units running at 1Mhz,slow serial connection to PC, 96KB ofRAM, 84 MHz clock speed, 32 bitwords
resonating magnetic loop antenna,3-15 turns of wire (TX) and ferriteantenna (RX)
amplifiers moderately shielded againstcapacitive coupling,
voltage regulators
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 3 / 35
Maximum Viable Byproduct
-0.5
-0.4
-0.3
-0.2
-0.1
0
0.1
0.2
0.3
0.4
0.5
-10 -8 -6 -4 -2 0 2 4 6 8 10
'/tmp/artifacts' u 1:2
reqirement: -60 decibels dampening
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 4 / 35
Spectrum Plot
0
1
2
3
4
5
-0.5 0 0.5 1 1.5 2 2.5 3 3.5 4
'/tmp/artifactsspectrum' u 1:4
handle this with a hardware filter
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 5 / 35
Analogue and Digital Signal Processing
Filters pass on different frequency components of the signalwith different amplification A(f)They
help create low-noise signals in the first place.
recover the original signal from a distorted and noisy channel
Filters are needed for both
baseband signals, here: −300Hz < f < 300Hz , before modulation, digital
bandpass signals, here: : 136, 4kHz < f < 137kHz , after modulation, analogue
Filters with arbitrary frequency responsecan be created as digital convolution filters
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 6 / 35
1st Order Low Pass Filters
analogue:x y
τ = RC
f0 =1
2πτ
digital:
1 y += ( x−y)>>k ;
I one clock cycle/sample
Iτ
Ts≈ 2k
I
f0fs
≈ 2−k
2π
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 7 / 35
RC-Frequency Response Function
-40.00
-35.00
-30.00
-25.00
-20.00
-15.00
-10.00
-5.00
0.00
5.00
10.00
-30-25-20-15-10 -5 0 5 10152025303540
20*log 10(|A|)
20*log10(f/f0)
RC-filtertransferfunction'smodulus
-1.57
-1.18
-0.79
-0.39
0.00
-30-25-20-15-10 -5 0 5 10152025303540
arg(A)
20*log10(f/f0)
RC-filtertransferfunction'sphase
A(f ) = 11+i· ff0
∈ C A: complex amplitude
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 8 / 35
RC-Impulse Response Function
0.00
1.00
2.00
3.00
4.00
5.00
6.00
7.00
0 0.25 0.5 0.75 1
RC-filterimpulseresponsefunction
K = A
K (f ) = A(f ) =
∫ ∞−∞
K (t) · e−2πitf · dt
y = x ∗ K
y(t) = (x∗K )(t) =
∫ ∞−∞
x(p)·K (t−p)·dp
K (t) =
{1τ e− t
τ t ≥ 0
0 t < 0K : convolution kernel
This generalizes to arbitrary frequency response filters
digital kernels may live on both sides of the y-axis
digital kernels are actually discrete
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 9 / 35
Modulation
Modulation is multiplication in the complex plane ,
W (t) = e iωt ·B(t), t = time, B(t) ∈ C
with a complex oscillator.
e iωt = cos(ωt) + i · sin(ωt)
de-modulation is modulation with the oscillator in reverse gear
B(t) = e−iωt ·W (t)
but we need low pass filters after demodulation to come back to the original signalif we transmit only the real part of W
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 10 / 35
Modulation Code (µC)
1 vo id DACC Handler ( ) {2 v o l a t i l e u i n t 1 6 t ∗ d e s t i n a t i o n = &dmaTX[ i ∗ chunkSizeTX ] ;3 i = (1 + i ) % numChunks ;4 DACC−>DACC TNPR = ( u i n t 3 2 t )&dmaTX [ ( ( 1 + i )%numchunks )∗ chunkSizeTX ] ;5 DACC−>DACC TNCR = chunkSizeTX ;6 s td : : a r r ay<ba s i c i n tComp l e x<i n t 3 2 t >, 2> LP = s t a t i c LP ;7 uns igned t = s t a t i cT ime ;8 f o r ( i n t 3 2 t ou t e r = 0 ; ou t e r < numComplexPerChunk ; ++ou t e r ) {9 ba s i c i n tComp l e x<i n t 3 2 t> BASEB32( baseBand . at ( ou t e r ) ) ;
10 f o r ( i n t 3 2 t i n n e r = 0 ; i n n e r < d i v i de rTX ; ++inne r , ++d e s t i n a t i o n ) {11 LP [ 0 ] . r e ( ) += (BASEB32 . r e ( ) − LP [ 0 ] . r e ( ) ) >> LPshi f tTX ;12 LP [ 0 ] . im ( ) += (BASEB32 . im ( ) − LP [ 0 ] . im ( ) ) >> LPshi f tTX ;13 LP [ 1 ] . r e ( ) += (−LP [ 0 ] . r e ( ) − LP [ 1 ] . r e ( ) ) >> LPshi f tTX ;14 LP [ 1 ] . im ( ) += (−LP [ 0 ] . im ( ) − LP [ 1 ] . im ( ) ) >> LPshi f tTX ;15 i n t 3 2 t w i r e S i g n a l = EXPTABLE[ t ] . r e ( ) ∗ (LP [ 1 ] . r e ( ) >> p r e S h i f t )16 − EXPTABLE[ t ] . im ( ) ∗ (LP [ 1 ] . im ( ) >> p r e S h i f t ) ;17 t = −1 + ( t ? t : EXPTABLE t : : LENGTH) ;18 ∗ d e s t i n a t i o n = 2048 + ( w i r e S i g n a l >> p o s t S h i f t ) ;19 }20 }21 baseBand . p op f r o n t ( numComplexPerChunk ) , s t a t i c LP = LP , s t a t i cT ime = t ;22 }
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 11 / 35
De-modulation Code (µC)
1 vo id ADC Handler ( ) {2 s td : : a r r ay<ba s i c i n tComp l e x<i n t 3 2 t >, 2> LP = s t a t i c LP ;3 u i n t 1 6 t ∗ s ou r c e = &dmaRX[ i ∗ chunkS i ze ] ;4 i = ( i+ 1) % numChunks ;5 ADC−>ADC RNPR = ( u i n t 3 2 t )(&dmaRX [ ( ( i+1)%numChunks )∗ chunkS i ze ] ) ;6 ADC−>ADC RNCR = chunkS i ze ;7 i n t 3 2 t LS = las tSamp le , t = s t a t i cT ime ;8 uns igned i n t e = BBend . l o ad ( ) ;9 u i n t 3 2 t ∗ ds t = &baseBand [ s r . s r i o b u f f e r . numComplexRX ∗ e ] ;
10 f o r ( i n t 3 2 t ou t e r =0; oute r<s r . s r i o b u f f e r . numComplexRX;++oute r ,++ds t ){11 f o r ( i n t 3 2 t i n n e r = 0 ; i n n e r < d i v i d e r ; ++inne r , s ou r c e+=Sstep ) {12 i n t 3 2 t ad c va l = ∗ s ou r c e ;13 i n t 3 2 t d i f f v a l = ( adc va l − LS) << p r e Sh i f t , LS = adcva l ;14 LP [ 0 ] . r e ( ) += (EXPTABLE[ t ] . r e ( ) ∗ d i f f v a l−LP [ 0 ] . r e ( ) ) >> LPshi f tRX ;15 LP [ 0 ] . im ( ) += (EXPTABLE[ t ] . im ( ) ∗ d i f f v a l−LP [ 0 ] . im ( ) ) >> LPshi f tRX ;16 t = −1 + ( t ? t : EXPTABLE t : : LENGTH) ;17 LP [ 1 ] . r e ( ) += (−LP [ 0 ] . r e ()−LP [ 1 ] . r e ( ) ) >> LPshi f tRX ;18 LP [ 1 ] . im ( ) += (−LP [ 0 ] . im()−LP [ 1 ] . im ( ) ) >> LPshi f tRX ;19 } ;20 ∗ ds t =(( u i n t 3 2 t (LP [ 1 ] . r e ())>>16)) |((( u i n t 3 2 t (LP [ 1 ] . im())>>16))<<16);21 }22 BBend=(( e+1)%numBBbuffersRX ) , s t a t i cT ime=t , l a s tSamp l e=LS , s t a t i c LP=LP ;23 }
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 12 / 35
Data Forwarding (µC)
1 vo id l oop ( ) {2 s t a t i c uns igned BBbegin {0} ;3 s t a t i c u i n t 3 2 t sequenceNr {0} ;4 uns igned e = BBend . l oad ( ) ;5 uns igned f i l l = ( ( numBBbuffersRX+e)−BBbegin)%numBBbuffersRX ;6 wh i l e ( f i l l ) {7 s r . s r i o b u f f e r . SEQ NR = sequenceNr ;8 s r . s r i o b u f f e r . RXMCUbuf ferF i l l = f i l l ;9 s r . s r i o b u f f e r . DIAGNOSTIC = g l o b a l S amp l eD i s t r i b u t i o n ;
10 g l o b a l S amp l eD i s t r i b u t i o n = 0 ;11 s r . wr i teFrame (12 ( intComplex ∗) &baseBand [ s r . s r i o b u f f e r . numComplexRX∗BBbegin ]13 ) ;14 BBbegin = ( BBbegin + 1) % numBBbuffersRX ;15 ++sequenceNr ;16 e = basebandEnd . l oad ( ) ;17 f i l l = ( ( numBBbuffersRX + e ) − BBbegin ) % numBBbuffersRX ;18 }19 }
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 13 / 35
Delta Encoding (µC)
Serial Connection on µC is slow, so save bandwidth where possible:
12 vo id d i f f e r e n t i a t e ( intComplex ∗ s o u r c e I t e r a t o r , bu f f e rT & w) {3 intComplex l a s t y = l a s t y v a l u e ;4 w. complex ( ) = l a s t y ;5 i n t 8 t ∗ de s t = w. data ;6 f o r ( i n t s c = 0 ; sc < w. numComplexRX ; ++sc ) {7 intComplex y (∗ s o u r c e I t e r a t o r ) ;8 auto d e l t a y = y ;9 ++s o u r c e I t e r a t o r ;
10 d e l t a y −= l a s t y ;11 ∗ de s t = d e l t a y . r e ( ) ;12 ++de s t ;13 ∗ de s t = d e l t a y . im ( ) ;14 ++de s t ;15 l a s t y = y ;16 }17 l a s t y v a l u e = l a s t y ;18 }
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 14 / 35
This is not a pipe
-12-11-10-9-8
-7-6-5-4-3-2-10
123456789
101112
-24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
'/tmp/adcrecord.monitor'using2:3''using4:5
'/tmp/adcrecord.monitor2'using2:3
... yet. Target: QAM256 modulation scheme + pipe interface
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 15 / 35
QAM256
y=imag(symbol)
x=real(symbol)-10 10
Energy ∼ x2 + y2 = r2
r = length of symbol vector
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 16 / 35
Live Demo: Anything that can go wrong ...
-11
-10
-9
-8
-7
-6
-5
-4
-3
-2
-1
0
1
2
3
4
5
6
7
8
9
10
11
-19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
'/tmp/adcrecord.monitor'using2:3''using4:5
'/tmp/adcrecord.monitor2'using2:3
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 17 / 35
Clock SynchronizationTrick:
Allow multiple symbols represent the same info( tile pattern)
See for that the average complex amplitude of thesignal is real & positive in TX
Adjust RX clock speed according to the number ofrotations performed by the average amplitude ofthe received signal.
additional average energy/symbol: moderate
additional maximal energy/symbol: very moderate
imaginary
real-16
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 18 / 35
TX Phase Adjustment (PC)
1 vo id encode r : : ad j u s tPha s e ( in tComplex & symbol ) {2 i n t im = symbol . im ( ) , r e = symbol . r e ( ) ;3 i n t newReal = r e + t i l e ;4 i f ( newReal ∗ newReal + im ∗ im <= maxRadius ∗ maxRadius5 && newReal < t i l e )6 r e = newReal ;7 i n t newImag = im + t i l e ∗ ( i n t (0 > imagsum ) − i n t (0 < imagsum ) ) ;8 i f ( r e ∗ r e + newImag ∗ newImag <= maxRadius ∗ maxRadius9 && abs ( newImag ) < t i l e )
10 im = newImag ;11 imagsum += im ;12 r e a l a v g −= r e a l a v g / rea lTau , r e a l a v g += re / rea lTau ;13 symbol . r e ( ) = re , symbol . im ( ) = im ;14 i f ( ( r e a l a v g < 3 . 5 ) && (maxRadius < g loba lMaxRad ius ) ) {15 ++maxRadius ;16 } e l s e i f ( ( ( abs ( imagsum ) ) >= 64) && (maxRadius < g loba lMaxRad ius ) ) {17 ++maxRadius ;18 } e l s e i f ( maxRadius > g l oba lRad iu sMin ) {19 −−maxRadius ;20 }21 }
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 19 / 35
RX Phase Adjustment & Clock Sync (PC)
1 auto BBS = complextype ( r awS i gna l . a t ( 0 ) . r e ( ) , r awS i gna l . a t ( 0 ) . im ( ) ) ;2 BBS += complextype ( 0 . 5 − ( 0 . 5 / 65536) , 0 . 5 − ( 0 . 5 / 65536 ) ) ;3 pend ing += rota t i onsPe rBBS ∗ expTable . s i z e ( ) ;4 i n t d e l t a = ( pend ing >= 1) − ( pend ing <= −1);5 pend ing −= de l t a ;6 pha se Index = ( phase I ndex+d e l t a+expTable . s i z e ( ) ) % expTable . s i z e ( ) ;7 BBS ∗= expTable . a t ( pha se Index ) ;8 TxTime += t imeSubd i v i s i o n + d e l t a ;9 auto no rma l i z e dDe l t a = −LP [ 1 ] ;
10 f o r ( i n t c = 0 ; c != LP . s i z e ( ) ; ++c ) {11 LP [ c ] −= LP [ c ] / LPtau [ c ] ;12 LP [ c ] += ( c ? LP [ c − 1 ] : BBS) / LPtau [ c ] ;13 }14 no rma l i z e dDe l t a += LP [ 1 ] ;15 no rma l i z e dDe l t a . n o rma l i z e (LP [ 1 ] ) ;16 p h a s e I n t e g r a l += no rma l i z e dDe l t a . imag ( ) ;17 ro ta t i onsPe rBBS = ph a s e I n t e g r a l ∗ ro ta t ionsPerBBSandPh i ;
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 20 / 35
Intermission
Things to determine:
signal Amplitude
When to sample and round the baseband signal? (Every symbol duration time,but in which time slice?)
clock speed difference !
signal Phase !
Things to deal with:
distortions, e. g., by resonators
arbitrary noise outside the transmission band (large amplitude)
random noise inside the transmission band (small amplitude)
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 21 / 35
RX Baseband Filter Frequency Response
-0.6
-0.4
-0.2
0
0.2
0.4
0.6
0.8
1
1.2
-1 -0.8 -0.6 -0.4 -0.2 0 0.2 0.4 0.6 0.8 1
'/tmp/rhoresponse.h' u 1:2'' u 1:3'' u 1:4
x-unit = symbol rate
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 22 / 35
RX Baseband Filter Convolution Kernel
-50000
0
50000
100000
150000
200000
250000
300000
0 200 400 600 800 1000 1200
'/tmp/rhokernel.h' u 0:1
x-unit = 1 Baseband sample
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 23 / 35
Error Correction Code
1 c l a s s e r r o r C o r r e c t i o n t {2 s t a t i c const char NIBBLES END = 19 ;3 const uns igned char codeword [ NIBBLES END ] { 0b01110000 , 0b11010001 ,4 0b10100010 , 0b01100011 , 0b10110100 , 0b00010101 , 0b01010110 ,5 0b10000111 , 0b11101000 , 0b10111001 , 0b11011010 , 0b00011011 ,6 0b10001100 , 0b00101101 , 0b00111110 , 0b01001111 , 0b00000000 ,7 0b11111111 , 0b11100101 } ;8 pub l i c :9 uns igned char fwd ( const uns igned char x ) const {
10 r e t u r n codeword [ x ] ;11 }12 uns igned char r e v ( uns igned char c , uns igned & e r r o r s , boo l v e r bo s e ) {13 . . . }14 } ;
Hamming distance >= 3, i.e., one bit error is always corrected, sometimes two
Values 0..15 are used for data transmission, 16,17,18 for control purposes
Error rate 10−5 in the uncorrected stream (near field longwave version)
Noise from switched-mode power supplies introduces many errors.
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 24 / 35
Gray Code
1 c l a s s g rayCode t {2 pub l i c :3 char r e v ( const char x ) const {4 r e t u r n gray [ x ] ;5 // Frank Gray (1887−1969)6 }7 char fwd ( const char x ) const {8 r e t u r n p i e dC i ph e r [ x ] ;9 }
10 g rayCode t ( ) {11 f o r ( i n t c = 0 ; c < 16 ; ++c )12 p i e dC i ph e r [ g ray [ c ] ] = c ;13 }14 p r i v a t e :15 const char gray [ 1 6 ] = { 0b0111 , 0b0101 , 0b0100 , 0b1100 , 0b1101 , 0b1111 ,16 0b1110 , 0b1010 , 0b1011 , 0b1001 , 0b1000 , 0b0000 , 0b0001 , 0b0011 ,17 0b0010 , 0b0110 } ;18 char p i e dC i ph e r [ 1 6 ] = { } ;19 } ;
limits number of bit flips due to analogue off-by-one errors
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 25 / 35
Amplitude & Time Slice Gauge
Can be done only after clock sync.
1. Amplitude Approximation by signal root mean square (RMS)
1% accuracy required.
2. Sampling Time Slice & Amplitude Approximation byFourier Transforms of Amplitude distributions:
imag
real
0.5 7.5-7.5
P(imag) ≈
1
16: big red dot
1
32: small red dot
0 : elsewhere
in the correct time slice
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 26 / 35
Fourier Transform
-20
-15
-10
-5
0
5
10
15
20
0 50 100 150 200 250 300 350 400 450 500
re(x/170)
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 27 / 35
Fourier Transform from sampled data
-200
-100
0
100
200
0 32 64 96 128 160 192 224 256 288 320 352 384 416 448 480 512
'/tmp/adcrecord.ampStat'u0:1
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 28 / 35
Amplitude & Time Slice Gauge
1 i n t 6 4 t t s = f i l t e r e d S i g n a l . a t ( c ) . t imestamp ;2 i n t c y c l e I n d e x = ( t s / t imeS l i c eT ime ) % s l i c e sP e r S ymbo l ;3 r e a l t y p e de l t aAmp l i t ude = p r e s c a l e4 ∗ f i l t e r e d S i g n a l . a t ( c ) . s i g . imag ( ) / f r e q 1 i n d e x5 ∗ expTable2 . s i z e ( ) ;6 r e a l t y p e ampTimesFreq = de l t aAmp l i t ud e / 2 ;7 f o r ( i n t f r e qu en c y = 0 ; f r e qu en c y < 512 ; ++f r equ en c y ) {8 t im e S l i c e [ c y c l e I n d e x ] [ f r e qu en c y ] ∗= 0 . 9 9 7 ;9 t im e S l i c e [ c y c l e I n d e x ] [ f r e qu en c y ] +=
10 expTable2 [ u i n t 6 4 t ( s t d : : l r o und ( ampTimesFreq ) ) % expTable2 . s i z e ( ) ] ;11 ampTimesFreq += de l t aAmp l i t ude ;12 }
One timeSlice[cycleIndex] array contains the fourier transform shown above
The negative peaks of the timeSlice variable yieldboth the time slice and the amplitude reference.
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 29 / 35
Live Demo: This is a pipe
1 $ ca t o u t f i l e > /tmp/ s d r t x23 $ r e p o r t4 R : 4 . 4 S : 75 # count−down 36 # count−down 27 # count−down 18 # s t a r t o f t r a n sm i s s i o n9 R : 5 . 1 S : 7
10 . . .11 R : 15 S : 712 # count−up 013 # count−up 114 # count−up 215 # r e c e i v e d 100800 bytes , 800 oob by t e s16 # 2 b i t e r r o r s d i c o v e r e d i n 1612832 raw b i t s , e r r o r r a t e : 1 .24005 e−0617 # oob 18 +i ∗ 318 # oob 18 +i ∗ 419 # oob 18 +i ∗ 5
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 30 / 35
Copyright (c): Heiko Frederik Bloch
(The slides have been slightly edited since November 2017.Today’s improved version ofthe hardware is more resistant to electrostatic noise)
References:
www.longhaulmail.de/misc/sdr2.pdf
J. G. Proakis, Masoud Salehi: Digital Communications, 5th ed., McGraw-Hill
L. Grafakos: Classical Fourier Analysis 2nd ed., Springer
J. Franz: EMV. Storungssicherer Aufbau elektronischer Schaltungen. 4. Aufl.,Teubner/Vieweg
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 31 / 35
Roadmap1 Band-limited Signals
2 Microcontroller Hardware
3 Maximum Viable Byproduct
4 Signal Processing
5 Modulation
6 Serial Interface
7 This is not a pipe
8 QAM256
9 Clocks
10 Intermission
11 RX Baseband Filters
12 Errors
13 Gauge
14 This is a pipe
15 Copyright & References
16 Appendix
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 32 / 35
Appendix
1 Fast Fourier Transform
2 Cache-friendly Sine and Cosine Lookup
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 33 / 35
Fast Fourier Transform
1 // computat ion t ime : 6 ns ∗ moduleRank ∗ l o g 2 ( moduleRank )2 s t a t i c vo id f a s t ( moduletype & out , const moduletype & i n ) {3 s td : : v e c to r<r i n g t yp e> b u f f e r (2 ∗ moduleRank ) ;4 r i n g t p t r o l dda t a = &bu f f e r [ 0 ] , newdata = &bu f f e r [ moduleRank ] ;5 f o r ( u i n t 3 2 t pos = 0 ; pos < moduleRank ; ++pos )6 newdata [ pos ] = i n [ b i t swap ( pos ) ] ;7 f o r ( u i n t 3 2 t l e v = 0 ; l e v < numDyadicLeve l s ; ++l e v ) {8 auto l e v e l B i t = u i n t 3 2 t (1 ) << l e v ;9 s td : : swap ( o lddata , newdata ) ;
10 f o r ( u i n t 3 2 t pos = 0 ; pos < moduleRank ; ++pos ) {11 u i n t 3 2 t ph i = pos << ( numDyadicLeve l s − 1 − l e v ) ;12 ! r e v e r s e | | ( ph i = −ph i ) ;13 auto acc = o l dda t a [ pos | l e v e l B i t ] ;14 acc ∗= roo tOfUn i t y : : t t ( ph i ) ;15 acc += o ldda t a [ pos & ˜ l e v e l B i t ] ;16 newdata [ pos ] = acc ;17 }18 }19 out . a s s i g n ( newdata , newdata + moduleRank ) ;20 }
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 34 / 35
Cache-friendly Sine and Cosine Lookup
1 template<c l a s s r e a l t y p e , u i n t 3 2 t N>2 c l a s s c omp l e x r o o t o f u n i t y {3 s t a t i c const u i n t 3 2 t numChunks = ( ( u i n t 3 2 t ) 1) << (N / 2 − 1 ) ;4 s t a t i c const u i n t 3 2 t chunk s i z e = ( ( u i n t 3 2 t ) 1) << (N − N / 2 − 1 ) ;5 s t a t i c s t d : : a r r ay<s t d : : complex<r e a l t y p e >, chunks i z e> e x p t a b l e l o ;6 s t a t i c s t d : : a r r ay<s t d : : complex<r e a l t y p e >, numChunks> e x p t a b l e h i ;7 pub l i c :8 s t a t i c s t d : : complex<r e a l t y p e> t t ( u i n t 3 2 t k ) {9 auto c = e x p t a b l e l o [ k & ( chunks i z e −1)]
10 k >>= (N − N / 2 − 1 ) ;11 c ∗= e x p t a b l e h i [ k & ( numChunks−1) ] ;12 k >>= (N / 2 − 1 ) ;13 sw i tch (3 & k ) {14 case 1 : r e t u r n {−c . imag ( ) , c . r e a l ( ) } ;15 case 2 : r e t u r n −c ;16 case 3 : r e t u r n {c . imag () ,− c . r e a l ( ) } ;17 }18 r e t u r n c ;19 }20 }
Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 35 / 35