Differences
This shows you the differences between two versions of the page.
hu:arduino:modbus [2022/04/21 15:02] |
hu:arduino:modbus [2022/04/21 15:02] () |
||
---|---|---|---|
1: | 1: | ||
+ | ====== Arduino - Modbus TCP/RTU ====== | ||
+ | ===== Modbus kommunikáció ===== | ||
+ | A Modbus protokoll kialakulása szorosan összefonódott az első PLC születésével. Az első PLC, a " | ||
+ | A Modbus két hordozóközegen bukkan fel a leggyakrabban, | ||
+ | |||
+ | {{ wiki: | ||
+ | |||
+ | A Modbus egy monomaster hálózatot vagy pont-pont kapcsolatot feltételez. Mindkét esetben egy master és legalább egy slave szükséges a kommunikációhoz. A Modbus RTU csak egy master egység jelenlétét teszi lehetővé. | ||
+ | |||
+ | ===== Modbus master / slave ===== | ||
+ | Fontos megjegyezni, | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | ===== Multimaster ===== | ||
+ | A Modbus hálózaton egyszerre több master is jelen lehet (multimaster), | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | A TCP esetén az RTU-t telepítették a TCP-re, így az ethernetes hálózatok összes előnyét sikerült beágyazni a Modbusba. Mivel az etherneten az állomások címe nagyságrendekkel magasabb, mint az RTU/ | ||
+ | |||
+ | ===== Modbus funkciókódok ===== | ||
+ | ^Function Code^Register Type| | ||
+ | |1|Read Coil| | ||
+ | |2|Read Discrete Input| | ||
+ | |3|Read Holding Registers| | ||
+ | |4|Read Input Registers| | ||
+ | |5|Write Single Coil| | ||
+ | |6|Write Single Holding Register| | ||
+ | |15|Write Multiple Coils| | ||
+ | |16|Write Multiple Holding Registers| | ||
+ | |||
+ | ====== Modbus RTU ====== | ||
+ | Az RS-485 technikai jellemzői: | ||
+ | ^ ^RS-485| | ||
+ | ^Működési mód|[[hu: | ||
+ | ^Meghajtók és vevők\\ száma egy vonalon|32 állomás szegmensenként| | ||
+ | ^Adatátvitel módja|[[hu: | ||
+ | ^Adatátvitel|[[hu: | ||
+ | ^Max. kábelhosszúság|1200 m| | ||
+ | ^Max. adatátvitel\\ 12 m\\ 1200 m|\\ 35 Mbps\\ 100 kbps| | ||
+ | ^Max. jelváltozási\\ sebesség (slew rate)|n.a.| | ||
+ | ^Vevő bemeneti\\ ellenállás|≧ 12 kΩ| | ||
+ | ^Meghajtó terhelés-\\ impedancia|54 Ω| | ||
+ | ^Vevő " | ||
+ | ^Vevő feszültségszint|--7..12 V| | ||
+ | ^Meghajtó kimenő\\ feszültség max.|--7..12 V| | ||
+ | ^Meghajtó kimenő\\ feszültség min. (terheléssel)|±1.5 V| | ||
+ | ^Meghajtó kimeneti\\ rövidzárási áram limit|150 mA tól Test felé\\ 250 mA Vcc felé| | ||
+ | ^Vevő hiszterézis|50 mV| | ||
+ | |||
+ | Az RS-485 egy szimmetrikus átviteli mód. Az EIA-485 megnevezés azonos az RS-485 standarddal. A 32 egység / szegmens elvi határon belül az adó és vevő egységek száma szabadon variálható (multipoint). | ||
+ | |||
+ | A maximum 32 egység / szegmens határ az előre definiált meghajtó terhelés (Unit Load [**UL**]) mellett érvényes, ami az RS-485 esetében 12 kΩ. Az egységek száma emelhető, ha a meghajtó terhelés csökken. Jellemzően ezt - az UL-t - a negyedére (48 kΩ) vagy nyolcadára (96 kΩ) szokás csökkenteni, | ||
+ | |||
+ | Az RS-485 120 Ω vonalimpedanciát tételez fel a vezetéktől. A szegmens két végét 680 Ω-os 120W-os (10%, 1/2 watt) véglezárókkal szükséges zárni. | ||
+ | |||
+ | === RTU/ASCII === | ||
+ | A slave-ek száma nem haladhatja meg a 246-ot, címzésük az 1..247-es tartományban történhet. A gyakorlat szerint egy szegmensben 32 állomás lehet, és csak repeater-ekkel bővíthető a hálózat. A 0. címmel broadcast üzeneteket lehet küldeni, amennyiben ez a művelet logikai szinten nincs korlátozva. A master jellemzően az 1. címet szokta megkapni, Modbus RRU egy hálózat-szegmensben csak egy master-t enged meg. | ||
+ | |||
+ | === RS-485 jelráta === | ||
+ | Az RS-485-nek nincs definiálva maximális hossz, de jellemzően a jeleket 1200 méter távolságig tudja továbbítani, | ||
+ | |||
+ | {{wiki: | ||
+ | |||
+ | === RS-485 jelszintek === | ||
+ | {{wiki: | ||
+ | |||
+ | A meghajtó kimenő feszültsége +12V..-7V tartományban kell, hogy maradjon. A +0.2V..-0.2V a holtsáv. A +0.2V..+6V tartomány a vevő oldalon a logikai " | ||
+ | |||
+ | === RS-485 half duplex kapcsolás === | ||
+ | {{wiki: | ||
+ | |||
+ | === RS-485 full duplex kapcsolás === | ||
+ | {{wiki: | ||
+ | |||
+ | === RS-485 / Modbus RTU kapcsolás === | ||
+ | A Modbus RTU-hoz jellemzően a félduplex vezetékezést szokás használni, így három vezetéket tartalmaz az átvitel D+, D- és GND. | ||
+ | A vezetékek feszültségszintjeit ellenállásokkal szokás stabilizálni (a puulup, pulldown esetén a lenti ellenállás a minimális érték, ez akár pár kΩ is lehet): | ||
+ | |||
+ | {{: | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | === Arduino Modbus RTU könyvtárak === | ||
+ | |||
+ | Modbus RTU slave: https:// | ||
+ | Modbus RTU slave RS-485: https:// | ||
+ | Modbus RTU master: https:// | ||
+ | Modbus RTU ESP8266: https:// | ||
+ | ModbusConfig ESP8266/ | ||
+ | |||
+ | ===== MAX485 modul ===== | ||
+ | A MAX 485 modul egy egyszerű csatlakozási lehetőséget kínál az Arduino oldalról a Modbus RTU hálózathoz. A modul viszonylag egyszerűen csatolható az Arduinokhoz: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | == Vezetékezés == | ||
+ | {{: | ||
+ | |||
+ | |Pin|Leírás| | ||
+ | |Vcc|5V DC| | ||
+ | |A|A+ Modbus| | ||
+ | |B|B- Modbus| | ||
+ | |GND|GND| | ||
+ | |RO|receiver output (Rx)| | ||
+ | |RE|Receiver enable| | ||
+ | |DE|driver enable| | ||
+ | |DI|driver input (Tx)| | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | {{ : | ||
+ | ===== RS-485 shield ===== | ||
+ | Az RS485-Shield kibővítheti az Arduinót egy RS-485 interfésszel. | ||
+ | Az Arduinók többsége csak egy UART soros porttal van ellátva, ennek a funkcióit bővíti ki (cseréli le) ez a shield RS485-re. | ||
+ | |||
+ | A bővítmény az Arduino D0-D7 közötti portjait tudja az RS-485-re " | ||
+ | |||
+ | **A modbus shield részei:** | ||
+ | |||
+ | {{: | ||
+ | |||
+ | * 1: címkijelölő port, a serialhoz D0 az RX, a D1 a TX | ||
+ | * 2: kommunikációs jellemző, érdemes TX_CTRL-en hagyni | ||
+ | * 3: a kommunikáció jelzése: ha felváltva néha felvillan, nyertünk | ||
+ | * 4: a Modbus csatlakozók, | ||
+ | * 5: tápfeszültség kiválasztása, | ||
+ | |||
+ | A board mind Modbus Slave mind Master funkcióval is felruházható. Ebben az esetben javaslom ezeknek a libeknek az alkalmazását: | ||
+ | |||
+ | * ArduinoRS485.h : https:// | ||
+ | * ArduinoModbus.h : https:// | ||
+ | |||
+ | ==== Modbus slave példaprogram ==== | ||
+ | * a D8 portra kötöttem egy LEDet a 2.regiszter állapotjelzésére (ha nem nulla, világít a LED) | ||
+ | * a D4 portra egy DS18B20 hőmérséklet szenzor onewire kommunikációval, | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | /* | ||
+ | OB121 Modbus slave example, 2021. Vamos Sandor | ||
+ | | ||
+ | reg 0: life register | ||
+ | reg 1: temperature (*100) | ||
+ | reg 2: led on/off | ||
+ | reg 3: copy to reg 4 | ||
+ | reg 4: copy from reg 3 | ||
+ | */ | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // Data wire is plugged into port 4 | ||
+ | #define ONE_WIRE_BUS 4 | ||
+ | |||
+ | // Setup a oneWire instance to communicate with any OneWire devices | ||
+ | OneWire oneWire(ONE_WIRE_BUS); | ||
+ | |||
+ | // Pass our oneWire reference to Dallas Temperature. | ||
+ | DallasTemperature sensors(& | ||
+ | |||
+ | uint8_t sensor1[8] = { 0x28, 0x20, 0x54, 0x29, 0x05, 0x00, 0x00, 0xF4 }; //copied from the address scanner | ||
+ | |||
+ | float tempSensor1; | ||
+ | uint16_t reg0, reg1, reg2, reg3, reg4; | ||
+ | bool ledsta; | ||
+ | const int ledPin = LED_BUILTIN; | ||
+ | |||
+ | void setup() { | ||
+ | sensors.begin(); | ||
+ | Serial.begin(9600); | ||
+ | |||
+ | // start the Modbus RTU server, with (slave) id 1 | ||
+ | if (!ModbusRTUServer.begin(1, | ||
+ | while (1); | ||
+ | } | ||
+ | |||
+ | // configure the LED | ||
+ | pinMode(8, OUTPUT); | ||
+ | digitalWrite(8, | ||
+ | |||
+ | // configure Holding Registers from address 0x00 | ||
+ | ModbusRTUServer.configureHoldingRegisters(0x00, | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | sensors.requestTemperatures(); | ||
+ | tempSensor1 = sensors.getTempC(sensor1); | ||
+ | | ||
+ | // poll for Modbus RTU requests | ||
+ | ModbusRTUServer.poll(); | ||
+ | |||
+ | reg1 = (word)(tempSensor1*100); | ||
+ | reg0++; | ||
+ | |||
+ | ModbusRTUServer.holdingRegisterWrite(0, | ||
+ | ModbusRTUServer.holdingRegisterWrite(1, | ||
+ | reg2 = ModbusRTUServer.holdingRegisterRead(2); | ||
+ | reg3 = ModbusRTUServer.holdingRegisterRead(3); | ||
+ | ModbusRTUServer.holdingRegisterWrite(4, | ||
+ | // read the current value of the coil | ||
+ | //int coilValue = ModbusRTUServer.coilRead(0x00); | ||
+ | | ||
+ | if (reg2 == 0) { | ||
+ | | ||
+ | digitalWrite(8, | ||
+ | } else { | ||
+ | | ||
+ | digitalWrite(8, | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ |