简体中文 / [English]


Running Your Own Carrier Part.Ex - Building a Meshtastic LoRa Mesh Network at School

 

This article is currently an experimental machine translation and may contain errors. If anything is unclear, please refer to the original Chinese version. I am continuously working to improve the translation.

0x00 Background (Irrelevant Rambling)

Earlier, my HomeLab backup caused such a huge upload volume that the ISP flagged me as a PCDN user and throttled my connection. On top of that, TR069-based networking was blocked by Suzhou Mobile. I once considered establishing a P2P communication link between two locations roughly 2–3km apart, completely independent of any carrier.

To achieve carrier-free communication, I’d need to build my own physical channel. Wired solutions—like burying fiber optic cables under city streets—seem like an expensive and complicated project. I couldn’t find any examples of individuals doing this in urban areas: no idea who to hire, how to get municipal approval, or how to maintain it afterward…

So I turned to wireless networking. Under civilian license-free bands and power limits, achieving 2–3km range often results in speeds below 10Kbps—so slow it’s practically useless for my use case. (Eventually solved by filing an online complaint against the ISP about the throttling)


But now that I’m back on campus, and with some free time on my hands, I figured: why not finally try out Meshtastic, the project I had found earlier?

(Also, this experiment was co-run with Bob, who will probably publish his own blog post about it soon.)

0x01 Introduction to Meshtastic

According to its official website, Meshtastic is an open-source, off-grid (no carrier required), decentralized mesh network running on low-power devices.

More specifically, network organizers buy small microcontroller boards equipped with wireless modules and deploy them as “nodes” across various locations. Users connect their smartphones via Bluetooth or Wi-Fi to the nearest node to send messages. These messages are broadcast by the node and then routed and forwarded by every other node that receives them, hopping through the network until they reach all reachable destinations. The recipient, connected to their nearest node via the app, sees the sender’s message. In this way, all participating nodes and users form a distributed mesh network.

0x02 Getting Started~

Meshtastic officially supports a range of off-the-shelf hardware, priced between 100–300 RMB. These devices typically include a dev board, a wireless module, and sometimes optional extras like a small screen, GPS module, or plastic enclosure.

But being an open-source DIY project, I naturally wanted to build my own setup. Looking at the list of supported hardware: the MCUs are mainly from the ESP, Raspberry Pi, and nRF52 families, and the radio modules are mostly Semtech’s SX126x/SX127x series LoRa modules. As for screens—they’re completely unnecessary. So I decided to go the DIY route with these components.

I dug out an old ESP32 dev board and a Raspberry Pi Zero from my parts bin, then ordered two SX1278 modules from Taobao: one with pre-soldered headers (20 RMB), and one in postage-stamp form (10 RMB), which needed either flying wires or a 2.0mm-to-2.54mm adapter board.

Pi Zero + plug-and-play SX1278 (that terrible antenna in the photo foreshadows the poor signal ahead)Pi Zero + plug-and-play SX1278 (that terrible antenna in the photo foreshadows the poor signal ahead)

ESP32 + postage-stamp SX1278 soldered by handESP32 + postage-stamp SX1278 soldered by hand

After wiring everything up, the ESP32 node could be flashed directly using the Web Flasher with a precompiled firmware matching the TLoRa V2 configuration. The Pi runs meshtasticd using a prebuilt binary. For pin connections, refer to the corresponding definitions in the firmware repo.


Once both devices were running, I installed the Meshtastic app on my phone and connected via Bluetooth or USB to the ESP32. After setting the frequency band (470–510 MHz for China), I was able to send my first message.

First successful "contact" on 2025/2/24, devices less than 1 meter apartFirst successful "contact" on 2025/2/24, devices less than 1 meter apart

0x03 Signal Testing & Optimization

Hardware Version 1 (Range: 30 meters, plug-and-play version ~40 RMB)

Hardware used: ESP32 + SX1278 + spring antenna

The initial setup worked, but for a wireless mesh network, transmission range is obviously critical.

This setup—using SX1278 modules with spring antennas—performed terribly. At its worst, the signal dropped just walking from one floor to another in my dorm, losing connection in under 30 meters. This setup couldn’t even beat Wi-Fi! Clearly, signal optimization was needed.

Neither I nor my classmates had any background in radio engineering or antenna theory—we were completely clueless. But that tiny spring antenna looked suspiciously weak. With the naive belief that “throwing money at the problem makes it better,” I decided to upgrade the entire hardware and antenna setup.

(p.s. It’s not that SX1278 is inherently bad—the main issue was the antenna.)

