I am more of an ESP and YAML guy these days but I have a requirement to delve back into Arduino for a one-off task and need some help.
I have a solar controller that uses RS485 and a custom modbus. The controller stores settings and real-time data in registers which do not appear to be individually referenceable. The sequence to pull the data is to send a hex-formatted command to the controller and it will send back a hex string with all the contents of the registers.
I have an Arduino Uno hooked up to an C25B RS485 board using pin 0 (RX), pin 1 (TX) and pin 2 as control.
I need a script that will transmit '0x01 0xA3 0x01 0x00 0x00 0x00 0x00 0xA5' and then receive the response from the controller. The string is made up of 'slave address + command type + control code + data1-4 + checksum'. The command type determines which register data is returned.
I've built the same thing in YAML using an ESP32 but the controller is not responding so I want to try a different platform and see if I can get a response.
I'm not entirely sure that modbus actually factors into this and I think that a simple uart.write command should suffice but I'm interested to see how the hive-mind here would approach the challenge. Its been a few years since I wrote code in IDE so I'm definitely rusty.
Thank you. Reading through both the thread and the code, that seems to be a method to validate the checksum. I have the checksum (it is non-standard or, at least, non-common using Modulo 256). What I need to do is send the hex to the controller and receive the response.
Its also quite possible that I'm missing the key information in the links you posted.
What I think I am looking for is more like this thread but with the ability to send the hex string rather than poll a register.
It seems that as I am using an Uno, I also need to implement SoftwareSerial for the Uno>RS485.
Currently, I have this code that I'm looking to improve although I haven't yet figured out the SoftwareSerial changes that I need to make.
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
#define MAX485_DE 3
#define MAX485_RE_NEG 2
ModbusMaster node;
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}
void setup()
{
// put your setup code here, to run once:
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
// Modbus communication runs at 115200 baud
Serial.begin(9600);
//Modbus slave ID 1
node.begin(1, Serial);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop()
{
byte buf[] = {0x01, 0xA3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xA5};
Serial.write(buf, 8);
Serial.write('\n');
int hexIn = Serial.read();
delay(30000);
}