Three LoRa modules show up again and again in maker projects: the Ebyte E220-900T30D, the Reyax RYLR998, and the Reyax RYLR993 Lite. They look similar — small PCBs, UART interface, sub-GHz operation — but underneath they are quite different. The differences sit at the chip level, the firmware level, and the antenna interface, and these differences determine whether your project gets 200 m or 5 km, whether it works with The Things Network or only point-to-point, and whether it will survive a configuration mistake.
This post goes through what is actually inside each module, how to pick between them, the antenna and connector subtleties that catch new builders, and how to wire any of them to an ESP32-C6 — a strong host MCU choice because its 2.4 GHz WiFi 6 and Thread radios do not interfere with sub-GHz LoRa traffic.
1. The Chip Inside the Module
Every LoRa module is a reference design built around a Semtech transceiver IC. The module vendor adds a microcontroller for AT-command parsing, a UART interface, flash for firmware, and optionally external power amplification or specialized receive chains. Almost every meaningful spec — sensitivity, max TX power, supported spreading factors, current draw — is set by the choice of Semtech chip.
Ebyte E220-900T30D — Semtech LLCC68 + external PA
The LLCC68 is Semtech's "LoRa Smart Home" variant of the SX1262. It is pin-compatible with SX1262 and supports SF5 through SF12 at 125 kHz and 250 kHz bandwidths — SF11 and SF12 are unavailable only at 500 kHz bandwidth. At 125 kHz, sensitivity rivals the SX1276 (~−137 dBm at SF12). On-chip max TX is +22 dBm, but Ebyte adds an external PA to reach +30 dBm (1 W). The module achieves excellent RX sensitivity from the Semtech silicon's internal LNA design. The default centre frequency is 873.125 MHz — outside several regional bands, including India — so reconfiguration before first transmit is mandatory in most countries.
Reyax RYLR998 — Nuvoton MCU + Semtech SX1276
The SX1276 is the classic LoRa chip — the one that made the technology popular. It supports SF6 through SF12 and bandwidths from 7.8 kHz to 500 kHz. Max on-chip TX is +20 dBm (100 mW); the RYLR998 has no external PA, so this is also the module's max output. The Nuvoton MCU on the module handles the AT-command parser, so the host MCU never touches SPI or registers — it just speaks UART text commands at 115200 baud. The RYLR998 has a built-in PCB-trace antenna option but also exposes an IPEX/U.FL connector for an external antenna.
Reyax RYLR993 Lite — Semtech SX1262 with onboard LoRaWAN stack
The SX1262 is the newer cousin of the SX1276 — about half the receive current draw (~4.6 mA versus ~10 mA), the same +22 dBm max TX, and slightly better sensitivity. The "Lite" variant is an evaluation breakout. The differentiator versus the RYLR998 is firmware: the RYLR993 ships with a full LoRaWAN 1.0.3 stack built in, so joining a LoRaWAN network is just AT commands — no application-layer firmware needed. Max TX is +15.5 dBm, lower than the RYLR998, because it is tuned for LoRaWAN compliance rather than maximum P2P range.
Side-by-side comparison
| Ebyte E220-900T30D | Reyax RYLR998 | Reyax RYLR993 Lite |
| Semtech chip | LLCC68 | SX1276 | SX1262 |
| Max TX power | +30 dBm (1 W) | +20 dBm (100 mW) | +15.5 dBm (~35 mW) |
| Spreading factors | SF5–SF12 (at 125/250 kHz) | SF6–SF12 | SF7–SF12 |
| External PA | Yes | No | No |
| RX sensitivity (SF12, 125 kHz) | −137 dBm | −137 dBm | −137 dBm |
| RX current draw | ~5–7 mA | ~11–12 mA | ~4.6 mA |
| Host interface | UART + M0/M1/AUX pins | UART (AT) | UART (AT) |
| LoRaWAN stack onboard | No | No | Yes (1.0.3) |
| Antenna connector | SMA-K (female) | IPEX + on-board PCB | IPEX + on-board PCB |
| Power supply | 3.3 V logic (5V VCC damages UART pins without shifter) | 3.3 V | 3.3 V |
| Power peaks during +max TX | >500 mA | ~120 mA | ~50 mA |
| Default centre frequency | 873.125 MHz | 915 MHz (US/Asia variant) | Region-locked at order time |
For maximum raw range from a single hop, the Ebyte E220-900T30D wins by a wide margin. +30 versus +20 versus +15.5 dBm is a 10 dB and 14.5 dB advantage respectively — roughly 3× and 5× the free-space range. The trade-off is higher current draw, higher power supply demands, no LoRaWAN stack, and the need to reconfigure the centre frequency before first transmit.
2. Antenna Types — More Choice Than You Think
The antenna is at least as important as the module. A high-gain antenna on a +20 dBm module will outperform a stubby antenna on a +30 dBm module in almost every test. Here is what the categories actually mean:
- PCB antennas — copper traces etched on the module itself. Cheap, compact, and surprisingly weak: gain is typically −2 to +1 dBi (often negative). The Reyax RYLR998 has one as the serpentine pattern at the edge of its dove-shaped board. Good for 50 m to 200 m at SF10+.
- Chip antennas — tiny SMT ceramic components. Slightly better than PCB antennas, similar form factor. Common in space-constrained wearables.
- Helical / spring antennas — small coiled wires, common on cheap 433 MHz modules. Quarter-wave antennas wound into a coil to save space, ~2.15 dBi, but they need a ground plane to work — which is why they often disappoint on small breakout boards.
- Whip / rubber duck — the classic stubby SMA antennas. Half-wave dipoles inside a rubber sheath, 2 to 3 dBi. No ground plane needed. Best general-purpose choice.
- Fiberglass omnidirectional — long outdoor collinear antennas, 5 to 8 dBi, weatherproof, mast-mountable. The typical match for a +30 dBm module in an outdoor deployment.
- Yagi directional — 10 to 16 dBi in a narrow beam, often around 30°. Massive range gain in one direction; useless outside the beam.
Connectors are a separate trap
- SMA — standard 50 Ω screw-thread connector. Male pin in the centre, female socket. The Ebyte E220-900T30D uses SMA-K (female socket on the module).
- RP-SMA — "reverse polarity" SMA with the pin and socket swapped. Not compatible with SMA, even though the threads look identical. RP-SMA on a 50 Ω SMA module will not screw together properly, and even with an adapter you lose ~0.3 dB per junction.
- IPEX / U.FL / MHF — tiny snap-on coaxial connectors used on small modules like the Reyax RYLR998 and RYLR993. Rated for only ~30 mating cycles, so they wear out fast. Use a U.FL-to-SMA pigtail to convert to a more durable connector for repeated antenna swaps.
3. ESP32-C6 as the Host MCU
The ESP32-C6 is a strong host choice for LoRa. Native 2.4 GHz WiFi 6 and Thread/Zigbee radios do not interfere with sub-GHz LoRa, so a clean dual-band IoT node fits in one chip. The RISC-V core has plenty of GPIOs and two UARTs — exactly what these modules need.
Wiring the Ebyte E220-900T30D
The E220 exposes these key pins:
- M0, M1 — mode pins.
00 = transparent transmission, 01 = WOR (wake-on-radio), 10 = configuration mode, 11 = deep sleep.
- TXD, RXD — UART, configurable baud rate, 9600 default.
- AUX — status pin. Goes low during TX and during wake-up. Always read AUX before sending the next packet, or you will drop data.
- VCC, GND — 3.3 V supply recommended. The PA pulls peaks above 500 mA during +30 dBm transmit.
Wire M0 and M1 to two ESP32-C6 GPIOs to flip between run and config modes in software. Wire AUX to a GPIO with an interrupt for accurate TX timing.
Power supply and voltage levels are critical. The +30 dBm Ebyte module draws current peaks well above what most ESP32 dev boards can deliver from their onboard 3.3 V regulator. Symptoms of an undersized supply: brownout resets on the ESP32 during transmission, corrupted packets, reduced effective TX power. Use a dedicated 3.3 V regulator (LM1117-3.3 or a small buck converter) sized for at least 700 mA for the radio, ideally separate from the ESP32's supply. Additionally, the E220's UART logic pins are 3.3 V only — connecting a 5V Arduino TX pin or unregulated supply directly will damage the module. Use a level shifter if your host supply is above 3.5V. Also: connect the antenna before powering up — running the PA into an open or shorted port can damage the module.
Configuring the E220 centre frequency
Pull M0 high and M1 high to enter configuration mode. The E220 uses fixed 9600 baud (8N1) in configuration mode regardless of the runtime baud rate. The centre frequency is set by channel number, where the base frequency and step are firmware-specific and must be verified in your module's revision manual. For many common variants:
- Channel 15 → 865.125 MHz (inside Indian SRD band) — typical E220-900T variants
- Channel 18 → 868.125 MHz (just outside Indian band, inside EU band)
- Channel 65 → 915.125 MHz (inside US/AU band)
⚠️ Critical: Base frequency and channel step vary across E220-900T, E220-400T, and regional variants. Do not assume channel mappings without verifying against your specific module's datasheet revision. The simplest and safest approach is to use Ebyte's free Windows configuration tool to verify the channel and confirm the resulting frequency, then record the exact byte sequence before porting into firmware.
A typical configuration command for IN865 channel 15, address 0x0001, might look like:
// Header ADDH ADDL REG0 REG1 REG2 (channel)
0xC0 0x00 0x06 0x00 0x01 0x65 0x00 0x40 0x0F
Always verify against the official Ebyte E220 user manual for your firmware revision — register layouts can change. The safest workflow is: (1) use Ebyte's config tool on Windows to set your region, (2) read back the byte sequence, (3) hard-code that sequence into your firmware once, and (4) verify transmission on a spectrum analyser or with a known gateway.
Wiring the Reyax modules
Both the RYLR998 and the RYLR993 Lite expose only UART, VCC (3.3 V), and GND. No mode pins. Everything is an AT command at 115200 baud.
A minimal P2P configuration for the RYLR998:
AT+BAND=865500000 // centre frequency 865.5 MHz
AT+NETWORKID=5 // group ID — both nodes must match
AT+ADDRESS=1 // my address
AT+PARAMETER=9,7,1,12 // SF=9, BW=125 kHz, CR=4/5, preamble=12
AT+SEND=2,11,Hello World // send 11 bytes to address 2
The AT+PARAMETER command is the key one. The four numbers are SF, bandwidth code, coding rate code, and preamble length.
Bandwidth codes on RYLR998 are firmware-specific. In most Reyax firmware revisions for the SX1276, bandwidth code 7 = 125 kHz. Using 0 will typically select 7.8 kHz (the minimum SX1276 bandwidth) or return a firmware error. Always consult your module's current AT command reference — Reyax has released multiple firmware versions with different encodings. Coding rate codes: 1 = 4/5, 2 = 4/6, 3 = 4/7, 4 = 4/8.
The RYLR993 Lite uses the same AT command syntax for P2P. Switching to LoRaWAN mode is a separate command (numbering varies by firmware revision — current Reyax documentation is the source of truth). Once in LoRaWAN mode, standard provisioning commands apply: AT+DEUI, AT+APPEUI, AT+APPKEY, AT+JOIN.
4. Computing Time-on-Air Before You Transmit
Time-on-air (ToA) is the duration of one LoRa packet on the air. It matters for three reasons: duty-cycle compliance, collision probability, and battery life. Most regulators (including India and the EU) cap duty cycle at 1% — meaning if a packet is on the air for 1 second, the radio must stay silent for 99 seconds afterwards.
The Semtech reference formula for symbol time and packet airtime:
T_sym = 2^SF / BW
n_payload = 8 + max( ⌈(8·PL − 4·SF + 28 + 16·CRC − 20·H) / (4·(SF − 2·DE))⌉ × (CR + 4), 0 )
T_packet = (n_preamble + 4.25 + n_payload) × T_sym
Where PL is payload length in bytes, CR is the coding rate code (1–4), CRC is 1 if CRC enabled, H is 0 if explicit header, DE is 1 for low-data-rate optimisation.
Low Data Rate (LDR) optimisation — a critical detail
LDR optimisation must be enabled whenever the LoRa symbol duration exceeds 16.38 ms. This occurs at 125 kHz bandwidth for SF11 and SF12. If two nodes do not agree on the LDR setting, they will not decode each other's packets, even if all other parameters match perfectly. This is a common and frustrating "why can't the nodes hear each other?" trap.
A worked example
11-byte payload, SF10, BW 125 kHz, CR 4/5, 8-symbol preamble, explicit header, CRC enabled, no LDR optimisation:
- Tsym = 2^10 / 125000 = 8.192 ms
- n_payload = 8 + max(⌈(88 − 40 + 28 + 16 − 0) / 32⌉ × 5, 0) = 8 + ⌈92/32⌉ × 5 = 8 + 3 × 5 = 23
- T_packet = (8 + 4.25 + 23) × 8.192 ms = 35.25 × 8.192 ms ≈ 289 ms
With a 1% duty cycle limit, that single packet means the radio must sit idle for ~28.9 seconds before transmitting again on the same channel. Worth knowing before you write a "send every 10 seconds" loop.
Most engineers do not memorise this formula — they use Semtech's free LoRa Calculator spreadsheet. The point is that ToA scales fast with SF: a 5-byte payload at SF12 / BW 125 kHz is over a second, while the same payload at SF7 is under 50 ms. Choose SF deliberately, not by default.
5. Spreading Factor and Coding Rate — The Levers You Actually Tune
Spreading factor — range vs throughput
Each step up in SF gains roughly 2.5 dB of link budget (more processing gain) but doubles the symbol time and halves the bit rate.
| SF | Sensitivity (BW 125 kHz) | Bit rate | Use case |
| 7 | −123 dBm | ~5.5 kbps | Short range, low latency, urban |
| 9 | −129 dBm | ~1.76 kbps | Balanced default for many deployments |
| 10 | −132 dBm | ~980 bps | Range priority, modest throughput |
| 12 | −137 dBm | ~250 bps | Maximum range, very low duty |
SF7 to SF12 gains 14 dB of sensitivity — roughly 25× the free-space range, or ~5× in real-world propagation. The cost is airtime: SF12 packets take ~10× longer than SF7 packets.
Coding rate — robustness vs airtime
LoRa adds Hamming-style forward error correction (FEC) on every payload. The coding rate sets how much redundancy is added.
| CR | Code rate | Overhead | Robustness |
| 1 | 4/5 | +25% | Detects 1 bit error per nibble |
| 2 | 4/6 | +50% | Detects 2, corrects 1 |
| 3 | 4/7 | +75% | Detects 3, corrects 1 |
| 4 | 4/8 | +100% | Detects 4, corrects 2 |
CR 4/5 is the default — fast, with minimal FEC. CR 4/8 doubles airtime but survives much higher bit error rates. Industrial environments with switching power supplies or motor noise benefit from CR 4/7 or 4/8; clean rural deployments stay at 4/5.
6. Real-World Range Optimisation
Things that are not in the datasheets but matter as much as anything that is:
- Get the antenna up. RF energy near the ground is absorbed. Even 1.5 m versus 3 m of antenna height makes a noticeable difference. The Fresnel zone for an 866 MHz, 5 km link wants ~21 m of midpoint clearance — rarely achievable, but get as high as you can.
- Never coil excess coax. RG316 loses ~1 dB/m at 868 MHz — half your power over 3 m of cheap cable. Use the shortest run possible; switch to LMR-240 or LMR-400 for runs over 2 m.
- Match polarisation. A vertically mounted dipole is vertically polarised. If one end is horizontal and the other vertical, you lose ~20 dB instantly. The most common range-test failure mode.
- Mind the ground plane. Quarter-wave whips need a metal ground plane of at least λ/4 radius (~8.6 cm at 866 MHz) to radiate efficiently. Bare modules on breadboards have almost no ground plane.
- Respect the duty cycle. Running over 1% duty cycle is illegal in many regions (including India and the EU) and, more practically, causes your own deployment to collide with itself.
- Pick CR intentionally. CR 4/5 by default, CR 4/7 or 4/8 in noisy environments. Do not just leave it at whatever shipped.
- Use Channel Activity Detection (CAD). Both the SX1262 and LLCC68 support CAD — a quick listen-before-talk that detects an incoming LoRa preamble with minimal power. Skipping CAD on a busy band causes collisions.
- Placement beats power. A +30 dBm module at waist height inside a metal enclosure loses to a +17 dBm module on top of a 3 m fiberglass pole, every single time.
7. Which Module to Pick
- Ebyte E220-900T30D — for maximum raw range from a single P2P link, when LoRaWAN is not needed and you are willing to handle mode-pin logic and a larger power budget. The cheapest path to +30 dBm in a small form factor. Mandatory: verify the centre frequency mapping for your firmware revision and confirm with Ebyte's config tool before deployment.
- Reyax RYLR998 — for the fastest path from unboxing to a working link. Pure AT commands, integrated antenna option, +20 dBm. Ideal for students, prototypes, and projects where development time matters more than raw range. Verify bandwidth codes in your firmware revision's AT command reference.
- Reyax RYLR993 Lite — when LoRaWAN is required. Joining The Things Network, Helium, or a private ChirpStack server is a few AT commands. Per-link range is lower, but with gateway infrastructure you do not need extreme single-hop range. Lower power draw than RYLR998 makes it ideal for battery-operated gateways.
Closing
All three modules use Semtech transceivers underneath, but their differences in TX power, sensitivity floor, onboard firmware, and power budgets mean they fit different jobs. Match the module to the deployment: high-power P2P with careful power supply engineering, fast-prototype P2P, or LoRaWAN infrastructure. Then put real engineering into the antenna, the impedance match, and the placement — that is where range actually comes from. Test on actual hardware with a spectrum analyser or a known gateway before rolling out 100 nodes.