www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

ModBus RTU protokol - branje (in pisanje vrednosti....)

 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Arduino sekcija
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
malci
Član
Član



Pridružen-a: Sob 15 Sep 2007 21:05
Prispevkov: 871
Aktiv.: 4.03
Kraj: Polhov Gradec

PrispevekObjavljeno: Tor Jul 02, 2024 9:12 pm    Naslov sporočila:  ModBus RTU protokol - branje (in pisanje vrednosti....) Odgovori s citatom

Pozdrav.

Z serijsko RS485 komunikacijo in z protokolom ModBus se srečujem prvič. In pomagam si z UI. Medtem ko mi arduino kodo, katero je predlagal Googlov Gemini že prevajalnik zavrnil (in je predlagal tudi dve knjižnici -modbus master in modbus slave), je predlagano kodo od ChatGPT prevedlo brez napak, malo sem jo priredil za svoje potrebe, a deluje pa ne.

Želel bi iz naprave (EVSE kontroler), katera ima po defaultu ID 255 pridobiti vrednost registra 109.

Uporabljam arduino nano pro ploščico, kamor imam preko softwareSerial prikloljen BT modul HC-05, na hardwareSerial pa RS232 >> RS485 converter

Če gledam z logičnim analizatorjem linijo A in B se mi zdi, da arduino pošlje neke uporabne podatke (predvsem vidim addreso 109 - 6D in Slave ID 255), kakšen je odziv, če sploh je, pa ne vem, ker polnilnica ni v bližini računalnika (analizatorja)

Bi kateri poznavalec modbus protokola lahko pogledal spodnjo kodo ( predvsem void GetModBusData), kje bi lahko bila težava?

lp
Uroš

Koda:

#include <stdint.h>
#include <Arduino.h>
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
#include "pins.h"
 
// instantiate ModbusMaster object
   ModbusMaster node;
   SoftwareSerial mySerial(10, 11); // RX, TX   

// Modbus naprava z ID 255
const uint8_t deviceID = 255;

// Register, iz katerega želimo brati in vanj pisati (109)
const uint16_t registerAddress = 109;   

String inData;

void setup() {
      
   Serial.begin(38400);
   mySerial.begin(38400);
   
// Inicializiramo Modbus mojstra
    node.begin(deviceID, Serial);

   Serial.println("Evse control");
   mySerial.println("Evse control ( BT)");
}

//**************************************************************************

void GetModBusData(){
      
    uint8_t result;
    uint16_t data;
   
   // Pošljemo zahtevo za branje enega registra z naslovom 109
    result = node.readHoldingRegisters(registerAddress, 1);
    // Če je zahteva uspešna
    if (result == node.ku8MBSuccess) {
        // Preberemo podatke iz registra
        data = node.getResponseBuffer(0);
       
        // Izpišemo vrednost na serijski terminal
        mySerial.print("Vrednost v registru 109: ");
        mySerial.println(data);
       
        // Spremenimo vrednost za demonstracijo
        data = data + 1; // Povečamo vrednost za 1 (ali katerokoli drugo operacijo)

        // Zapišemo novo vrednost v register 109
        result = node.writeSingleRegister(registerAddress, data);
       
        // Preverimo, ali je pisanje uspelo
        if (result == node.ku8MBSuccess) {
            mySerial.print("Nova vrednost uspešno zapisana v register 109: ");
            mySerial.println(data);
        } else {
            mySerial.print("Napaka pri pisanju v register: ");
            mySerial.println(result, HEX);
        }
    } else {
        // Izpišemo napako, če branje ni uspelo
        mySerial.print("Napaka pri branju registra: ");
        mySerial.println(result, HEX);
    }
   
}
//*************************************************************************

void SendModBusData(uint16_t data){
      
    uint8_t result;
   
   
    // Zapišemo novo vrednost v register 109
    result = node.writeSingleRegister(registerAddress, data);
   
    // Preverimo, ali je pisanje uspelo
    if (result == node.ku8MBSuccess) {
         mySerial.print("Nova vrednost uspešno zapisana v register 109: ");
            mySerial.println(data);
        } else {
            mySerial.print("Napaka pri pisanju v register: ");
            mySerial.println(result, HEX);
        }   
}
//************************************************************************

