aboutsummaryrefslogtreecommitdiffstats
path: root/notebooks/FrameSynchronization.ipynb
blob: b9e387138a6e88b88ed0b81d650171f073fb9fca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "57a55a8c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc4b9dfd",
   "metadata": {},
   "source": [
    "# Digital Frame Synchronization\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc118de2-937b-4157-a5a1-9b7f152bf59b",
   "metadata": {},
   "source": [
    "First we need to create the access code, a barker sequence which has a very good autocorrelation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "20dcd173-2889-4e21-9746-3d0a0ab060e8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Access code: 13 bit pattern [1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1] = left padded bytes [31, 53]\n"
     ]
    }
   ],
   "source": [
    "ac = [ 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, ]\n",
    "\n",
    "ac_pad = [0] * int(8 * np.ceil(len(ac) / 8) - len(ac)) + ac\n",
    "ac_bytes = list(np.packbits(ac_pad))\n",
    "\n",
    "print(f\"Access code: {len(ac)} bit pattern {ac} = left padded bytes {ac_bytes}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5cfd3c9a-d697-4462-bc26-26e82d25cbfd",
   "metadata": {},
   "source": [
    "To correlate with the access code we need its symbols, thus the functions to modulate the access code."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d328e765-e977-4de9-9694-35012193a0aa",
   "metadata": {},
   "source": [
    "### Symbols for QPSK"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "515891a9-dbd2-4088-9a41-b792d878f0fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "def modulate_qpsk(m):\n",
    "    ampl = 1\n",
    "    sym = {\n",
    "        0: ampl * (-1 -1j) / np.sqrt(2),\n",
    "        1: ampl * ( 1 -1j) / np.sqrt(2),\n",
    "        2: ampl * (-1 +1j) / np.sqrt(2),\n",
    "        3: ampl * ( 1 +1j) / np.sqrt(2)\n",
    "    }\n",
    "\n",
    "    return map(lambda k: sym[k], m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "3a4c834f-7012-4e22-b9f3-865527d09c02",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Modulate chunks [0, 1, 3, 3, 0, 3, 1, 1] with QPSK into 8 symbols:\n",
      "[(-0.7071067811865475-0.7071067811865475j), (0.7071067811865475-0.7071067811865475j), (0.7071067811865475+0.7071067811865475j), (0.7071067811865475+0.7071067811865475j), (-0.7071067811865475-0.7071067811865475j), (0.7071067811865475+0.7071067811865475j), (0.7071067811865475-0.7071067811865475j), (0.7071067811865475-0.7071067811865475j)]\n",
      "\n",
      "Reversed complex conjugate list for FIR filter:\n",
      "[(0.7071067811865475+0.7071067811865475j), (0.7071067811865475+0.7071067811865475j), (0.7071067811865475-0.7071067811865475j), (-0.7071067811865475+0.7071067811865475j), (0.7071067811865475-0.7071067811865475j), (0.7071067811865475-0.7071067811865475j), (0.7071067811865475+0.7071067811865475j), (-0.7071067811865475+0.7071067811865475j)]\n"
     ]
    }
   ],
   "source": [
    "# convert into chunks of 2 bits for QPSK\n",
    "chunks = list(np.matmul(np.array(ac_pad).reshape((-1,2)), np.array([2, 1])))\n",
    "syms = list(modulate_qpsk(chunks))\n",
    "print(f\"Modulate chunks {chunks} with QPSK into {len(syms)} symbols:\\n{syms}\\n\")\n",
    "\n",
    "fir_syms = list(np.conj(syms[::-1]))\n",
    "print(f\"Reversed complex conjugate list for FIR filter:\\n{fir_syms}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d6155b2e-9405-4d20-8c05-72af45575a04",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1440x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, (left, right) = plt.subplots(1, 2, figsize = (20, 4))\n",
    "\n",
    "left.plot(np.real(syms), \".-\")\n",
    "left.plot(np.imag(syms), \".-\")\n",
    "left.set_title(\"Access Code\")\n",
    "\n",
    "right.plot(np.real(fir_syms), \".-\")\n",
    "right.plot(np.imag(fir_syms), \".-\")\n",
    "right.set_title(\"FIR Filter\")\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "8163c2e0-0652-43c5-ad32-eaf0e94a638e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1440x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, (left, right) = plt.subplots(1, 2, figsize = (20, 4))\n",
    "\n",
    "left.plot(np.real(syms), np.imag(syms))\n",
    "left.set_title(\"AC Constellation Diagram\")\n",
    "\n",
    "xc = np.convolve(fir_syms, syms)\n",
    "right.plot(np.abs(xc))\n",
    "right.set_title(\"AC Autocorrelation\")\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc633da5-61b7-4569-adaf-3d019e0f1b17",
   "metadata": {},
   "source": [
    "## Symbols for 16-QAM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "b56d782d-fcea-4fb9-b0c1-9c3933d5ce6c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def modulate_16qam(m):\n",
    "    sym = {\n",
    "        # first column\n",
    "         0: -3 -3j,\n",
    "         1: -3 -1j,\n",
    "         2: -3 +3j,\n",
    "         3: -3 +1j,\n",
    "        # second column\n",
    "         4: -1 -3j,\n",
    "         5: -1 -1j,\n",
    "         6: -1 +3j,\n",
    "         7: -1 +1j,\n",
    "        # fourth column\n",
    "         8: 3 -3j,\n",
    "         9: 3 -1j,\n",
    "        10: 3 +3j,\n",
    "        11: 3 +1j,\n",
    "        # third column\n",
    "        12: 3 -3j,\n",
    "        13: 3 -1j,\n",
    "        14: 3 +3j,\n",
    "        15: 3 +1j,\n",
    "    }\n",
    "    return map(lambda k: sym[k] if k in sym.keys() else None, m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "2fb687aa-0061-4626-bf6b-3ec7d628d739",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 10, 3, 4]\n",
      "[(-3-1j), (3+3j), (-3+1j), (-1-3j)]\n"
     ]
    }
   ],
   "source": [
    "# convert into chunks of 4 bits for QPSK\n",
    "chunks = list(np.matmul(np.array(ac_pad).reshape((-1,4)), np.array([4, 3, 2, 1])))\n",
    "syms = list(modulate_16qam(chunks))\n",
    "\n",
    "print(chunks)\n",
    "print(syms)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}