**Modbus** on jadaside protokoll, mille töötas 1979. aastal välja Modicon (nüüd Schneider Electric), kasutamaks seda oma programmeeritavas loogikakontrolleris (PLC). Aja jooksul on sellest oma lihtsuse tõttu saanud sideprotokollide tunnustatud standard ja on nüüdseks tavapäraselt saadaval võimalus tööstuslike elektroonikaseadmete ühendamiseks.

Ajalugu
-------

Aasta oli 1979, kui PLC tootja Modicon avalikustas Modbusi kommunikatsiooni liidese *multidrop*-võrgu jaoks baseerudes ülem/alam (inglise keeles *Master/slave*) võrguarhitektuuril. Informatsiooni vahetamine Modbusi võrguharude ühenduspunktide vahel saavutati sõnumitega. Tegu oli avatud standardiga, mis kirjeldas sõnumite edastamise struktuuri. Modbusi liidese füüsiline kiht oli vabalt valitav. Originaalne Modbusi liides kasutas RS-232 standardit, aga enamus hilisematest Modbusi teostustest kasutasid RS-485 sel põhjusel, et RS-485 võimaldas pikemaid vahemaid ja suuremaid kiirusi. Lühikese aja jooksul kogus Modbusi protokoll palju kuulsust ja üllatavalt kiiresti pärast protokolli väljatöötamist võttis suur arv tarnijaid oma seadmetes selle süsteemi kasutusele.

Modbusi protokollide arendamine ja uuendamine on toimunud alates aprillist 2004 Modbus Organizationi  poolt, kui Schneider Electric andis õigused üle sellele organisatsioonile.

Seadmed ja kommunikatsioon
--------------------------

Igale seadmele, mis jagab informatsiooni Modbusi kaudu, antakse unikaalne aadress. Seade, mis küsib informatsiooni, on Modbusi ülem (ingl *Modbus master*) ja seadmed, mis jagavad informatsiooni on Modbusi alamad (ingl *Modbus slaves*). Standardses Modbusi võrgus on üks ülem ja kuni 247 alamat, mille juures iga alam on määratud oma unikaalse alamaadressiga, mis varieerub vahemikus 1–247. Tavaliselt on ühes võrgus seadmeid umbes 240. Ülemal on samuti olemas volitused kirjutamaks informatsiooni alamatele.

Eksisteerib palju modemeid ja võrguväravaid, mis toetavad Modbusi, kuna see on väga lihtne protokoll ja tihtipeale seda ka kopeeritakse. Marginaalne osa neist on spetsiifiliselt valmistatud selle protokolli jaoks. Erinevad teostused kasutavad kas wireline-kaablitehnoloogiat, traadita infoedastust, nagu näiteks ISM band ja isegi lühisõnumite teenust (SMS) või üldist raadio-pakettandmeside teenust (GPRS). Tihti esinevad tüüpprobleemid on näiteks pikk latentsusaeg ja sünkroonimisega seotud probleemid.

Sõnumistruktuur
---------------

Modbusi teabevahetuse liides on ehitatud tuginedes teadetele (sõnumitele). Nende sõnumite vorming on eraldiseisev kasutatud füüsilisest liideset. RS232 standardiga kasutatakse samu sõnumeid, mis ka Mobdus/TCP Etherneti kaudu. Ühte ja sama protokolli saab kasutada sõltumata ühenduse tüübist. Tänu sellele tagab Modbus võimaluse uuendada tööstuslike võrkude riistvara struktuuri nõudmata selleks suuri muudatusi tarkvaras. Seade saab suhelda mitme Modbusi võrguharude ühenduspunktiga isegi juhul, kui nad on ühendatud erinevate liidesetüüpidega, ilma vajaduseta kasutada iga ühenduse jaoks erinevat protokolli.

Igal Modbusi sõnumil on identne struktuur. Igas sõnumis on neli erinevat baaselementi. Nende osade järgnevus on ühtne kõikide sõnumite puhul, et lihtsustada vastava Modbus teate sisu sõelumist. Vestlust alustatakse Modbusi võrgus alati ülema poolt. Ülem saadab sõnumi ja seejärel – olenevalt sõnumi sisust – alam aktiviseerub ja tegutseb vastavalt saadud teatele. Sõnumi adresseerimist kasutatakse selgitamaks, milline seade peab vastama saadetud sõnumile. Ülejäänud võrguharude ühenduspunktid, mis asuvad ka Modbusi võrgus, eiravad saadetud sõnumit juhul, kui aadressiväli ei vasta nende endi aadressile.

