Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/pr-build-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ jobs:
- Heltec_v3_room_server
# nRF52
- RAK_4631_companion_radio_ble
- RAK_4631_companion_radio_ethernet
- RAK_4631_repeater
- RAK_4631_repeater_ethernet
- RAK_4631_room_server
- RAK_4631_room_server_ethernet
# RP2040
- PicoW_repeater
# STM32
Expand Down
23 changes: 23 additions & 0 deletions docs/cli_commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This document provides an overview of CLI commands that can be sent to MeshCore
- [GPS](#gps-when-gps-support-is-compiled-in)
- [Sensors](#sensors-when-sensor-support-is-compiled-in)
- [Bridge](#bridge-when-bridge-support-is-compiled-in)
- [Ethernet](#ethernet-when-ethernet-support-is-compiled-in)

---

Expand Down Expand Up @@ -975,3 +976,25 @@ region save
**Note:** Returns an error on boards without power management support.

---

### Ethernet (when Ethernet support is compiled in)

Ethernet support is available on RAK4631 boards with a RAK13800 (W5100S) Ethernet module. Use the `_ethernet` firmware variants (e.g. `RAK_4631_repeater_ethernet`) to enable this feature.

---

#### View Ethernet connection status
**Usage:**
- `eth.status`

**Output:**
- `ETH: <ip>:<port>` when connected (e.g. `ETH: 192.168.1.50:23`)
- `ETH: not connected` when Ethernet is not active

**Notes:**
- Available on repeater and room server firmware only. Companion radio ethernet firmware does not expose a CLI.
- The Ethernet interface obtains an IP address via DHCP automatically on boot.
- A TCP server listens on port 23 (default) for CLI connections.
- Connect with any TCP client (e.g. `nc`, PuTTY) to access the same CLI available over serial.

---
25 changes: 25 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ A list of frequently-asked questions and answers for MeshCore
- [7.5. Q: What is the format of a contact or channel QR code?](#75-q-what-is-the-format-of-a-contact-or-channel-qr-code)
- [7.6. Q: How do I connect to the companion via WIFI, e.g. using a heltec v3?](#76-q-how-do-i-connect-to-the-companion-via-wifi-eg-using-a-heltec-v3)
- [7.7. Q: I have a Station G2, or a Heltec V4, or an Ikoka Stick, or a radio with a EByte E22-900M30S or a E22-900M33S module, what should their transmit power be set to?](#77-q-i-have-a-station-g2-or-a-heltec-v4-or-an-ikoka-stick-or-a-radio-with-a-ebyte-e22-900m30s-or-a-e22-900m33s-module-what-should-their-transmit-power-be-set-to)
- [7.8. Q: How do I use Ethernet with a RAK4631?](#78-q-how-do-i-use-ethernet-with-a-rak4631)

## 1. Introduction

Expand Down Expand Up @@ -880,3 +881,27 @@ For companion radios, you can set these radios' transmit power in the smartphone
| **Heltec V4** | Standard Output | 10 dBm | 22 dBm | |
| | High Output | 22 dBm | 28 dBm | |
---

### 7.8. Q: How do I use Ethernet with a RAK4631?
**A:**
MeshCore supports Ethernet on RAK4631 boards using the [RAK13800](https://docs.rakwireless.com/product-categories/wisblock/rak13800/datasheet/) WisBlock Ethernet module (based on the W5100S chip).

**Hardware required:**
- RAK4631 WisBlock Core
- RAK19007 or RAK19018 WisBlock Base Board (with an available IO slot)
- RAK13800 WisBlock Ethernet module
- Ethernet cable connected to a network with a DHCP server

**Firmware:**
Flash one of the Ethernet-enabled firmware variants:
- `RAK_4631_repeater_ethernet` - Repeater with Ethernet CLI access
- `RAK_4631_room_server_ethernet` - Room server with Ethernet CLI access
- `RAK_4631_companion_radio_ethernet` - Companion radio over Ethernet (replaces BLE)

**Connecting:**
- The device obtains an IP address via DHCP automatically on boot.
- For repeaters and room servers, connect to the device on TCP port 23 using any TCP client (e.g. `nc <ip> 23` or PuTTY in raw mode). This gives you the same CLI available over serial/USB.
- For companion radio firmware, the Ethernet interface replaces BLE as the transport to companion apps. Connect on TCP port 5000 (same as the WiFi companion radio).
- Use the `eth.status` CLI command to check connection status and see the assigned IP address.

---
47 changes: 36 additions & 11 deletions examples/companion_radio/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@ static uint32_t _atoi(const char* sp) {
return n;
}


#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
#include <InternalFileSystem.h>
#if defined(QSPIFLASH)
#include <CustomLFS_QSPIFlash.h>
DataStore store(InternalFS, QSPIFlash, rtc_clock);
#else
#if defined(EXTRAFS)
#include <CustomLFS.h>
CustomLFS ExtraFS(0xD4000, 0x19000, 128);
DataStore store(InternalFS, ExtraFS, rtc_clock);
#else
DataStore store(InternalFS, rtc_clock);
#endif
#if defined(EXTRAFS)
#include <CustomLFS.h>
CustomLFS ExtraFS(0xD4000, 0x19000, 128);
DataStore store(InternalFS, ExtraFS, rtc_clock);
#else
DataStore store(InternalFS, rtc_clock);
#endif
#endif
#elif defined(RP2040_PLATFORM)
#include <LittleFS.h>
Expand Down Expand Up @@ -74,13 +75,21 @@ static uint32_t _atoi(const char* sp) {
#ifdef BLE_PIN_CODE
#include <helpers/nrf52/SerialBLEInterface.h>
SerialBLEInterface serial_interface;
#elif defined(ETHERNET_ENABLED)
#include <helpers/nrf52/SerialEthernetInterface.h>
SerialEthernetInterface serial_interface;
#else
#include <helpers/ArduinoSerialInterface.h>
ArduinoSerialInterface serial_interface;
#endif
#elif defined(STM32_PLATFORM)
#include <helpers/ArduinoSerialInterface.h>
ArduinoSerialInterface serial_interface;
#ifdef ETHERNET_ENABLED
#include <helpers/nrf52/SerialEthernetInterface.h>
SerialEthernetInterface serial_interface;
#else
#include <helpers/ArduinoSerialInterface.h>
ArduinoSerialInterface serial_interface;
#endif
#else
#error "need to define a serial interface"
#endif
Expand All @@ -107,7 +116,6 @@ void halt() {

void setup() {
Serial.begin(115200);

board.begin();

#ifdef DISPLAY_CLASS
Expand Down Expand Up @@ -152,10 +160,23 @@ void setup() {

#ifdef BLE_PIN_CODE
serial_interface.begin(BLE_NAME_PREFIX, the_mesh.getNodePrefs()->node_name, the_mesh.getBLEPin());
the_mesh.startInterface(serial_interface);
#elif defined(ETHERNET_ENABLED)
Serial.print("Waiting for serial to connect...\n");
unsigned long timeout = millis();
while (!Serial) {
if ((millis() - timeout) < 5000) { delay(100); } else { break; }
}
Serial.println("Initializing Ethernet adapter...");
if (serial_interface.begin()) {
the_mesh.startInterface(serial_interface);
} else {
Serial.println("ETH: Init failed, continuing without Ethernet (mesh only)");
}
#else
serial_interface.begin(Serial);
#endif
the_mesh.startInterface(serial_interface);
#endif
#elif defined(RP2040_PLATFORM)
LittleFS.begin();
store.begin();
Expand Down Expand Up @@ -225,4 +246,8 @@ void loop() {
ui_task.loop();
#endif
rtc_clock.tick();

#ifdef ETHERNET_ENABLED
serial_interface.loop();
#endif
}
36 changes: 36 additions & 0 deletions examples/simple_repeater/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
static UITask ui_task(display);
#endif

#ifdef ETHERNET_ENABLED
#define ETHERNET_CLI_BANNER "MeshCore Repeater CLI"
#include <helpers/nrf52/EthernetCLI.h>
#endif

StdRNG fast_rng;
SimpleMeshTables tables;

Expand All @@ -18,6 +23,9 @@ void halt() {
}

static char command[160];
#ifdef ETHERNET_ENABLED
static char ethernet_command[160];
#endif

// For power saving
unsigned long lastActive = 0; // mark last active time
Expand Down Expand Up @@ -90,6 +98,9 @@ void setup() {
mesh::Utils::printHex(Serial, the_mesh.self_id.pub_key, PUB_KEY_SIZE); Serial.println();

command[0] = 0;
#ifdef ETHERNET_ENABLED
ethernet_command[0] = 0;
#endif

sensors.begin();

Expand All @@ -99,13 +110,18 @@ void setup() {
ui_task.begin(the_mesh.getNodePrefs(), FIRMWARE_BUILD_DATE, FIRMWARE_VERSION);
#endif

#ifdef ETHERNET_ENABLED
ethernet_start_task();
#endif

// send out initial zero hop Advertisement to the mesh
#if ENABLE_ADVERT_ON_BOOT == 1
the_mesh.sendSelfAdvertisement(16000, false);
#endif
}

void loop() {
// Handle Serial CLI
int len = strlen(command);
while (Serial.available() && len < sizeof(command)-1) {
char c = Serial.read();
Expand All @@ -124,14 +140,34 @@ void loop() {
Serial.print('\n');
command[len - 1] = 0; // replace newline with C string null terminator
char reply[160];
reply[0] = 0;
#ifdef ETHERNET_ENABLED
if (!ethernet_handle_command(command, reply)) {
the_mesh.handleCommand(0, command, reply);
}
#else
the_mesh.handleCommand(0, command, reply); // NOTE: there is no sender_timestamp via serial!
#endif
if (reply[0]) {
Serial.print(" -> "); Serial.println(reply);
}

command[0] = 0; // reset command buffer
}

#ifdef ETHERNET_ENABLED
ethernet_loop_maintain();
if (ethernet_read_line(ethernet_command, sizeof(ethernet_command))) {
char reply[160];
reply[0] = 0;
if (!ethernet_handle_command(ethernet_command, reply)) {
the_mesh.handleCommand(0, ethernet_command, reply);
}
ethernet_send_reply(reply);
ethernet_command[0] = 0;
}
#endif

#if defined(PIN_USER_BTN) && defined(_SEEED_SENSECAP_SOLAR_H_)
// Hold the user button to power off the SenseCAP Solar repeater.
int btnState = digitalRead(PIN_USER_BTN);
Expand Down
35 changes: 35 additions & 0 deletions examples/simple_room_server/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

#include "MyMesh.h"

#ifdef ETHERNET_ENABLED
#define ETHERNET_CLI_BANNER "MeshCore Room Server CLI"
#include <helpers/nrf52/EthernetCLI.h>
#endif

#ifdef DISPLAY_CLASS
#include "UITask.h"
static UITask ui_task(display);
Expand All @@ -17,6 +22,9 @@ void halt() {
}

static char command[MAX_POST_TEXT_LEN+1];
#ifdef ETHERNET_ENABLED
static char ethernet_command[MAX_POST_TEXT_LEN+1];
#endif

void setup() {
Serial.begin(115200);
Expand Down Expand Up @@ -67,6 +75,9 @@ void setup() {
mesh::Utils::printHex(Serial, the_mesh.self_id.pub_key, PUB_KEY_SIZE); Serial.println();

command[0] = 0;
#ifdef ETHERNET_ENABLED
ethernet_command[0] = 0;
#endif

sensors.begin();

Expand All @@ -76,6 +87,10 @@ void setup() {
ui_task.begin(the_mesh.getNodePrefs(), FIRMWARE_BUILD_DATE, FIRMWARE_VERSION);
#endif

#ifdef ETHERNET_ENABLED
ethernet_start_task();
#endif

// send out initial zero hop Advertisement to the mesh
#if ENABLE_ADVERT_ON_BOOT == 1
the_mesh.sendSelfAdvertisement(16000, false);
Expand All @@ -99,14 +114,34 @@ void loop() {
if (len > 0 && command[len - 1] == '\r') { // received complete line
command[len - 1] = 0; // replace newline with C string null terminator
char reply[160];
reply[0] = 0;
#ifdef ETHERNET_ENABLED
if (!ethernet_handle_command(command, reply)) {
the_mesh.handleCommand(0, command, reply);
}
#else
the_mesh.handleCommand(0, command, reply); // NOTE: there is no sender_timestamp via serial!
#endif
if (reply[0]) {
Serial.print(" -> "); Serial.println(reply);
}

command[0] = 0; // reset command buffer
}

#ifdef ETHERNET_ENABLED
ethernet_loop_maintain();
if (ethernet_read_line(ethernet_command, sizeof(ethernet_command))) {
char reply[160];
reply[0] = 0;
if (!ethernet_handle_command(ethernet_command, reply)) {
the_mesh.handleCommand(0, ethernet_command, reply);
}
ethernet_send_reply(reply);
ethernet_command[0] = 0;
}
#endif

the_mesh.loop();
sensors.loop();
#ifdef DISPLAY_CLASS
Expand Down
Loading