Hardware Version 2 (Range: >400 meters, ~22 RMB)

Hardware used: nRF52840 + SX1268 (on small PCB) + adapter cable with rubber ducky antenna

Following Meshtastic’s official wiki and hardware recommendations, we upgraded to SX1268, the newer version of SX1278. The spring antenna was clearly out, so we bought several different antennas for testing.

Choosing the SX1268 module turned out to be tricky: although the SX1268 chip is the same, the module form factors and interfaces vary wildly. Many UART-based modules don’t work with Meshtastic, and SPI modules usually come in postage-stamp form, requiring soldering.

Since soldering was unavoidable anyway, package type didn’t matter. We went with the cheapest option we could find: E22-400MM22S modules (thanks to a first-order discount from Taobao’s Ebyte, 12 RMB for two—just 6 RMB each). We also got an nRF52840 board (~13 RMB) and a few cheap antennas to test.


The module’s pin pitch was 1.27 mm—attempting Iraqi-style soldering failed repeatedly. Eventually, I designed a small PCB on JLCPCB (free), converting the 1.27 mm pads to 2.54 mm headers.

Prototype of v2 hardware—the small board with SX1268 is custom-madePrototype of v2 hardware—the small board with SX1268 is custom-made

I forgot to include an antenna connector when designing the board, so I had to improvise a mysterious SMA-to-Dupont adapter cable to connect the antenna to the SX1268.

Finally, the combo of nRF52840 + SX1268 + a random 3 RMB rubber ducky antenna performed noticeably better. With one node on the 5th floor of the CS building (Fei Yimin Building), the handheld unit could reach over 350 meters away.

Node placed in CS building server roomNode placed in CS building server room

Tested distance from CS building to the far side of the field. Signal degraded beyond that due to building obstructions—better performance in open areas.Tested distance from CS building to the far side of the field. Signal degraded beyond that due to building obstructions—better performance in open areas.

The phone app shows SNR (Signal-to-Noise Ratio) and RSSI (Received Signal Strength Indicator), as shown below. We found that the SX1268 needed SNR > -15 dB and RSSI > -110 dBm to receive messages reliably.

Signal measurement logs visible on the phoneSignal measurement logs visible on the phone

VNA

While v2 was usable, it still fell short of the advertised 2–3km range. To better test different antennas, I bought a VNA.

Connecting a calibrated VNA to an antenna reveals some useful parametersConnecting a calibrated VNA to an antenna reveals some useful parameters

The abstract-looking soda can in the photo was an attempt to create a “ground plane” for antenna optimization, but it didn’t help much and was later abandoned. Since I’m not experienced with VNA usage, I’ll quote the table from that guide:

ParameterWithout Ground PlaneWith Ground PlaneExplanation
SWR22.574 @ 486.4 MHz1.467 @ 486.4 MHzSWR close to 1 means good match; >3 indicates high loss
Impedance15.24 + j120.40Ω50.86 + j19.43ΩMeasured complex impedance; ideal is ~50 + j0Ω. Large deviation reduces efficiency
Impedance MatchSeverely off 50ΩClose to 50ΩBest signal transfer when close to 50Ω
Smith ChartPoint far from centerPoint near centerGood match = point near center of Smith chart

VNA tests showed that the 3 RMB short rubber ducky antenna had an SWR of 1.15 at ~470 MHz and impedance of 53.37-j6.32Ω—pretty solid parameters for the price. However, the DIY adapter cable degraded performance significantly. Here are all the antennas we bought:

DIY adapter that ruins antenna performanceDIY adapter that ruins antenna performance

Antenna lineupAntenna lineup

From left to right: 20 RMB / 3 RMB / free (bundled with module) / 3 RMB. The first and fourth antennas performed well on VNA, while the second and third were poor.

Hardware Version 3 (Range: >700 meters, ~22 RMB)

Hardware used: nRF52840 + SX1268 + adapter board + rubber ducky antenna + (optional) GPS module

Due to the missing antenna port in v2 and signal loss from the adapter, I redesigned the board for v3—integrating SX1268, nRF52840, SMA antenna connector, and the GPS module (Bob’s idea) onto a single PCB.

Blank board, soldered board, and final assembled unitBlank board, soldered board, and final assembled unit

With the proper SMA connector, signal quality improved dramatically. Plus, no more messy Dupont cables—much more portable.

Pinout matches NRF52 Pro-micro DIY, so it can run official precompiled firmware directly. PCB files available here. Designing it wasn’t hard: open LCSC EDA in browser, find components in the library, connect the pins, auto-route—done. (whispers: and it ships free to your door—so convenient)

