Modbus hoe functie op slave te triggeren

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Nu online
Voor mijn project gebruik ik een raspberry pi (master) en een aantal arduino slaves.

Ik vanuit de master de slaves bepaalde functies laten uitvoeren. Om te communiceren gebruik ik modbus.
Momenteel kan de raspberry pi via het modbus protocol lezen en schrijven in de registers van de arduino.

Gezien modbus voorgedefinieerde functies heeft, ben ik op zoek naar de juiste manier om de slave een actie uit te laten voeren.

Mijn huidige (relevante) implementatie op de slave is als volgt :

code:
1
2
3
4
5
6
7
8
#include <SimpleModbusSlave.h>
void loop() {
  modbus_update();
  if(holdingRegs[1] != 0) { //Action received
    run_function()
    holdingRegs[1] =0
  }
}


Vanaf de pi kan ik dus in register 1 schrijven, wat zorgt dat er code getriggerd word.

Python:
1
2
3
4
import minimalmodbus
instrument = minimalmodbus.Instrument(....)
instrument.mode = minimalmodbus.MODE_RTU 
instrument.write_register(1,1)


Bovenstaande code gebruikt modbus functie code 1 om een single coil te schrijven.
Mbv functie 16 kan ik paramters verzenden.

Welke modbus functie is bedoeld om de slave een actie uit te laten voeren?
Een register blijven pollen voelt een beetje vreemd.

Lost In Music

Beste antwoord (via Sgrovert op 12-03-2018 23:53)


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Je kunt er over discussieren of Modbus het meest geschikte protocol is: feit is wel dat het door zijn eenvoud en open karakter nog ondersteund wordt door de bakker op de hoek.

Sterker, 6.19 ( 0x2B) Encapsulated Interface Transport, alhoewel vrij exotisch, definieert eigenlijk wat jij aan het doen bent : een specifieke functie encapsulaten in een modbus transactie.

Daarnaast legt modbus niet vast wat de bitjes in je registers betekenen : dat is geheel implementatie afhankelijk.

Jouw implementatie is op zich zo gek nog niet, ik zou alleen wel een speciale functiecode gebruiken zodat het duidelijk is dat je iets aan het doen bent waat afwijkt van de reguliere functies.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Alle reacties


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Sgrovert schreef op woensdag 28 februari 2018 @ 18:39:
Voor mijn project gebruik ik een raspberry pi (master) en een aantal arduino slaves.

Ik vanuit de master de slaves bepaalde functies laten uitvoeren. Om te communiceren gebruik ik modbus.
Momenteel kan de raspberry pi via het modbus protocol lezen en schrijven in de registers van de arduino.

Gezien modbus voorgedefinieerde functies heeft, ben ik op zoek naar de juiste manier om de slave een actie uit te laten voeren.

Mijn huidige (relevante) implementatie op de slave is als volgt :

code:
1
2
3
4
5
6
7
8
#include <SimpleModbusSlave.h>
void loop() {
  modbus_update();
  if(holdingRegs[1] != 0) { //Action received
    run_function()
    holdingRegs[1] =0
  }
}


Vanaf de pi kan ik dus in register 1 schrijven, wat zorgt dat er code getriggerd word.

Python:
1
2
3
4
import minimalmodbus
instrument = minimalmodbus.Instrument(....)
instrument.mode = minimalmodbus.MODE_RTU 
instrument.write_register(1,1)


Bovenstaande code gebruikt modbus functie code 1 om een single coil te schrijven.
Mbv functie 16 kan ik paramters verzenden.

Welke modbus functie is bedoeld om de slave een actie uit te laten voeren?
Een register blijven pollen voelt een beetje vreemd.
Modbus kent niet zoiets als RPC (Remote Procedure Calls), als dat is wat je bedoeld.
Als je Modbus aan het gebruiken bent puur om functies aan de remote kant aan te roepen dan is Modbus niet het meest voor de hand liggende communicatieprotocol.

Om bij jouw implementatie te blijven; ik zou meer in de richting van 'operation modes registers' gaan denken met bijbehorende parameters in plaats van een register te pollen en direct weer te resetten.

