quadrature amplitude modulation (qam) in c++ · we discuss the c++ part of a transmitter/receiver...

36
Abstract Quadrature Amplitude Modulation (QAM) is used for wireless and cable data transmissions. While QAM is notoriously straightforward mathematically, it is in permanent need of amendments and trade-offs to work properly in the physical world. We discuss the C++ part of a transmitter/receiver (TX/RX) pair that is fed with binary data from a pipe, encodes into a QAM signal, performs DA and AD conversions on microcontrollers, and recovers the original data. It can be used with different analog channels, including fiber optic and long wave radio. The implementation goes a long way to cope with distortions, discretization artifacts, out-of-band noise (literally), in-band noise, out-of sync clocks, varying signal strength, and blocking input. It is vital to control error propagation during signal processing and apply forward error correction. Electromagnetic compatibility requirements restrain signal generation in software and call for low pass filters in hardware. As timing and speed are critical, timed Direct Memory Access (DMA) is mandatory for data transport to and from the Digital to Analog Conversion (DAC) and ADC units. Indeed, timing is so critical that when you put a finger on one of the quartz crystals that drive the DMA channels, observable program behavior changes. Cope with it in software! Heiko Frederik Bloch Quadrature Amplitude Modulation (QAM) in C++ November 21, 2017 1 / 35

Upload: hoanglien

Post on 10-Apr-2018

241 views

Category:

Documents


3 download

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

Ts≈ 2k

I

f0fs

≈ 2−k

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