Listen the way the tools that work on this band listen
Still nothing, with rtl-433 receiving the same sensors on the same aerial from a different receiver. That settles where the fault is not: not the aerial, not the sensors, not the band. So the sensible thing is to stop differing from the configuration known to work on that aerial, and this differed from it in three ways, every one of them mine. It tuned a quarter of a megahertz to one side of 433.92 and shifted the signal back in software, to keep the receiver's own spike off a signal that works by being switched off. That is a real effect and avoiding it this way is a bad trade: at the sample rate this ran at, the shift is followed by a filter, and a filter narrow enough to reject the spike is narrow enough to lose a transmitter that has drifted -- or to lose the signal outright if a dongle presents its samples the other way round, which is not a thing to depend on. The spike is a steady addition to the envelope and a burst rises clear of it. Tuning straight at the sensors now, which is what the established tools do. It sampled at a megasample a second where a quarter of one is plenty: the shortest pulse these send is two hundred microseconds, which is fifty samples at the lowest rate a dongle will do. The extra rate bought nothing but the room for that filter to exist in. At 250 kS/s nothing after the mixer is narrower than the band, so the offset now does nothing at all whatever it is set to, and says so. And it turned on the RTL2832's digital gain control along with the tuner's. The two pump: the gain winds up through the silence between one burst and the next, lifting the noise towards the signal and squeezing the very difference the burst detector works on. It matters here in a way it does not for aircraft, where a frame is found by correlating a preamble over microseconds rather than by comparing a burst with the quiet around it. Three more faults found while going over the rest of it, all the same mistake in different clothes -- treating the middle of a distribution as though it were the quiet part of one. The check that skips an empty block measured the peak against the median. A recording that is mostly burst measures its own burst against its own burst, finds no difference and is discarded as silence, which is what happened to every short capture. The gate's scatter had the same trouble one level down and could come out above the peak, which is the one setting that cannot be right, so it is now capped below it. And the rule deciding where one message ends keyed on the middle gap in a burst. Where a one is drawn as a gap three times a zero and most of the bits are zeroes, the middle gap is the short one, twice it still falls inside the message, and every one-bit ended a burst -- the message coming apart into pieces of three pulses. It keys on the widest gap now, which is a fact about the message rather than about the data it happened to carry. The pieces of a message are also put back together after being sliced rather than before. Grouping has to be tight, because the group is what fixes the threshold and a group holding two sensors of unequal strength fixes it on the louder; but the gaps inside one message run from two hundred microseconds on the newer sensors to four thousand on the oldest, and a grouping tight enough for the first tears the second into a bit at a time. So each piece is measured at its own amplitude and joined to its neighbours afterwards, and anything that comes out longer than the longest message there is gets cut at its largest gaps. Measured rather than argued: across four hundred and eighty combinations of pulse and gap timing, 464 now read where 417 did; across twenty-one gap-keyed combinations, 18 where 12 did; and eighty seconds of receiver noise still yields nothing at all. --from-iq FILE reads a saved capture instead of the receiver, so a recording made where the aerial is can be worked on anywhere, as many times as it takes. Everything downstream of the dongle is the real thing, which is what tells a receiver problem and a decoder problem apart. --save-iq writes the settings beside the samples, a file of raw samples with no record of its rate being unreadable by anything. The invented garden now waits like a dongle instead of running as fast as the machine allows, which it should have done from the start: --seconds meant nothing against it and a capture came out fifty times too large. Full suite 2331 passed; this work checked against sixteen deliberately broken builds, two of which it survived until the tests were made to catch them, and one change was removed for being unable to earn a test at all. Built as 2026-09-07_03. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PsWPTweCT6pwxKngvVxcg
This commit is contained in:
parent
335d83f8a0
commit
706c632f47
10 changed files with 978 additions and 92 deletions
67
README.md
67
README.md
|
|
@ -1942,22 +1942,27 @@ burst does. A real message begins after the sync and runs to the end.
|
|||
|
||||
### Off the air
|
||||
|
||||
Three things happen between the aerial and a bit, in this order.
|
||||
The receiver is tuned straight at 433.92 MHz, at 250 kS/s, with the tuner's own
|
||||
gain control doing its job and the RTL2832's digital AGC left off — which is
|
||||
what the established tools for this band do, and there is nothing to be gained
|
||||
by differing from them.
|
||||
|
||||
The receiver is tuned a little to one side of 433.92 MHz, because every
|
||||
RTL-SDR puts a spike of its own at whatever it is tuned to, and a spike
|
||||
sitting on top of a signal that works by being switched on and off is the one
|
||||
thing that stops it being off. The sensors are shifted back to the middle in
|
||||
software, which puts the spike out at the edge instead. `--offset 0` tunes
|
||||
straight at them, which is worth trying once to see what the spike was costing.
|
||||
Each of those was once something else, and each was wrong. Tuning to one side
|
||||
and shifting the signal back in software avoids the spike every RTL-SDR puts at
|
||||
whatever it is tuned to, which sounds worth doing until you notice that a
|
||||
filter narrow enough to reject that spike is narrow enough to lose a
|
||||
transmitter that has drifted — and that which way round a dongle presents its
|
||||
samples is not a thing to depend on. The spike is a steady addition to the
|
||||
envelope and the burst rises clear of it. `--offset` is still there and does
|
||||
nothing at all at the default rate: shifting a signal only matters if something
|
||||
afterwards is narrower than the band, and at 250 kS/s nothing is.
|
||||
|
||||
Then a running average of the complex samples, long enough that its first null
|
||||
lands on the spike. It is a crude filter and a deliberately crude one: what it
|
||||
has to reject is one tone at a frequency this end chose.
|
||||
|
||||
Only then is the magnitude taken. Filtering before detection rather than after
|
||||
is what keeps the neighbours — a doorbell, a tyre sensor, a car key — from
|
||||
adding themselves to the envelope of the sensor.
|
||||
The digital AGC is off because it pumps. It winds the gain up through the
|
||||
silence between one burst and the next, which lifts the noise towards the
|
||||
signal and squeezes the very difference this depends on. It matters here in a
|
||||
way it does not for aircraft, where a frame is found by correlating a preamble
|
||||
over a few microseconds rather than by comparing a burst with the quiet around
|
||||
it.
|
||||
|
||||
**Finding the bursts is done in two passes, and the reason is having more than
|
||||
one sensor.** The first pass only asks where anything is happening at all, and
|
||||
|
|
@ -1976,8 +1981,15 @@ block with one loud sensor in it yields exactly one sensor however many are out
|
|||
there.
|
||||
|
||||
**Slicing the envelope into bits never measures anything against a clock**,
|
||||
and assumes as little as it can about how a bit is drawn. Three things are not
|
||||
assumed. Which of the pulse and the gap carries the bit — the newer sensors
|
||||
and assumes as little as it can about how a bit is drawn. Nor about how long
|
||||
the silences in it are: the gaps inside one message range from 200 µs on the
|
||||
newer sensors to 4000 µs on the oldest, so what belongs to one transmission is
|
||||
settled from each burst's own widest gap rather than from a figure that would
|
||||
have to suit every model at once. Anything that comes out longer than the
|
||||
longest message there is gets cut at its largest gaps, because that is what a
|
||||
boundary between two copies physically is.
|
||||
|
||||
Three further things are not assumed. Which of the pulse and the gap carries the bit — the newer sensors
|
||||
vary the pulse, the older two vary the gap. Whether the gap is the complement
|
||||
of the pulse, so that every bit takes the same time, or just a fixed spacer:
|
||||
judged against a fixed 200 µs spacer a short pulse of 220 µs is longer than its
|
||||
|
|
@ -2051,9 +2063,9 @@ only what is shown and can be changed afterwards on an old log.
|
|||
|---|---|---|---|
|
||||
| Receiver | `--device` | 0 | which receiver, when more than one is plugged in |
|
||||
| Gain | `--gain` | auto | tuner gain in dB, or automatic |
|
||||
| Sample rate | `--rate` | 1.024 MS/s | how fast to sample; 250 kS/s is the minimum |
|
||||
| Sample rate | `--rate` | 250 kS/s | how fast to sample; this is also the minimum |
|
||||
| Sensors on | `--frequency`, `--freq` | 433.92 MHz | where the sensors transmit |
|
||||
| Tuning offset | `--offset` | 250 kHz | how far to one side of them to tune |
|
||||
| Tuning offset | `--offset` | 0 | how far to one side of them to tune; does nothing at the default rate |
|
||||
| Invent a garden | `--simulate` / `--no-simulate` | no | six sensors that are not there |
|
||||
| Listen for | `--seconds` | until stopped | how long before stopping |
|
||||
| Write a log | `--log` / `--no-log` | yes | one line of JSON per message |
|
||||
|
|
@ -2067,7 +2079,8 @@ only what is shown and can be changed afterwards on an old log.
|
|||
| Also write a spreadsheet | `--csv` / `--no-csv` | no | CSV beside the log |
|
||||
|
||||
`--name ID=NAME` is not a setting: it names a sensor and is repeatable.
|
||||
Neither is `--save-iq FILE`, which is a one-off capture of the raw samples.
|
||||
Neither is `--save-iq FILE`, a one-off capture of the raw samples, nor
|
||||
`--from-iq FILE`, which reads one back instead of the receiver.
|
||||
|
||||
Saved in `weather.yaml` beside the other settings, from the menu's **s** or by
|
||||
hand. `bandsaunter readings` also takes `--sensor NAME` to narrow a log to one
|
||||
|
|
@ -2138,8 +2151,20 @@ When the listening stops it says which of those it was, once:
|
|||
```
|
||||
|
||||
`--save-iq FILE` writes the raw samples alongside, for working out anything the
|
||||
diagnosis cannot. It is 8 MB a second at the default rate, so bound it with
|
||||
`--seconds 60`.
|
||||
diagnosis cannot. It is 2 MB a second at the default rate, so bound it with
|
||||
`--seconds 60` — that is plenty, since every sensor reports at least twice in
|
||||
a minute. It writes the settings it was taken at beside it, because a file of
|
||||
raw samples with no idea what rate it was recorded at cannot be read back by
|
||||
anything: at the wrong rate every pulse in it is the wrong length.
|
||||
|
||||
`--from-iq FILE` reads one back instead of the receiver, so a recording made
|
||||
where the aerial is can be worked on anywhere, as many times as it takes, with
|
||||
different settings each time. Everything downstream is the real thing — the
|
||||
same filter, the same slicer, the same decoders — because the only part being
|
||||
stood in for is the dongle. That is what tells a receiver problem and a
|
||||
decoder problem apart: a capture that yields nothing on replay yields nothing
|
||||
for anybody, and a capture that yields readings on replay but not on the air
|
||||
is a setting.
|
||||
|
||||
## Meters on 900 MHz
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue