This blog is in support of the Remote Monitoring & Control Project14 Challenge:
"So that is my challenge - make a datalogger of 24 sensors logging data every one minute that could run without mains power or human intervention for 7 days with no wires to avoid a million dollar a day loss"...
-Sean
PROJECT VIDEO
Below is are best attempt at edutainment detailing our project and the working Arduino Mega Modbus Datalogger:
BILL OF MATERIALS
Arduino MegaArduino Mega
LCD 2x 16, I2CLCD 2x 16, I2C
Real Time ClockReal Time Clock
Arduino SD/Ethernet Shield
INTRODUCTION
The Energy, Petroleum, Chemicals, and Materials industries drive a lot of business for tech companies, IT companies, construction companies, consultants...the list goes on and on. But sometimes, a fast, practical, and economical solution just hasn't been made yet in your "space". Being a non-electrical engineer with a career in fixed equipment/mechanical engineering, this led me to my Remote Monitoring & Control Project: Ad Hoc, Freaky Intense, Fixed Equipment Vital Health Monitoring.
To put this into context, let's look at a recent event. If you live on the east coast, you probably heard about the 2019 Philadelphia refinery explosion.
Fortunately, no one was hurt:
It is said to be the east coast's oldest refinery. With Refining already over 100 years old, the industry is tasked with ensuring their assets keep their mechanical integrity. In other words, making sure they can "keep it in the pipes", as we say at work. With the age of assets and higher environmental standards, monitoring the fixed assets for erosion, corrosion, and cracking mechanisms that could lead to catastrophic failure and loss of containment has never been at a higher peak. For Refining, when it gets out of the pipes, it usually means a fire or explosion comes with it.
For reference in this blog, "Fixed Equipment" refers to non rotating, non sensing assets such as piping and vessels. This is opposed to the engineering fields of "Rotating Equipment" (pumps and compressors) and "Control Systems". They too need monitoring, but compared to those tech savvy disciplines, someone that works on Fixed Equipment doesn't have a voltmeter or wire snips in their tool bag. When you say Java, we say "don't mind if I do" and head to the break room. That's what is cool about the Maker phenomenon - some very unique developments can occur as I hope you will find below.
KEEPING IT IN THE PIPES
The American Petroleum Institute has developed codes over the last century that serve as the industry's REGAGAP. This acronym stands for Recognized and Generally Accepted Good Engineering Practices. The US government's OSHA 1910 considers API 510, 570, and 579 codes as REGAGAP for fixed equipment (among others). These codes provide specific asset condition requirements to trigger repair or increased monitoring.
One of the most common thing that is monitored is thickness of piping and vessel walls. Over time, all metal slowly migrates into the process steams due to erosion or corrosion. It does this to the point that pinholes occur or even a fish mouth rupture (not good). Carbon steel rusts away when oxygen is present to form iron oxide on the surface and then water comes and washes it away. Most folks have seen that with cheaper outdoor furniture and grills. It's a process called rusting away.
However, carbon steel will also corrode away without oxygen present such as when used to transfer a liquid containing sulfur. That corrosion process is called sulfidation. It will eat the pipe from the inside out even if the pipe is beautifully painted once a year. In addition to corrosion, you can have other metal damage mechanisms called cracking. For example, if you go to Lowes, you'd think Stainless Steel is the end all metal need of the planet. Just try to run some chlorides through it like found in crude oil and then heat it up. It cracks and ruptures catastrophically! So, you have to keep things under check.
The US didn't take over the top spot of petroleum product production by shutting down for every nick and scratch. No refinery anywhere could stay in business if it had to shut down due to a thin spot of pipe. But it also couldn't stay afloat if it had a fire every other day. So, the code API 579 provides REGAGEP for operating under Fitness for Service (aka FFS). This is a term applied when a defect is found on fixed equipment such as for pipe walls that have become thin enough to require more frequent inspection or vessel shells that have developed a crack on the surface that hasn't gone all the way through. Shutting down could result in millions of dollars of sales loss, could present a local consumer fuel price crisis, and also presents many safety challenges for securing the equipment that normally contains hazardous materials for human interaction and work.
Now, at first read, this may seem shocking to someone outside of this 100 year old industry. Don't worry, though - FFS calculations have a significant safety factor built in. All of this is to just trigger proper attention way ahead of true physical limitations. Thus, Insurance and Process Safety Management auditors and state code fully adopt API 579 for REGAGEP.
So, applying a lot of math, an engineer can allow the site to confidently operate with the defect under Fitness for Service (FFS) to make the run until the next major scheduled turnaround - which could be two or more years away. However, the math is contingent that operating conditions (typically temperature, pressure, and flows) are generally the same and that corrosion rates, vibration, and any other damage mechanism isn't introduced. Here is where I've challenged myself - I want ad hoc freaky, intense fixed equipment vital health monitoring. (I made that phrase up. Just now. Feel free to use it.). API code just requires inspecting at the half life calculation. For instance, take a 3 year end of life calculation to an 18 month next inspection. But like Freddy said, I want it all and I want it now.
TRADITIONAL MANUAL MONITORING OF MECHANICAL INTEGRITY
In the last 20+ years, various techniques to monitor fixed equipment have emerged. In the earlier years, they'd just drill a hole partway through pipe and vessel walls. If that shallow, tell-tale hole leaked, you knew it was time to replace it. Sounds like commons sense, right? Weeeeeeeelllllllll....common sense is actually "hindsight bias". Fast forward 50 years, and hindsight (and injury) proved that tell-tale holes were no longer the common sense approach. It assumed that the system would erode or corrode evenly on every face of its geometry. It didn't account for cracking mechanisms or localized damage due to how the process flowed in the vessel or pipes.
Today's techniques are phenomenal at predicting problems without even having to shutdown the process. However, many of them require expensive scaffolding to be built so humans can perform the inspections. With that comes safety concerns and high costs. Scaffold erection alone cost five figures. Dependent on the process service, a business may do the monitoring anywhere from 3 to 10 years. You could have process upsets that lead to corrosion in between that totally confuse you.
Below is an example of an inspection technique called Radiography (x-ray). It is used to measure the wall thickness.
Radiography (aka X-ray) is a frequently used manual
technique for measuring pipe thickness.
Other techniques are Ultrasonic Thickness.
Both can be costly, manual processes.
If the wall loss surpasses the thickness alert rate, it goes under Fitness for Service. Once a piece of equipment goes under Fitness for Service (aka FFS), monitoring has to be increased. Here comes the Maker project. Instead of just settling on the present era method of doubling the frequency of inspection (say from every 3 years to every 18 months), one could make a device to monitor every minute!
AD HOC FREAKY, INTENSE FIXED EQUIPMENT VITAL HEALTH MONITORING
Now don't get me wrong - there are some big players in this market to measure thickness all the time. However, it is very expensive to pull cable in the field for ad hoc desires. Typically, permanent installations only have a few locations covered to provide an indication of general thinning. This project is about allowing one to put out a temporary monitoring system to deal with a one off issue found in a remote area that doesn't have a permanent monitoring system installed. Which is most of the industry.
Luckily, some other technology has emerged: wireless industrial transmitters. They can be used to automate the monitoring needed as well as make it easy to install without a major capital project. The transmitters meet all the electrical classification requirements of Class I Div II Areas - which means their enclosures can contain an explosion inside of them if they were to spark - and they would keep out external gases that could ignite. So, one would never have to worry about the atmosphere around the devices or require a Low Energy permit as long as the enclosure stayed closed - just as any control box in the field.
Rosemount 648 Industrial Sensor Transmitter - Loving to Meet the Arduino
By taking Rosemount 648 Wireless Transmitters used for normal internal process condition monitoring, one can establish an adhoc strategy to measure the fixed equipment vital conditions where the hurt is:
- Surface Temperature
- Strain
- Vibration
- Thickness
They just need to pair with sensors made for permanent installations as shown below.
Top Left: Permasense Thickness Monitoring
Top Right: Strain Gage
Bottom Left: RTD temperature sensor
Bottom Right: vibration sensor
Normally, control systems monitor what is in the pipes and vessels - not the assets themselves (with the exception of large furnace tubes and rotating equipment). As stated before, inspection technicians are sent out with hand held devices to take X-rays, shoot IR guns for temperature, and measure thickness with UT meters.
To automate such monitoring for ad hoc freaky, intense fixed equipment vital health monitoring, Rosemount Wireless transmitters can link together and repeat their wireless network to a Emerson 1410 Gateway. You can daisy chain the transmitters such that you can get the sensor data in the remote location all the way back to your office.
Rosemont Auto-organizing Network
Capable of hopping 120ft between transmitters
all the way to your office
Here's the big bummer - the gateway doesn't store data! For permanent installations, versus this project's adhoc freaky increased monitoring, it would normally be hardwired into a site's Distributive Control System (DCS ) to allow its data historian to do the logging.
Emerson 1410 Gateway: Pretty Much a Boss for Industrial Wireless Data Brokering
The Wireless version of the Rosemount Wireless Transmitters make for a great solution for ad hoc freaky, intense fixed equipment vital health monitoring. But, you have to have a way to collect the data, not just monitor it. In walks good ole' Arduino.
DESIGNING A FIXED EQUIPMENT VITALS ARDUINO MEGALOGGER
The idea of going from every 18 months of human based monitoring to every minute of mega awesome monitoring is an easy sell. But what good is monitoring if you don't record the data!
Rather than just use this in my office, I'd also like to have the gateway mobile as well. So, when powering the Emerson 1410 Gateway with a practical amount of batteries, I got about 7 days. So that is my Project 14 challenge - make a datalogger of 24 sensors logging data every one minute that could run without mains power or human intervention for 7 days with no wires.
Looking at the Arduino Mega, an SD/Ethernet Shield, a Real Time Clock, the math worked out:
A Spreadsheet to Estimate How Often The Datalogger Would Need Attention
One could get 1002 days of data every minute for 24 sensors and 2004 days with 12 sensors. Also, using the Real Time Clock approach to shut off the Arduino in between datalogs, one could get 18 days of run time versus just 7. With just a couple more 12V batteries in the suitcase, one could basically only have to check on it twice a month. Now we're talking true ad hoc freaky, intense fixed equipment vital health MEGA monitoring!
Of course, one could acquire a control system datalogger at the expense of 5 figures of costs and services - but then I wouldn't be able to present this Project 14 Maker Remote Logging challenge solution, would I?
EMULATING A MODBUS SERVER
Since 1979, an open source protocol for serial transmission has been in use called Modbus owned now by Schneider Electric. Its original company developed it for their process control hardware so that manufacturers of automated valves and sensors could use it to communicate with their controllers. It's like I2C, SPI, and the rest of the Master-Slave serial communication protocols.
To develop the Arduino code to poll the gateway for data, I needed to emulate a Modbus device for development at the house. The device is considered the server or slave in the Modbus protocol. I elected to use my PC to host such an emulator. So, first I needed to install Python for Windows. I retrieved it from here: https://www.python.org/downloads/
I then found this nice little Python Modbus emulator named uModbus: https://umodbus.readthedocs.io/en/latest/client/tcp.html#api
Here is the server side code that would emulate my Emerson 1410 setup:
#!/usr/bin/env python # scripts/examples/simple_data_store.py import logging from socketserver import TCPServer from collections import defaultdict from umodbus import conf from umodbus.server.tcp import RequestHandler, get_server from umodbus.utils import log_to_stream # Add stream handler to logger 'uModbus'. log_to_stream(level=logging.DEBUG) # A very simple data store which maps addresses against their values. data_store = defaultdict(int) # Enable values to be signed (default is False). conf.SIGNED_VALUES = False print("Starting Server...") TCPServer.allow_reuse_address = True app = get_server(TCPServer, ('localhost', 502), RequestHandler) @app.route(slave_ids=[1], function_codes=[1, 3], addresses=list(range(7000, 7010))) def read_data_store(slave_id, function_code, address): """" Return value of addresses. """ return data_store[address] @app.route(slave_ids=[1], function_codes=[6, 15], addresses=list(range(7000, 7010))) def write_data_store(slave_id, function_code, address, value): """" Set value for address. """ data_store[address] = value if __name__ == '__main__': try: app.serve_forever() finally: app.shutdown() app.server_close()
(If you have trouble getting this to work, try opening port 502 on your firewall.)
I needed some data to pull from the server by my Arduino code. To first seed the data at register 7001 and 7002 of the Modbus server, I made a client emulator to push over some values that are similar to what I expect from the Rosemount 648 wireless transmitters to land on the gateway.
#!/usr/bin/env python # scripts/examples/simple_tcp_client.py import socket from umodbus import conf from umodbus.client import tcp # Enable values to be signed (default is False). conf.SIGNED_VALUES = True sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('192.168.1.239', 502)) # Returns a message or Application Data Unit (ADU) specific for doing # Modbus TCP/IP. message = tcp.write_single_register(slave_id=1, address=7002,value=30000) #message = tcp.read_holding_registers(slave_id=1, starting_address=7001,quantity=2) #you can un comment line 13 and comment line 12 to read back from the server print("About to send message...") response = tcp.send_message(message, sock) print(response) sock.close() print("Completed successfully")
THE ARDUINO MEGA DATALOGGER SOLUTION
I first prototyped my solution with an Arduino Uno. I found an existing Arduino library that handled all the heavy lifting of communicating using Modbus using TCP/IP. I used a common shield (W5100) to handle the SD card logging, ethernet communication, and a Real Time Clock triggering a MOSFET to provide a deep sleep cycle.
Left to Right: DS3231 Realtime Clock, Arduino UNO with W5100 SD/Ethernet Shield, 2x16 LCD Screen
Here was the code used in prototyping:
#include <SPI.h> #include <SD.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #include "DS3231.h" unsigned int param_value_int[7]; #include <Ethernet.h> #include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library #include <ArduinoModbus.h> byte mac[] = {0x90, 0xA2, 0xDA, 0x0E, 0x94, 0xB5 }; IPAddress ip(192, 168, 1, 94); IPAddress server(192, 168, 1, 239); IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); EthernetClient client; ModbusTCPClient modbusTCPClient(client); LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display RTClib RTC; //real time clock void setup() { Serial.begin(9600); Ethernet.begin(mac, ip, gateway, subnet); lcd.init(); lcd.backlight(); lcd.setCursor(0,0); lcd.print(" PHILLIPS 66"); lcd.setCursor(1,1); lcd.print("JJ8 Megalogger"); pinMode(4, OUTPUT); digitalWrite(4, HIGH); // To disable slave select for SD card; depricated. delay(2000); } void loop() { lcd.display(); lcd.clear(); lcd.setCursor(0,0); lcd.print("Working...Please"); lcd.setCursor(0,1); lcd.print("Stand By..."); ethernetLoop(); lcd.clear(); lcd.setCursor(0,0); writeToFile(getTime()); lcd.clear(); lcd.print(getTime()); delay(3000); } String getTime() { DateTime now = RTC.now(); return (String)(now.year()) + '-' + (String)(now.month()) + '-' + (String)(now.day()) + " " + (String(now.hour())) + ":" + (String)(now.minute()) +":" + (String)(now.second()); } void writeToFile(String the_string) { // Open serial communications and wait for port to open: File myFile; if (!SD.begin(4)) { lcd.clear(); lcd.print("FAILED CARD!"); while (1); } // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. myFile = SD.open("JJ8.txt", FILE_WRITE); // if the file opened okay, write to it: if (myFile) { myFile.println(the_string); // close the file: myFile.close(); lcd.clear(); lcd.print("Write success!"); lcd.setCursor(0,1); lcd.print("You may power down."); delay(5000); } else { // if the file didn't open, print an error: lcd.clear(); lcd.print("error opening test.txt"); while (1); } } void ethernetLoop() { long response; if (!modbusTCPClient.connected()) { // client not connected, start the Modbus TCP client Serial.println("Attempting to connect to Modbus TCP server"); if (!modbusTCPClient.begin(server)) { Serial.println("Modbus TCP Client failed to connect!"); Serial.println(modbusTCPClient.lastError()); return; } else { Serial.println("Modbus TCP Client connected"); } } else Serial.println("Modbus TCP Client connected"); Serial.println("About to read holding registers..."); response=modbusTCPClient.holdingRegisterRead(1,7001); //https://www.arduino.cc/en/ArduinoModbus/ModbusClientholdingRegisterRead Serial.println("complete "); if (!response) { Serial.println("Could not read register! "); Serial.println(modbusTCPClient.lastError()); } else { Serial.println("Register Value=" + String(response) ); lcd.clear(); lcd.print("Did it:" + String(response)); delay(3000); } // wait for 1 second modbusTCPClient.stop(); delay(100); }
As you can see, there is a lot of code and libraries. I surpassed the UNO dynamic (RAM) memory. The UNO couldn't handle the load of an LCD, SD card, ethernet port, and Real Time Clock all under one board. In my 8 years of using Arduino, I finally had a project that outgrew it!
So, based on the math above...and the overall RAM I needed for my code to pull it off, I selected an Arduino Mega 2560 Rev 3 to pull it off.
Arduino Mega 2560: Selected it for its Low Power and High RAM to handle all my code
Using the Arduino, I can hit a Modbus controller of any brand through the gateway's TCP/IP port to read the current values of its registers. All I need to know is the slave id (typically 1) and the address of the registers I want to read.
You may think, how do you know you don't have bad data coming in? Well, they thought of that all the way back in 1979 when they developed the Modbus protocol. At the end of its bit packet is a checksum. If the prior bits don't sum up to the checksum value, we trap and handle it. So far, I've never lost a bit.
After uploading the code to the Mega and adjusting for my particular registers and SD write timing, I powered it by batteries and achieved the goal of 1 week datalogging.
ASSEMBLY OF THE FINAL PROJECT
I used Autodesk Fusion 360 to design the case. Fortunately, all the devices in my project had already been modeled and found on grabcad.com. This site is a great place to look for off the shelf models to save you hours of time establishing "obstruction models" for your own designs.
Autodesk Fusion 360 Design
Fully Assembled Arduino Mega Datalogger
Running the Code
You can find the Autodesk Fusion 360 file along with the Arduino .ino file at our Github repository: https://github.com/RaisingAwesome/Arduino-Modbus-Mega-Logger
PROJECT CONCLUSION
This was a great project to show how the lines have blurred in Engineering disciplines in recent time. The Maker revolution over the last 10 years has changed the university approach to engineering and I'm glad to find that graduates are coming in with Arduino experience and coding skills regardless of discipline. We still have a lot of barriers to break down between IT, Electrical Engineering, and Mechanical Engineering, but I see it happening every day.
There is no doubt that code is what will change the world to come as the hardware is already available and very inexpensive. I hope this blog tieing age old industrial communication protocols to modern maker magic provides insight that will inspire others to embrace code and the hardware and change the world!!
-Sean
PS. Although you see a lot of products here - I have no affiliation with those companies or any endorsement from them - they are just industry standards I have worked with over the years.
Top Comments