====== Modbus TCP ==
Collected informations for using [[wp>Modbus]] on TCP/IP. Libmodbus is used as master on any Linux computer ([[Sheevaplug]]). Wago fieldbuscouplers [[http://www.wago.com/wagoweb/documentation/750/ger_manu/342/m034200d.pdf|750-342]] (or alternatively [[http://www.wago.com/wagoweb/documentation/750/ger_manu/841/m084100d.pdf|750-841]]) are used as slaves.
===== Modbus Command Overview ==
^ Code ^ Target ^ Count ^ Direction ^ Name in Spec ^ Libmodbus 3 fkt name ^ libmodbus 2 fkt name ^
| ''01 0x01'' | DO | many | read | Read Coils | ''modbus_read_bits'' | ''read_coil_status'' |
| ''02 0x02'' | DI | many | read | Read Discrete Inputs | ''modbus_read_input_bits'' | ''read_input_status'' |
| ''03 0x03'' | AO | many | read | Read Holding Registers | ''modbus_read_registers'' | ''read_holding_registers'' |
| ''04 0x04'' | AI | many | read | Read Input Register | ''modbus_read_input_registers'' | ''read_input_registers'' |
| ''05 0x05'' | DO | one | write | Write Single Coil | ''modbus_write_bit'' | ''force_single_coil'' |
| ''06 0x06'' | AO | one | write | Write Single Register | ''modbus_write_register'' | ''preset_single_register'' |
| ''15 0x0f'' | DO | many | write | Write Multiple Coils | ''modbus_write_bits'' | ''force_multiple_coils'' |
| ''16 0x10'' | AO | many | write | Write Multiple registers | ''modbus_write_registers'' | ''preset_multiple_registers'' |
| ''23 0x17'' | AI/AO | many | both | Wrt/Rd Multiple registers | ''modbus_write_and_read_registers'' | :?: |
Sources [[http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf|Spec]] [[http://libmodbus.org/site_media/html/libmodbus.html|Manpage]]
More information sources:
* http://www.anybus.de/technologie/modbustcp.shtml
* http://www.modbus.org/docs/PI_MBUS_300.pdf
* http://jamod.sourceforge.net/kb/protocol.html
===== Wago 750-342 ==
==== Setting the IP with bootp ==
Basic principle: The bootp client (750-342) sends its MAC address to the bootp server (eg. a slackware linux computer). The server in turn provides the client with an IP address.
Example: To provide the client host with the name ''etb-130'' who has the MAC address ''0030DE010A2C'' with the IP address ''192.168.132.130'' and an appropriate subnet mask, add the following line to ''/etc/bootptab'':
etb-130:ht=1:ha=0030DE010A2C:ip=192.168.132.130:sm=255.255.255.0
Then, on the server machine, start the bootp daemon by uncommenting the following line in ''/etc/inetd.conf''
bootps dgram udp wait root /usr/sbin/bootpd bootpd
...and restart the inetd:
/etc/rc.d/rc.inetd restart
Now connect the Client with the server eg over crosslink cable and boot the client.
The 750-342 fetches its IP from the bootp server only when bootp is enabled. Otherwise it uses the IP saved in its EEPROM. Pseudcode:
ipNumber= bootpEnabled ? getIpNumberFromBootpServer() : getIpNumberFromEeprom()
Web access to 750-342 is ''admin / wago''
See also: [[http://www.wago.com/wagoweb/documentation/750/ger_manu/841/m084100d.pdf|Wago manual]] p.82ff and [[man>bootptab]]
===== Libmodbus ==
==== Usage / Doc ==
See http://libmodbus.org/site_media/html/libmodbus.html
==== Installation ==
Download the [[http://github.com/downloads/stephane/libmodbus/libmodbus-3.0.2.tar.gz|source]] and use the [[http://think-deep.com/becki/slackbuilds/pack.php?n=libmodbus|Slack build script]].
The rest of this section is obsolete
Note: You could get the latest devel release with ''git clone http://github.com/stephane/libmodbus.git'', but this has no ''configure'' script, so we use the lataest stable release instead.
Download v 2.0.3 from [[http://libmodbus.org/download/|here]]
Libmodbus has the unpleasant behaviour, that it prints error messages to ''stdout'' instead of ''stderr''. If you plan to build your application like a filter which commuicates over ''stdin / stdout'' to the world, than you will get problems, in that libmodbus may interfere your protocoll or whatever with error messages. Therfore we patch the source a little bit and are writing error messages to ''stderr'' instead of ''stdout''. Look for the function ''error_treat'' in ''modbus/modbus.c'' and replace the ''printf'' function with ''fprintf'':
static void error_treat(modbus_param_t *mb_param, int code, const char *string)
{
printf("\nERROR %s (%d)\n", string, code);
static void error_treat(modbus_param_t *mb_param, int code, const char *string)
{
fprintf(stderr, "\nERROR %s (%d)\n", string, code);
Now do the usual ''./confiure; make; su; make install;''. This installs the following objects to ''/usr/local/'':
lib/libmodbus.so
lib/libmodbus.la
lib/libmodbus.so.2.0.0
lib/pkgconfig/modbus.pc
lib/libmodbus.so.2
include/modbus/modbus.h
Then do ''ldconfig'' to update the library system info.
===== Wago Adressing in Libmodbus ==
==== Bit-based access to digital IOs ==
* Bit-based function codes are # 1,2,5,15
* The first digital input and output bits have both address 0
* The 2nd digital input and output bits have both address 1
* Addressing of inputs and outputs are independent (ie. there exists DI 0 and DO 0)
* Each input/output bit consumes one member of the ''uint8_t dest[]'' array. I.e. each bit consumes one byte.
==== Register-based access to analog IOs ==
* Register-based (16bit) function codes are # 3,4,6,16
* The first analog input and output register have both address 0
* Contrary to the Wago manuals the 2nd analog input and output registers have address 1 :!:
==== Register-based access to digital IOs ==
* Access to digital inputs and outputs is also possible with the register-based function codes
* Digital input and output addresses are automatically appended after the analog addresses. This means the digital addresses are dependend of the number of the analog devices.
* Each digital IO consumes on //bit// in the ''uint16_t dest[]'' array