 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
malci Član


Pridružen-a: Sob 15 Sep 2007 21:05 Prispevkov: 871 Aktiv.: 4.03 Kraj: Polhov Gradec
|
Objavljeno: Tor Jul 02, 2024 9:12 pm Naslov sporočila: ModBus RTU protokol - branje (in pisanje vrednosti....) |
|
|
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);
}
|
Opis: |
|
Velikost datoteke: |
159.3 KB |
Pogledana: |
9 krat |

|
Opis: |
|
Velikost datoteke: |
109.04 KB |
Pogledana: |
12 krat |

|
_________________ Elektronika za hobi |
|
Nazaj na vrh |
|
 |
mosqito Član


Pridružen-a: Čet 07 Apr 2016 23:22 Prispevkov: 3531 Aktiv.: 31.57
|
Objavljeno: Tor Jul 02, 2024 11:15 pm Naslov sporočila: |
|
|
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 |
|
 |
mateik Član

Pridružen-a: Sob 06 Avg 2022 18:31 Prispevkov: 261 Aktiv.: 7.50 Kraj: Ljubljana
|
Objavljeno: Tor Jul 02, 2024 11:16 pm Naslov sporočila: |
|
|
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 |
|
 |
California Član

Pridružen-a: Pet 26 Avg 2005 19:48 Prispevkov: 236 Aktiv.: 1.00 Kraj: Hrastnik
|
|
Nazaj na vrh |
|
 |
|
|
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
|