3

enter image description hereI'm a medium user in Arduino. I baught a pHmeter controller with RS485 output (MODBUS RTU protocol). I want to get pH value read by the controller over RS485 module and Arduino. According the controller's manufacturer, we should operate as bellow: Sent by computer : 00 03 00 00 00 01 85 DB Return from controller : 00 03 02 02 AE 05 58.


#include SoftwareSerial.h

#define SSerialRX        10  //Serial Receive pin
#define SSerialTX        11  //Serial Transmit pin
#define SSerialTxControl 3   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW
#define Pin13LED         13

SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
byte byteSend;

void setup()   
{
  // Start the built-in serial port, probably to Serial Monitor
  Serial.begin(9600);
  Serial.println("SerialRemote");  // Can be ignored

  pinMode(Pin13LED, OUTPUT);   
  pinMode(SSerialTxControl, OUTPUT);  

  digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver


  RS485Serial.begin(9600);   
  delay(2000);
  digitalWrite(SSerialTxControl, RS485Transmit);  
   RS485Serial.write((byte)0x00);         
   RS485Serial.write((byte)0x03);                 
   RS485Serial.write((byte)0x00);                 
   RS485Serial.write((byte)0x00);                   
   RS485Serial.write((byte)0x00);                 
   RS485Serial.write((byte)0x01);         
   RS485Serial.write((byte)0x85);                
   RS485Serial.write((byte)0xDB); 
   Serial.println(" "); 

   digitalWrite(Pin13LED, LOW);  
   delay(10);
   digitalWrite(SSerialTxControl, RS485Receive);

}
void loop()   
{

  if (RS485Serial.available()) 
  {
    byteSend = RS485Serial.read();   // Read the byte
    Serial.print(byteSend, HEX);
    Serial.print(" ");
  }
}

I tried this following sketch who does not work. I would like to know if it is the good way to send request to the controller?

  • add to question a wiring schema and complete sketch – Juraj Mar 11 '18 at 20:10
  • Post update with wiring and complete sketch – Teddol Mar 11 '18 at 20:51
  • If you ask if there is a better way to send the request, then yes there is. but it will not make it work. byte request[] = {0, 0x03, 0, 0, 0, 0x01, 0x85, 0xDB}; RS485Serial.write(request, sizeof(request)); – Juraj Mar 12 '18 at 8:56
  • Good, it's working well. – Teddol Mar 12 '18 at 20:02
3

To send series of bytes over Serial or any other Stream (Print) implementation use the "write buffer" method size_t write(const uint8_t *buffer, size_t size)

For the case in question:

byte request[] = {0, 0x03, 0, 0, 0, 0x01, 0x85, 0xDB}; 
RS485Serial.write(request, sizeof(request));

If someone is curios about the Modbus RTU request bytes. They are:

  • station address
  • function - 0x03 Read Multiple Holding Registers
  • register address - 2 bytes
  • number of registers to read - 2 bytes
  • checksum - 2 bytes

The response:

  • station address return
  • function or error code
  • data length
  • data - length bytes
  • checksum - 2 bytes

Not the answer you're looking for? Browse other questions tagged or ask your own question.