Acties:
  • 0 Henk 'm!

  • Alain
  • Registratie: Oktober 2002
  • Niet online
Modbus is juist bedoeld om data op polling basis uit te wisselen. Een client leest of schrijft data van of naar een server.

Het lijkt erop dat jij wilt dat de server data naar de client schrijft. Moet je server dus niet een client zijn?

You don't have to be crazy to do this job, but it helps ....


Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Nu online
Ik heb straks 10 slaves en 1 master.
De master moet altijd de communicatie initieren, zodat de communicatie van de slaves niet door elkaar gaat lopen. Hierbij zijn voor de master read and write functions gedefineerd.

Gezien het volgende stukje op wikipedia :
Wikipedia: Modbus


En dan vooral code 5 "Acknowledge" en code 6 "Slave Device Busy" lijkt het er sterk of dat het de bedoeling is dat de slave code gaat uitvoeren.

Met mijn huidige implementatie uit de op vermoed ik echter dat als mijn slave busy is, er momenteel altijd een timeout zal optreden. Gedurende het uitvoeren van mijn functie word er namelijk geen nieuwe call naar modbus_update() gemaakt.

Vandaar dat ik op zoek ben naar een betere implementatie
EddoH schreef op donderdag 1 maart 2018 @ 13:45:
[...]
Modbus kent niet zoiets als RPC (Remote Procedure Calls), als dat is wat je bedoeld.
Als je Modbus aan het gebruiken bent puur om functies aan de remote kant aan te roepen dan is Modbus niet het meest voor de hand liggende communicatieprotocol.
Ik communiceer over en rs485 bus. Mocht je een geschikter protcoll weten, graag.
Dit is namelijk de eerste keer dat ik een dergelijk systeem bouw.

[ Voor 24% gewijzigd door Sgrovert op 01-03-2018 20:44 ]

Lost In Music


Acties:
  • 0 Henk 'm!

Verwijderd

Modbus is een protocol uit de jaren 70. Het is ook een zeer eenvoudig protocol.

Het kan over RS485, of over TCP/IP en ook UDP.

Ben je van plan om Modbus protocol zelf te implementeren of echt alleen te gebruiken? Er zijn immers gewoon bibliotheken voor praktisch echt alles betreft Modbus, en dus ook Arduino.

Zoek maar eens op "modbus RTU arduino".
Video uitleg met arduino die praat met wago PLC: YouTube: Arduino Modbus RTU Slave Example

En dit is beter als wikipedia: http://www.simplymodbus.ca/FAQ.htm waar modus uitgelegd is.

Een slave is vaak meer een "houder" van een stuk geheugen waar de master data in manipuleert. (Vandaar ook holding registers) Intern in de slave lees je de data uit deze registers functiecode 3 of coils met functiecode 1 bijvoorbeeld.

Slaves kunnen niet met elkaar praten. En als je meerdere slaves aan een RS485 lijntje hebt hangen ga je ze addresseren met een ID.

Registers zijn altijd 16 bits dus wil je daar grotere getallen uit halen moet je dit dus opsplitsen e.d.
In de praktijk gebruik ik praktisch altijd functiecode 3 voor het uitlezen van de slave register, en functiecode 16 om de registers van een slave te schrijven vanuit de master. Waarom coils gebruiken als je gewoon bits kan uitlezen uit een 16 bits word. Vandaar dat ik die nooit gebruik.

Bij TCP/IP heet het Server(slave) en Client(master), waarbij de server dus de "data" host als het ware.

Dus als je een slave een actie wil laten uitvoeren moet je in de slave dus code maken die dus continu zijn eigen variabelen pollt. En vanuit de master ga je met FC16 dus deze register schrijven.

[ Voor 67% gewijzigd door Verwijderd op 01-03-2018 21:44 ]


Acties:
  • 0 Henk 'm!

  • Alain
  • Registratie: Oktober 2002
  • Niet online
