Считывание данных со счетчика электроэнергии с использованием Modbus RTU в Arduino Mega

Пытаюсь прочитать данные со счетчика электроэнергии. Код предполагает считывание данных о напряжении и возврат, но отображаются некоторые случайные числа. Где я ошибаюсь в коде? Счетчик конзерв EM6436 Energy Meter. Пробовал: - 1) сбой преобразования данных в uint16_t 2) сбой чтения других регистров 3) Счетчик энергии показывает правильные данные на modscan. Ссылка на регистрацию измерителя энергии

 #include<ModbusMaster.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() {
      pinMode(MAX485_RE_NEG, OUTPUT);
      pinMode(MAX485_DE, OUTPUT);
// Init in receive mode 
      digitalWrite(MAX485_RE_NEG, 0);  
      digitalWrite(MAX485_DE, 0);  
  
      Serial.begin(19200,SERIAL_8E1);  
//slave ID 1  
      node.begin(1, Serial);  

      Serial.println("Starting Modbus Transaction:");  
      node.preTransmission(preTransmission);  
      node.postTransmission(postTransmission);  
  }
  
  uint16_t newData = 0;
  float floatData;
  double dataOne;
  
void loop() {                           // loop starts from here.
static uint32_t i;
uint8_t j, result;
uint16_t data[10];

i++;
result = node.readHoldingRegisters(3036,1);

Serial.println(" ");
  
if (result == node.ku8MBSuccess) {
  
  Serial.print("\nSuccess, Received data 0: ");
  
  for (j = 0; j < 1; j++) {
    data[j] = node.getResponseBuffer(j);
    floatData, dataOne= node.getResponseBuffer(j);
    Serial.print("\nHex data:");
    Serial.print(data[j], HEX);
    Serial.print(" ");
    Serial.print("\nDec data:");
    Serial.print(data[j], DEC);
    Serial.print("\nfloat data:");
    Serial.print(floatData);
    
    
  }
} else {
  Serial.print("Failed, Response Code: ");
  Serial.print(result, HEX);
  Serial.println(" ");
  delay(5000); 
}
delay(1000);
}

Результат:-

Success, Received data 0: 
-> Hex data:648F 

-> Dec data:25743

-> float data:25743.00⸮

person Saurabh Sakhare    schedule 22.03.2021    source источник
comment
Я думаю, вам может понадобиться прочитать 2 16-битных регистра, то есть readHoldingRegisters(3036,2), и объединить результат в FLOAT32?   -  person Bosz    schedule 22.03.2021


Ответы (1)


Как Бос предложил в комментариях выше, первое, что вам нужно сделать, это прочитать два регистра Modbus вместо 1. Итак, измените:

result = node.readHoldingRegisters(3036,1);

to:

result = node.readHoldingRegisters(3036,2);

Затем вам нужно поработать с обоими регистрами и объединить их, чтобы получить искомое число с плавающей запятой:

if (result == node.ku8MBSuccess) {

Serial.print("\nSuccess, Received data 0: ");

for (j = 0; j < 2; j++) {
  data[j] = node.getResponseBuffer(j);
}

unsigned long temp = (unsigned long)data[0] + (unsigned long)data[1]*65536;
floatData = *((float*)&temp);
  
Serial.print(floatData);

}

Это преобразование должно работать для любых FLOAT32 значений в списке регистров вашего устройства.

Эта конкретная проблема обсуждалась в нескольких местах, например, вы можете увидеть здесь.

person Marcos G.    schedule 24.03.2021
comment
@Marcus G. спасибо за ответ, он решил мою проблему. - person Saurabh Sakhare; 24.03.2021