Inductive Automation IIOT recently announced the release of Ignition Edge–a new offering of their Ignition platform as an edge of network resource. The new licensing model offers a stripped down version of Ignition for edge of network HMI applications for about $1000. Consumers can add on MQTT and Store and Forward–to integrate the edge of network gateway with a central enterprise gateway–for a few hundred dollars more. This announcement motivated me to put together a quick demo of Ignition using the Cirrus Link MQTT modules, a Raspberry Pi, and ESP8266 Arduino and Kepserver IOT Gateway.
The goal here is to help interested developers and end users quickly put together an MQTT Ignition environment to develop in… the process is easy, painless and a lot of fun.
This post is a companion to a comprehensive video we released on Wednesday 3/16/17. You can view the video here.
Steps:
- Install Mosquitto on Raspberry Pi
- Pi will be our broker in this example
- Install MQTT Spy on Windows
- MQTT Spy will be a publisher and subscriber
- Setup ESP8266 Arduino
- Arduino will read an LM35 temperature sensor and publish two topics
- Intellic/Pyramid/Temp
- outTopic
- Arduino will read an LM35 temperature sensor and publish two topics
- Install and Setup the Cirrus Link MQTT Modules in Ignition
- Install and Setup Kepserver IOT Gateway
- Build a test window and play around
Step 1. Install Mosquitto on Raspberry Pi
The best instructions I found for installing Mosquitto were here.
- Install Mosquitto
- Stop the server
- Update Mosquitto.conf
- Restart server
- Open a new terminal and subscribe to a topic
- mosquitto_sub -d -t hello/world
- Open another terminal and publish to the topic
- mosquitto_pub -d -t hello/world -m ‘Test’
- Revel in your glory… you just set up a Raspberry Pi3 as an MQTT Broker, subscribed to and published to a topic!
Step 2. Install MQTT-Spy on Windows
Documentation for MQTT-Spy are here. MQTT-Spy will be used to publish and subscribe to topics from one of our servers. Essentially, we use it in this demo as another agent to show the versatility of MQTT-Spy.
- Download MQTT-Spy
- Run the jar
- Setup a connection with the broker (in our case, 192.168.0.33:1883)
- Use hashtag to subscribe to all topics
- Revel in your glory… you just set up MQTT-Spy to talk to your broker!
Step 3. Setup the ESP8266 Arduino with LM35 Temperature Sensor
Documentation on the ESP8266 can be found here.
- Wire up the LM35 to A0 (ADC) analog in
- Open up the Arduino IDE and use the code below (add in your SSID and Password and your broker IP address).
/* Basic ESP8266 MQTT example This sketch demonstrates the capabilities of the pubsub library in combination with the ESP8266 board/library. It connects to an MQTT server then: - publishes "hello world" to the topic "outTopic" every two seconds - subscribes to the topic "inTopic", printing out any messages it receives. NB - it assumes the received payloads are strings not binary - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led, else switch it off It will reconnect to the server if the connection is lost using a blocking reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to achieve the same result without blocking the main loop. To install the ESP8266 board, (using Arduino 1.6.4+): - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs": http://arduino.esp8266.com/stable/package_esp8266com_index.json - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266" - Select your ESP8266 in "Tools -> Board" */ #include <ESP8266WiFi.h> #include <PubSubClient.h> // Update these with values suitable for your network. const char* ssid = "**********"; const char* password = "**********"; const char* mqtt_server = "192.168.0.33"; WiFiClient espClient; PubSubClient client(espClient); long lastMsg = 0; char msg[50]; int value = 0; void setup() { pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output Serial.begin(115200); // initialize the ADC pin as an input pinMode(A0, INPUT); setup_wifi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); } void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); // Switch on the LED if an 1 was received as first character if ((char)payload[0] == '1') { digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level // but actually the LED is on; this is because // it is acive low on the ESP-01) } else { digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH } } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect("ESP8266Client")) { Serial.println("connected"); // Once connected, publish an announcement... client.publish("outTopic", "hello world"); client.publish("Intellic/Pyramid/Temp","0"); // ... and resubscribe client.subscribe("inTopic"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } // Declare variables for the analog input from temp sensor int sensorPin = A0; int sensorValue = 0; String mes = "0"; void loop() { // Read the sensor sensorValue = analogRead(sensorPin); if (!client.connected()) { reconnect(); } client.loop(); long now = millis(); if (now - lastMsg > 2000) { Serial.print("Raw Sensor Value:"); Serial.println(sensorValue); lastMsg = now; ++value; snprintf (msg, 75, "hello world #%ld", value); Serial.print("Publish message: "); Serial.println(msg); client.publish("outTopic", msg); mes = String(sensorValue); client.publish("Intellic/Pyramid/Temp",(char*)mes.c_str()); } }
- Subscribe to the new topics in the Raspberry Pi
- mosquitto_sub -d -t Intellic/Pyramid/Temp
- mosquitto_sub -d -t outTopic
- Confirm that the updates are showing up in the Raspberry Pi and MQTT Spy
- Revel in your glory… you just successfully set up an ESP8266 with LM35 temperature sensor to publish to your MQTT Broker!
Step 4. Install and Setup the Cirrus Link MQTT Modules in Ignition
Download Ignition and the Cirrus Link Modules here. Documentation for the modules are here.
- Install Ignition and Modules
- Configure MQTT Engine for your broker
- Create Custom Namespace with # to subscribe to all topics
- Test tags in Ignition
- Revel in your glory… you have successfully setup Ignition to talk to your broker over MQTT!
Step 5. Setup Kepserver IOT Gateway
This process is straight forward… download Kepserver and install. Create a new agent (that points to your broker) under the IOT Gateway and drop some tags in. The video link at the beginning of this post covers the details very well.
Step 6. Build Your Demo Project
Once you have tags in Ignition, building a project is the same as with traditional tags. The difference here is that as soon as new topics are published to the broker, they will just show up in the tag structure under the MQTT Engine. I like to call this Self Aware SCADA.
There you have it… a simple demo in Ignition using a Raspberry Pi 3, Arduino ESP8266, MQTT-Spy and Kepserver IOT Gateway.
For a more detailed discussion about the implications of MQTT and the future of SCADA and the Industrial Automation space, please watch the video we put together here.
Thanks for reading!