» »

Esp8266 / arduino modbusRTU

Esp8266 / arduino modbusRTU

simont ::

Pozdravljeni,
Se kdo mogoče spozna na modbusRTU programiranje za arduino.

BigWhale ::

Najbrz se kdo ampak brez konkretnega vprasanja se najbrz nikomir ne bo dalo priti sem samo pofockat. :)

simont ::

V osnovi je že vprašanje precej ozko. Pa kljub temu velja poizkusiti.

Arduino = Master, Naprava = Slave

Naprava pričakuje poslan paket na slave naslov točno določen hex paket -> torej se pošlje na RS485:
Primer:
Send : 01 10 90 00 00 04 08 01 00 00 00 00 00 00 00 B6 E7
Receive : 01 10 90 00 04 1C EE

Torej paket je sestavljen po tej tabeli. Ker mi slika NE deluje prilagam samo povezavo
Tabela

Zgodovina sprememb…

  • spremenilo: simont ()

AndrejO ::

In kje je vprašanje?

simont ::

Poslati bi bilo potrebno tale paket ? Kako
01 10 90 00 00 04 08 01 00 00 00 00 00 00 00 B6 E7

AndrejO ::

Pogledaš v specifikacijo za UART na tvojem MCU, da ugotoviš kako se mu nastavi ustrezne parametre komunikacije in kako se pošlje podatke.

Lahko poveš še kaj več, ali pa bo potrebno ugibati, če želiš uporabljati UART na ESP MCU ali UART na enem izmed množice različnih in med seboj tudi nekompatibilnih MCU-jev, ki pridejo pod oznako "Arduino"? Brez zamere, ampak s pinceto vleči nekaj ven iz človeka, ki išče "nekakšno pomoč", potem pa ne zna opisati niti kje je sploh težava ... je duhamorno.

Pokaži shemo, povej kaj sploh uporabljaš ali načrtuješ uporabiti, pokaži kaj si naredil do sedaj in potem vprašaj za pomoč. Tako, kot si se tega lotil sedaj, lahko samo upaš na kakšnega telepata, ki ti bo znal prebrati misli.

BigWhale ::

Za modbus RTU imas ze narejeno arduino kniznjico. Predlagam, da si jo ogledas.

https://www.arduino.cc/en/ArduinoModbus...

simont ::

Pošiljanje in branje RS232/485 preko testiranih večih knjižnic načeloma ni taka huda težava. Večji problem mi predstavlja priprava specifičnega Hexadecimalnega paketa, ki ga je potrebno poslati oz. način.

Prilagam proizvajalčev protokol, če je volja pogledati stran 6-10. Prilagam tudi enega izmed primerov arduino kode.

Navodila

Arduino primer

Stikalo ::

Saj imaš v primernu naprogramiran primer??

byte msg [] = {
    0x01,
    0x10,
    0x90,
    0x00, 
    0x00,
    0x04,
    0x08,
    0x01,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0xB6,
    0xE7  
};

for (int i = 0; i < sizeof(msg); i++) {
     Serial.print(msg[i], HEX);
     rs485.write(msg[i]);
     Serial.print(", ");
}


A to ne deluje?

Stikalo ::

@simont kaj pravzaprav hočeš poslati za en ukaz, da vidim če je pravilno oblikovan?

AndrejO ::

simont je izjavil:

Pošiljanje in branje RS232/485 preko testiranih večih knjižnic načeloma ni taka huda težava. Večji problem mi predstavlja priprava specifičnega Hexadecimalnega paketa, ki ga je potrebno poslati oz. način.

Prilagam proizvajalčev protokol, če je volja pogledati stran 6-10. Prilagam tudi enega izmed primerov arduino kode.

Ker je govora o RTU, to pomeni, da pošiljaš binarne podatke. Tam kjer ti piše "hex 2f", pripraviš vrednost 0x2f za pošiljanje in to je to.

Ko sestavljaš "svoje" ukaze, moraš na koncu izračunati in dodati še CRC16 kontrolno kodo, ravno tako bo dobro, da jo preveriš pri odgovorih.

Za pomoč, da boš vedel, če si lasten paket pravilno sestavil in, če ima pravilno CRC kodo, si lahko pomogaš s spletnim enkoderjem/dekoderjem: http://modbus.rapidscada.net/

Edit: CRC16 je prav

Zgodovina sprememb…

  • spremenil: AndrejO ()

simont ::

Zaenkrat hvala za odgovore.

