Meshtastic
Overview
Meshtastic is an open source, low bandwidth mesh network that runs on 933MHz in the U.S. It runs on LoRa radio technology which is very low power, line of sight. Nodes can broadcast for miles if you are high on a hill. In an urban, flat area you might get 0.25 miles. But the power of the mesh is that if just one node can hear your message, then it can be relayed on to others.
Some people use these nodes when they are out camping in the wilderness without any cell phone service. The nodes automatically repeat messages and share their GPS location. It's a great way for a team to stay in touch.
Of course if you are the only person in your area running a Meshtastic node, then you won't have anyone to chat with. If you want to join a local mesh then you should web search for a group of enthusiasts in your area. Often an area will use radio settings that are different from the defaults, so you need to know what they are. For example, in the San Francisco Bay Area there is an active group named Bay Mesh. They use Discord to help people grow the mesh.
You can buy a node for as little as $25. The node pairs with your phone over Bluetooth and you control it via the Meshtastic app. Once you have your node running you can send text messages to other nodes, or send a message to the "general" channel. Channels are encrypted but the General channel has a default encryption key of AQ== so everyone can read those messages.
You can read up on this fascinating technology at the Meshtastic web site.
Check out their glossary of terms and their configuration tips.
The first Meshtastic node was probably Kevin Hester, one of the guys who kicked off the whole thing. It got going sometime around 2018 or 2019. Not sure what the first LongName, ShortName, or Hex ID was. Here's an article on the history of Meshtastic
Why this page?
While the documentation is good, it feels like a lot is left unsaid. This page holds tips, tricks, and just bits of knowledge that we have come across in bringing up our own nodes into the BayMesh. If you read something here that you know is in the docs, please comment or email and we'll replace whatever we have here with a link to the official docs. OR, if you read something here that you think is wrong or off base, please post to the #docs channel on Discord.
Hopefully we'll get this knowledge into the official docs, but that can take a while. In the meantime, this page can be updated on the spur of the moment.
AND, if the reader feels like it, please take information from this page and add it to the official docs.
Low Level Details
Low level, but still crucial to get right.
Radio Things
Bay Mesh has some good hardware recommendations.
Height above ground will dramatically improve your experience. The higher the better. If you drive to the top of a hill your signal will propagate much further. Like A LOT further. In one experiment we got good reception 1/4 mile down the block in an urban setting; the same devices with one on a hill worked at 3 miles! Nothing beats a high placement with clear line of sight.
Line of sight planning tools
- The official Site Planner shows how far your radio will reach
- Move two pins and see what's between them
- Pick a location and see the horizon view
- Give it your location and see the peaks
The cable between your node and the antenna makes a difference. Sometimes you might want the antenna a ways away from your node. Then cable loss can be a big factor and depend on the type of cable. KMR 240 would be fine under 5-10 feet. KMR400 or KRM600 is better and also allows you to go 10-30 feet. It’s usually easier to just put the radio on the pole close to the antenna with a long power or network cable.
Adapters also introduce signal loss. Try to avoid them.
Some antennas have a built in right-angle joint. It seems convenient but in testing several of these we found that while straight they had a SWR of almost 1:1, when in right-angle position the SWR was 3:1 - yikes!
If you have a node that can run high power, like the Station G2, then you can up the RF output to compensate for antenna configuration. What if you have a small unit like a Heltec V3? You might wonder which is better:
- a well tuned 2.5dBi whip antenna with a short cable
- a nice 6dBi antenna with two short cables and an adapter to connect them
If you figure this out, let us know!
If you are in a noisy area, then a well tuned RF filter can boost your signal reception dramatically. They are pricey.
Protocol Details
Best to read the official docs
LoRa Details
Meshtastic runs over LoRa. LoRa is a spread spectrum technology. Read Meshtastic overview for a good start.
LoRa spread spectrum technology is very good in noisy environments. The radio can reliably receive data at -14dB or better.
The LoRa Physical Header contains a sync word, which is a unique identifier that allows different LoRa networks to distinguish themselves. For Meshtastic, this sync word is set to 0x2B. This allows Meshtastic radios to recognize and process packets that are intended for their network and filter out other LoRa traffic that might be on the same frequency.
For those familiar with LoRa you might wonder what settings are used. Meshtastic allows any of the LoRa parameters, but also supplies a number of "presets". This is important because radios must use the same LoRa settings (e.g. network id, bandwidth, spreading factor, frequency slot) to be able to communicate. For example, if some nodes use a spreading factor of 7 and others use 9, they will not communicate; you will have two meshes. There are a few exceptions.
Coding Rate does not affect the ability to communicate between nodes. A node in a noisy environment could choose to use a lower coding rate and still participate in the network. The lower coding rate would only affect communication to the first hop. Lower coding rate will make the messages take more air time, thus increasing congestion.
The actual center radio frequency used is configured using the Frequency Slot. Nodes using different Slots cannot communicate with each other. Different regions have a different number of Slots available. The number of slots also depends on the LoRa Bandwidth setting. More info Note that Medium Slow uses Slot 52; Medium Fast, 45; Long Fast, 20. Use the frequency calculator to discover the actual center frequency.
On iOS, if you set the Slot to 0, then the firmware will pick a Slot based on the name of your Primary Channel. Your Primary Channel name should either be blank, or match the camel case name of the preset you use. For example, if you set Frequency Slot to 0 when using the Medium Slow preset, your Primary Channel name should be MediumSlow or blank. If not, you will not be on the same Frequency Slot as the general population of nodes using Medium Slow preset.
By choosing LoRa settings and/or frequency slot that does not match one of the presets you will create your own independent mesh. But where's the fun in that?
Long Fast? Medium Slow? Something Else?
Presets make it easy for different people to configure their nodes into the same mesh. As said above, if the user configures these settings by hand, they have to get all of them exactly the same.
The Presets were created to offer a balance of distance and speed but to be more biased towards distance rather than speed. Long Fast is actually pretty slow, but gives long distance.
In areas where the mesh is more dense we can tip the balance towards speed rather than distance. Even though it is called "Medium Slow", this Preset is still faster than Long Fast at the expense of a little bit of distance.
Speed is important in a busy mesh. The slower the transmission, the longer each message takes. And if two nodes transmit at the same time then no nodes will be able to understand the message. Faster speed means less air time for each message and lower overall utilization of the mesh air waves - less congestion.
Many other meshes are starting to bias even further towards speed by using Medium Fast, Short Fast, etc. You can read the article on it.
The Mesh
Time Windows
With all the nodes rebroadcasting messages you might think the mesh would collapse from congestion; Meshtastic uses some clever algorithms to prevent this.
First, there are three different time windows that a node might broadcast in: Early, Default, Late.
- The Early window is used by Routers and Repeaters - nodes in strategic positions. When these nodes rebroadcast a message a lot of other nodes will hear them and decide not to rebroadcast the message.
- The Default window is used by Client and other variations of Client. This is the main rebroadcast window that nodes use. Below we will describe how nodes decide when to rebroadcast a message.
- The Late window starts after the Default window. It starts after the end of the longest client resend wait window (a second or two). This gives Client nodes a chance to mesh messages before the ROUTER_LATE resend would shut them down. It is used by ROUTER_LATE to rebroadcast a message without disturbing the normal mesh that is being handled by other node types.
Managed Flood Routing
- When a message is received a node does not immediately resend it. It puts the message in a queue to resend. The queue can hold 30 messages of all types. If the queue is full, then older messages are dropped; this should only happen in the case of high network congestion.
- Nodes keep a list of the messages they have recently received. When a node is ready to resend a message it checks if the message is already on that list; if so then the node does not resend it.
- A node that receives a message notes the Signal-to-Noise Ratio (SNR) of the transmission. A node waits some time before resending the message. The stronger the signal it received, the longer it waits before resending. The idea here is that a high SNR means the sending node is nearby; a low SNR means the sending node is far away. With this algorithm nodes that are furthest from the sender (theoretically) will resend the message first thus pushing the message further away from the sending node. Nodes between the sender and the rebroadcaster will see the resend and that will stop them from resending the message. The range is between 0 and 16 multiples of the slot time.
- Each node monitors the radio utilization. If the utilization is "too high" it waits for the utilization to drop below a certain value.
- When a node is ready to send a message it monitors the radio and waits for a time when the air waves are clear (Channel Activity Detection or CAD). The amount of time needed for this process is called a "slot time".
About Device Roles
An interesting blog post about choosing the right device role. And one specifically about ROUTER_LATE. Both are good reads.
- 2.7.10 introduced a new role CLIENT_BASE. It acts as ROUTER for messages that are to/from a Favorite node. Otherwise acts as CLIENT. This role is useful for a rooftop node that acts as the connection for your other nodes. For instance, your house has a handful of lower power nodes that have trouble being heard by the mesh. You set them to CLIENT_MUTE and put one node on your roof in the CLIENT_BASE role. That high up node will make sure your other nodes can send and receive to the larger mesh.
- A ROUTER node resends quickly in the Early window and it always sends every message it gets. The assumption is that only nodes in key mesh positions will be set to ROUTER. When the ROUTER node sends a message many clients waiting to resend the message will hear the ROUTER's resend and then not resend the message themselves. If everyone runs as ROUTER then every node would be sending every message, "managed flood routing" goes away, and the mesh will collapse from over utilization.
- A ROUTER_LATE node will first act as a normal Client and work the managed flooding algorithm during the default window. However, if it loses the race and sees another node rebroadcast during the Default window, then it will still resend the message in the Late window. This is intended for the case of a directional antenna that is specifically pointed to link to another far away area. Think of this as "try to be normal but if someone shuts you down, then wait until the other mesh nodes are done, and speak anyway".
Messages
When a node wants to send a message, it waits for a clear time on the radio. See the doc. A node will buffer up to 30 messages waiting for a clear time or while waiting for the send timer on any particular message. At 25% utilization, telemetry and other low value messages will start getting dropped.
When a message is sent, remote nodes in the same mesh may receive it and decide to resend it.
A broadcast message is one sent with no recipient. For example, automated Node Info and telemetry "broadcasts". Any message sent on one of the Channels (see below) is considered a broadcast message because it does not have a recipient. If the sending node hears its message rebroadcast by another node, then the message is marked "acknowledged".
Messages that are not acknowledged will be resent up to two more times. Typically within a few seconds.
A direct message (DM) is one sent with a designated recipient node. Nodes are designated using their hex id. For example, !432e1cd4 When the sending node hears its message rebroadcast by another node, the status becomes "acknowledged by another node". When the message reaches the designated recipient node, that remote node will reply with an ACK message. If that message makes it back to the sending node, then the message status is "acknowledged" and a green lock icon appears on the message (iOS).
Note that a mesh is dynamic. A message might make it to another node and be rebroadcast, yet the originating node does not hear the rebroadcast for some reason, so it sends the message again. If this happens 3 times the status will be "Max Retries Reached", even though the message made it to the mesh. Or the ACK from a recipient might be lost on the way back to the sender. These things can be more common in a mesh that is experiencing congestion. So your local node might think a message was not acknowledged even though the message was received by the mesh and the designated recipient.
The longer the message, the more likely it is to fail. Reason being, these devices have relatively slow data transfer rates. The signal has to be strong enough at the receiving end for the entire message. Shorter messages are less likely to be 'broken' by having bits lost in transmission.
Each message is sent to a "port" with port numbers being:
- 1: "Text"
- 67: "Telemetry"
- 3: "Position"
- 70: "Traceroute"
- 4: "Node Info"
- 71: "Neighbour Info"
- 73: "Map Report"
Encrypted Send Failed
A node sending a DM to a remote node may get the "Encrypted Send Failed" message. This happens when the sending node has a public key that does not match the key of the recipient node. These keys are kept in the NodeDB and advertised by periodic Node Info messages. A node might have a bad key for a remote client that has changed its public key, perhaps through a full reinstall of the firmware. To correct this, the sending node should delete the remote node from its NodeDB and wait for the entry to be added again. Having the remote node send a message on the Primary Channel that the local node sees can facilitate this.
No Channel
Similar to the Encrypted Send Failed error, this can happen when the recipient node has aged out of the device NodeDB after the phone app has already pulled the NodeDB. Thus the phone app has a node in it that is not present in the device NodeDB. Fix this by exiting the phone app and reconnecting to the device.
Note, however, that if the recipient node is no longer in the device NodeDB, then you will not see it in your node list after restarting the app - that node is gone. To prevent this, you should mark nodes as "favorite". Nodes that are marked as Favorite are not aged out of the device NodeDB.
(In a future version of the apps, any node that you DM will automatically be marked as a Favorite.)
Configuration Notes
The default is "Client". In this mode your node will participate in the mesh by retransmitting messages it receives. (This is a simplification, read the Meshtastic web site for more details.) However, this can clog up the mesh. Unless you are building your own network in some remote wilderness, your nodes should always be configured as "Client Mute", or "Client Hidden". NEVER configure as "Repeater" or "Router" until you know your local mesh needs that.
One exception - Suppose you have several devices in your home / building. In this case you could have one node put up high, maybe in the attic or on the roof, set to "Client" while all your other nodes are "Client Mute". This way your mute node messages will get picked up by your roof top node and it will send them on to further nodes.
Channels
The Meshtastic documentation uses the term "Channel" when discussing radio (modem) presets. This is confusing. I discourage the use of Channel when talking about radio presets.
A Channel in Meshtastic is a communication mesh on top of the radio mesh. Each channel has a name and an encryption key. When a node receives a message it will try to decrypt it. The clear text message header has a hint in it (a one byte hash of the channel name) so the receiving node can guess which encryption key in its configuration to try - it does not have to try them all. If a node has the correct decryption key for the message, then it can read the contents.
While nodes in the mesh will rebroadcast channel messages, only nodes that know the channel name and encryption key can read the messages sent on that channel. If a node can read a message is it considered to be on a "local" mesh; other messages are considered on a "foreign" mesh.
Nodes can be set to only rebroadcast messages that are on their "local" mesh.
When a node receives a message that it can decrypt, it adds the originating node to its NodeDB and traffic from or to that node is considered "local". Note that setting a node to rebroadcast only "local" mesh traffic does not clear out the NodeDB. So it is possible that after setting a node to rebroadcast only "local" mesh traffic, it will continue to send messages that it is unable to decrypt. This will continue until the nodes addressed in the messages are aged out of the NodeDB. So, if you want to immediately stop forwarding "foreign" mesh traffic you should set local-only and clear your NodeDB. < Could use some double checking on this point. >
Each node has one Primary Channel, Channel 0. The name of the Primary Channel is used to determine the Frequency Slot that the node radio uses. Only nodes that use the same Frequency Slot can participate in a mesh. The user can also manually set the Frequency Slot, then the name of the Primary Channel is irrelevant. Frequency bands in US.
Channels have other control attributes, such as whether to share exact position with other nodes in that channel.
Default Channel
Each mesh has a default Channel configuration that is the camel cased name of the preset and the encryption key of AQ==. This generates a Frequency Slot. Different presets generate different default Frequency Slots. LongFast / AQ== indicates Slot 20; MediumSlow / AQ== indicates Slot 52. (Note that in the iOS app the default channel name is just left blank and the firmware in the node fills in the channel name.)
If NOT using a preset and the Channel 0 name is blank, then the firmware will use the word “Custom” to determine the frequency slot.
Primary Channel
Typically the Primary Channel uses the default Channel name and key.
Node telemetry data is sent over the Primary Channel - such as periodic Node Info messages. Automatic broadcasts, such as periodic Node Info messages, are always sent over the Primary Channel.
Some owners prefer to change the Primary Channel for their node. They do this by changing the name or encryption key (preferably both). In this way only nodes who have a channel with the same name and encryption key can read messages sent by this node. Thus, telemetry messages like Node Info sent over the Primary Channel are not readable by all other mesh participants. However, when they change the Primary Channel name their node is likely to pick a different Frequency Slot. If an owner wants to participate in their local public mesh, then when changing the name of the Primary Channel, they should purposely set the Frequency Slot for the preset they are using (see Default Channel above).
However, when node X sees a message from node W in a channel they both have configured, it may issue a Node Info request to node W in the same channel and node W might respond with Node Info in that channel. Of course, node X and W must share a Channel for this to happen. A node will not request a Node Info exchange if the node is just resending a message is cannot decrypt.
Questions:
- Is there a configuration to stop these node info responses on the Primary Channel?
- In this configuration, if the node issues a position request to another node does it go out on the Primary Channel? If so, then unless the other node also has the same channel name/key it will not respond, right?
- If a node does not have any channel configured with the default channel, then messages from all the "normal" nodes on the network will be encrypted and its nodedb will never get Node Info messages.
Secondary Channels
A node may have several other channels called Secondary Channels. Each Secondary Channel has a name and encryption key. These channels all use the same radio Frequency Slot determined by the settings of the Primary Channel for the node.
Messages in these Secondary Channels can only be read by other nodes that have a channel with the same name and encryption key. Thus, a Secondary Channel is a way for a group of nodes to communicate with each other in private, while still using the mesh to transport their messages.
Suppose a node changes its Primary Channel to some other name/key. Another node uses the same name/key pair for a Secondary Channel. The two nodes can still communicate as long as they have compatible radio settings.
Question:
- So, when a node receives a message does it try to decrypt the message with all the channel keys in its configuration?
Deleting a Channel
To delete a channel, open the channel config and set the channel to Disabled.
MQTT
Channels have the option for MQTT Uplink and MQTT Downlink. Uplink means you upload the packets you hear to an MQTT server, useful to show up on the internet map, or gather statistics. Downlink means you receive and then broadcast all packets from the MQTT server, this is mostly hot garbage. If you enable Downlink you might just saturate your local mesh - don't do it. In theory it's useful to bridge networks otherwise disconnected via LoRa limitations but in practice that not how it was used most of the time.
900Mhz lora is like < 1~10kbps and MQTT on WiFi could do 54Mbps. That means even extremely slow MQTT connections can saturate a LoRa mesh. Back in the day it wasn't uncommon to have someone enable MQTT downlink, then they would make LoRa unusable for everyone in their neighborhood since they would constantly hog the spectrum with random messages from MQTT.
Unless you know what you are doing, leave MQTT Downlink disabled.
Position Info
Note that position info is specified by the sending node and can be completely fabricated. A node can report itself at any lat/long it wants.
When positional information is automatically shared, it goes out on the Primary Channel (Channel 0). UPDATE 2025 August 7: Recently a firmware update was added so that if position is Disabled on Channel 0, your position will automatically be transmitted on the first secondary channel that has position enabled.
There are several ways to control how much positional information is shared. First, you can configure your node to not share position information, then nothing gets out. Second, if your device does not have its own GPS unit, then it gets the GPS position from your phone when you are connected. On an iPhone you can choose to share "precise location" or not. If you don't share precise location, then iOS takes care of fuzzing your location. Next, Meshtastic nodes have a position fuzzing function as well. You can choose to fuzz your location from 150 feet to 14 miles. Because Meshtastic position fuzzing just truncates lower order digits of the latitude/longitude the nodes using fuzzing will appear to lie on a grid when mapped.
Position sharing can also vary by Channel. You can choose to have the node not fuzz location on a particular channel. Of course, a node without GPS cannot report position any more accurately than what is provided by iOS; the errors build on each other.
The default primary channels (key of “AQ==“) can’t be set to have precise position enabled through the iOS app. This is because precise position is Personally Identifiable Info (PII) and Apple is very picky about that being shared. So the app doesn’t let you enable precise location on default channels to protect your privacy. You can enable precise location for default channels via the CLI.
If you set your node to use Fixed Location then when you save that choice the node gets a position update from your phone and uses that (subject to any fuzzing the phone does on location) but does not apply the Meshtastic fuzzing.
A node can send a position request to another node. If done through a phone app, then the request is sent on Channel 0. If the request is sent through the CLI, then it can be sent on a specific channel. If the receiving node does not have the channel configured, then it cannot decode the message and will not respond. A node might still not respond to a position request based on its settings.
Position Precision documentation
Questions
- Do nodes ever automatically request the position of another node?
- When a node receives a position request, does it always respond, based on configuration, or is there some minimum time between position responses, as there is with Node Info requests?
Node Information
NodeDB
Nodes each maintain a NodeDB. When you connect to a node with an app, the app will read the NodeDB and display information from it.
You can designate nodes as "favorite" and typically the app will put those nodes at the top of the displayed node list.
Nodes are added to the NodeDB when the node receives a NodeInfo message from a remote node.
The node's NodeDB holds 80 entries. They age out FIFO. A node that has been marked as a "favorite" will not age out of the NodeDB.
You can "reset NodeDB" to clear the NodeDB on the node. You might do this if you change meshes (choose a different pre-set) or if you change location and want to focus only on nodes in the new location. Resetting the NodeDB will wipe out favorites as well.
You can only Direct Message (DM) a node that is in your NodeDB. That's the only way your local node knows the public encryption key of the destination node. It is possible that the smart phone app displays nodes that have been aged out of your local node's NodeDB. If you DM a node that is not in the NodeDB on your local node, then the message is sent out on Channel 0.
Node Info
Node Info messages contain the node name, hardware type, location (if allowed), firmware version, etc.
Nodes will send out a Node Info message on Channel 0 based on the interval in Settings / Device / Node Info Broadcast Interval. It is recommended to set that to 3 hours or more in big meshes. On busy networks the node will send even less frequently than the configured interval. On a really small network (like 10 nodes in the NodeDB) a node might send more frequently. In general it can, and should, take hours to discover all nearby nodes. The firmware uses this algorithm
ScaledInterval = Interval * (1.0 + ((NumberOfOnlineNodes - 40) * 0.075))
NodeInfo messages are sent with the configured Message Hop Count Limit.
If a node receives a message on a Channel that it can read (decrypt) and it does not have the sending node in its NodeDB, then it will send a node info request to the sending node. A node will not respond to a Node Info request if it has broadcast a Node Info message within the last 5 minutes.
If you change your device name, other nodes will NOT immediately pick up the change; their own NodeDB will have the old information. Other nodes will update when they receive the next NodeInfo message from your node. If a remote node changes their private/public key (for example by a reinstall of the software without backing up the keys) then when you try to DM that node you will get an error - until your node's NodeDB gets an update from the remote node.
Consider that not every Node Info message will reach every node in the mesh. If you have been moving around with your node then many remote nodes may have old node info data for a long time.
Questions:
- Does the interval scaling only apply to telemetry? Or does it also apply to NodeInfo?
OK To MQTT
This value is set by the node that originates the message. If the message reaches a node that bridges the mesh to MQTT on the internet then only messages marked OK To MQTT should be passed on. In reality this is a request and an MQTT bridge node could ignore that flag if it wanted to.
Some areas (like the SF Bay Area) have some nodes that send traffic to a public logger using MQTT. In this particular case you can monitor the #_logger channel in their Discord server and see traffic there. This is an excellent way to see that your messages are making it into the mesh. It takes just a few seconds for your message to appear in the logger.
Note that if a gateway node (one that sends messages to MQTT) refuses to resend a message due to channel utilization, it also will not send the message to MQTT.
Traceroute
The firmware will not do more than one traceroute every 30 seconds. This is to prevent congestion.
A node in a traceroute might be listed as "unknown" because it is not in the local node's NodeDB. Nodes that receive a Traceroute reply do not add all the nodes in the reply to their own NodeDB; that only happens when they receive a message from a particular node.
A node might be listed as "Repeater" (when it is not configured as a Router) because
- it does not have the channel name and key that were used for the channel that the traceroute was sent on.
- it is running firmware older than 2.5
In this case we only know there was a node involved because it decremented the hop count in the message.
Nodes will show up as FFFF in Traceroutes when they don't have the public channel set up. Or it might be a node configured for REPEATER.
If you see a node name but a ? for SNR, that is pre-2.5 firmware.
An example traceroute
> Route: jschrempp makernexus.org --> jbs1 base San Carlos makernexus.org (8.75dB) --> Herkimer-O (-16.5dB) --> Herkimer-1!433d26b8 (8.5dB) < Route Back: Herkimer-1!433d26b8 —-> Herkimer-O (8.25dB) --> jbs1 base San Carlos makernexus.org(-4.75dB) --> jschrempp makernexus.org (8.25dB)
Traceroute messages are sent with the configured Message Hop Count Limit. This is also true of the response. For example, say the node sending the TR has a hop limit of 6 and it takes 5 hops to reach the destination. If the destination is configured with a hop limit of 3, the reply might not make it back.
If you don't get a traceroute reply, you can still get a lot of information about your situation by looking at the outbound flood on Meshview.
- Go to SF Bay Area Meshview
- Search for your node
- Filter for traceroutes (or just find one in the list of your node's traffic)
- Click on the "graph" link at the bottom of a traceroute message
- To see the position of the links click the little magnifying glass at the top of the TR you are looking at. Only nodes that report their position will be shown on the map. The number in each circle represents the hops away of that node.
Device Config
Questions:
- Under Display / Carousel Interval: in iOS app the value can be "off". What value does the correspond to in the web config app where the selector goes +/- ? Is it 0? -1?
Rainbow Bridge
This is available in the San Francisco Bay Area (Baymesh). It allows your messages to get further reach.
Many nodes in Baymesh network will send messages they receive over the internet to an MQTT topic for Baymesh. Another way to access the bridge is to configure your node's MQTT module to be an "MQTT Client Proxy". In this case messages your node sends will be sent to the MQTT topic via your phone's internet connection. To set this up for the Bay Area mesh:
- In MQTT Config
- Enabled
- MQTT Client Proxy enabled
- Connect to MQTT via Proxy enabled
- root topic: msh/US/bayarea
- address: mqtt.bayme.sh
- username: meshdev
- password: large4cats
- Channel Config
- Set uplink in the Channel(s) you want to send on to MQTT
The Rainbow bridge subscribes to the Baymesh MQTT topic. If it receives a message from MQTT it queues that message and waits 10-15 seconds. If it does not receive the same message over the radio from the mesh, then the Rainbow bridge will send the message over the radio mesh.
The Rainbow bridge runs on a high peak in the Easy Bay named Sunol. Thus, if your message can make it to any of the MQTT bridges in the mesh (and there are many), it will eventually be resent by Sunol and get much wider distribution over the SF Bay Area.
A message might be sent to the MQTT topic by a number of different MQTT bridges. In the message that it resends, the Rainbow bridge will use the hop count of the first copy of the message it received over MQTT.
For your messages to be rebroadcast by the Rainbow Bridge several things must be true:
- Your node must have OK to MQTT enabled - so that your message will be sent by an MQTT bridge to the MQTT topic
- AND you must either
- Opt-in to have all your messages relayed by the Rainbow bridge
- On a message-by-message basis add the rainbow emoji 🌈 to the text of the message
- "Tap back" to a message with a 🌈 or 💩 emoji within 5 minutes of the message being sent and that message will be rebroadcast by the Rainbow bridge (we use the poop emoji because there is no rainbow emoji in iOS).
Node Communication
Depending on your hardware, you can communicate and control the node through a serial cable, Bluetooth, or over WiFi.
Bluetooth
The simplest way to configure and communicate through your node is with the smart phone Meshtastic app. You pair the node with your phone over Bluetooth and then can see data from the node. There are also Mac and Windows apps that work to some degree - I've found them a bit flakey.
While a node can be paired with several devices, it can only be connected to one at a time. If you connect to a node with your phone and then go to the laptop app you won't see the node there. You need to disconnect the phone from the node before you can see it in the laptop app - or with another phone.
If you get the message "you might have to forget this device" on your phone, then you do that, and eventually try to re-pair your node but the node does not display the Blue Tooth key ... Perhaps your node is currently connected to another device? Maybe you ran the Meshtastic client on your laptop and it automatically reconnected to your node and so now it isn't available to your phone? Not that this happened to me and took me 20 minutes of angst to figure out. Nope, not me. Asking for a friend.
Sometimes things have become pretty confused and we had to "forget" the node on our Bluetooth devices to get it all working again.
Serial
If you run the laptop app you can connect a serial cable to the node. This seems pretty stable. However, you MUST use a cable that supports data. A lot of cheap USB cables are power-only and this can be very frustrating. If it isn't working, check the cable.
WiFi
Some nodes support WiFi. Often when you enable WiFi it disables Bluetooth. WiFi REQUIRES an SSID on 2.4GHz that is NOT SHARED with a 5GHz network. For example, many home WiFi networks use the same SSID for 2.4 and 5 bands. The access point then "steers" devices to the correct band. This confuses the node and you'll have intermittent success. Find a way to have an SSID for just the 2.4GHz WiFi band and you'll see things work.
When on WiFi you can use a browser to connect to the node through the Meshtastic client. I've found that works, but is confusing. If you get stuck, refresh the page and start again.
Another excellent choice is MeshSense software. This open source solution connects to nodes and gives you great insight into what's going on. It is not good for having text conversations, that is best done in the phone app.
Via the Mesh
Like one up on a pole. Administer it over the mesh.
Node Control Software
CLI
The command line interface is available in Python CLI
The --configure command does not take all the configs from the exported file, however. This is an issue with restoring configs. Don't count on the restore to bring back your whole config.
You can request Telemetry from another node using the CLI. Telemetry includes items like battery level, temperature, and info about any sensors that are connected.
Apple iPhone App
DMs
DM Help is available if you go to Messages / Direct Messages and tap on the little question mark circled in the lower left of your display. This is a hidden gem!
In a DM, a little green lock means the specific node you messaged has acked you. Your message made it.
Errors on DM
Each node keeps a NodeDB with information on other nodes it has seen. This is displayed as a list and a map in the app. Nodes keep about 80 entries in their NodeDB, aging out older ones that are not marked as favorites. However, the iPhone app can hold information on more than 80 nodes. So, it is possible to see nodes on the map on your iPhone that are no longer in the device's NodeDB. If you try to DM one of these nodes you will get an error.
When you DM a node it is automatically favorited so that the keys don't roll out of the firmware's NodeDB.
A node can only be connected to one device at a time. When you disconnect from a node the info remains in the app for you to see. When you next connect to a "new" node with the app it will forget everything from the previous node and gather the node db from the current node.
In the node list ...
- The green lock icon represents the node having a public/private key. An amber unlock icon indicates one of two situations. 1) They are running a firmware version that predates the public key encryption for DMs. 2) They are running with HAM mode enabled.
the node map
- pulsing nodes are ones that have been seen "recently", whatever that means.
- a halo around a node indicates that the node is not sharing precise GPS location. The node is just "somewhere inside that halo".
- Nodes that do not share position information are not shown on the map.
- tap on a node circle on the map to bring up details about that node
The map displays nodes that have been seen by the connected node in the last 3 days. It is a arbitrary number based on the assumption that if it is not up for 3 days it must be dead.
Clear Stale Nodes
The app can be configured to "Clear Stale Nodes". Enabling this allows you to select a "purge after" days. Nodes are eligible to be automatically purged from the app's DB based on the last time they were heard. So if you select 7 days, it wont be until the node hasn't been heard for 7 days that it can be purged from the app. There are some caveats where a node won't be automatically purged from the app (it's a favorite, it's been "ignored", it is still in the node's DB). The routine to purge stale nodes runs periodically (every 60 minutes). So if you change the setting, it won't act on that setting until the next time the the routine runs.
Misc
Nodes running "older" versions of the firmware will incorrectly show up as "directly connected" in the node list because they cannot handle the hop start info in the messages. They still resend messages.
When you click to View Logs, it can take quite some time for the display to populate.
If you want to suppress notifications for messages on a channel, go to Messsages / Channels then long press on a channel name.
Note that you can not send a Telemetry request from the iOS app. You have to use the CLI.
The Range Test module has a default Sender Interval of 0. In the app this appears as the choice "Unset".
Unexpected Behavior
Not bugs, because this is how the team wants it to work.
- If you experiment with non-preset radio settings, the iOS app does not always communicate the changes in an effective way. One known limitation is that when running a custom setting the iOS app allows you to specify a Bandwidth of 250 kHz but the node receives a value of 0, and the firmware does not interpret that correctly.
- Power Setting - While the documentation says that 0 is recommended, if using an Apple app a 0 transmit power will be "no power". On a low power node you need to set it to 30dBm and the firmware will select the highest transmit power for the hardware. On a powerful node (like the Station G2) you need to select the appropriate transmit power to remain legal - see the section below about the Station G2.
Sept 2025 release
- icon at the top right shows when the app is sending or receiving from the connected node. Useful to know that the app has all the data when connecting to a new node.
- TCP support. If your node is on your IP network then it shows up as a possible client when you are not connected to any other node.
- If your node is on your network but doesn't show up, then it might be that your network does not pass mDNS (bonjour) messages. Try tapping the + icon and entering the IP address manually.
- Visit iOS permissions on devices and allow Meshtastic to connect to networks. iOS should prompt you to do this, but sometimes it does not. (and the option to allow this won't show up until the app actually tries to connect to an IP address)
- The BLE RSSI while connected and Advertising data during discovery are both being updated more often, you can better see your connection quality while connected now, and nodes don't linger in the available nodes if they are no longer in range anymore.
Questions
- iOS: iOS has a location setting called "only when using app". Assume this is set. I then run Meshtastic connected to my node. I then run a different app. I then lock my phone. I drive around with my node in my pocket. Does my node get new position updates from the phone? Does the iOS location setting "Always" change this behavior?
Apple MacOS App
There is an app that functions like the iOS app. Very good for running a node from a Mac.
Browser Based Control
There is a web GUI to a node. It used to be flashable to the node but that functionality was removed. Now you run the web site on a laptop/phone and it will control a local node. Web Client or try the lastest test version.
You can also download the web GUI from GitHub and host it on your own system. It can be installed via a Docker container. If you need to then update that installation:
- Identify the container you want to update and the name of the image it's based on.
- Use the command docker stop <container_name>
- Remove the stopped container using docker rm <container_name>
- Download the latest version of the image using docker pull <image_name>
- Start a new container using the updated image. If you used docker run to create the original container, use the same command with the updated image. If you used docker-compose, you can use docker-compose up -d to recreate the containers.
- Verify that the updated container is running as expected.
- If you no longer need the old image, you can remove it using docker rmi <image_name>
Meshmonitor is a new development to manage several nodes from one UI.
MeshSense App
This app can be used to monitor and control a node. MeshSense is open source (GitHub) and gives great insight into what your node is doing for the network.
It is recommended that you turn off "Automatically send Traceroute requests to active nodes when missing or when hops change" because it can result in a lot of mesh traffic. You find this through the gear icon in the upper right corner, then Settings. Note that if you do not turn this off, then MeshSense will send a LOT of traceroutes since it sends one whenever the hop count to a node changes.
Questions:
- Is there a way to set Favorite for a node?
- Can MeshSense change the configuration of a node or is it just read only?
- Is there a way to view a conversation in a Channel?
- Can we tell if a message has been acknowledged by another node?
- Is there any way to search the node list?
Visualize the Mesh
Your node has a view of the mesh based on the nodes it has heard from. To get a bigger view of the mesh in your area, look for a local group that logs and plots nodes. For example, the Bay Area group has an online map view of the nodes. Note that you can filter this to show nodes on just one of the meshes in the Bay Area: long-fast, medium-slow, medium-fast.
Other options to view MQTT logged data
These are implementations of open source software. If you like what you see, then you could go to GitHub and get what you need to start one in your area.
- Meshview Bay Area BayMe.sh logger
- Meshview Bay Area Development branch
- Meshyview, an alternative to Meshview
- BayMalla, a Malla implementation
- Smerty a different view of the BayMe.sh data
- Sacramento Valley
- Meshview of all of California run by Nathan
Meshview
This is the software used by many to visualize mesh traffic. It is written in Python. This GitHub repo has excellent instructions for installing the software on your own system. The software will monitor MQTT topics and deposit the data in a SQLite database: packets.db. If you want to explore the data yourself, there's nothing like having your own database on your own laptop.
Main Map Page
- Nodes are shown if they have a valid position in the database AND have been seen in the last 3 days.
- The color indicates the radio preset reported in NodeInfo. (MediumSlow, LongFast, etc)
- Routers have a slightly larger marker.
- A node will flash yellow four times when a new packet from that node is logged. (see note below)
- Click on a node and additional data is displayed
- Only data from the last 48 hours is displayed
- Traceroutes: blue dashed lines to any node that was listed next to this node on a traceroute - that is, the clicked node spoke directly to the other node when passing on a traceroute message. This data includes all traceroutes that were logged, not just ones that reached their destination. Note that you might see a solid blue line - ?? what does that mean ?? (Deduplicating the edge list did not eliminate edges)
- NeighborInfo: red solid lines, slightly thicker than a traceroute line, to each reported neighbor node. The clicked node does not have to have NeighborInfo enabled; it could have been reported as the neighbor of another node that does have NeighborInfo enabled.
NOTE: If you leave the map open updates happen about every 17 minutes. The map will stop updating if you switch to another tab in your browser or another application. When you return to the page it will update then. However, nodes logged for the first time are NOT added to the map unless you refresh the page.
Logging Mesh Traffic with MQTT
In the Baymesh Discord is a channel #-logger-ms. If a message makes it to one of the MQTT bridge nodes, and the message has "ok to MQTT" set, then it will get added to a local logging database and appear in the #-logger-ms channel in just a few seconds.
In the logger channel, all of the links take you to a page within the mesh view website. You can browser around there and find all kinds of stats and things. For instance, go to your node page, find your trace route, study the graphs. To have something to study, you should run five traces to a node that is many hops away.
A node in the logger might show as a gateway. That means it has MQTT Uplink enabled and pointed to Baymesh topic:
topic: msh/US/bayarea server: mqtt.bayme.sh
It can take 10 minutes for your message to appear in the Baymesh Discord logging channel.
The Baymesh Discord allows users to "claim" their nodes. When claimed, the Discord user name will appear with the node messages in the logging channels. To claim a node go to any channel and type /Linknode
You can create your own database of mesh traffic if you know the MQTT server and topic that your local area uses. Meshview gives more tips about this.
Hardware
A good soul maintains a list of Meshtastic parts on Amazon.
Antenna Notes
Are there downsides of having a 6 foot cable to my antenna? It really depends what kind of cable. Basic nodes transmit at 150mw which is often reduced to effectively 80mw after a 2 db loss from cables and connectors. At the low end every decibel is precious. It's often better to keep the cable to the antenna short, minimize connector count, and place the node with the antenna.
With a powerful node (Station G2 or the 1 watt Pi hats for example) then compensate with an extra dB on transmit.
Some web sites provide a line-of-sight analysis between any two points.
- Gives a good line between two sites
- Lets you view obstructions from one place
Outdoor Nodes
Solar powered nodes in strategic placements can really improve and extend the mesh. Many people have built solar powered nodes to put up in trees or on mountain tops.
Some people have used the Harbor Breeze Solar Light to power a node. It's definitely the cheapest way to get into a solar node. You can make better ones but in CA where is is sunny all the time it's just fine. If you were in Washington it might not be sunny enough for this solution. Harbor Breeze how to
Here is a nice solar build step by step and the parts list.
This is an Instructable for a waterproof solar node.
This is a pre built outdoor node 150mw from Seeed Studio
And a nice, tight package from Rak.
Or cheapest node we've seen.
A node with a larger solar panel.
Heltec V3
We have personally used the Heltec V3. It is small and simple to use. It transmits at 125mw. It offers both BLE and WiFi.
The Heltec V3 has a standby power draw of 110mA at 5v. Transmit is 262mA at 5v.
It comes with a small whip antenna. When we upgraded with this inexpensive antenna our connectivity went way up. Another tip is to use a directional antenna to get your node onto the local mesh. If you know where other stable nodes are, then you can point your antenna in their direction. Directional antennas are easier to find and cheaper than buying a more powerful radio. For a stationary node you can tape a 10" x 10" sheet of aluminum foil to a piece of cardboard and place it about 3.1 inches behind your antenna to increase the directionality of the antenna. We had a 3dBm antenna and the aluminum element dramatically helped.
If your device does not have a battery, it has been reported that using USB-C cable for power can cause messages to fail to send. If you add a USB-C to USB-A adapter then delivery success goes up. Having the battery makes this a non-issue.
The "program" button will cycle the little display through the last 8 message screens.
A better antenna can be added. Basically all radios use a IPEX connector on the board, and then an antenna pigtail that changes the IPEX connector to a SMA Female. Then the actual antenna has a SMA Male connect.
Changing network connection: Suppose you have changed from Blue Tooth to WiFi and want to change back. You must first disable Wifi and reboot. THEN enable BTooth. The interface will let you turn on BT while WiFi is enabled, but that does not work.
Questions
- The display shows an arrow and a dot for the displayed node location. What does the config value "always point north" mean?
B&Q Station G2
The Station G2 is a big gun for a stationary node. It will transmit 1 watt of RF power (4 watts if you run in the "ham licensed" mode) which assures that someone will hear you. It costs $110, way more than other little nodes. You also need a beefy power brick to run it; 15 vdc at 20 watts.
The Station G2 has a resting power of 43mA at 15v. Transmit is 660mA at 15v.
The setting for LoRa Transmit Power defaults to 30dBm. That is the output of the LoRa chip. The G2 has an RF power amplifier and that pushes the actual transmit power to 4 watts. You should set the Transmit Power to 10dBm or less in the US.
19dBm == 4.4 watt 10dBm == 1 watt 6dBm == 0.4 watt (still about 2.5 times more than the Heltec V3 and other smaller nodes)
The G2 has three LEDs on the side: Red, Green, Blue. All three should be on. If not, then your power supply is not strong enough for the G2 and you are not getting the full transmit power that you want.
According to some, the G2 has notoriously bad Wi-Fi reception.
When flashing firmware to a G2 we got "
error on web firmware flash to Station G2 esptool.js Serial port WebSerial VendorID 0x303a ProductID 0x1001 Connecting... NetworkError: Failed to execute 'open' on 'SerialPort': Failed to open serial port.
We had to use the CLI to flash the firmware. It wasn't hard to do. However, note that the test of esptool.py chip_id did not work but the firmware flash still did.
boot loop
It has been reported ... on a fresh install the firmware sets the TX power at 30 which is way too high for the built-in amplifier. If you're in a boot loop, try powering it from a regular USB 5v only charger, this disables the amplifier but keeps everything else running. You can then set the TX power to 10 and it should hopefully stop the boot loop.
RAK Wisblock
RAK Wisblock Core documentation says it draws 24.6mA at 3.6v for transmit. Standby draws 3.8mA. It offers BLE but not WiFi.
We deployed a RAKwireless Mini Meshtastic Starter Kit inside a Harbor Breeze solar light as described elsewhere. It did last overnight with just one day's charge of the battery.
In our experience this node has better quality transmit and receive than the Heltec V3. It is more expensive and has no display.
Other Mesh Solutions
Another solution is Meshcore. It is more structured and requires planning while Meshtastic is meant to be self organizing. Comparison of Meshcore vs Meshtastic
A Typical Meshtastic Journey?
I've seen this played out several times; it is my story as well. If you're new to Meshtastic, this is what might happen to you.
- Buy a Heltec V3 because it is inexpensive and a good place to start.
- Wonder why your node sees nothing.
- Find a local Meshtastic group and realize that they are all using a different Preset. Change yours to theirs.
- See a lot of nodes, yea!
- Wonder why your messages are never acknowledged.
- Buy another Heltec V3 (or maybe 2 more since they are inexpensive).
- Discover that your nodes can talk to each other easily. Hmmm.
- Decide that funky little antenna on the Heltec might be the problem. But one or two different antennas.
- Also buy a case for the Heltec, it will keep it safe.
- Better antennas don't seem to help much.
- Put one of your nodes with what you think is the best antenna in a second story window pointing towards a big node you see in the node map. Now every once in a while a message will be acknowledged. Yea!
- Realize that moving your antenna just one foot to the side might improve message receipt. What?
- Buy a Station G2. It's expensive and not portable, but it will put out 1W of power; 8 times more than the Heltec.
- No difference. Huh?!?
- Realize that all three lights on the Station G2 are not lit up. Figure out what that means. Oh.
- Spend time figuring out what kind of power supply that Station G2 needs. Try a bunch at home, find that none work.
- Spend $15 on a beefy Anker power supply that will put out 15v. (link, you're welcome)
- Bingo! Every message is acknowledged!!
- Realize that setting 30dB transmit power in the phone app translates to 3 watts of RF power in the G2. Ooops. Change it down to 10dB in the app, which gives you 1 watt of RF power in the G2. Now every message is still acknowledged.
- Well, almost every message.
- The story continues ... But now it's like you are really part of the mesh.
