This is a mobile MeshCore repeater for a vehicle. It reports where it stops. When the vehicle stops for a few minutes, the node sends its GPS location to Meshtastic and MeshCore together. The node then shows on both maps, at the location where you stopped.
This is a fork of the meshtastic_beacon project. It
uses the same Meshtastic interop code, with no changes. It replaces the
fixed-interval beacon with a park-triggered beacon. The beacon updates
the two networks together.
| mtbeacon | car node | |
|---|---|---|
| Location source | a location that you set (fixed) | the live GPS location when the vehicle stops |
| Trigger | a fixed interval (minutes) | the vehicle stops (more than park seconds); a small presence also goes out each interval minutes |
| Networks updated | Meshtastic only | Meshtastic and MeshCore together |
| While driving | it sends a beacon at intervals | it sends a presence only (NodeInfo, no location) each interval |
| CLI command | mtbeacon … | carnode … |
| Configuration file | /mtbeacon | /carnode |
The node sends a location update when the GPS location does not move for park seconds (default 5 minutes). A small presence keeps the node visible between updates.
The same GPS location updates the Meshtastic beacon and sends a new MeshCore advert. This occurs in one event.
The node shows as a named node and a map point. It can also send text. The node does not route or repeat traffic.
Hold the user button near 3 seconds to put the node into its lowest-power state. Push the button to wake the node.
carnode zone add <name> stores a place where you stop frequently (up to 4). When you stop in a zone, the node sets repeat to off and stops all transmissions. That location does not go on the air.
block #dispatches stops the repeater from repeating a #hashtag channel. Use the name only; you do not need a key. The firmware calculates the channel hash from the name.
nRF52 boards start a hardware watchdog. If the node stops, it starts again; it does not continue dead. get pwrmgt.bootreason shows the cause of the last reset.
If the radio does not report the TxDone interrupt, the node reads the chip status flag. The node then knows if the update transmitted, and sends the failed updates again. After several dead transmits, the node starts the radio again. mtbeacon stats shows the totals.
Each transmission includes Meshtastic telemetry. A vehicle that stops for days shows its battery decrease in a Meshtastic client.
The node monitors its GPS location. When the location moves more
than radius metres, the node is driving and sends no
location. When the location stays in radius for park
seconds (default 5 minutes), the vehicle is parked. The node then sends
one update:
NodePrefs and sends a new advert, so all MeshCore nodes know
where you stopped.radius removes duplicates).
mtbeacon send sends an update immediately. The node keeps the
MeshCore location in flash, so it stays after a restart while parked.
radius for near
15 seconds before the node is driving. carnode status shows
the live data (d<n>m = the distance of the filtered location
from the park point; (raw) while the filter starts;
<n>min = the time the vehicle has been stopped). If the node
changes to driving while the vehicle is stopped, increase
carnode radius.
interval minutes (default 30; 0 = park only).
This keeps the node in the Meshtastic node lists. When the vehicle is parked,
the presence includes Position and refreshes the point. When the vehicle is
driving, or there is no location, the node sends NodeInfo only. Thus the map
point does not move to a location in the middle of a drive. The location
updates only when the vehicle parks.
mtbeacon text message is
event-driven. When the repeater sends a MeshCore advert (the park
advert, the periodic advert, or the CLI advert command), the text
goes out on a Meshtastic burst a few seconds later. Each park at a new location
sends its text. The advert command is also a good test.
mtbeacon status shows the schedule, for example
txt1x~47h(due 13h), or (due now) when a text is
ready. At home, the node transmits nothing. A ready text waits until you drive
away.
sleep hours
(default 20), the node stops repeating. Remote status shows it as
disabled, and it is not in node-discover. A vehicle that is parked for a day
is usually in a place where no person needs a mobile repeater. The node still
receives, answers its own commands, sends adverts, and beacons. It repeats
again when it detects movement. A GPS loss while parked (an underground garage)
does not wake it; only movement wakes it. carnode sleep 0
stops this function.
set repeat on|off setting; they
do not write to it. Thus get repeat always shows your selection,
and no sleep state writes to flash. The node always starts awake after a
restart. carnode status shows rpt:off while
suppression is active. This is the one place where the two can be different.
set repeat on one time while parked outside all zones. This
corrects it.
carnode zone add home. The node stores the current location with
that name (kept in flash). After this, when you park in the zone radius
(default 100 m), the node sets repeat to off immediately. It does
not wait for the sleep timer. It keeps the node radio-quiet: the park
burst, the MeshCore advert, and the periodic presence are all off. That
location does not go on the air (carnode send still transmits if
you ask). When you drive away, the node starts all functions again. You can set
up to 4 zones — home, work, a frequent location — each with its own
radius. carnode zone lists them and shows the zone you are in.
carnode home is a short form for the zone with the name
home. A home from an older build moves across automatically.
hops 0. Direct
neighbours receive them; other nodes do not repeat them. A car node transmits
from where it parks, so it is not good manners to send its location across
another person's mesh. mtbeacon hops <0-3> increases the
limit if you need more range.
carnode status
shows adv!N if the node stopped a park advert fully. Usually it is
not shown.
These are the firmware files for the three boards. The two Heltec boards need an external NMEA GPS module on the GPS UART pins. The T1000-E has a GPS on the board. The GPS is on by default.
invalid header: 0xffffff):
install the -full file at 0x0. It includes the bootloader and the partition table..bin file at 0x10000.esptool.py write_flash 0x0 heltec_v4_carnode-75b523f8-full.bin # new board
esptool.py write_flash 0x10000 heltec_v4_carnode-75b523f8.bin # update
.zip file with adafruit-nrfutil on the serial port. Or install the .hex file with a debugger.adafruit-nrfutil dfu serial -pkg heltec_t114_carnode-dfu.zip -p /dev/ttyACM0 -b 115200
T1000-E USB drive shows. Copy the .uf2
file to it. This keeps the standard bootloader.bootloader mode → copy t1000e_dualmode_carnode-75b523f8.uf2 to the T1000-E drive
Checksums: SHA256SUMS.txt ·
Built from the carnode branch (commit 75b523f8). This
is not an official MeshCore release. After you install it, the ver
command shows v1.17.1+carnode-75b523f8. Check it to make sure that
you have this build.
Use the USB serial port or an admin remote-CLI session. There are
two command groups, but one beacon engine (no second transmitter).
mtbeacon sets the Meshtastic beacon. carnode sets the
park behaviour.
mtbeacon — the Meshtastic beacon (RF and appearance)| Command | Function |
|---|---|
mtbeacon / status | Show the beacon RF configuration. |
stats / stats clear | Show the transmit health from boot. / Set the counters to zero. |
on / off | Set the beacon to on. / Set the beacon to off. |
send | Send a location update now (both networks). |
interval <min> | The presence interval between parks (0–1440; 0 = park only; default 30). |
preset <name> | The modem preset (LongFast, MediumFast, and others). |
region <name> | The region and band (US, EU_868, and others). |
freq <MHz|auto> | Set the frequency manually. auto calculates it again. |
power <dBm> | The TX power (−9 to 22). The region limit applies. |
hops <0-3> | The Meshtastic hop limit for the presence and text (default 0 = direct neighbours only). |
text <string> | The chat text (63 characters maximum). |
text.mult <N> | The text schedule. The text goes with each flood advert, and N−1 more times each period (0 = never). |
short <str|auto> | The Meshtastic short name / map label (4 characters maximum). auto = MC and 2 hex characters. |
nodeinfo on/off | Include NodeInfo (the node name). Default on. |
position on/off | Include Position (the map point). Default on. |
telemetry on/off | Include Telemetry (battery and run time). Default on. |
presets / regions | Show the available values. |
carnode — the park behaviour| Command | Function |
|---|---|
carnode / status | The drive state (nofix/driving/parked/sleeping/zone) and the park configuration. |
park <sec> | The stopped time before an update (30–86400; default 300). |
radius <m> | Movement in this distance is "stopped" (5–2000; default 30). |
advertdelay <sec> | The time from the Meshtastic burst to the MeshCore advert (0–600; default 10). |
sleep <hours> | Parked this many hours → stop repeating until it drives again (0–720; 0 = never; default 20). |
zone | Show the quiet zones (up to 4). |
zone add <name> | Make a quiet zone at the current location. Park in it → repeat off immediately, radio quiet. |
zone del <name> | Delete that zone. |
zone radius <name> <m> | The zone radius (5–2000; default 100). |
home [clear|radius <m>] | A short form for the zone with the name home. |
mtbeacon on. The OLED home screen shows
CarNode driving / parked / sleeping / <zone name>.
block — channels this repeater does not repeat| Command | Function |
|---|---|
block / block list | Show the blocked channels and their hash byte. |
block #dispatches | Stop the repeat of that #hashtag channel (up to 8). |
unblock #dispatches | Start the repeat of it again. |
#hashtag channels calculate their key from
the name (SHA-256("#name")[:16]). Thus the firmware calculates the
channel hash, and you type the name only — you do not paste a key. Two limits
come from the wire format. First, it operates for #-name channels
only (the firmware cannot calculate the key of a private channel with a random
key). Second, the channel id on the air is one byte, so a block sometimes also
stops a different channel with the same byte (near 1 in 256; the hash in the
list makes a collision easy to see). Adverts, DMs, and ACKs do not change.
Hold the user button on the board for near 3 seconds. The node
then goes to its lowest-power state with board.powerOff().
sd_power_system_off). The GPS is off. The user button or reset wakes it.Use PlatformIO with the
carnode branch
of the MeshCore-mtbeacon fork. The car node is in
examples/car_node/.
pio run -e heltec_v4_carnode # Heltec V4 (ESP32-S3, SX1262)
pio run -e Heltec_t114_carnode # Heltec T114 (nRF52840, SX1262)
pio run -e t1000e_dualmode_carnode # Seeed T1000-E (nRF52840, LR1110, dual-mode)
The env extends the repeater of the board
and adds the car-node code. (The T114 env also sets
-D ENV_INCLUDE_GPS=1.)
[env:heltec_v4_carnode]
extends = env:heltec_v4_repeater
build_flags = ${env:heltec_v4_repeater.build_flags}
-D WITH_CAR_NODE
-D MT_HW_MODEL=110
-I examples/meshtastic_beacon
-I examples/car_node
lib_deps = ${env:heltec_v4_repeater.lib_deps}
The project README has all the details.
This is a one-way presence only. The node shows as a named node
and a map point, and it sends text. It does not route or repeat traffic. A park
sends a MeshCore advert to all nodes and adds airtime to a shared public
Meshtastic channel. Thus keep park at a sensible value. Obey the
limits of your region. Do not beacon onto channels that you do not operate. The
Meshtastic side uses hops 0 by default, so other persons' nodes do
not repeat what it sends.