Bij Modbus RTU praat je over een master die met slaves communiceert.
Bij Modbus TCP praat je over een client die met servers communiceert.
Sgrovert schreef op donderdag 1 maart 2018 @ 20:42:
Ik heb straks 10 slaves en 1 master.
De master moet altijd de communicatie initieren, zodat de communicatie van de slaves niet door elkaar gaat lopen. Hierbij zijn voor de master read and write functions gedefineerd.
Dat gaat prima. De slave controleert zijn eigen adres en hoeft ervoor geen poll te doen.
En dan vooral code 5 "Acknowledge" en code 6 "Slave Device Busy" lijkt het er sterk of dat het de bedoeling is dat de slave code gaat uitvoeren.
Dit zijn exception codes. Die vertellen je dat er iets mis gaat. Respectievelijk: "Ik probeer je te helpen, maar het is nogal druk" en "Het is te druk, dus ik kan je niet helpen".
Met mijn huidige implementatie uit de op vermoed ik echter dat als mijn slave busy is, er momenteel altijd een timeout zal optreden.
Nee. De communicatie is goed gegaan. Het apparaat dat de data moet verwerken is echter te druk om je data te verwerken. Je zal het opnieuw moeten proberen.
Ik communiceer over en rs485 bus. Mocht je een geschikter protcoll weten, graag.
Dit is namelijk de eerste keer dat ik een dergelijk systeem bouw.
Wat je wilt kan waarschijnlijk wel met modbus, maar daar is het niet echt voor bedoeld. Wat voor protocollen heb je beschikbaar?

You don't have to be crazy to do this job, but it helps ....


Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Nu online
Verwijderd schreef op donderdag 1 maart 2018 @ 21:26:
Ben je van plan om Modbus protocol zelf te implementeren of echt alleen te gebruiken? Er zijn immers gewoon bibliotheken voor praktisch echt alles betreft Modbus, en dus ook Arduino.
Ik gebruik voot arduino momenteel de SimpleModbusSlave library. Momenteel ben ik niet op zoek naar de library die de juiste functies ondersteund, maar naar de theorie hoe het geimplementeerd moet worden. Zodra ik weet welke functies het best geschikt zijn, ga ik op zoek naar een library die deze ondersteund.
Dus als je een slave een actie wil laten uitvoeren moet je in de slave dus code maken die dus continu zijn eigen variabelen pollt. En vanuit de master ga je met FC16 dus deze register schrijven.
Dat is idd de implementatie die ik zelf bedacht had. Ik vind dit echter niet de meeste elegante methode.
Knuffelbeer schreef op donderdag 1 maart 2018 @ 22:18:
Dit zijn exception codes. Die vertellen je dat er iets mis gaat. Respectievelijk: "Ik probeer je te helpen, maar het is nogal druk" en "Het is te druk, dus ik kan je niet helpen".
ik schrijf zelf de code op de slave. Ik zou graag dit soort exceptions genereren, maar met de inplementatie uit de op, word de modbus_update() functie niet gecalled tijdens het uitvoeren van "run_function()". Ik heb het nog niet getest, maar ik heb het vermoeden dat ik een timeout zal krijgen, ipv de juiste exception.
Wat je wilt kan waarschijnlijk wel met modbus, maar daar is het niet echt voor bedoeld. Wat voor protocollen heb je beschikbaar?
Ik heb een seriele verbinding (over rs485 2 aders) beschikbaar.
Elk protocol dat seriele communicatie (rx tx) en een write enable pinondersteund is dus beschikbaar.
Ik heb in mijn hardware namelijk geen automatische write enable gebouwd, en trigger deze via arduino pin 2.

[ Voor 36% gewijzigd door Sgrovert op 03-03-2018 02:10 ]

Lost In Music


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Je kunt er over discussieren of Modbus het meest geschikte protocol is: feit is wel dat het door zijn eenvoud en open karakter nog ondersteund wordt door de bakker op de hoek.

Sterker, 6.19 ( 0x2B) Encapsulated Interface Transport, alhoewel vrij exotisch, definieert eigenlijk wat jij aan het doen bent : een specifieke functie encapsulaten in een modbus transactie.

Daarnaast legt modbus niet vast wat de bitjes in je registers betekenen : dat is geheel implementatie afhankelijk.

Jouw implementatie is op zich zo gek nog niet, ik zou alleen wel een speciale functiecode gebruiken zodat het duidelijk is dat je iets aan het doen bent waat afwijkt van de reguliere functies.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1