diff --git a/docs/wiredmbus-testing.md b/docs/wiredmbus-testing.md new file mode 100644 index 0000000..03fa072 --- /dev/null +++ b/docs/wiredmbus-testing.md @@ -0,0 +1,108 @@ +# TSS721ADR Wired M-Bus Module Documentation (S0 Baseboard) + +## Overview + +The **TSS721ADR** is a **Wired M-Bus (Meter-Bus) transceiver** designed for reliable communication with **wired M-Bus compliant utility meters**, such as **water, heat, gas, and electricity meters**. + +On the **S0 Baseboard**, the TSS721ADR enables **direct physical connection** to wired M-Bus meters and acts as the **physical layer interface** between the meters and the S0 board. + +This module allows the S0 board to collect meter data from the Baseboard and forward it to SuperMQ via protocols like MQTT, CoAP, HTTP and the rest. + +--- + +## What is Wired M-Bus? + +**Wired M-Bus (EN 13757-2 / EN 13757-3)** is a European standard for wired meter reading. It supports: + +- Multi-drop bus topology +- Long cable lengths +- Low power consumption at the meter +- Reliable communication in industrial environments + +Wired M-Bus is commonly used in: + +- Apartment buildings +- Industrial facilities +- District heating systems +- Utility metering cabinets + +--- + +## Role of the TSS721ADR on the S0 Board + +The TSS721ADR performs the following functions: + +- Provides **voltage level shifting** and **signal conditioning** for the M-Bus line +- Handles **current modulation and detection** +- Protects the MCU from direct exposure to the M-Bus line +- Enables **half-duplex communication** over the M-Bus + +S0 communicates with the TSS721ADR using the **UART interface**, while the TSS721ADR interfaces with the **M-Bus lines (MBUS+ / MBUS−)**. + +--- + +## Key Features of the TSS721ADR + +- Fully compliant with **Wired M-Bus standards** +- Supports **master mode operation** +- Integrated current limiting and line protection +- Operates from a single supply voltage +- UART-based interface to the host MCU +- Industrial-grade reliability + +--- + +## Hardware Connections (Typical) + +### MCU ↔ TSS721ADR + +| Signal | Description | +| ------ | ---------------- | +| TX | UART TX to MCU | +| RX | UART RX from MCU | +| VB | Power supply | +| GND | Ground | + +### TSS721ADR ↔ Meter Bus + +| Signal | Description | +| ------ | ------------ | +| MBUS+ | M-Bus line | +| MBUS− | M-Bus return | + +--- + +## How to Test the TSS721ADR Module + +### 1. Prerequisites + +Before testing, ensure you have: + +- S0 Baseboard powered +- S0, or a microcontroller of your choice powered and programmed +- A **wired M-Bus compatible meter** or a (12-42)V DC power supply connected at the MBUS lines with the proper M-Bus wiring (polarity observed) +- Serial logging enabled on the S0 or Microcontroller of your choice +- Correct UART configuration (typically 2400 or 9600 baud) + +--- + +### 2. Electrical Verification + +1. Measure voltage on the **M-Bus lines**: + - Typical M-Bus idle voltage: **(12–42) V** +2. Verify the TSS721ADR is powered correctly + +--- + +### 3. UART Communication Test + +Configure the MCU UART connected to the TSS721ADR: + +- Baud rate: **2400 / 9600** +- Data bits: **8** +- Parity: **Even** +- Stop bits: **1** + +Send a simple test frame from the MCU and observe UART activity. + +Example code for this test can be found in the [Wired MBUS test code](https://github.com/absmach/s0-docs/blob/mbus-work/test-codes) diff --git a/docs/wirelessmbus-testing.md b/docs/wirelessmbus-testing.md new file mode 100644 index 0000000..eadd532 --- /dev/null +++ b/docs/wirelessmbus-testing.md @@ -0,0 +1,96 @@ +# RC-S2LP Wireless M-Bus Transceiver + +## Overview, Hardware Connection, and Test Procedure + +## Introduction + +The **RC-S2LP** is a sub-GHz RF transceiver module based on the **STMicroelectronics S2-LP** radio IC. It is commonly used in **Wireless M-Bus (wM-Bus)**, **smart metering**, and **low-power IoT gateway** applications operating in the **868 MHz ISM band**. + +In the **S0 board**, the RC-S2LP is responsible for receiving and transmitting Wireless M-Bus frames from devices such as heat meters, water meters, and gas meters. + +--- + +## What the RC-S2LP Module Is Used For + +The RC-S2LP enables: + +- Wireless M-Bus communication (T1, T2, C1, C2 modes) +- Sub-GHz long-range communication +- Low-power RF reception from battery-powered meters +- Gateway-to-meter RF communication +- Custom proprietary RF protocols + +Typical applications include: + +- Smart utility meters +- IoT gateways +- Industrial telemetry +- Building automation systems + +--- + +## Key Specifications + +| Feature | Description | +| ----------------- | --------------------------------- | +| RF IC | STMicroelectronics S2-LP | +| Frequency Band | 868 MHz ISM band | +| Modulation | 2-FSK, GFSK, OOK, MSK | +| Data Rate | Up to 500 kbps | +| Output Power | Up to +14 dBm | +| Sensitivity | Down to −130 dBm (mode-dependent) | +| Interface | SPI | +| Operating Voltage | 1.8 V – 3.6 V | +| Low-Power Modes | Sleep, Standby | + +--- + +## Hardware Connection + +The RC-S2LP communicates with the host MCU using **SPI** and several control signals. + +### Required Signals + +| Signal | Description | +| ------ | --------------- | +| MOSI | SPI Master Out | +| MISO | SPI Master In | +| SCK | SPI Clock | +| CS | SPI Chip Select | +| VCC | 3.3 V supply | +| GND | Ground | +| RF | 868 MHz antenna | + +--- + +### Example Connection (ESP32) + +| RC-S2LP Pin | MCU Pin | +| ----------- | -------- | +| MOSI | SPI MOSI | +| MISO | SPI MISO | +| SCK | SPI SCK | +| CS | GPIO | +| VCC | 3.3V | +| GND | GND | + +⚠️ Ensure a **proper 868 MHz antenna** is connected before transmitting. + +--- + +## Software Test Procedure + +### Test Objective + +The test verifies that: + +- The RC-S2LP is powered correctly +- SPI communication is functional +- Registers can be read and written +- RF transmission and reception work + +--- + +## SPI Communication Test + +Example code for this test can be found in the [Wireless MBUS test code](https://github.com/absmach/s0-docs/blob/mbus-work/test-codes) diff --git a/mkdocs.yml b/mkdocs.yml index f15fd19..0a820d8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -39,4 +39,6 @@ nav: - COAP-DTLS: coaps.md - MQTTS: mqtts.md - HTTPS: https.md - + - Module Tests: + - Wired MBUS: wiredmbus-testing.md + - Wireless MBUS: wirelessmbus-testing.md diff --git a/test-codes/MBUS_test_code.ino b/test-codes/MBUS_test_code.ino new file mode 100644 index 0000000..aa6e248 --- /dev/null +++ b/test-codes/MBUS_test_code.ino @@ -0,0 +1,46 @@ +// TSS721A + ESP32 UART Test + +// UART pins +#define MBUS_RX 18 // ESP32 receives from TSS721A TXD +#define MBUS_TX 19 // ESP32 transmits to TSS721A RXD + + +void setup() { + Serial.begin(115200); + delay(500); + + Serial.println("TSS721A ESP32 M-Bus Test Starting..."); + + Serial1.begin(2400, SERIAL_8E1, MBUS_RX, MBUS_TX); + // M-Bus default: 2400 baud, Even parity, 1 stop + + Serial.println("Ready. Listening for M-Bus data..."); + +} + +void loop() { + // Read data from M-Bus + while (Serial1.available()) { + byte b = Serial1.read(); + Serial.print("RX: 0x"); + Serial.println(b, HEX); + } + + // Send test every 5 sec + static uint32_t last = 0; + if (millis() - last > 20000) { + last = millis(); + + while (Serial1.available()) { + byte b = Serial1.read(); + Serial.print("RX: 0x"); + Serial.println(b, HEX); + } + + byte pingFrame[] = { 0x10, 0x40, 0x40, 0x16 }; // Standard M-Bus SND-NKE + Serial1.write(pingFrame, sizeof(pingFrame)); + + Serial.println("TX: Sent SND-NKE frame (reset command)"); + } + +} diff --git a/test-codes/WMBUS_test.ino b/test-codes/WMBUS_test.ino new file mode 100644 index 0000000..2d7e0a4 --- /dev/null +++ b/test-codes/WMBUS_test.ino @@ -0,0 +1,126 @@ +#include + +// SPI Pins for ESP32C6 +#define PIN_SPI_MOSI 23 +#define PIN_SPI_MISO 19 +#define PIN_SPI_SCK 18 +#define PIN_SPI_CS 5 + +// Optional Interrupt Pin +#define PIN_GDO0 4 + +// S2LP Command Strobes / Registers +#define CMD_SRES 0xFE // RESET +#define CMD_SNOP 0x00 // NO OP + +// Define buffer size for TX / RX +#define BUFFER_SIZE 64 + +SPIClass *vspi = NULL; + +void rcS2lpWriteReg(uint8_t reg, uint8_t value) { + digitalWrite(PIN_SPI_CS, LOW); + vspi->transfer(reg | 0x00); // WRITE + vspi->transfer(value); + digitalWrite(PIN_SPI_CS, HIGH); +} + +uint8_t rcS2lpReadReg(uint8_t reg) { + digitalWrite(PIN_SPI_CS, LOW); + vspi->transfer(reg | 0x80); // READ + uint8_t value = vspi->transfer(0); + digitalWrite(PIN_SPI_CS, HIGH); + return value; +} + +void rcS2lpStrobe(uint8_t cmd) { + digitalWrite(PIN_SPI_CS, LOW); + vspi->transfer(cmd); + digitalWrite(PIN_SPI_CS, HIGH); +} + +void setup() { + Serial.begin(115200); + delay(1000); + + Serial.println("RC-S2LP Wireless M-Bus SPI Test"); + + pinMode(PIN_SPI_CS, OUTPUT); + digitalWrite(PIN_SPI_CS, HIGH); + + pinMode(PIN_GDO0, INPUT); + + // Initialize VSPI + vspi = new SPIClass(VSPI); + vspi->begin(PIN_SPI_SCK, PIN_SPI_MISO, PIN_SPI_MOSI); + + // Hardware reset RC-S2LP if needed (wire RESET pin) + // pinMode(PIN_RESET, OUTPUT); + // digitalWrite(PIN_RESET, LOW); + // delay(100); + // digitalWrite(PIN_RESET, HIGH); + // delay(100); + + // Reset chip + Serial.println("Sending chip reset..."); + rcS2lpStrobe(CMD_SRES); + delay(100); + + // Read version / part number (example register) + uint8_t partnum = rcS2lpReadReg(0x01); // PARTNUM register addr + Serial.print("Part Number: 0x"); Serial.println(partnum, HEX); + + // Set some basic registers (Example — see datasheet) + Serial.println("Configuring basic registers..."); + rcS2lpWriteReg(0x02, 0x01); // Example: Write some register + + Serial.println("Ready!"); +} + +void loop() { + static uint32_t lastSend = 0; + + // Example: Transmit a test packet every 5 seconds + if (millis() - lastSend > 5000) { + lastSend = millis(); + + Serial.println("Sending test packet..."); + + // Build test packet + uint8_t packet[] = "HELLO FROM ESP32-C6"; + uint8_t packetSize = sizeof(packet); + + // Send strobe for TX FIFO loading (depends on S2LP FIFO interface) + digitalWrite(PIN_SPI_CS, LOW); + vspi->transfer(0x66); // WRITE FIFO command (example) + for (uint8_t i = 0; i < packetSize; i++) { + vspi->transfer(packet[i]); + } + digitalWrite(PIN_SPI_CS, HIGH); + + // Strobe TX (example) + rcS2lpStrobe(0x35); // STX + + Serial.println("Packet sent!"); + } + + // Example: Basic receive check + if (digitalRead(PIN_GDO0) == HIGH) { + Serial.println("Packet received!"); + uint8_t rxBuf[BUFFER_SIZE]; + + // Read RX FIFO (example) + digitalWrite(PIN_SPI_CS, LOW); + vspi->transfer(0x7F); // READ FIFO command + for (uint8_t i = 0; i < BUFFER_SIZE; i++) { + rxBuf[i] = vspi->transfer(0); + } + digitalWrite(PIN_SPI_CS, HIGH); + + Serial.print("Data: "); + for (uint8_t i = 0; i < BUFFER_SIZE; i++) { + Serial.write(rxBuf[i]); + } + Serial.println(); + } +}