Skocz do zawartości

Błąd odczytu napięcia ORNO OR-WE-504 po Modbus RTU podłączonego do ARDUINO Mega


Pomocna odpowiedź

Napisano

Dzień dobry wszystkim,

Co prawda opisałem poniższy problem na innym forum, ale ze względu na termin wykonania chciałbym trafić do szerszego grona użytkowników.

Zakupiłem prosty wskaźnik energii OR-WE-504 firmy ORNO w celu monitoringu napięcia oraz prądu. Konfiguracja sprzętowa to Arduino Mega + konwerter TTL <-> RS485 + OR-WE-504. W pierwszej kolejności przetestowałem odpytywanie z dedykowanym programem od producenta i komunikacja działa prawidłowo. Podłączyłem urządzenie do sterownika PLC i również mogłem odpytywać wartości, w trybie ciągłym, ale z małymi problemami typu slave response time, niezależnie od tego jak długi był ustawiony czas, np 5000 ms. Po kontakcie z producentem dowiedziałem się, że urządzanie jest po prostu wolne i musi być odpytywane z przerwami. Po ustawieniu MessageToMessage Delay na 100 ms, komunikacja była płynna, bez błędów. Następnym krokiem było podłączenie do Arduino Mega poprzez konwerter sygnałów TTL <-> RS485. W programie używam software serial dla pinów 12,13. Program działał bez zarzutu dla podobnego urządzenia, które ma takie same ustawienia fabryczne komunikacji oraz podobne rejestry. Po podłączeniu urządzenia OR-WE-504 okazało się, że komunikacja odbywa się w jakimś stopniu, ponieważ nie mam problemu z slave response time. Natomiast podczas odpytywania dostaję odpowiedź 0xE3 co dla biblioteki ModbusMaster oznacza "invalid response CRC exception".

Zastanawiam się, czy nie jest potrzebna modyfikacja biblioteki ModbusMaster, gdzie musiałbym dodać jakieś opóźnienie w komunikacji.
Czy Ktoś ma może wiedzę, jak rozwiązać ten problem?

Poniżej załączam kod prostego programu:

#include <Arduino.h>
#include <avr/io.h>
#include <SPI.h>
#include <ModbusMaster.h>
#include <SoftwareSerial.h> 

// Software serial
SoftwareSerial WE_Serial(12,13); //rx, tx
ModbusMaster node;
static uint8_t WE_SlaveAddr = 0x01;

void setup()
{
  WE_Serial.begin(9600); 
  node.begin(WE_SlaveAddr, WE_Serial);
  Serial.begin(115200);
}

void loop()
{
  // ================================================
  // ============= TEST POMIARU NAPIĘCIA ============
  // ================================================

  delay(1000);
  
  uint8_t result;
  float AktualneNapiecie;
  result = node.readInputRegisters(0x0000, 1); //read the 1 registers of the PZEM-016
  Serial.println(result, HEX);
  
  if (result == node.ku8MBSuccess)
  {
    Serial.println("Ok");
    float AktualneNapiecie = node.getResponseBuffer(0x0000);
    AktualneNapiecie = AktualneNapiecie / 10;
    Serial.println((String) "Napięcie: " + AktualneNapiecie + (String) " V");
  } 
  else
  {
    Serial.println("Błąd komunikacji z miernikiem");
  }
}

 

  • Lubię! 1

Bosze, książki piszesz o programowaniu AVR w C, a tu takie problemy.

😄

Na początek użyj sprzętowego UART, może softwarowy generuje jakieś błędy i stąd problem z CRC.

  • Lubię! 1

😄 Nie ten Tomasz 🙂 Problem polega na tym, że płytka jest już gotowa pod serialowy port i działa dobrze z podobnym miernikiem, ale ze względu na jego częste awarie kupiłem ORNO. Może być to faktycznie problem z portem serialowym, aczkolwiek wyglądam mi to na jakiś szczegół w bibliotece.

Domyślałem się, że masz coś już tak przygotowane, że na MEGA nie używasz jednego z 4 sprzętowych serial, ale na czas testu wyciągnij sobie sygnał i przetestuj na sprzętowym. Albo po prostu użyj innej płytki, wystarczy jakieś NANO/UNO, jeszcze lepiej MICRO czy LEONARDO z wolnym UART. Mam ORNO i nie chciał działać z jednym konwerterem UART-RS485.

Mam licznik ORNO i funkcja do odczytu wygląda podobnie, pewnie inspirowaliśmy się tym samym źródłem:

