0

I'm a Arduino newbie. I have an Electric meter with an RS485 output. I want to get the MeterID value over the RS485 module and the Arduino. I just have document from manufacturer.

Sent by computer : 68 99 99 99 99 99 99 68 01 02 67 F3 C3 16. 
Return from meter : FE 68 99 99 99 99 99 99 68 81 08 67 F3 A6 9B 34 4B 33 33 6F 16. 

My Arduino code:

#include <SoftwareSerial.h>

#define SSerialRX        10
#define SSerialTX        11
#define SSerialTxControl 3
#define RS485Transmit    HIGH
#define RS485Receive     LOW

SoftwareSerial RS485Serial(SSerialRX, SSerialTX);
byte request[] = {0x68, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x68, 0x01, 0x02, 0x67, 0xF3, 0xC3, 0x16}; 
int byteRead;

void setup()   
{
  Serial.begin(9600);
  RS485Serial.begin(1200);
  pinMode(SSerialTxControl, OUTPUT);
  digitalWrite(SSerialTxControl, RS485Receive);
  delay(20);
  Serial.println("Get Meter Address App");
}
void loop()   
{
  digitalWrite(SSerialTxControl, RS485Transmit);
  RS485Serial.write(request, sizeof(request));
  delay(2000);
  digitalWrite(SSerialTxControl, RS485Receive);
  delay(2000);
  if (RS485Serial.available()) 
  {
    byteRead = RS485Serial.read();
    Serial.println(byteRead, HEX);
  }
}

Serial Monitor show: enter image description here

I'm using combo like this topic modbus-rtu-controller-monitoring-with-arduino-and-rs485-module. My code is in C# below. I used the code before and it worked fine, but on the computer I use a COM port (Baudrate 1200, data 8bits, Parity EVEN, Stopbit 1) with an RS485-R232 converter:

#Send data
dataOUT = WriteData("68 99 99 99 99 99 99 68 01 02 67 F3 C3 16");
serialPort_Meter.Write(dataOUT, 0, dataOUT.Length);

#WriteData method
private static byte[] WriteData(string hex)
{
return hex.Split(' ').Select(s => Convert.ToByte(s, 16)).ToArray();
}

#Read data
private static string ReadData(SerialPort serial)
{
byte[] buffer = new byte[serial.BytesToRead];
serial.Read(buffer, 0, buffer.Length);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < buffer.Length; i++)
sb.AppendFormat("{0:X2} ", buffer[i]);
return sb.ToString();
}
  • you don't have delays in C#. why do you have delays in Arduino? – Juraj Mar 5 at 8:47
  • It's still blank – Cosi Nguyen Mar 5 at 10:43
  • with delay you missed the data. without delay you check too early – Juraj Mar 5 at 10:47
  • Please advise me – Cosi Nguyen Mar 5 at 10:59
  • Hi Cosi Nguyen. Can you share some details about the electric meter you are trying out this with? Even the document you are referring to can be helpful to understand. – Sumit Panse Mar 5 at 14:13
0

Using readBytes would do the same as your C# code. readBytes is blocking. It will wait for every byte until timeout. Default timeout is 1 second. If the count of bytes is smaller then the size of the buffer, it will wait a second after the last byte received. You can set the timeout with RS485Serial.setTimeout(500); (500 milliseconds for example).

void loop()   
{
  digitalWrite(SSerialTxControl, RS485Transmit);
  RS485Serial.write(request, sizeof(request));
  RS485Serial.flush();
  digitalWrite(SSerialTxControl, RS485Receive);
  int recvLen = RS485Serial.readBytes(buffer, sizeof(buffer));
  for (int i = 0; i < recvLen; i++) {
    Serial.println(buffer[i], HEX);
  }
}
  • It's still blank. I think issue from the sent request ? – Cosi Nguyen Mar 6 at 2:59
  • You mean i need create another function and call in loop() ? – Cosi Nguyen Mar 6 at 10:47
  • Thank your advise my new code to fix this problem – Cosi Nguyen Mar 7 at 10:52
  • #include <CustomSoftwareSerial.h> CustomSoftwareSerial RS485Serial(SSerialRX, SSerialTX); RS485Serial.begin(1200, CSERIAL_8E1); – Cosi Nguyen Mar 7 at 10:53
  • sorry, I overlooked that you set non standard serial parameters – Juraj Mar 7 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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