Skocz do zawartości

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


Pomocna odpowiedź

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
Link do komentarza
Share on other sites

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
Link do komentarza
Share on other sites

😄 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.

Link do komentarza
Share on other sites

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
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.