Range does not depend only on power and antenna. There is a third participant, usually remembered last — the air itself, which you share with a lot of other things.
Who else lives on 868 MHz
The 863–870 MHz band is open to low-power devices, and it is not only radio amateurs who use it. Door phones, weather stations, water and electricity meters, car alarms, apartment sensors all live there. In a city that is a noticeable background, and an uneven one: one frequency is quiet, the next one has someone clicking away constantly.
While the channel was chosen by guesswork, there was no way to check. So the firmware got a simple addition: the radio walks through all twenty-three channels, listens, and shows the noise level on each.
One detail turned out to matter. The level is taken as the loudest sample of a series, not the average. Interference rarely holds steady: it comes in bursts, and by the average a channel looks quiet while in reality someone's packet drives through it once a second — exactly what kills voice. The maximum is more honest.
The very first bench measurement showed a fifteen-decibel spread between the quietest and the noisiest channel. That is a lot: fifteen decibels is the difference between having a link and not having one at distance.
Why one channel solves nothing
Then came the unpleasant part. Finding a quiet channel is not enough — everyone has to move to it: radios currently in other people's hands, and the repeater, which may sit on a roof or across town.
The community put it plainly: the quiet channel is detected fine, but there is no way to hand it out to all the nodes, so each one has to be set by hand. And when some of the stations are out walking with people, setting them by hand is impossible in principle.
A command that travels by air
The solution sounds simple: the radio broadcasts "everyone move to channel N in ten seconds". Everyone who hears it, the repeater included, moves at the same time.
Simple in words only. Here is what had to be accounted for.
The command goes out as three copies in a row. The air is half-duplex, a single packet is easily lost, and the cost of losing this one is high: a station that misses it stays on the old channel and disappears from the group.
The sender leaves last. While it is still on the old channel, the command can be repeated. Had it left first, stragglers would have lost contact with the very station that called them.
A straggler needs a way back. A station that moved to the new channel and heard nobody there returns to the old one on its own. Otherwise one lost command would mean walking up to the device.
Where we got it wrong
Now for the part actually worth reading.
Mistake one: a safeguard that harms. The "I hear nobody, I am going back" rule was designed for a lone radio. But a repeater is always silent: it only repeats other people's traffic and never speaks for itself. It dutifully moved with the group, heard nobody for two minutes — and went back. The stations stayed on the new channel, the repeater on the old one, and the link broke at exactly the point the repeater was raised for.
From the group this arrived as a single sentence: the nodes changed channel, the repeater did not.
Mistake two: the wrong measure of silence. The same two minutes applied to ordinary radios. But a group can simply be quiet: the presence beacon goes out once every five minutes, so two minutes of "silence" only means nobody was talking. Stations at the edges of the network had time to decide they were alone and went back — which looked from outside like "it works every other time".
The window is now ten minutes, and after moving, every station announces itself three times with a random spread so that neighbours hear it. A repeater that received the command from its own page does not go back at all: a person pressed that button deliberately.
Mistake three, a technical one. Changing frequency does not resume reception by itself — it needs an explicit command afterwards. Without it the radio arrived on the new channel deaf: able to transmit, unable to hear. And separately: the channel number was kept in two places, in the radio module and in the main program, so the repeater really did switch while its page and the app still showed the old channel.
What follows from this
The main lesson is not about channels. It is about safeguards.
A "if something went wrong, return to the previous state" mechanism looks harmless and is easy to add. But it fires on an indirect signal — silence, a timeout, a missing reply — and that signal is easy to confuse with normality. A quiet group looks like a lost group. A repeater, silent by its very nature, looks lost permanently.
So the second version of the fallback works differently: different timeouts for different roles, an explicit announcement on air after the move, and no fallback at all where a person made the decision.
Details on finding a quiet channel and moving everyone at once are in the documentation. What is happening in the project right now is in the Telegram group.