-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathidx.html
558 lines (523 loc) · 36.9 KB
/
idx.html
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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="pragma" content="no-cache; charset=utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>si4703 RDS dumper</title>
<style type="text/css">
body {background-color:#FFFFDD}
//td {vertical-align:top;padding:0px;margin:0px}
p {text-align:justify;margin-bottom:0px}
td.gchord {font-size:75%;font-weight:bold;padding:0px;margin:0px;padding-top:0px;padding-right:3px;text-align:left;font-family:verdana,arial;color:#888888;position:relative;top:3px}
td.gtxt {text-align:left}
.dettitle {border-bottom:1px lightgray dashed}
.dettitle2 {border-bottom:1px lightgray dashed}
h2 {margin-top:20px; background-color:xgray}
h3 {background-color:xyellow;margin-top:30px;text-decoration:underline}
h4 {padding-left:0px;margin-left:0px;text-decoration:underline;color:#333333}
ul {margin-top:0px;padding-top:0px}
.ref {color:gray}
.gr {color:gray}
.grsm {color:gray;font-size:80%}
.err {color:red;font-weight:bold}
a {text-color:blue;text-decoration:underline}
a:HOVER {border-bottom:1px blue;color:red}
a.index {text-decoration:none}
a.index:HOVER {text-decoration:underline;color:red}
.preFile {background-color:lightgray;padding:0.5em}
td.imgthumb {vertical-align:top;padding:5px;font-size:80%}
img.ico {width:12px;height:12px;overflow:visible;position:relative;margin-top:-5px}
.imginc {max-width:100%;max-height:80vh}
.imginccap {text-align:left;padding-bottom:0.5em}
div.code {margin:0px;padding:0px;padding-left:30px;}
.code {font-family:courier,fixed;color:green;}
.cmd {font-family:courier,fixed;color:red;background-color:#FFEEDD;font-weight:bold;white-space:pre-wrap;padding-left:0.5em;;padding-right:0.5em;padding-top:0.5em;padding-bottom:0.5em}
.cmd::first-line {color:darkred;}
.cmd::before {content:'> ';}
.cmdresp {font-family:courier,fixed;color:blue;background-color:#EEEEFF;white-space:pre-wrap;padding-left:0.5em;;padding-right:0.5em;}
.cmdresp::first-line {color:darkblue;}
.cmdresp::before {content:' ';}
.comm {font-family:courier,fixed;color:red;background-color:#FFEEDD;font-weight:bold;white-space:pre-wrap;padding-left:0.5em;;padding-right:0.5em;}
.comm::first-line {color:darkred;}
.comm::before {content:'> ';}
.commresp {font-family:courier,fixed;color:blue;background-color:#EEEEFF;white-space:pre-wrap;padding-left:0.5em;;padding-right:0.5em;}
.commresp::first-line {color:darkblue;}
.commresp::before {content:'< ';}
.bang {font-weight:bold;color:red}
// unsupported by everything except apple, so far
//@media screen and (inverted-colors: inverted) {
//.cmd {background-color:#0000CC;color:lightblue;}
//.cmd::first-line: {color:blue}
//.cmdresp {background-color:#CC0000;color:lightred}
//.cmdresp::first-line: {color:red}
//}
@media print{
body {font-size:80%}
.noprint {display:none;visibility:hidden}
.xnopbr {page-break-inside:avoid}
td.gchord: {color:black}
.nopbr {}
.preFile {background-color:white;border:1px dotted black}
}
</style>
<meta property="og:title" content="si4703 RDS dumper" />
<meta property="og:type" content="website" />
<meta property="og:x-url" content="http://:" />
<meta property="og:description" content="packet dumper and analyzer of radio data system sent via FM radio" />
</head>
<body>
<h1>si4703 RDS dumper</h1><hr class="noprint" /><div class="noprint"><a class="index indexlev2" href="#Why" title="">Why</a><br /><a class="index indexlev2" href="#RDS" title="RDS">RDS</a><br /> <small><a class="index indexlev3" href="#packetstructure" title="RDS.packet structure">packet structure</a></small><br /> <small><a class="index indexlev3" href="#groups" title="RDS.groups">groups</a></small><br /> <small><a class="index indexlev3" href="#details" title="RDS.details">details</a></small><br /><a class="index indexlev2" href="#How" title="How">How</a><br /> <small><a class="index indexlev3" href="#hardware" title="How.hardware">hardware</a></small><br /> <small><a class="index indexlev4" href="#gotcha" title="How.hardware.gotcha">gotcha</a></small><br /> <small><a class="index indexlev4" href="#antenna" title="How.hardware.antenna">antenna</a></small><br /> <small><a class="index indexlev4" href="#woes" title="How.hardware.woes">woes</a></small><br /> <small><a class="index indexlev3" href="#software" title="How.software">software</a></small><br /> <small><a class="index indexlev4" href="#hardwareconfiguration" title="How.software.hardware configuration">hardware configuration</a></small><br /> <small><a class="index indexlev4" href="#noninteractivemodes" title="How.software.noninteractive modes">noninteractive modes</a></small><br /> <small><a class="index indexlev4" href="#interactivemode" title="How.software.interactive mode">interactive mode</a></small><br /><a class="index indexlev2" href="#Files" title="Files">Files</a><br /><a class="index indexlev2" href="#Todo" title="Todo">Todo</a><br /></div><hr /><a name="Why"></a><h2>Why
</h2>
<p>
Because it is there.
</p>
<hr /><a name="RDS"></a><h2>RDS
</h2>
<p>
The <a class="w" href="https://en.wikipedia.org/wiki/Radio_Data_System" title="Wikipedia link: Radio Data System" target="_blank">Radio Data System</a> is a packet based digital data transmission over <a class="w" href="https://en.wikipedia.org/wiki/FM_radio" title="Wikipedia link: FM radio" target="_blank">FM radio</a>.
</p>
<p>
The low-level transfer is done by modulating the data on a 57kHz subcarrier, Manchester-encoded, 1187.5 bit/s, in 104-bit group.
The group consists of four pairs of 16 and 10 bits, where the latter is a checksum and data-recovery portion. Only recovered
data (and two-bit error-recovery status for each word) are available from the Si4703 chip. Raw data can be acquired with software-defined radio,
eg. by the <a class="w" href="https://en.wikipedia.org/wiki/GNU_Radio" title="Wikipedia link: GNU Radio" target="_blank">GNU Radio</a> module <a class="a" href="https://github.com/bastibl/gr-rds/" title="remote link: https://github.com/bastibl/gr-rds/" target="_blank">https://github.com/bastibl/gr-rds/</a>.
</p>
<p>
The data are sent as fixed-size packets of four 16-bit words (A,B,C,D). The "header" is fixed, the variable
payload consists of 37 bits (5 bits in word B, and 16 each in words C and D).
</p>
<p>
The header contains inter alia the packet group ID, the type of the subprotocol used. There are 32 possible
groups (16, each with variant A and B). Some are fixed, others can be assigned to specific application.
</p>
<p>
The groups are well-documented here: <a class="a" href="http://www.g.laroche.free.fr/english/rds/groupes/listeGroupesRDS.htm" title="remote link: http://www.g.laroche.free.fr/english/rds/groupes/listeGroupesRDS.htm" target="_blank">http://www.g.laroche.free.fr/english/rds/groupes/listeGroupesRDS.htm</a>
</p>
<p>
The 5 bits in word B are often used as a packet subvariant, or a pointer to text buffer, and/or various flags.
Or they can be used as part of the whole payload.
</p>
<a name="packetstructure"></a><h3> packet structure
</h3>
<p>
The signal is received on a 57kHz subcarrier (3x the pilot 19kHz), as four block of 16 bits of data plus 10 bits of corrections.
</p>
<p>
The four blocks, A-B-C-D, are the elementary packets of the protocol, with header and payload.
The payload is specific to a group type, a sub-protocol specified in the header.
</p>
<p>
The header consists of 16+11 bits.
</p>
<ul><li> <span class="code">block A</span>, 16 bits
</li><ul><li> A[15..0] - <span class="code">PI</span>, program identifier
</li><ul><li> A[15..12] - country identifier, overloaded, no two neighbouring countries share a country ID
</li><li> A[11..8] - coverage area, usually static, can be dynamically changed by some stations
</li><li> A[7..0] - program reference number, arbitrary assignment
</li></ul></ul><li> <span class="code">block B</span>, 16 bits
</li><ul><li> B[15..5] - group type, program type, flags
</li><ul><li> B[15..12] - <span class="code">group type</span>, 0..15
</li><li> B[11] - B0, <span class="code">group subtype</span>, A/B
</li><li> B[10] - <span class="code">TP</span> - Traffic Program, 1 if station contains periodic traffic reports
</li><li> B[9..5] - <span class="code">PTY</span> - program type, in a 5-bit lookup table
</li></ul><li> B[4..0] - VARY - payload, often flags and index bits
</li></ul><li> <span class="code">block C</span>, 16 bits
</li><ul><li> payload, group dependent; in some group subtypes B it contains repeated block A, the PI
</li></ul><li> <span class="code">block D</span>, 16 bits
</li><ul><li> payload, group dependent
</li></ul></ul><a name="groups"></a><h3> groups
</h3>
<p>
Common fixed groups are:
<ul><li> <span class="code">0A</span> - 8-byte station name and its alternative frequencies; station name sent by 2 bytes per packet
</li><li> <span class="code">2A</span> - <span class="code">Radiotext</span>, 64-byte freeform text, sent by 4 bytes per packet
</li><li> <span class="code">3A</span> - <span class="code">ODA</span> (Open Data Applications), arbitrary services and their group assignments; mapping the 16-bit ODAAID identifier to a 5-bit group ID (effectively 4-bit as B subgroup is rarely used)
</li><li> <span class="code">4A</span> - <span class="code">clock</span>, time/date sent once per minute
</li><li> <span class="code">8A</span> - <span class="code">TMC</span> (<a class="w" href="https://en.wikipedia.org/wiki/Traffic_message_channel" title="Wikipedia link: Traffic message channel" target="_blank">Traffic message channel</a>), usually also in conjunction with 3A
</li><li> <span class="code">10A</span> - <span class="code">PTYN</span> (program type name), a 8-byte ASCII-encoded program type (music, sport...) instead of type by enumeration from a list
</li><li> <span class="code">14A</span> - <span class="code">EON</span>, <a class="w" href="https://en.wikipedia.org/wiki/Enhanced_other_networks" title="Wikipedia link: Enhanced other networks" target="_blank">Enhanced other networks</a>, eg. presence of traffic announcement on other stations
</li></ul></p>
<p>
Less common fixed groups are:
<ul><li> <span class="code">0B</span> - station name without alternative frequencies; rarely used
</li><li> <span class="code">1A</span> - program item number, slow label
</li><li> <span class="code">1B</span> - program item number
</li><li> <span class="code">2B</span> - <span class="code">Radiotext</span>, 2x 32-byte freeform text, rarely used
</li><li> <span class="code">14B</span> - <span class="code">EON</span>, <a class="w" href="https://en.wikipedia.org/wiki/Enhanced_other_networks" title="Wikipedia link: Enhanced other networks" target="_blank">Enhanced other networks</a>, eg. presence of traffic announcement on other stations; rarely used
</li><li> <span class="code">15B</span> - fast switching, essentially blocks A and B repeated in blocks C and D, for faster acquisition of data; rarely used
</li></ul></p>
<p>
Groups that can be used for specific applications or as ODA are:
<ul><li> <span class="code">5A</span>, <span class="code">5B</span> - transparent data channels
</li><li> <span class="code">6A</span>, <span class="code">6B</span> - in-house applications
</li><li> <span class="code">7A</span> - radio data paging
</li><li> <span class="code">8A</span> - TMC
</li><li> <span class="code">9A</span> - EWS (Emergency Warning System)
</li><li> <span class="code">13A</span> - Enhanced Radio Paging
</li></ul></p>
<p>
The other groups (7B, 8B, 9B, 10A, 10B, 11A, 11B, 12A, 12B) can be assigned as ODA, Open Data Application. The application and associated group are specified
in the 3A group packets. The application is specified by ODAAID, ODA application identifier. These are assigned
centrally. E.g. the TMC data are sent as AID=0xCD46 (and group 8A), and RT+ (Radiotext+) tags as AID=0x4BD7.
</p>
<a name="details"></a><h3> details
</h3>
<p>
The online documentation is often lacking, the official specs are heavily paywalled. Other people's source code can be a substitute.
A good parser is in the v4l-ctl utils, <a class="a" href="https://github.com/gjasny/v4l-utils/blob/master/lib/libv4l2rds/libv4l2rds.c" title="remote link: https://github.com/gjasny/v4l-utils/blob/master/lib/libv4l2rds/libv4l2rds.c" target="_blank">https://github.com/gjasny/v4l-utils/blob/master/lib/libv4l2rds/libv4l2rds.c</a>
</p>
<hr /><a name="How"></a><h2>How
</h2>
<p>
A module with Si4703 chip by Silicon Laboratories was obtained. Cheap one, with older Si4703-B16 flavor (variant B,
firmware version 16); more modern one is Si4703-C19.
</p>
<p>
There are many other Si47xx receivers. One of the best is Si4743, able to handle not just VHF FM (64-108 MHz) but
also LW (153-288 kHz), MW (520-1710 kHz) and SW (2.3-30 MHz), and WB, the NOAA weather band (162.4-162.55 MHz)
</p>
<a name="hardware"></a><h3> hardware
</h3>
<p>
The chip was attached to a Raspberry Pi via I2C and a pair of GPIO. One for RESET signal, the optional
other for interrupt from the chip.
</p>
<p>
The interrupt wire is optional. As-is, it is used only for the tuning operations; the RDS reception
is done by I2C polling. Which is grossly suboptimal but works.
</p>
<p>
The module uses headphones as an antenna. External antenna of better quality can be attached. The antenna
is a major performance factor.
</p>
<a name="gotcha"></a><h4> gotcha
</h4>
<p>
The chip has to be initialized to 2-wire mode (aka I2C).
</p>
<p>
The chip can run either in 3-wire (SPI) or 2-wire (I2C/TWI) mode. If it is not seen on the I2C bus, it is in the wrong mode.
</p>
<p>
As-connected, the chip does not appear on the I2C bus. It is necessary to pulse low the RESET pin, while holding the
SDIO (I2C SDA) pin low. Then it appears on i2c-detect at address 0x10.
</p>
<p>
The "internal crystal oscillator" in the datasheet is only the support circuitry, the crystal is external.
It is possible to get rid of it by replacing the crystal with an oscillator. The crystal uses two pins, GPIO3 and
RCLK, both available on the crystal solder pads. In theory, after removal of the xtal and pulling GPIO3 up to 3.3v,
the init dance of mode1 can be replaced with much easier mode2 init without fiddling with SDIO. This may be needed when
using an I2C-to-USB interface, or other way where we do not have bitbang-class access to SDIO. (A diode to some random GPIO
on-hand, to pull down the line, may be a solution. This will however interfere with existing bus traffic, if it is shared
with other processes.)
</p>
<p>
Using the internal oscillator, the chip is sensitive to spurious signals from the SDIO line during seeking/tuning.
This may impair performance when the bus is shared.
</p>
<p>
If the application (research?) requires extra luxurious frequency stability, a 32.768kHz TCXO can be used.
</p>
<a name="antenna"></a><h4> antenna
</h4>
<p>
The FM antenna is connected to the FMI input of the chip.
</p>
<p>
It's just around 100 MHz, that's almost DC.
</p>
<p>
The antenna guidelines are described in the <a class="a" href="si4703-AN383.pdf" title="local link: si4703-AN383.pdf" target="_blank">AN383</a> appnote.
</p>
<p>
The on-chip tuning VCO runs at high frequency and its harmonics at gigahertz range are subject to leakage to chip's pins and cause
various parasitic emissions from there. Various optional RC or LC filters can be applied. Including the antenna connection filter,
using a 6pF capacitor between FMI and ground, and a ferrite bead (Murata BLM15GA750SN1, or anything with low DC resistance and
high resistance at around 100 MHz) between FMI and antenna.
</p>
<p>
The FM wavelength is about 3.4m (88 MHz) to 2.8m (108 MHz), requiring 1.7-1.4m for half-wave and 0.85-0.7m for quarter-wave.
Headphones are often used as the antenna, due to their cable's approximately correct length.
</p>
<p>
On the module, the ground wire of the headphones (from the onboard connector) is connected to the FMI pin, via
a L-C filter (capacitor to the FMI pin to pass the high frequency, inductor to ground to stop the high frequency
but allow the return current from the audio to go through).
</p>
<p>
ESD diodes, with parasitic capacitance below 1 pF, may be a good idea. The antenna will be exposed to all sorts of
interference, including direct discharges when touched.
</p>
<p>
It should be easy to break it out to a SMA connector or even just a header pin. Remove the capacitor (or use it to bypass the new antenna
connector), and optionally short the inductor. Or use a pair of header pins to select between the headphones and a real antenna.
</p>
<a name="woes"></a><h4> woes
</h4>
<p>
The module itself has a tendency to insensitivity after initialization. Multiple inits with different antenna positions may be necessary.
Possibility for manual deinit and init was added to the interactive user interface to mitigate the annoyance.
</p>
<a name="software"></a><h3> software
</h3>
<p>
Python was chosen as the platform, for simplicity and ease. The <a class="a" href="https://github.com/ryedwards/si4703RaspberryPi" title="remote link: https://github.com/ryedwards/si4703RaspberryPi" target="_blank">si4703RaspberryPi</a> project
was chosen as the basis. Then it grew.
</p>
<p>
The software can run even without the chip, but only for the parsing of rds-spy logs coming from stdin.
</p>
<a name="hardwareconfiguration"></a><h4> hardware configuration
</h4>
<p>
in main code source file (TODO: arguments and/or config file)
</p>
<p>
The chip-interacting code is hardware-dependent, due to the reset requiring pulsing the GPIO for the RESET pin.
The hardware reset is segregated to a routine selectable by the "hw" parameter in the radio object creation. Currently supported
are "raspi" for raspberry pi, and "none" for skipping the hardware init.
</p>
<p>
However, parsing of the stdin-input .spy files does not require any hardware initialization
and should therefore run on any machine.
</p>
<a name="noninteractivemodes"></a><h4> noninteractive modes
</h4>
<pre class="preFile">si4703 FM radio RDS data handler
Usage: ./si4703rds.py [command] [arguments...]
Where:
info print expected hardware configuration
-n do not access hardware
-i force hardware init
-v verbose init (with -i)
scan perform scan of radio stations, list names and RDS groups encountered
-i force hardware init
dump connect to chip, dump raw data to stdout in rds-spy log format
-n skip attempt to get station name from RDS
parse read rds-spy raw data from stdin, parse, output to stdout
-n do not print parsed data (use with -s, -t)
-s print RDS statistics
-t print RDS-TMC data
-v some extra verbosity/debug data somewhere
cmd <cmd> command for the chip (volume up/down, seek up/down)
-h list of commands
-i force init
help print help (also -h, --help)
-i print interactive commands help instead of commandline
<none> enter interactive mode
-i force hardware init
</pre><p>
The software can dump and and analyze RDS datastream in <a class="a" href="https://rdsspy.com/" title="remote link: https://rdsspy.com/" target="_blank">RDS-Spy</a> format.
</p>
<p>
To dump data from a station:
<ul><li> run the interactive console, tune the radio, exit with shift-Q
</li><li> dump the data:
</li><div class="cmd">si4703rds dump >> file.spy</div></ul></p>
<pre class=""><recorder="Si4703-shad" date="2023-11-27" time="19-00-06" source="1" name="COUNTRY " location="" notes="89.5 MHz">
2337 2725 6E65 2072 @2023/11/27 18:00:06.95
2337 A720 2020 2020 @2023/11/27 18:00:07.04
2337 0729 0250 594D @2023/11/27 18:00:07.13
2337 2726 6168 696F @2023/11/27 18:00:07.22
2337 A721 2022 2020 @2023/11/27 18:00:07.30
2337 072A DF8F 5452 @2023/11/27 18:00:07.39
2337 2727 2064 6F20 @2023/11/27 18:00:07.48
2337 A730 2020 2020 @2023/11/27 18:00:07.56
6337 512F BBCD 5920 @2023/11/27 18:00:07.65
2337 2728 6E65 6B6C @2023/11/27 18:00:07.74
2337 A731 2020 0323 @2023/11/27 18:00:07.83
2337 0728 E614 434F @2023/11/27 18:00:07.91
2337 2729 6964 6E65 @2023/11/27 18:00:08.01
2337 A720 2020 2020 @2023/11/27 18:00:08.09
...
<br/></pre><p>
To analyze a rds-spy format dump, send it to stdin of the program:
<div class="cmd">cat file.spy | si4703rds parse</div></p>
<p>
It is possible to simultaneously dump and analyze the RDS data:
<div class="cmd">si4703rds dump | tee -a file.spy | si4703rds parse</div></p>
<p>
A number of RDS-Spy logs from different countries can be found at <a class="a" href="https://github.com/walczakp/rds-spy-logs" title="remote link: https://github.com/walczakp/rds-spy-logs" target="_blank">https://github.com/walczakp/rds-spy-logs</a>.
</p>
<p>
The dump can be also easily shared through eg. MQTT, for remote decoding:
<div class="cmd">si4703rds dump | mosquitto_pub -t "RDS"</div><div class="cmd">mosquitto_sub -t "RDS" | si4703rds parse</div></p>
<a name="interactivemode"></a><h4> interactive mode
</h4>
<pre class="preFile">
Keyboard keypress controls:
===========================
<space> pause/resume output
- + volume
[ ] prev/next station
? help
f filter RDS, hide 0A and 2A "spam"
h hide/show fixed header
g toggle 2A radiotext string vs group stats
s show RDS string buffers
t show RDS-TMC traffic data log
S stations scan
i reset/initialize chip
I powerdown chip
r show chip registers
q quit, switch off radio
Q quit, keep radio running
status line format:
freq RSSI "station" state current-group seen-groups "radiotext"/stats [<paused/filtered>]
state can be P for paused, F for filtering, R flashing when group was received
Filters: [[], ['0A', '2A'], ['=2A'], ['=3A'], ['=8A']]
</pre><p>
Example output:
<pre class=""> 92.6 9 0000 2424:0443:c5a1:2020 PIC=2424 TP=1 PTY=2 VARY=03 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=3 "R-PLUS " [b' '] Dx=0000 AF=107.2 AF=103.6
92.6 9 0000 2424:8446:cb29:11b7 PIC=2424 TP=1 PTY=2 VARY=06 GTYPE=8A:TMC 06:cb29:11b7 userMsg multi 1st contIdx=6 diversion=1 dir=1 scale=1 event=809 loc=11b7
92.6 9 0000 2424:0440:2885:522d PIC=2424 TP=1 PTY=2 VARY=00 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=0 "R-PLUS " [b'R-'] Dx=0000 AF=091.5 AF=100.8
92.6 9 0000 2424:244b:736b:6120 PIC=2424 TP=1 PTY=2 VARY=0b GTYPE=2A:radioText 11 [ska ] "Pro a proti - Nejvetsi protest v historii Ceska ____d pondeln..."
92.6 9 0000 2424:0441:428c:504c PIC=2424 TP=1 PTY=2 VARY=01 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=1 "R-PLUS " [b'PL'] Dx=0000 AF=094.1 AF=101.5
92.6 9 3103 241f:3450:4080:cd46 bad blocks, skipping
92.6 9 3100 9027:8446:cb29:11b7 bad blocks, skipping
92.6 9 0000 2424:0442:673c:5553 PIC=2424 TP=1 PTY=2 VARY=02 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=2 "R-PLUS " [b'US'] Dx=0000 AF=097.8 AF=093.5
92.6 9 0000 2424:244c:7369:206f PIC=2424 TP=1 PTY=2 VARY=0c GTYPE=2A:radioText 12 [si o] "Pro a proti - Nejvetsi protest v historii Ceska si od pondeln..."
92.6 9 0000 2424:0443:4035:2020 PIC=2424 TP=1 PTY=2 VARY=03 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=3 "R-PLUS " [b' '] Dx=0000 AF=093.9 AF=092.8
92.6 10 0000 2424:8446:61a2:ac00 PIC=2424 TP=1 PTY=2 VARY=06 GTYPE=8A:TMC 06:61a2:ac00 userMsg multi 2ndGrp=1 grpOrder=2 data=1a2ac00
92.6 9 0000 2424:0440:ef33:522d PIC=2424 TP=1 PTY=2 VARY=00 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=0 "R-PLUS " [b'R-'] Dx=0000 AF=[follow:15] AF=092.6
92.6 10 0000 2424:244d:6420:706f PIC=2424 TP=1 PTY=2 VARY=0d GTYPE=2A:radioText 13 [d po] "Pro a proti - Nejvetsi protest v historii Ceska si od pondeln..."
92.6 10 0000 2424:8446:61a2:ac00 PIC=2424 TP=1 PTY=2 VARY=06 GTYPE=8A:TMC 06:61a2:ac00 userMsg multi 2ndGrp=1 grpOrder=2 data=1a2ac00
92.6 10 0000 2424:0441:3a4f:504c PIC=2424 TP=1 PTY=2 VARY=01 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=1 "R-PLUS " [b'PL'] Dx=0000 AF=093.3 AF=095.4
92.6 10 0001 2424:3450:0647:cd46 PIC=2424 TP=1 PTY=2 VARY=10 GTYPE=3A:openDataAppId 10:0647:cd46 grp=8A msg=0647 appId=cd46(TMC ALERT-C) varcode=0 loctable=0019 altfreq=0 transmode=0 internat=0 national=1 regional=1 urban=1
92.6 10 0000 2424:0442:9026:5553 PIC=2424 TP=1 PTY=2 VARY=02 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=2 "R-PLUS " [b'US'] Dx=0000 AF=101.9 AF=091.3
92.6 9 0000 2424:244e:6e64:656c PIC=2424 TP=1 PTY=2 VARY=0e GTYPE=2A:radioText 14 [ndel] "Pro a proti - Nejvetsi protest v historii Ceska si od pondeln..."
92.6 10 0310 2424:044c:49ad:2020 bad blocks, skipping
92.6 9 0030 2424:8446:1c45:0158 bad blocks, skipping
92.6 9 0000 2424:0440:2885:522d PIC=2424 TP=1 PTY=2 VARY=00 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=0 "R-PLUS " [b'R-'] Dx=0000 AF=091.5 AF=100.8
92.6 9 0000 2424:244f:6e2e:2e2e PIC=2424 TP=1 PTY=2 VARY=0f GTYPE=2A:radioText 15 [n...] "Pro a proti - Nejvetsi protest v historii Ceska si od pondeln..."
92.6 9 0000 2424:8446:1025:0158 PIC=2424 TP=1 PTY=2 VARY=06 GTYPE=8A:TMC 06:1025:0158 userMsg multi 2ndGrp=0 grpOrder=1 data=0250158
92.6 9 0000 2424:0441:428c:504c PIC=2424 TP=1 PTY=2 VARY=01 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=1 "R-PLUS " [b'PL'] Dx=0000 AF=094.1 AF=101.5
92.6 10 0010 2424:0442:673c:5553 PIC=2424 TP=1 PTY=2 VARY=02 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=2 "R-PLUS " [b'US'] Dx=0000 AF=097.8 AF=093.5
92.6 9 0000 2424:2440:5072:6f20 PIC=2424 TP=1 PTY=2 VARY=00 GTYPE=2A:radioText 00 [Pro ] "Pro a proti - Nejvetsi protest v historii Ceska si od pondeln..."
92.6 10 0000 2424:0443:4035:2020 PIC=2424 TP=1 PTY=2 VARY=03 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=3 "R-PLUS " [b' '] Dx=0000 AF=093.9 AF=092.8
92.6 9 0000 2424:8446:0000:0000 PIC=2424 TP=1 PTY=2 VARY=06 GTYPE=8A:TMC 06:0000:0000 userMsg multi 2ndGrp=0 grpOrder=0 data=0000000
92.6 9 0000 2424:0440:ef33:522d PIC=2424 TP=1 PTY=2 VARY=00 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=0 "R-PLUS " [b'R-'] Dx=0000 AF=[follow:15] AF=092.6
92.6 8 "R-PLUS " R 8A 0123488^ "Pro a proti - Nejvetsi protest vp@istorii Ceska si od pondeln..." <paused>
</pre></p>
<p>
The event lines are as follows:
<pre class=""> 92.6 10 0010 2424:0442:673c:5553 PIC=2424 TP=1 PTY=2 VARY=02 GTYPE=0A:basicTuning TA=0 MS=0 DI=0 C=2 "R-PLUS " [b'US'] Dx=0000 AF=097.8 AF=093.5
freq | | | | | |
RSSI, signal strength | | |
data recovery flags (0=received ok, 1=1-2 errors, 2=3-5 errors, 3=uncorrectable (>5 errors or error in checkword
raw data, A:B:C:D | | |
fixed header data from A:B | |
group type, name if known
group-specific data, if format known and decoder implemented
</pre></p>
<p>
The status line at bottom is as follows:
<pre class=""> 92.6 8 "R-PLUS " R 8A 0123488^ "Pro a proti - Nejvetsi protest vp@istorii Ceska si od pondeln..." <paused>
freq | | | | | | |
RSSI| | | | | |
8-byte station name from group 0A |
P=paused, F=filtered, R=RDS packet received |
most recent RDS group received |
list of groups seen, hex, lowercase=variant-A, uppercase or with ^ suffix=variant B, shows misreceived group 8B
radiotext from group 2A/2B |
paused/filtered (with filter designation), or none when running
</pre></p>
<p>
Strings and statistics (key "<span class="code">S</span>"):
<pre class=""> 0A "COUNTRY "
0Ab "0001"
2 "GLEN CAMPBELL - OL NORWOODS COMING HOME "
PTYN " "
TMCID "________"
clock 2118-12-10 04:13
stat: [-- 289x 7.2%] [0A 1227x 33.1%] [2A 1242x 33.5%] [4A 2x 0.1%] [10A 1235x 33.3%]
stat: suspected bad: [3A 1x 0.0%] [11B 1x 0.0%]
ODA:
</pre></p>
<p>
stats from poorly received station, with show of corrupted data fields
<pre class=""> 0A "R-PLUS "
0Ab "0000"
2 "Cesk____zhlas Plus - politika-spolecnost-byznys-veda ____ "
PTYN b(b'____a\xb6@@')
TMCID "DIC ____"
clock 2169-7-7 22:17
stat: [-- 3046x 95.1%] [0A 69x 43.7%] [2A 37x 23.4%] [3A 15x 9.5%] [4A 2x 1.3%] [8A 29x 18.4%]
stat: suspected bad: [1A 1x 0.6%] [2B 1x 0.6%] [9A 1x 0.6%] [10A 1x 0.6%] [12A 2x 1.3%]
ODA: [8A 0xCD46(TMC) 7x]
</pre></p>
<p>
another stats block, from a highly noisy source, shows spurious ODA data
<pre class=""> 0A "COUNTRY "
0Ab "0001"
2 "ZALM!~ A SPOL - HO HO WATANAY &# "
PTYN "@8 "
TMCID "________"
clock 1959-11-29 20:17
stat: [-- 8588x 46.7%] [0A 3295x 33.6%] [2A 3276x 33.5%] [4A 2x 0.0%] [10A 3157x 32.2%]
stat: suspected bad: [0B 1x 0.0%] [1A 4x 0.0%] [2B 2x 0.0%] [3A 10x 0.1%] [6A 13x 0.1%] [8A 5x 0.1%] [9A 6x 0.1%] [11A 4x 0.0%] [11B 1x 0.0%] [12A 9x 0.1%] [14A 7x 0.1%] [15A 1x 0.0%]
ODA: [8A 0x434F 1x] [11B 0x5920 1x] [9A 0x5452 1x] [8B 0x554E 1x]
</pre></p>
<ul><li> 0A = station name from group 0A
</li><li> 0Ab = D bits from group 0A
</li><li> PTYN = program type/name, from group 10A
</li><li> TMCID = TMC identification string, from group 8A
</li><li> clock = clock from group 4 (shown miscalculated clock from corrupted data)
</li><li> stat = statistic of groups; -- for rejected packet (shows horribly weak signal), group:count,percentage (shows lots of misreceived groups, the sub-percent ones are misread)
</li><ul><li> rejected packet percenteage is from packets total, other percentage is from nonrejected
</li><li> suspected bad are packets with less than 2% prevalence, except group 4A which is only once per minute
</li></ul><li> ODA = list of open-data groups assigned from group 3A, [group number(name) count]
</li><ul><li> ODA list is populated only from packets received without error correction; on weaker stations this may take time
</li></ul></ul><p>
Filters can be applied to the realtime output; <span class="code">f</span> key cycles through the presets which are possible to edit in the main program file,
or switch off with <span class="code">F</span>. Preset filters are:
<ul><li> none - show everything
</li><li> <span class="code">0A, 2A</span> - hide the most common "spam"
</li><li> <span class="code">=2A</span> - show only the radiotext, good to get a feel for the packet-based string transfer
</li><li> <span class="code">=3A</span> - show only the ODA declarations
</li><li> <span class="code">=8A</span> - show only the TMC data
</li></ul></p>
<p>
Example scan output:
<pre class="">scan start
freq rssi name badgrp seen RDS group counts
STATION: 88.2 12 [EVROPA 2] --:1 0A:38 1A:3 2A:18
STATION: 89.5 12 [COUNTRY ] --:0 0A:20 2A:20 10A:20
STATION: 90.3 12 [EXPRESFM] --:10 0A:45 2A:5
STATION: 92.6 9 [R-PLUS ] --:36 0A:12 2A:6 3A:1 8A:4 ODA:8A:1:0xCD46(TMC)
STATION: 93.7 4 [HITRADIO] --:0 0A:36 2A:18 3A:3 11A:2 ODA:11A:3:0x4BD7(RT+)
STATION: 94.1 9 [ FAJN ] --:27 0A:22 2A:8 3A:1 11A:1 ODA:11A:1:0x4BD7(RT+)
STATION: 94.6 3 [R-ZURNAL] --:0 0A:30 1A:5 2A:7 3A:4 8A:11 ODA:8A:4:0xCD46(TMC)
STATION: 95.3 15 [ BEAT ] --:0 0A:20 2A:20 10A:19
STATION: 95.7 13 [ SIGNAL ] --:1 0A:29 2A:30
STATION: 96.6 15 [ IMPULS ] --:16 0A:25 2A:19
STATION: 98.7 10 [CLASSIC ] --:6 0A:46 2A:6
STATION: 102.5 9 [RADIO F1] --:0 0A:38 1A:4 2A:18
STATION: 105.0 3 [R-VLTAVA] --:0 0A:40 2A:10 14A:10
scan end
</pre></p>
<hr /><a name="Files"></a><h2>Files
</h2>
<ul><li> <b><a class="F" href="si4703rds.zip" title="local file">si4703rds.zip</a></b> - all files
</li><li> <a class="F" href="si4703rds.py" title="local file">si4703rds.py</a> - main code
</li><li> <a class="F" href="_libsi4703.py" title="local file">_libsi4703.py</a> - chip library
</li><li> <a class="F" href="_rdslists.py" title="local file">_rdslists.py</a> - lists/dicts of RDS-related data
</li></ul><hr /><a name="Todo"></a><h2>Todo
</h2>
<ul><li> !!! solve the post-initialization sensitivity issues (how???)
</li><li> option for non-Europe band settings
</li><li> more hardware options (eg. for USB-I2C dongles)
</li><li> dump to <a class="a" href="https://rftap.github.io/specifications/" title="remote link: https://rftap.github.io/specifications/" target="_blank">RFtap protocol</a>, for wireshark and other tools
</li><ul><li> segregate hardware-specific code - interrupts, GPIOs... - to separate code module
</li><li> commandline options for hardware config
</li></ul><li> commandline options for individual commands for the chip
</li><li> TMC event codes, support for TMC location codes
</li><li> alt-frequencies list
</li><li> get a si4743 chip, try multiband radio
</li><li> MQTT, for remote control/status/messages
</li><li> for areas with EWS, consider a module monitoring the data stream, sending to home automation; can be tested with 8A/TMC traffic
</li></ul><!-- feedback -->
<!-- /feedback -->
</body>
</html>