PLC/RTU
A Programmable Logic Controller, PLC or Programmable Controller is a digital computer used for automation of electromechanical processes, such as control of machinery on factory assembly lines, amusement rides, or light fixtures. PLCs are used in many industries and machines. http://en.wikipedia.org/wiki/Programmable_logic_controller
A remote terminal unit (RTU) is a microprocessor-controlled electronic device that interfaces objects in the physical world to a distributed control system or SCADA (supervisory control and data acquisition) system by transmitting telemetry data to a master system, and by using messages from the master supervisory system to control connected objects.[1] Another term that may be used for RTU is remote telemetry unit. http://en.wikipedia.org/wiki/Remote_Terminal_Unit
Arduino Modbus
This setup can turn your Arduino into a PLC or RTU like device that can communicate via the Modbus protocol.There are a lot of arduino modbus libraries out there however this is the one that I love, it just works. It can also be easily extended to include more internal bits or holding registers to return internal data, counters, scaled values, or WHATEVER YOU WANT!
Demonstration
How to build it!
Resources
Forum post on the Arduino website http://forum.arduino.cc/index.php?topic=150181.0
Where to get the library http://code.google.com/p/arduino-modbus-slave/downloads/detail?name=MODBUS.zip&can=2&q=
My blog post on building the accompanying Mango M2M HMI https://electronhacks.com/2014/04/afordable-arduino-modbus-plc-or-rtu/?utm_medium=facebook&utm_source=twitterfeed
Code
#include <modbus.h> #include <modbusDevice.h> #include <modbusRegBank.h> #include <modbusSlave.h> /* PINS Add more registers if needed Digital input pins 2,3,4,5,6,7 Digital output pins 8,9,12,13 Analog output pins 10,11 (PWM) Analog input pins 0,1,2,3,4,5 */ modbusDevice regBank; modbusSlave slave; int AI0,AI1,AI2,AI3,AI4,AI5; void setup() { regBank.setId(10); ///Set Slave ID //Add Digital Input registers regBank.add(10002); regBank.add(10003); regBank.add(10004); regBank.add(10005); regBank.add(10006); regBank.add(10007); // Add Digital Output registers regBank.add(8); regBank.add(9); regBank.add(12); regBank.add(13); //Analog input registers regBank.add(30001); regBank.add(30002); regBank.add(30003); regBank.add(30004); regBank.add(30005); regBank.add(30006); //Analog Output registers regBank.add(40010); regBank.add(40011); slave._device = ®Bank; slave.setBaud(9600); pinMode(2,INPUT); pinMode(3,INPUT); pinMode(4,INPUT); pinMode(5,INPUT); pinMode(6,INPUT); pinMode(7,INPUT); pinMode(8,OUTPUT); pinMode(9,OUTPUT); pinMode(12,OUTPUT); pinMode(13,OUTPUT); } void loop(){ while(1){ //Digital Input byte DI2 = digitalRead(2); if (DI2 >= 1)regBank.set(10002,1); if (DI2 <= 0)regBank.set(10002,0); byte DI3 = digitalRead(3); if (DI3 >= 1)regBank.set(10003,1); if (DI3 <= 0)regBank.set(10003,0); byte DI4 = digitalRead(4); if (DI4 >= 1)regBank.set(10004,1); if (DI4 <= 0)regBank.set(10004,0); byte DI5 = digitalRead(5); if (DI5 >= 1)regBank.set(10005,1); if (DI5 <= 0)regBank.set(10005,0); byte DI6 = digitalRead(6); if (DI6 >= 1)regBank.set(10006,1); if (DI6 <= 0)regBank.set(10006,0); byte DI7 = digitalRead(7); if (DI7 >= 1)regBank.set(10007,1); if (DI7 <= 0)regBank.set(10007,0); //Digital output int DO8 = regBank.get(8); if (DO8 <= 0 && digitalRead(8) == HIGH)digitalWrite(8,LOW); if (DO8 >= 1 && digitalRead(8) == LOW)digitalWrite(8,HIGH); int DO9 = regBank.get(9); if (DO9 <= 0 && digitalRead(9) == HIGH)digitalWrite(9,LOW); if (DO9 >= 1 && digitalRead(9) == LOW)digitalWrite(9,HIGH); int DO12 = regBank.get(12); if (DO12 <= 0 && digitalRead(12) == HIGH)digitalWrite(12,LOW); if (DO12 >= 1 && digitalRead(12) == LOW)digitalWrite(12,HIGH); int DO13 = regBank.get(13); if (DO13 <= 0 && digitalRead(13) == HIGH)digitalWrite(13,LOW); if (DO13 >= 1 && digitalRead(13) == LOW)digitalWrite(13,HIGH); //Analog input ***READ Twice deliberately AI0 = analogRead(0); delay(10); AI0 = analogRead(0); regBank.set(30001, (word) AI0); delay(10); AI1 = analogRead(1); delay(10); AI1 = analogRead(1); regBank.set(30002, (word) AI1); delay(10); AI2 = analogRead(2); delay(10); AI2 = analogRead(2); regBank.set(30003, (word) AI2); delay(10); AI3 = analogRead(3); delay(10); AI3 = analogRead(3); regBank.set(30004, (word) AI3); delay(10); AI4 = analogRead(4); delay(10); AI4 = analogRead(4); regBank.set(30005, (word) AI4); delay(10); AI5 = analogRead(5); delay(10); AI5 = analogRead(5); regBank.set(30006, (word) AI5); delay(10); //Analog output word AO10 = regBank.get(40010); analogWrite(10,AO10); delay(10); word AO11 = regBank.get(40011); analogWrite(11,AO11); delay(10); slave.run(); } }