void odczytModbus()
{
  // Toggle the coil at address 0x0002 (Manual Load Control)
  //result = node.writeSingleCoil(0x0002, state);
  //state = !state;

  // Read 16 registers starting at 0x3100)
//  result = node.readHoldingRegisters(0x40000, 10); 
  //OR
  result = node.readHoldingRegisters(0, 10);
  if (result == node.ku8MBSuccess)
  {VAR4=0;
//   Serial.begin(115200);  
//  Serial.write(27);       // ESC command
//  Serial.print("[2J");    // clear screen command
//  Serial.write(27);
//  Serial.print("[H");     // cursor to home command
//      Serial.print("Voltage: \t\t");
      VAR1=node.getResponseBuffer(0x00)/10.0;
//    Serial.println(node.getResponseBuffer(0x00)/10);
//    Serial.print("Current: \t\t");
//    Serial.println(node.getResponseBuffer(0x01)/10);
//    Serial.print("Freq: \t\t\t");
//    Serial.println(node.getResponseBuffer(0x02)/10);
//    Serial.print("Ac. Power: \t\t");
    VAR2=node.getResponseBuffer(0x03);
//    Serial.println(node.getResponseBuffer(0x03));
//    Serial.print("Reac. Power: \t\t");
//    Serial.println(node.getResponseBuffer(0x04));
//    Serial.print("App. Power: \t\t");
//    Serial.println(node.getResponseBuffer(0x05));
//    Serial.print("Power fact: \t\t");
//    Serial.println(node.getResponseBuffer(0x06)/1000);
/*        
    Serial.print("x06: ");
        Serial.println(node.getResponseBuffer(0x06));
    Serial.print("x07: ");
        Serial.println(node.getResponseBuffer(0x07));
*/

kwh=((uint32_t) node.getResponseBuffer(0x07))<<16;

//kwh=kwh<<16; Albo tak
 kwh=kwh|(node.getResponseBuffer(0x08));
VAR3=kwh/1000.0; 
//     Serial.print("x07|08 Energy Act: \t");
//        Serial.println( kwh/1000);

kwh=((uint32_t) node.getResponseBuffer(0x09))<<16;
 
 kwh=kwh|(node.getResponseBuffer(0x0A));
//     Serial.print("x09|0A Energy Reac: \t");
//        Serial.println( kwh/1000);
        
/*    Serial.print("x08: ");
        Serial.println(node.getResponseBuffer(0x08));
    Serial.print("x09: ");
        Serial.println(node.getResponseBuffer(0x09));
    Serial.print("x0A: ");
        Serial.println(node.getResponseBuffer(0x0A));
   */
/*  
    kwh=(node.getResponseBuffer(0x06));
    kwh=kwh<<16;
    
   uint32_t temp=(node.getResponseBuffer(0x07));
   kwh=(kwh|temp);
    Serial.println(kwh);*/
    
  } 
}

Poza tym ja mam w programie jeszcze zdefiniowane pin (piny na konwerterze zwarłem) DE do kierunku transmisji i funkcje PRE i POST, które banglują tym pinem. I są podane do biblioteki jako callbacks, żeby sobie ich używała:

void preTransmission()
{
  //digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
 // digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

void ModbusBegin()
{
// 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
  sSerial.begin(9600);

  // Modbus slave ID 2
  node.begin(2, sSerial);
  // Callbacks allow us to configure the RS485 transceiver correctly
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission); 
}

No i na początku, jak jeszcze byłem na etapie rozgryzania tematu to kupiłem tani konwerter USB i nie działał z ORNO, może nie każdy mu podchodzi.

  • Lubię! 1

Dziękuje za podpowiedź. Faktycznie jest problem z softwarowym portem. Zadziałało na sprzętowym tak jak pisaliście. Ze względu na brak możliwości modyfikacji płytek, zainwestowałem w bardziej markowy miernik i wszystko działa w porządku. Wniosek jest taki, że mierniki ORNO zamulają z komunikacją i z tego co wyczytałem w innych tematach potrafią się zawieszać w taki sposób, że bez resetu zasilania nie wstaną co wyklucza je tak czy inaczej z mojej aplikacji.

Bardzo dziękuję za pomoc i uznaję temat za zamknięty 🙂

  • Lubię! 1
  • 1 rok później...

Witam,

odgrzewam temat 🙂 odczytu licznika Orno or-we 504 - niby prosta rzecz a "nie działa" .... Czy koledzy mogą podzielić się kawałkiem kodu który z Arduino Mega 2560 łączy się poprzez konwerter UART-RS485 do orno 504 ? Wszystkie poszczególne elementy są działające, jedyna różnica to ta że nie wykorzystuję funkcji pre/postTransmission - posiadam konwerter bez/z automatycznym wyborem DE/RE - i na pewno działa bo odczytuję nim orno or-we 516, a 504 - niby prostsze coś mi nie idzie ...

Frigos

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...