Point-to-point transmission of PV inverter data via 868 MHz radio signal to MQTT client with WiFi interface.
- Transmitter: Connection to PV inverter via Modbus interface (USB or RS-485)
- Radio transmission via 868 MHz ISM band; FSK modulation; max. range: ~150 m
- Revceiver: MQTT client with WiFi interface

growatt2lorawan-v2 worked totally fine for quite a while, but now my LoRaWAN node cannot communicate with any public gateway (The Things Network or Helium Network) any more from its present location. Presumably a new building and/or its scaffolding within line-of-sight between node and TTN gateway are blocking the radio signal path. This project is a workaround by using point-to-point transmission.
The implementation is based on a few existing projects.
- Hardware Requirements
- Inverter Modbus Interface Options
- Power Supply
- Pinning Configuration
- Library Dependencies
- Software Build Configuration
- MQTT Integration
- Legal
- ESP32 (optionally with LiPo battery charger and battery)
- SX1276 or SX1262 (or compatible) LoRaWAN Radio Transceiver
- 868 MHz Antenna
- Transmitter
- optional: RS485 Transceiver - 3.3V compatible, half-duplex capable (e.g Waveshare 4777 module)
- optional: USB-to-TTL converter for Debugging (e.g. AZ Delivery HW-598)
- DFR0478 - FireBeetle ESP32 IoT Microcontroller
- TEL0125 - LoRa Radio 868MHz - FireBeetle Covers
- 868 MHz Antenna
-
USB Interface
The inverter's USB port operates like a USB serial port (UART) interface at 115200 bits/s. If the length of a standard USB cable is sufficient to connect the ESP32 to the inverter (and there are no compatibility issues with the ESP32 board's USB serial interface), this is the easiest variant, because no extra hardware is needed.
As pointed out in otti/Growatt_ShineWiFi-S, only CH340-based USB-Serial converters are compatible - converters with CP21XX and FTDI chips do not work!
-
COM Interface
The inverter's COM port provides an RS485 interface at 9600 bits/s. An RS485 tranceiver is required to connect it to the ESP32.
The desired interface is selected by pulling the GPIO pin INTERFACE_SEL
(defined in settings.h
) to 3.3V or GND, respectively:
Level | Modbus Interface Selection |
---|---|
low (GND) | USB Interface |
high (3.3V/open) | RS485 Interface |
The ESP32 development board can be powered from the inverter's USB port which only provides power if the inverter is active.
No sun - no power - no transmission! 😎
But: Some ESP32 boards have an integrated LiPo battery charger. You could power the board from a battery while there is no PV power (at least for a few hours).
GPIO define | Description |
---|---|
INTERFACE_SEL | Modbus Interface Selection (USB/RS485) |
GPIO define | Waveshare 4777 pin |
---|---|
MAX485_DE | RSE |
MAX485_RE_NEG | n.c. |
MAX485_RX | RO |
MAX485_TX | DI |
USB-to-TTL converter, e.g. AZ Delivery HW-598
GPIO define | USB to TTL Converter |
---|---|
DEBUG_TX | RXD |
DEBUG_RX | TXD / n.c. |
- ModbusMaster by Doc Walker
- RadioLib by Jan Gromeš
- arduino-mqtt by Joël Gähwiler
- ArduinoJson by Benoît Blanchon
- Lora-Serialization by Joscha Feth
- Install the Arduino ESP32 board package in the Arduino IDE
- Install all libraries listed in package.json — section
dependencies
— via the Arduino IDE Library Manager - Clone (or download and unpack) the latest (growatt2radio release)
- Transmitter
- Select your ESP32 board
- Check / modify pin configuration in src/growatt_cfg.h
- Build and upload examples/gw_transmitter/gw_transmitter.ino
- Receiver
- Select your ESP32 board
- Set your WiFi and MQTT credentials in
examples/gw_receiver/secrets.h
- Build and upload examples/gw_receiver/gw_receiver.ino
Arduino App: IoT MQTT Panel

You can either edit the provided IoT MQTT Panel configuration file before importing it or import it as-is and make the required changes in IoT MQTT Panel. Don't forget to add the broker's certificate if using secure MQTT! (in the App: Connections -> Edit Connections: Certificate path.)
Editing scripts/iot_mqtt_panel_growatt2radio.json
Change CONNECTIONNAME
, YOURMQTTBROKER
, USERNAME
and PASSWORD
as needed:
[...]
"connectionName": "CONNECTIONNAME",
"host": "YOURMQTTBROKER",
[...]
"username":"USERNAME","password":"PASSWORD"
[...]
See Datacake MQTT Integration Documentation.
scripts/datacake_uplink_decoder.js is an example payload decoder. Change device_id
and the MQTT topic variables as required.
With Datacake, you can get data reports as CSV files at regular intervals.
See scripts/home_assistant_configuration.yaml

- https://github.com/matthias-bs/growatt2lorawan-v2/blob/main/src/growattInterface.h
- https://github.com/matthias-bs/growatt2lorawan-v2/blob/main/src/growattInterface.cpp
- https://github.com/matthias-bs/growatt2lorawan-v2/blob/main/src/AppLayer.h
- https://github.com/matthias-bs/growatt2lorawan-v2/blob/main/src/AppLayer.cpp
- Arduino sketch
- FSK transmitter configuration based on https://github.com/matthias-bs/SensorTransmitter/blob/main/SensorTransmitter.ino (uses RadioLib)
- Operating sequence
- Power-on / wake-up
- Read data from PV inverter via Modbus interface
- Pack data into binary buffer
- Whitening / encryption?
- Add preamble, digest and transmitter ID
- Transmit packet via radio modem
- Sleep
- https://github.com/matthias-bs/BresserWeatherSensorReceiver/tree/main/src
- https://github.com/matthias-bs/BresserWeatherSensorReceiver/blob/main/examples/BresserWeatherSensorMQTT/BresserWeatherSensorMQTT.ino
- Arduino sketch
- FSK receiver configuration and based on BresserWeatherSensorReceiver (uses RadioLib)
- Operating sequence
- Power-on / wake-up
- Wait for radio message preamble
- Receive message
- Validate digest and transmitter ID (optional)
- De-whitening / decryption?
- Convert binary payload buffer to JSON (reverse lora-serialization)
- Publish JSON data using MQTT via WiFi
- Sleep
This project is in no way affiliated with, authorized, maintained, sponsored or endorsed by Growatt or any of its affiliates or subsidiaries.