Hi there,
I am currently in the early stages of a project to display battery % of an SMA Sunny Island system via an Arduino. SMA uses MODBUS and this is fairly new to me, I have a little experience programming with an Arduino and was hoping to get some further guidance.
My vision at the moment is reading in the data, converting it to the correct type and displaying it on a display of some kind. I am still in a theorising stage and as I don't actually have an Arduino on hand yet I wanted to talk about what I think I need to do and see if it sounds right.
So, the Sunny Island has pretty good documentation for MODBUS configuration and we are using modbus register 30845, the data will be given as an unsigned 32 bits over 2 registers. See here for further documentation: https://files.sma.de/downloads/SI-Modbus-BA-en-12.pdf
I have found a piece of code here: How to use Modbus RTU with Arduino to read Sensor Data
I want to comment on the parts I think I would need to change but there are bound to be things wrong regardless and would appreciate feedback on all of that.
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
// Create a SoftwareSerial object to communicate with the MAX485 module
SoftwareSerial mySerial(10, 11); // RX, TX
// Create a ModbusMaster object
ModbusMaster node;
void setup() {
// Initialize serial communication for debugging
Serial.begin(9600);
// 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");
} 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(2000);
}
So, starting from setup the only change I can see would be changing the slave ID if my sunny island device doesn't read as device 1.
In the main loop I believe I would need to change the "result" to a 16 bit and the data to a 32 bit? I do believe the array length of 2 is correct in this case? My register I believe in Hex would be 0x787D ?
Obviously for my use the code after the successful read would be different but I just wanted to get some proper advice with where my head is at. Thank you anyone who helps and once I have a bit more clarity on what to do I will get myself an actual Arduino and start playing around.