Modbusi sõnumi struktuur | Väli | Kirjeldus |
| --- | --- |
| **Seadme aadress** | Adressaadi aadress |
| **Funktsiooni kood** | Kood, mis määrab sõnumitüübi |
| **Andmed** | Andmejagu lisainformatsiooniga |
| **Veakontroll** | Numbriline kontrollväärtus testimaks teabevahetusvigade olemasolu |

Jadaedastuse režiimid
---------------------

Modbusi jadaühendused saavad kasutada kahte põhilist jadaedastuse režiimi, milleks on vastavalt ASCII ja RTU (*Remote terminal unit*). Jadaedastuse režiim jadasides määrab viisi, kuidas Modbusi sõnumeid kodeeritakse. Modbus/ASCII puhul on kõik sõnumid loetavas ASCII vormingus. Modbusi/RTU vorming kasutab binaarkodeerimist, mis muudab sõnumid vaatlejale loetamatuks, kuid vähendab iga teate mahukust, lubades sellega suurema hulga andmete vahetuse sama ajaühiku jooksul. Kõik ühe Modbusi võrgu segmendi võrguharude ühenduspunktid peavad kasutama sama jadaestastuse režiimi. Seade, mis on seadistatud kasutamaks Modbus/ASCII režiimi ei suuda mõista sõnumeid Modbusi/RTU režiimis ja ka vastupidi.

Modbus/ASCII puhul on kõik sõnumid kodeeritud kuueteistkümnendarvude väärtustena, esindatuna loetavate ASCII märkidena. Kodeerimises on kasutusel vaid märgid **0–9** ja **A–F**. Iga baidi informatsiooni jaoks läheb vaja kahte sidebaiti, kuna iga sidebait suudab määratleda kuueteistkümnendarvu süsteemis vaid 4 bitti. Modbus/RTU puhul vahendatakse andmeid binaarvormingus ja iga bait informatsiooni on kodeeritud ühe sidebaidiga.

Jadaühendustes ei saadeta Modbusi sõnumeid lihtvormingus. Need raamitakse, andmaks päringu vastuvõtjale lihtsa võimaluse sõnumi alguse ja lõpu tuvastamiseks. Kasutades Modbus/ASCII-d, võetakse kasutusele märgid, et määratleda raami algus ja lõpp. Koolonit (**:**) kasutatakse märgendamaks sõnumi algust. Modbus/RTU kasutab aga hoopis ajalisi *vaikushetki* sidevahetuse real, raamistamaks sõnumit.

Modbus/ASCII ja Modbus/RTU atribuudid |  | Modbus/ASCII | Modbus/RTU |
| --- | --- | --- |
| Märgid | ASCII **0–9** ja **A–F** | Kahendsüsteem **0–255** |
| Veakontroll | LRC (*Longitudinal Redundancy Check*) | CRC (*Cyclic Redundancy Check*) |
| Raami algus | Märk (**:**) | 3,5 märki *vaikust* |
| Raami lõpp | Märgid CR/LF | 3,5 märki *vaikust* |
| Tühimikud sõnumis | 1 sekund | 1,5 korda märgi pikkust |
| Algusbitt | 1 | 1 |
| Andmebitt | 7 | 8 |

Adresseerimine
--------------

Esmane informatsioonikild igas Modbusi sõnumis on adresseeritava aadress. See parameeter sisaldab ühe baidi jagu informatsiooni. Modbus/ASCII puhul on see kodeeritud kahe kuueteistkümnendarvu märgiga, Modbus/RTU puhul on kasutusel vaid üks bait. Kehtivad aadressid jäävad vahemikku 0–247. Väärtused 1–247 määratakse individuaalsetele Modbusi seadmetele ja väärtust 0 kasutatakse leviaadressina (*broadcast address*). Sõnumid, mis saadetakse viimasele aadressile aktsepteeritakse kõigi alamate poolt. Alam vastab alati Modbusi sõnumile. Sõnumile vastamise ajal kasutab alam sama aadressi, mida ülem kasutas päringu sooritamisel. Niimoodi saab ülem kindlaks teha, et seade reaalselt vastab päringule.