void uart1(){      
   
   char spr1;
   String sprejem1;
   int ii = 0;   
   
   while(mySerial.available()) { 
      char rcv = mySerial.read();
      inData += rcv;
      if(rcv == '\n') { // ko se zaključi branje vseh dospelih znakov oz ko naleti na CRLF
//         mySerial.println(String(inData));
         sprejem1=inData;// clear inData
         inData = "";   
      }
   }
   mySerial.print("Serial In (sprejem:): " + sprejem1);
   do {
      
     int modBusData;      
     int len1 = sprejem1.length();  if (len1 < 2) break;
     byte ind = sprejem1.indexOf(';', 0);
     String str1 = sprejem1.substring(0, ind);
     sprejem1 = sprejem1.substring(ind + 1, len1); // sprejem se zmanjša za niz do prvega podpičja
     spr1 = str1.charAt(0); // iz str1 pridobi prvi znak
     str1 = str1.substring(1, str1.length()); // str1 je preostanek ( običajno vrednost)
      switch (spr1) {
      
       
      case 99:             //c zapiši v evse controler
         mySerial.println("c write");      // vrednost PWM
         modBusData=str1.toInt();
         PostModBusData(modBusData);
         
//         mySerial.println ("value PWM: " + String(value));
        break; 
      case 100:             //d preberi evse controler reg 109
         mySerial.println("d read register 109:");      // vrednost PWM
         GetModBusData();
       break;     
   
        default:  mySerial.println("NZN"); break;
      }
   } while (ii = 1);
   
}


void loop() {

   if (mySerial.available() > 0)  uart1();   
   
   delay(500);
   
}




screenShot description.JPG
 Opis:
 Velikost datoteke:  159.3 KB
 Pogledana:  9 krat

screenShot description.JPG



screenShot analizator.JPG
 Opis:
 Velikost datoteke:  109.04 KB
 Pogledana:  12 krat

screenShot analizator.JPG



_________________
Elektronika za hobi
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
mosqito
Član
Član



Pridružen-a: Čet 07 Apr 2016 23:22
Prispevkov: 3531
Aktiv.: 31.57

PrispevekObjavljeno: Tor Jul 02, 2024 11:15 pm    Naslov sporočila:   Odgovori s citatom

Modbus-RTU gre takole:

Citiram:

Frame Format

Structure:
Address Field (1 byte): Specifies the slave address (1 to 247).
Function Code (1 byte): Indicates the type of action (e.g., read, write).
Data Field (variable length): Contains request parameters or response data.
CRC (Cyclic Redundancy Check) (2 bytes): Error-checking code to ensure data integrity.

Function Codes

Common Functions:
0x01: Read Coils
0x02: Read Discrete Inputs
0x03: Read Holding Registers
0x04: Read Input Registers
0x05: Write Single Coil
0x06: Write Single Register
0x0F: Write Multiple Coils
0x10: Write Multiple Registers


Kitajci imajo vsi eno in isto, kolikor sem jaz gledal ... pošlješ

0xff (address)
0x03 (Read Holding Register)
0x00 0x6d (register 109)
0x00 0x01 (dolžina en bajt)
0x00 0x09 (crc)

Ni nujno, da je to pravilno. Poskusi dobiti dokumentacijo, da vidiš kako moraš sestaviti paket.

_________________
Always going the extra mile.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
mateik
Član
Član



Pridružen-a: Sob 06 Avg 2022 18:31
Prispevkov: 261
Aktiv.: 7.50
Kraj: Ljubljana

PrispevekObjavljeno: Tor Jul 02, 2024 11:16 pm    Naslov sporočila:   Odgovori s citatom

Ugibam.
Tole probaj takole:
Koda:

// Modbus naprava z ID 255

// Register, iz katerega želimo brati in vanj pisati (109)
const uint16_t registerAddress = 109;   

String inData;

void setup() {
     
   Serial.begin(38400);
 
// Inicializiramo Modbus mojstra
    node.begin(255, Serial);


Mislim pa da naprava s katero hočeš komunicirati je potem Slave.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
California
Član
Član



Pridružen-a: Pet 26 Avg 2005 19:48
Prispevkov: 236
Aktiv.: 1.00
Kraj: Hrastnik

PrispevekObjavljeno: Sre Jul 10, 2024 10:25 pm    Naslov sporočila:   Odgovori s citatom

Nekaj na temo modbusa:
https://ipc2u.com/articles/knowledge-base/modbus-rtu-made-simple-with-detailed-descriptions-and-examples/

_________________
California
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Arduino sekcija Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Stran 1 od 1

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 492 dni


Powered by phpBB © 2001, 2005 phpBB Group