Upravljanje inverterja:
Trenutno delamo tako, da si preko GUI programa za windows (primer screenshot) Docklight, vneseš že pripravljeno hexadecimalno vrednost in pošlješ. Te vrednosti tudi pred pošiljanjem izračunaš in imaš predpripravljene za različne potrebe. To je tudi jasno in delujoče. Od množice programov kar smo jih uspeli testirati za modbusRTU samo ta počne zadevo primerno za ta inverter (seveda je bil to predlog proizvajalca)

Ker pa je želja da bi uporabljali Arduino/RaspberryPi kot enoto, ki jo lahko sami poljubno programiramo in nam služi tudi kot web vmesnik za pošiljanje/branje komand, ki jih pošilja na RS485 po istem principu kot to delamo preko GUI win programa se nam je pa ustavilo. Poizkusili smo že vse živo od modbuslib - Python, mbpool - Linux nativno, Arduino par knjižnic, predvidevam, da nekaj ne počnemo pravilno ali pa je rešitev toliko trivialna, da je ne vidimo.

Arduino primer kode sicer "pošlje" vendar read back ne dobi ničesar (Serial.write(rs485.read());)

AndrejO ::

Mojih top 5 razlogov, da mi modbus slave na RS485 ni vrnil odgovora so bili:
- Razlika v parametrih komunikacije (hitrost, št. bitov, pariteta, št. stop bitov).
- Napaka v izračunu CRC16.
- Napačen naslov (pomešal little in big endian).
- Napaka v moji kodi, kadar nisem uporabil knjižnico.
- Napaka v napeljavi: napačno terminiranje, pletenica, ki to ni bila, ipd.

Načini, kako sem se tega do sedaj loteval:
- RS485 na PC, da sem gledal kaj res pošiljam (pred leti je to bil RS485 na RS232, danes je to direktno RS485 USB dongle).
- Ko sem kaj zajel, uporaba modbus dekoderja (povezava od zgoraj - tako sem našel napačen CRC).
- "Duh!" trenutek, ko primerjam zajem iz originalnega SW in to, kar pošiljam jaz (napačen naslov).
- Multimeter in osciloskop (WTF trenutek, ko na kablu do PC pride skozi vse prav in v pravem vrstnem redu, slave na drugem kablu pa ne dobi ničesar).

AndrejO ::

simont je izjavil:

Poizkusili smo že vse živo od modbuslib - Python, mbpool - Linux nativno, Arduino par knjižnic, predvidevam, da nekaj ne počnemo pravilno ali pa je rešitev toliko trivialna, da je ne vidimo.

OK, neumno vprašanje. Ampak to, da je RS485 standard za električno signalizacijo, to veš? Kako imaš to iz RPi oz. Arduino (in kateri Arduino sploh uporabljaš?) dejansko zvezano na povezavo? Imaš shield? Kateri shield oz. konverter iz TTL na RS485 in nazaj?

BigWhale ::

Mogoce ima ze skurjen Arduino, pa se ne ve. ;)

AndrejO ::

Hmnja ... tudi to je možno. Ampak, če je poskusil tudi z RPi, bi tudi tega skurilo, pa bi to na njem verjetno bilo bolj očitno.

Čeprav, če signalizacija ne bi bila prava, potem tudi slave verjetno ne bi ničesar sprejel, da bi vključil svoj driver in ubil Arduino ali pa RPi.

Čas za ledice? :))

BigWhale ::

AndrejO je izjavil:

Čeprav, če signalizacija ne bi bila prava, potem tudi slave verjetno ne bi ničesar sprejel, da bi vključil svoj driver in ubil Arduino ali pa RPi.


Ja, o tem sem tudi jaz razmisljal, ne poznam interface-a tolk dobr, nisem pa sel gledat a je kaka linija po defaultu high.

Bi pa RPi verjetno prej crknil kot Arduino. Te male igracke so kr zilave. Jaz sem taksno napako naredil z RS-232...

"Hmm, mam USB to Searial, to lahk kr priklopim na RS-232."

Po cudezu je vse prezivelo. :)))

AndrejO ::

Sem sel pogledati dejansko specifikacijo za RS485 ... 0 je nad +200mV, 1 je pod -200mV. Če je imel oklopljen kabel (skupno maso) in običajen dvožilni half-duplex pristop, potem se ne bi smelo nič zgoditi. Če je bilo eno izmed napajanj izolirano, kabel pa je šel direktno na pin MCU-ja, pa je skurjen UART čisto možen rezultat.

Bolj banalna možnost je, da RS485 shield in knjižnica nista srečna skupaj in bo potrebno najti/nastaviti pravilen pin, ki bo preklapljal med oddajanjem in sprejemanjem.

Ergo ... zato je dobro pri takšnih embedded vprašanjih dodati tudi kakšno skico el. povezav. Vsaka malenkost šteje.

Zgodovina sprememb…

  • spremenil: AndrejO ()

simont ::

Mogoče za začetek prenos iz Windows GUI APP - Docklight na RPI - USB
Uporaba USB dongla na USB-RS485-WE enota
Kaj bi priporočali za command line utility ali python kodo da pošljem za test paket
01 10 90 00 00 04 08 01 00 00 00 00 00 00 00 B6 E7

AndrejO ::

simont je izjavil:

Mogoče za začetek prenos iz Windows GUI APP - Docklight na RPI - USB
Uporaba USB dongla na USB-RS485-WE enota
Kaj bi priporočali za command line utility ali python kodo da pošljem za test paket
01 10 90 00 00 04 08 01 00 00 00 00 00 00 00 B6 E7

Upam, da je to ta: https://www.ftdichip.com/Support/Docume...

Shema je na str. 11 in izgleda generično. RS485 transciever je ZT485E, ki ima (kot običajno) TX zvezan nazaj na RX. FT232 je tudi klasičen USB UART in glede na vezavo, bo na transcieverju sprejem vedno vključen, oddajanje pa se bo (glede na specifikacijo) vključilo en bit pred prvim bitom za pošiljanje in avtomatično izključilo, ko je poslan zadnji stop bit.

To pomeni, da je logika načeloma trivialna.

SPORT=/dev/ttyAMA___  <- tu vpišeš port.
stty -F ${SPORT} 9600 cs8 -cstopb -parenb  raw <- Nastaviš pravilne parametre za komunikacijo: hitrost, št. bitov, pariteta, št. stop bitov. Podani primer je za 9600N1. "raw" je zato, da onemogočiš medpomnilnik.
cat ${SPORT} > /tmp/input.bin  <- to zaženeš v enem terminalu
echo "01 10 90 00 00 04 08 01 00 00 00 00 00 00 00 B6 E7" | xxd -r -p > ${SPORT} <- s tem v drugem terminalu pošlješ podatke


Ko se pošiljanje konča + kakšna sekunda, prekineš cat in narediš
xxd /tmp/input.bin


V datoteki boš verjetno videl vse, kar si poslal (zakaj to pričakujem, je razvidno iz specifikacije za ZT485E) in, če imaš kabel pravilno zvezan (D+ na D+, D- na D-, da bo lažje imej vse na isti masi), boš moral videti tudi odgovor naprave.


Ah, pa še nekaj za BW ... vreči stran kakšno ATmego, me ne gane, vreči stran PC, bi me zelo ganilo. Zato je moje izbrano orodje za PC kar optično izoliran RS485 konverter. Verjetno so naokoli tudi cenejši, ampak ta je bil prvi, ki sem ga zagrabil in dela.

Zgodovina sprememb…

  • spremenil: AndrejO ()

BigWhale ::

AndrejO je izjavil:

Sem sel pogledati dejansko specifikacijo za RS485 ... 0 je nad +200mV, 1 je pod -200mV. Če je imel oklopljen kabel (skupno maso) in običajen dvožilni half-duplex pristop, potem se ne bi smelo nič zgoditi. Če je bilo eno izmed napajanj izolirano, kabel pa je šel direktno na pin MCU-ja, pa je skurjen


Sem sel gledat... Mal drugac dela, ce sem prav razumel dokumentacijo. +/-200mV je razlika med eno in drugo linijo. Na obeh linijah imas konstantno napetost, ki jo potem spreminjas. Ampak tle sva ze off-topic.

simont ::

AndrejO -> hvala za poslano (tudi ostalim), je premaknilo zadevo vsaj iz stališča sprejem oddaja in načina razmišljanja. Inverter posledično na tak način sprejme in odda povratno informacijo. Sedaj samo še porting na arduino ? Ali je paket "01 10 90 00 00 04 08 01 00 00 00 00 00 00 00 B6 E7" potrebno kakorkoli formatirati oz. kakšne so izkušnje glede tega ?

LP

AndrejO ::

simont je izjavil:

