Электросчетчик с Arduino и модулем RS485

Я новичок в Arduino. У меня есть электросчетчик с выходом RS485. Я хочу получить значение MeterID через модуль RS485 и Arduino. У меня есть только документ от производителя.

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. 

Мой код Arduino:

#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);
  }
}

Последовательный монитор показывает:

Я использую комбинацию, подобную этой теме modbus-rtu-controller-monitoring-with-arduino-and-rs485-module. Мой код на C# ниже. Раньше я использовал этот код, и он работал нормально, но на компьютере я использую COM-порт (скорость передачи данных 1200, данные 8 бит, четность EVEN, стоп-бит 1) с преобразователем RS485-R232:

#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();
}

, 👍0

Обсуждение

у вас нет задержек в C#. почему у вас задержки в Arduino?, @Juraj

Это все еще пусто, @Cosi Nguyen

с опозданием вы пропустили данные. без промедления, вы проверяете слишком рано, @Juraj

Пожалуйста, посоветуй мне, @Cosi Nguyen

Привет Коси Нгуен. Можете ли вы поделиться некоторыми подробностями об электросчетчике, с которым вы это пробуете? Даже документ, на который вы ссылаетесь, может быть полезен для понимания., @Sumit Panse

Привет, Сумит Пансе. Мой счетчик http://electrique.com.sg/?product_cat=amsys. Это частная компания в моей стране, и документ не публикуется в Интернете., @Cosi Nguyen

Привет всем, я понял, причина в том, что библиотека SoftwareSerial по умолчанию не поддерживает настройку соединения. Я использую CustomSoftwareSerial и исправил это, подключив необходимый бит данных, стоповый бит..., @Cosi Nguyen


1 ответ


Лучший ответ:

0

Использование readBytes будет делать то же самое, что и ваш код C#. readBytes блокируется. Он будет ждать каждый байт до истечения времени ожидания. Тайм-аут по умолчанию составляет 1 секунду. Если количество байтов меньше размера буфера, он будет ждать секунду после получения последнего байта. Вы можете установить таймаут с помощью RS485Serial.setTimeout(500); (например, 500 миллисекунд).

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);
  }
}
,

Это все еще пусто. Я думаю, проблема в отправленном запросе?, @Cosi Nguyen

Вы имеете в виду, что мне нужно создать еще одну функцию и вызвать цикл()?, @Cosi Nguyen

Спасибо, что посоветовали мой новый код, чтобы решить эту проблему., @Cosi Nguyen

#include <CustomSoftwareSerial.h> CustomSoftwareSerial RS485Serial(SSerialRX, SSerialTX); RS485Serial.begin(1200, CSERIAL_8E1);, @Cosi Nguyen

извините, я пропустил, что вы установили нестандартные параметры последовательного порта, @Juraj