Modbusi seadme piires määratakse hoidvatele registritele, sisenditele ja väljunditele number vahemikus **1–10000**. Modbusi sõnumites kasutatakse aadresse väärtusega vahemikus **0–9999**. Kui on vaja näiteks lugeda väljundi väärtust (ehk *coil*) **18**, siis on vaja täpsustada väärtust **17** Modbusi päringusõnumis. Järgnev tabel näitab aadressivahemikke *coil*'idele, sisenditele ja hoidvatele registritele ja aadressi kalkuleerimise viisi Modbusi sõnumis, kui on antud ühiku reaalne aadress alamseadmes. 

Seadme ja Modbusi aadresside vahemikud | Seadme aadress | Modbus aadress | Kirjeldus |
| --- | --- | --- |
| **1–10000**\* | aadress – 1 | *Coils*(väljundid) |
| **10001–20000**\* | aadress – 10001 | Sisendid |
| **40001–50000**\* | aadress – 40001 | Hoidvad registrid |

\**Maksimaalne väärtus sõltub kasutatavast seadmest*

Funktsioonikoodid
-----------------

Teine parameeter, mis sisaldub igas Modbusi sõnumis on funktsioonikood. See määrab ära sõnumitüübi ja vastava tegevuse, mida nõutakse alama (*slave*) poolt. Vastav parameeter sisaldab ühte baiti informatsiooni. Modbus/ASCII juures on see kodeeritud kahe kuueteistkümnendarvuga, Modbus/RTU (*Remote Terminal Unit*) juures on kasutuses vaid üks bait. Kehtivad funktsioonikoodid jäävad vahemikku 1–255. Kõik Modbusi seadmed ei tunnusta sama komplekti funktsioonikoode, need varieeruvad. Järgnevas tabelis on ära toodud levinud funktsioonikoodid.

Levinud funktsioonikoodid | Kood | Kirjeldus |
| --- | --- |
| **01** | Read coil status |
| **02** | Read input status |
| **03** | Read holding registers |
| **04** | Read input registers |
| **05** | Force single coil |
| **06** | Preset single register |
| **07** | Read exception status |
| **15** | Force multiple coils |
| **16** | Preset multiple registers |
| **17** | Report Slave ID |

Rakendused
----------

Peaaegu kõikidel rakendustel on variatsioone võrreldes originaalse standardiga. Eri variandid ei pruugi ühilduda, sest tegu on teistsuguse tehnikaga või erinevate tarnijaga. Mõningad levinumatest variatsioonidest on:

### Andmetüübid

* Ujukomaarv IEEE
* 32-bitised täisarvud
* 8-bitised andmed
* Erinevatest elementidest koosnevad andmetüübid
* Bittide väljad täisarvudes
* Kordajad vahetamaks andmeid täisarvudeks/täisarvudest. 256, 10, 100, 1000, 10 000 jne

### Protokolli laiendused

* 16-bitised alamaadressid
* 32-bitine andmepaketi suurus (1 aadress = 32 bitti andmeid tagastatud.)
* Sõnaga ära vahetatud andmed

Viited
------

1. ↑  Bill Drury (2009). "Control Techniques Drives and Controls Handbook" (pdf). *2nd edition* (inglise). 508-: Institution of Engineering and Technology.`{{netiviide}}`: CS1 hooldus: koht sisaldab numbrit (link) CS1 hooldus: tundmatu keel (link)
2. ↑  w3.usa.siemens.com. "Modbus Information" (pdf) (inglise). lk 2.`{{netiviide}}`: CS1 hooldus: koht sisaldab numbrit (link)
3. ↑  Modbus Organization, Inc. "Modbus home page" (inglise).
4. ↑  www.simplymodbus.ca (2013). "Simply Modbus" (inglise).
5. 1 2  w3.usa.siemens.com. "Modbus Information" (pdf) (inglise). lk 7.`{{netiviide}}`: CS1 hooldus: koht sisaldab numbrit (link)
6. 1 2  w3.usa.siemens.com. "Modbus Information" (pdf) (inglise). lk 6.`{{netiviide}}`: CS1 hooldus: koht sisaldab numbrit (link)
7. 1 2  w3.usa.siemens.com. "Modbus Information" (pdf) (inglise). lk 5.`{{netiviide}}`: CS1 hooldus: koht sisaldab numbrit (link)
8. 1 2  w3.usa.siemens.com. "Modbus Information" (pdf) (inglise). lk 8.`{{netiviide}}`: CS1 hooldus: koht sisaldab numbrit (link)

Välislingid
-----------

* Simply Modbus
* Modbus Organization