Pages

Sunday, February 16, 2025

RS485 Modbus to Raspberry Pi Pico 2W

 


A while ago I went to order a wind vane and Anemometer online and didn't pay attention and ended up receiving RS485 units rather than the 0-10VDC units I wanted....grin

This gave me the incentive to learn how to connect RS485 devices to ESP8266's, ESP32's and in this case a new Raspberry Pi Pico 2W that had just arrived.

Here is the TTL > RS485 board I am using:


The wind vane and Anemometer are already outside so I ordered a couple of Temperature & Humidity sensors that you see here to continue to experiment with the RS485 protocol. On the breadboard you can see the Pico 2W on the left and then side by side is the TTL > RS485 board and a RFID-RC522 board that I've been playing with on the Arduino Uno shown at the top of the picture.

I wasn't able to connect a RS485 device to a ESP8266 since, as I understand it, the main UART is used for the serial USB communication and the second UART is transmit only? So in the case of the wind vane and Anemometer I used a couple of ESP32's. Normally you can connect multiple RS485 devices on the same bus as long as you set unique addresses on each, however I haven't done that yet, so I connected each device to it's own ESP32. 

Given the low cost of the Pico 2W from  pishop.ca I was able to use the same software from the Arduino Modbus sketch and just change the Tx & Rx pin assignments.

The next step will be to add wireless & mqtt code to the Pico 2W so that it can transmit the temperature and humidity values to my mosquitto broker to be read by Node-Red on my Raspberry Pi

Thanks for reading!

Here is the code:

/* 

 *  TempHumidRS485a.ino

 *  Robin Greig

 *  2025.02.15

 *  

 *  Reads the Temp & Humidity of RS485 device and prints it to Serial Monitor

 *  

 *  Based on the ModbusMaster example below

*/



#include <ModbusMaster.h>       //https://github.com/4-20ma/ModbusMaster

#include <SoftwareSerial.h>

 

// Create a SoftwareSerial object to communicate with the MAX485 module

SoftwareSerial mySerial(1, 0); // RX, TX

 

// Create a ModbusMaster object

ModbusMaster node;

 

void setup() {

  // Initialize serial communication for debugging

  Serial.begin(115200);

  // Initialize SoftwareSerial for Modbus communication

  mySerial.begin(9600);

 

  // Initialize Modbus communication with the Modbus slave ID 1

  node.begin(1, mySerial);

 

  // Allow some time for initialization

  delay(1000);

}

 

void loop() {

  uint8_t result;   // Variable to store the result of Modbus operations

  uint16_t data[2]; // Array to store the data read from the Modbus slave

 

  // Read 2 holding registers starting at address 0x0000

  // This function sends a Modbus request to the slave to read the registers

  result = node.readHoldingRegisters(0x0000, 2);

 

  // If the read is successful, process the data

  if (result == node.ku8MBSuccess) {

    // Get the response data from the response buffer

    data[0] = node.getResponseBuffer(0x00); // Humidity

    data[1] = node.getResponseBuffer(0x01); // Temperature

 

    // Calculate actual humidity and temperature values

    float humidity = data[0] / 10.0;      // Humidity is scaled by 10

    float temperature = data[1] / 10.0;   // Temperature is scaled by 10

 

    // Print the values to the Serial Monitor

    Serial.print("Humidity: ");

    Serial.print(humidity);

    Serial.println(" %RH");

 

    Serial.print("Temperature: ");

    Serial.print(temperature);

    Serial.println(" °C");

    Serial.println();

  } else {

    // Print an error message if the read fails

    Serial.print("Modbus read failed: ");

    Serial.println(result, HEX); // Print the error code in hexadecimal format

  }

 

  // Wait for 2 seconds before the next read

  delay(5000);

}

No comments:

Post a Comment