Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 4605

C/C++ • SoftwareSerial & SerialPIO on Pico 2W

$
0
0
I'm not sure if this is posted to the correct sub-forum?
I'm building a weather station using 3 x RS485 devices, Anemometer, Wind Vane & Temp/Himidity sensor. I believe that all 3 could be on the same RS485 bus if I changed the ID's to be unique (all default to 1), however the documentation is sparse (Renke Anemometer & Wind Vane and unknown Temp/Humidity Sensor) so I have each communicating with their own TTL>RS485 board rather than take a chance and 'brick' them.

I'm now using a Pico 2W and program it thru the Arduino IDE using Earle Philhowers board library(?) and it works great. I've also discovered how to add a UART using the PIO of the Pico (Very Cool!). I've got pics and a bit more info on my blog: https://robingreig.ca

Initially I got one sensor communicating then simply duplicated the steps to add the second and then the third sensor, and I'm happy with the code. However there seems to be so much duplication and I thought I could reuse much of the code for each of the 3 sensors by utilizing Arrays or Strings, however have not been successful.

According to the Arduino IDE, it's not taking up much memory:
Sketch TempHumidRS485_3 with 3 separate loops for 3 separate devices
Sketch uses 323268 bytes (7%) of program storage space. Maximum is 4186112 bytes.
Global variables use 72840 bytes (13%) of dynamic memory, leaving 451448 bytes for local variables. Maximum is 524288 bytes.
Resetting /dev/ttyACM0
Converting to uf2, output size: 685568, start address: 0x2000

Here is the full code and please let me know any thoughts on how to optimize much of the duplication?

Code:

/*  *  TempHumidRS485_3.ino *  Robin Greig *  2025.02.17 *   *  Reads the Temp & Humidity of RS485 device and prints it to Serial Monitor *   *  Using both UARTS and PIO-based UART to read 3 RS485 > TTL inputs *  mySerial1 = Rx / Pin 2 / GPIO 1 & Tx / Pin 1 / GPIO 0 *  mySerial2 = Rx / Pin 7 / GPIO 5 & Tx / Pin 6 / GPIO 4 *  mySerial3 = SerialPIO = Tx / Pin 11 / GPIO 8 & Rx / Pin 12 / GPIO 9 *   *  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 moduleSoftwareSerial mySerial1(1, 0); // Rx / Pin 2 / GPIO 1 & Tx / Pin 1 / GPIO 0SoftwareSerial mySerial2(5, 4); // Rx / Pin 2 / GPIO 1 & Tx / Pin 1 / GPIO 0SerialPIO mySerial3(8, 9); // Tx / GPIO 8 / Pin 11 & Rx / GPIO 12 / Pin 10//for SoftwareSerial PIO-based UART// Create a ModbusMaster objectModbusMaster node1;ModbusMaster node2;ModbusMaster node3;float humidity1;float humidity2;float humidity3;float temperature1;float temperature2;float temperature3; void setup() {  // Initialize serial communication for debugging  Serial.begin(115200);  // Initialize SoftwareSerial for Modbus communication  mySerial1.begin(9600);  mySerial2.begin(9600);  mySerial3.begin(9600);   // Initialize Modbus communication with the Modbus slave ID 1  node1.begin(1, mySerial1);  node2.begin(1, mySerial2);  node3.begin(1, mySerial3);   // Allow some time for initialization  delay(1000);} void loop() {  uint8_t result1;   // Variable to store the result of Modbus operations  uint16_t data1[2]; // Array to store the data read from the Modbus slave  uint8_t result2;   // Variable to store the result of Modbus operations  uint16_t data2[2]; // Array to store the data read from the Modbus slave  uint8_t result3;   // Variable to store the result of Modbus operations  uint16_t data3[2]; // Array to store the data read from the Modbus slave   // Read 2 holding registers for node1 starting at address 0x0000  // This function sends a Modbus request to the slave to read the registers  result1 = node1.readHoldingRegisters(0x0000, 2);   // If the read is successful, process the data  if (result1 == node1.ku8MBSuccess) {    // Get the response data from the response buffer    data1[0] = node1.getResponseBuffer(0x00); // Humidity    data1[1] = node1.getResponseBuffer(0x01); // Temperature     // Calculate actual humidity and temperature values    humidity1 = data1[0] / 10.0;      // Humidity is scaled by 10    temperature1 = data1[1] / 10.0;   // Temperature is scaled by 10     // Print the values to the Serial Monitor    Serial.print("Humidity1: ");    Serial.print(humidity1);    Serial.println(" %RH");     Serial.print("Temperature1: ");    Serial.print(temperature1);    Serial.println(" °C");    Serial.println();  } else {    // Print an error message if the read fails    Serial.print("Modbus read failed: ");    Serial.println(result1, HEX); // Print the error code in hexadecimal format    Serial.println();  }  delay(200);  // Read 2 holding registers for node2 starting at address 0x0000  // This function sends a Modbus request to the slave to read the registers  result2 = node2.readHoldingRegisters(0x0000, 2);   // If the read is successful, process the data  if (result2 == node2.ku8MBSuccess) {    // Get the response data from the response buffer    data2[0] = node2.getResponseBuffer(0x00); // Humidity    data2[1] = node2.getResponseBuffer(0x01); // Temperature     // Calculate actual humidity and temperature values    humidity2 = data2[0] / 10.0;      // Humidity is scaled by 10    temperature2 = data2[1] / 10.0;   // Temperature is scaled by 10     // Print the values to the Serial Monitor    Serial.print("Humidity2: ");    Serial.print(humidity2);    Serial.println(" %RH");     Serial.print("Temperature2: ");    Serial.print(temperature2);    Serial.println(" °C");    Serial.println();  } else {    // Print an error message if the read fails    Serial.print("Modbus read failed: ");    Serial.println(result2, HEX); // Print the error code in hexadecimal format    Serial.println();  }  delay(200);  // Read 2 holding registers for node3 starting at address 0x0000  // This function sends a Modbus request to the slave to read the registers  result3 = node3.readHoldingRegisters(0x0000, 2);   // If the read is successful, process the data  if (result3 == node3.ku8MBSuccess) {    // Get the response data from the response buffer    data3[0] = node3.getResponseBuffer(0x00); // Humidity    data3[1] = node3.getResponseBuffer(0x01); // Temperature     // Calculate actual humidity and temperature values    humidity3 = data3[0] / 10.0;      // Humidity is scaled by 10    temperature3 = data3[1] / 10.0;   // Temperature is scaled by 10     // Print the values to the Serial Monitor    Serial.print("Humidity3: ");    Serial.print(humidity3);    Serial.println(" %RH");     Serial.print("Temperature3: ");    Serial.print(temperature3);    Serial.println(" °C");    Serial.println();  } else {    // Print an error message if the read fails    Serial.print("Modbus read failed: ");    Serial.println(result3, HEX); // Print the error code in hexadecimal format    Serial.println();  }   // Wait for 2 seconds before the next read  delay(5000);}

Statistics: Posted by RobinGreig — Tue Feb 18, 2025 3:29 am — Replies 0 — Views 23



Viewing all articles
Browse latest Browse all 4605

Trending Articles