EmonPi as base for Industrial Internet of Things

Tags: #<Tag:0x00007fc9167e1d28> #<Tag:0x00007fc9167e1c60>

For my PhD dissertation I am coming up systems at three different price points to connect legacy manufacturing equipment to the Industrial Internet of Things (IIOT). The goal is that with data, shows can become more profitable/optimized by increasing data in the decision process, providing operator training through a user interface with guides, and using he data for predictive maintenance. Prototyping and testing will be on bench top milling machines used by undergraduate students.

My low cost system I am hoping to base off the EmonPi since I was going to do a Raspberry Pi build for it. The idea is to gather motor power, vibration at the vise, acoustics of operation, spindle speed with a tachometer, and position with X, Y, and Z linear scales.

Using the I2C from the EmonPi, I hope to wire in the ADXL345 accelerometer and a ADS1115 16-bit ADC. The ADC will have analog microphone breakout boards attached. For spindle speed and position, I am trying to implement Yuriy’s Toy ( and have it communicate with the EmonPi and the Android app he developed on a tablet.

We have gotten all the different elements together, but the challenge will come from trying to program and connect all of these components.

Information that would be Helpful

  1. Where is the program written that runs the I2C LCD screen as of now in EmonSD
  2. Possibilities of adding more sensors and channels to EmonCMS
  3. Pitfalls you see in the project idea

Thanks for reading. I will try and post updates if anyone is interested.

1 Like

I am interest in I2C devices, so I Hope you don’t mind my feedback even if I don’t directly answer the question “Where is the I2C LCD program”.
I used EmonPi for an ADE9000 using SPI MISO, MOSI, SCK, CS and IRQ1. SPI is similar to I2C.
In summary, what I did was:

  1. enable SPI on the RPI, or in your case I2C.
  2. Write the code to read the SPI data.
  3. Put it in the proper format for the EmonPI, or should I say EmonCMS to read.
    Following is my C++ code to read SPI. I excluded spiComm.h, and spiComm.cpp files to keep it brief. If needed, let me know and I will post.

There is also influx & grafana for this, but Emoncms contains more features and more detailed analysis tools.

#include "spiComm.h"
#include <unistd.h>
#include <stdint.h>
#include <iostream>
#include <string>

using namespace std;
unsigned long interval = 50; 
unsigned long dccount = 1;
char postcmd[1024];
//char postcmd[256];
int main() {

	spiComm commObj;
double avrmsaccum, airmsaccum, awattaccum, avaaccum, apfaccum, bvrmsaccum, birmsaccum;
	double bwattaccum, bvaaccum, bpfaccum;
	string result;
    	cout << "Start Data\n";
	avrmsaccum = 0;
	airmsaccum = 0;
	awattaccum = 0;
	avaaccum = 0;
	apfaccum = 0;
	bvrmsaccum = 0;
	birmsaccum = 0;
	bwattaccum = 0;
	bvaaccum = 0;
	bpfaccum = 0;
	while(1) {
		avrmsaccum += commObj.readVoltage(R_AVRMS_REGISTER);
		airmsaccum += commObj.readCurrent(R_AIRMS_REGISTER);
		awattaccum += commObj.readPower(R_AWATT_REGISTER);
		avaaccum += commObj.readEnergy(R_AVA_REGISTER);
		apfaccum += commObj.readPowerFactor(R_APF_REGISTER);
		bvrmsaccum += commObj.readVoltage(R_BVRMS_REGISTER);
		birmsaccum += commObj.readCurrent(R_BIRMS_REGISTER);
		bwattaccum += commObj.readPower(R_BWATT_REGISTER);
		bvaaccum += commObj.readEnergy(R_BVA_REGISTER);
		bpfaccum += commObj.readPowerFactor(R_BPF_REGISTER);

		if(dccount >= interval)
double avrms, airms, awatt, avarms, apfrms, bvrms, birms, bwatt, bvarms, bpfrms, abwatt, abirms, abvrms;
			avrms = avrmsaccum/dccount;
			airms = airmsaccum/dccount;
			awatt = awattaccum/dccount;
			avarms = avaaccum/dccount;
			apfrms = apfaccum/dccount;
			bvrms = bvrmsaccum/dccount;
			birms = birmsaccum/dccount;
			bwatt = bwattaccum/dccount;
			bvarms = bvaaccum/dccount;
			bpfrms = bpfaccum/dccount;
			abwatt = (awattaccum + bwattaccum)/dccount;
			abirms = (airmsaccum + birmsaccum)/dccount;
			abvrms = ((avrmsaccum + bvrmsaccum)/2)/dccount;
			printf("avrms: %.2f\n", (avrms));
			printf("airms: %.2f\n", (airms));
			printf("awatt: %.2f\n", (awatt));
			printf("ava %.2f\n", (avarms));
			printf("apf %.2f\n", (apfrms));
			printf("bvrms: %.2f\n", (bvrms));
			printf("birms: %.2f\n", (birms));
			printf("bwatt: %.2f\n", (bwatt));
			printf("bva %.2f\n", (bvarms));
			printf("bpf %.2f\n", (bpfrms));
			printf("bpf %.2f\n", (abwatt));
			printf("Number of Samples Averaged: %ld\n", dccount);
			snprintf( postcmd, 1024,  "/usr/bin/curl --data \"node=13&data={L1V:%.2f,L1A:%.2f,L1W:%.2f,L1VA:%.2f,L1pf:%.2f,L2V:%.2f,L2A:%.2f,L2W:%.2f,L2VA:%.2f,L2pf:%.2f,L12W:%.2f,L12A:%.2f,L12V:%.2f,L12W2:%.2f}&apikey=6bd2aa3ad1970a8fafafb9c32d26838e\" \"\"", avrms, airms, awatt, avarms, apfrms, bvrms, birms, bwatt, bvarms, bpfrms, abwatt, abirms, abvrms, abwatt );			
			dccount = 0;
			avrmsaccum = 0;
			airmsaccum = 0;
			awattaccum = 0;
			avaaccum = 0;
			apfaccum = 0;
			bvrmsaccum = 0;
			birmsaccum = 0;
			bwattaccum = 0;
			bvaaccum = 0;
			bpfaccum = 0;



It’s in the Atmel ATMega 328P front end.

Actually the ATMega328P front end only handles the LCD for a very short period whilst the emonPi boots up, during start up there is a Python “emonPiLCD” service started that takes over control of the LCD.

See for the current code.

There are a couple of discussions about customising the display (and it’s push button) behaviour eg

But the physical connection is to the Atmel Front end, isn’t the data that’s sourced in the Pi routed serially into that?

IIRC the pi, the 328 and the LCD are all connected in parallel (i2c) with both the pi and the 328 being masters. The lcd works independently of the usual serial port comms.

So I just took a closer look to check (it was too late last night).

The schematic definitely shows the 2 I²C lines connecting to the Pi, ATMega328P and LCD.

The firmware basically seems to have 2 function calls in src.ino split by a 2sec delay and CT_Detect():

The first function just displays the FW version and “OpenEnergyMon”

The second function displays a line to confirm ac detection (or not) and the number of ct’s detected. Then after a 2 sec delay it displays the number of temp sensors and after another 2 secs it displays a “Booting . . . Please wait” message until the RPi takes over.

So there seem to be 4 LCD pages separated by 3x 2 sec delays and then the LCD stuff is over in the FW sketch, leaving it available for the emonPiLCD service to manage. I’m not sure how long the AC and CT detection takes without looking it up, but it sounds like the FW only uses the LCD for up to 10secs maybe?

I don’t have one to hand to try right now but how long that “booting” message is displayed is in the hands of the Pi not the FW, that moves on. This is why we have occasionally had users say their LCD is stuck on “booting” if the emonPiLCD service fails to start or has the wrong address etc.

Thank you all for your replies.
I am thinking that I will be able to wire the I2C sensors in parallel with the LCD screen and ATMega328P. Though I am wondering if I can use one of the ADC from the ATMega328P for the analog input of my electret microphone and then only have the I2C running the ADXL345.

@dlmpryor I think the plan would be to enable wire in the I2C sensors and write a python script to execute the sensor code and eventually try and put it into the boot functions so SSH and activating the script won’t be necessary.

Awesome project, and right up my alley. I operate a solar powered CNC router, and am using EmonPi to monitor the power draw on motors, spindle, and computer (as well as battery and solar generation). Following and interested in contributing.

The emonPi LCD is connected to both the ATmega328 and RaspberryPi. As @pb66 correctly mentioned above the ATmega328 only controls the LCD to provide immediate display at startup. Then the emonPiLCD python script takes over:

Feel free to customise operation as you see fit!

Other I2C devices could also be connected to the RasPi as long as they are on different addresses to the LCD. Currently, the LCD uses either 27 or 3f

I work in the IIOT space. We work for industrial, and government bodies, including the US Department of Energy. You asked for pitfalls. The biggest issue you have to overcome is security. It doesn’t matter how good your solution is, if there is another system that is more secure, that is the one that will get used.

Just running encryption between devices is not enough.

I made a video about it last week where I take a Raspberry Pi, and add security to it. It was for a blockchain company, but you might find it of interest.

Yeah, cybersecurity is going to be a big factor on a companies selection of a system. We are looking at the pros/cons of different levels of protection and the cost and potential dangers of it.
We have seen the downfalls of losing IP from a port being left open on HVAC systems, so making sure that the system doesn’t provide an inroad.
We are hoping that the low level of machine monitoring of motor power and maybe vibration would be low enough data channels that hackers could not reproduce what the part is or steal the designs from the condition monitoring.

I’d like to think that would be the case too, but do you really believe it? The number of cases where not only consumer, but also industrial and even military security has been compromised suggests to me that people tend to look at the functionality and only as an afterthought at the security. I hope that changes.

but do you really believe it?

Depends on the customer/requirement of course. But yes, it’s on peoples radars now, due to those well publicised security failures. Been in the business since mid-90’s, when security wasn’t really a thing. Now, it’s up there with cost. Security failures blow back on the person that commissions the project (or at least that’s the fear), so they tend to want some assurances.

When you get to the really big customers, who have their own in-house developers, then it becomes an even bigger issue. How do you change/revoke keys, should a disgruntled employee leak them. I guess that’s a post-Edward Snowden thing :slight_smile:

A post was split to a new topic: ATMega 328 unused inputs

A quick update. I’ve been able to include a ADXL345 MEMS accelerometer and the ADS1115 analog digital converter on the I2C circuit with the LCD screen.
I have also added a RC522 RFID scanner to the SPI ports, but am looking at how to add that to I2C as well.
The script we are currently running is a python script that you have to scan an RFID tag to start collecting data into a csv file saved under that RFID tags serial number.
Still trying to figure out how to read the power readings into the script.
Looking at building the Yuriy’s Toy Arduino next week and connecting it into the EmonPi using software serial. That will allow us to get the position readings and spindle speed on from the mill.
With the ADS1115, we are trying to connect MAX4466 electret microphones to read general noise from the process, this seems to be non-effective as of now, but will be revisited later.
Found a couple other grad students in the CSSE department who had some free time to play around with this stuff, so they are trying to get what we are doing up on Git Hub so they can work on it easier. When they do, I will share here as well.
Any advice or related projects as direction will be appreciated.