Out for another field test: now I could reach all the way from my dorm to near Zifeng Tower, over 700 meters, even with some building obstructions. A huge improvement.

Our self-made carrier now “covers” Zifeng Tower (x)Our self-made carrier now “covers” Zifeng Tower (x)

Lots of buildings in the way—this range is impressiveLots of buildings in the way—this range is impressive

0x04 Real-World Relay Testing

With decent nodes finally ready, it was time to build a real mesh—not just two nodes (that’d just be P2P).

We used two v3 nodes and one modified v1 node (with upgraded rubber ducky antenna) to set up a network across campus and test packet relaying. Meshtastic assigns default node names based on hardware addresses: v1 node is 169c, v3 nodes are eaba and 0636.


We kept the 169c node fixed on the 5th-floor north window of Nan Yuan Dorm 2. We carried eaba and 0636 toward the north campus.

Due to heavy building obstruction, eaba and 0636 struggled to reach 169c near the teaching buildings. We left the 0636 node in a 4th-floor classroom as a relay and continued with eaba, testing at various points.

Approximate node positions and heightsApproximate node positions and heights

In the Meshtastic app, you can send direct messages and see delivery confirmations. But there’s also a traceroute feature showing the actual message path and SNR at each hop.

At the first eaba position, traceroute revealed an asymmetric route: the outbound message reached 169c directly, but the reply came back via 0636. Classic dynamic mesh behavior.

eaba<->169c pulling off an asymmetric route right off the bateaba<->169c pulling off an asymmetric route right off the bat

Moving further, at the second eaba position, both outbound and return messages went through 0636.

eaba<->169c, now with both directions relayed via 0636—the “classic” relay scenarioeaba<->169c, now with both directions relayed via 0636—the “classic” relay scenario


Later, we placed eaba on the 3rd-floor south window of the CS building. Due to the elevated position, it unexpectedly established a strong direct link with 169c, bypassing building obstacles. Now, carrying 0636 around, eaba acted as the relay.

Node layout—eaba now functions as a mini signal tower on the 3rd floor, covering new areas with fewer obstructionsNode layout—eaba now functions as a mini signal tower on the 3rd floor, covering new areas with fewer obstructions

eaba node hanging outside the CS building windoweaba node hanging outside the CS building window

At this point, eaba and 169c together covered most of Nanjing University’s campus and could communicate with each other. Any third (or more) node deployed anywhere on campus could join the same mesh network and communicate with the rest.

0636<->169c at the edge of the field—0636 reaches 169c via eaba, despite no direct link0636<->169c at the edge of the field—0636 reaches 169c via eaba, despite no direct link

0x05 Summary

Sure, we’ve “covered” the campus with our DIY carrier, but since smartphones can’t directly transmit/receive LoRa signals, it’s not like a real cellular carrier where phones connect directly. To achieve true coverage, we’d need many more nodes so every phone could reach one via Bluetooth. That’s beyond the scope of this post.

I originally planned to 3D-print enclosures and add solar charging, but lithium batteries are risky, and I couldn’t find safe, permanent deployment spots—so I dropped those ideas.

Mesh networking turned out to be harder than expected. 470–510 MHz signals diffract worse than I thought—achieving decent range requires significant optimization and ideally open spaces or high vantage points. Even with this limited coverage, Meshtastic’s speed doesn’t exceed 1 kB/s, barely enough for simple text messages.

This project is finally wrapped up. Took me from February to late May—over three months of trial, error, and waiting for packages. Waiting days for each delivery was the most painful part. I tried adapting ESP32C3, driving OLED screens (both failed), destroyed a module’s solder pads, and fell into countless obscure pitfalls. The most memorable? Old Dupont cables from six years ago—80% of them were broken inside. Never expected wires to just… die on me.

Too lazy to design a PCB, tried some abstract soldering—ended up peeling the module’s pad right off. -6 RMBToo lazy to design a PCB, tried some abstract soldering—ended up peeling the module’s pad right off. -6 RMB

Work-in-progress drawer. Most of the time my desk is way messier, with wires and modules scattered everywhere.Work-in-progress drawer. Most of the time my desk is way messier, with wires and modules scattered everywhere.


Still, I managed to finish all the experiments before leaving school. See you in the next blog post o/

This article is licensed under the CC BY-NC-SA 4.0 license.

Author: lyc8503, Article link: https://blog.lyc8503.net/en/post/meshtastic-networking/
If this article was helpful or interesting to you, consider buy me a coffee¬_¬
Feel free to comment in English below o/