Ali je paket "01 10 90 00 00 04 08 01 00 00 00 00 00 00 00 B6 E7" potrebno kakorkoli formatirati oz. kakšne so izkušnje glede tega ?

Koliko imaš kaj izkušenj s programiranjem in branjem tehnične dokumentacije?

simont ::

Precej. Rad bi se izognil desetine iteracij kakšne tipe spremenljivk in katero knjižnico uporabiti v primeru Arduino kode glede na to, da smo preigrali v tej debati že nekaj neznank in predvidevam, da ti je verjetno tudi to vprašanje že jasno kako bi bilo najbolje reševati. Mogoče samo potrditev, da je softserial in byte tip spremenljivke prava pot ali kaj tretjega, saj modbus knjižnica očitno tukaj ni potrebna ali pa bo težava RTU zaradi binarnih paketov?

AndrejO ::

Kar bi potreboval je to, da ti firma plača ustrezno izobraževanje, da boš razumel zakaj tvoja vprašanja nimajo smisla. In to čisto resno.

Če se sprašuješ o "formatiranju" nekih podatkov oziroma nisi prepričan, če bo težava z RTU "zaradi binarni paketov", potem nekaterih osnov v programiranju še nimaš razčiščenih. Glede na to, da to delaš za denar, potem je najbolj pošteno, da ti izobraževanja plača tisti, ki ti že tako daje plačo. Če to delaš tudi za sebe, potem imaš na dnu nekaj predlogov, ki ne bodo rešili tvojega trenutnega problema, te bodo pa postavili na pravo pot.

Če ne veš katero knjižnico uporabiti, to pomeni, da v podjetju nimate nikakršnih izkušenj s tovrstnim delom, ti pa sedaj brez znanja (kaj šele izkušenj) izbiraš nekaj, kar bo definiralo vaš produkt ali produkte za naslednjih N let. Kar pojasni tvoja vprašanja, ni pa to dobra popotnica ne zate, ne za podjetje, ki bi lahko v tebe najprej investiralo, preden ti naloži takšno odgovornost.

Če se sprašuješ o podatkovnih tipih, potem tvoji izjavi o tem, da znaš že precej o programiranju, preprosto ni možno verjeti. O takšnih stvareh se pogovarjajo študenti na prvih urah programiranja. Kar je načeloma OK, ker smo vse enkrat bili začetniki. Ni pa OK, če se kot začetnik postaviš v vlogo strokovnjaka.


S konkretnim problemom ti zato lahko tako pomaga kdo drug, ki ga ne moti brezplačno svetovanje podjetjem pri njihovem produktnem razvoju.



-----------------------


Da pa ne bom samo bentil ... če te področje embedded prograpiranja dejansko zanima (strokovnjaki so v primerjavi z drugimi IT področju tudi med dobro plačanimi) in glede na do sedaj izkazano znanje tukaj, ti priporočam v branje in za izobraževanje:

Ker je veliko stvari v C ali C++ in, ker je embedded programiranje praktično sistemsko programiranje in zato, da se ne boš več nikoli spraševal "kateri tip spremenljivke uporabiti":
The C Programming Language, B. Kernighan in D. Ritchie

Ker embedded programiranje terja poznavanje strojne opreme na kateri se programska koda izvaja in zato, da se več ne boš spraševal o "formatiranju" podatkov:
Arhitektura računalniških sistemov, D. Kodek

Zato, da si pridobiš osnovno razumevanje o najpogostejših periferijah in nekaterih praktičnih rešitvah/pristopih v embedded sistemih:
Making Embedded Systems, E. White

Kar se tiče eksperimentiranja, praktično ves material za prve korake v embedded je dobavljiv v Sloveniji ali v Slovenijo ter hkrati dovolj poceni, da boš verjetno več plačal za knjige.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

merilec porabe toka

Oddelek: Elektrotehnika in elektronika
244959 (4206) fpbs
»

Siemens m35 - rs232 - AT commands

Oddelek: Mobilne tehnologije
233145 (2331) JanezovJanez
»

Kako na linuxu (Raspberry PI) prepričati NTP, da bo uporabil podatke iz GPS-a

Oddelek: Operacijski sistemi
202735 (2096) misek
»

Merjenje napetosti akumulatorja z Arduinom

Oddelek: Elektrotehnika in elektronika
449615 (8343) Red_Mamba
»

BSOD problem

Oddelek: Pomoč in nasveti
91723 (1381) Oktan

Več podobnih tem