Introduction
I designed and built 2 projects to go along with the RoadTest of the Eaton easyE4 PLC. These go with the RoadTest, but are extra information. I will try and keep my opinion to the review.
All pages are likely to be updated as I get to grips with adding information.
I tried to keep everything fairly basic as I was trying to test the PLC and the software that went along with it. As such I also tried to keep the voltage down to 12Vdc. A lot of what I ended up using (Arduino/Ras Pi) could have done the job of the PLC, but that wasn’t the point. I was trying to replicate industrial parts and automation. As such I stuck to using Ladder Diagrams (LD) as this is still seen in many old PLCs.
Pretty much all Arduino code, and the Raspberry Pi code I used, I butchered from previous projects I had done to some degree.
Although I know there is a standard for PLC programs (IEC 61131-3) I am not up to speed on the regulations. Therefore, there will no doubt be issues with the ladder diagram I put together not meeting the standards. If anyone does have the knowledge on these and can advise, I will happily take it on board.
Product LinkProduct Link
Planned Operation
This was going to be the simplest project out of a possible two.
This first project using the PLC was to replicate a lighthouse system that monitors the light level using LDRs, and switches on the main optic when the light level drops below a set value, then turns back off when the light level rises again. These two value are not the same, otherwise at dusk and dawn they would turn on/off as the light levels vary. The low value tends to be 100 LUX and the high value 150 LUX.
There are normally three LDRs when using a PLC for monitoring, which are connected together in a voter circuit so that at least two of the three have to reach the set value to indicate a change in the light level. A signal is sent to the PLC to say switch light on or off.
As the old systems are normally still made up of bulbs, some redundancy is added. I was also going to replicate this. The first way to check a bulb is operational is monitoring the current that the bulb is pulling. If it drops below a set value it will send a signal to change the bulb (as there is normally a lampchanger fitted), or switch to emergency lanterns. A main optic bulb has the same LDR and voter circuit as described above, but sitting next to the bulb. This also monitors the bulb as there are some bulbs and drivers that can develop a problem, but will still pull a current so the current monitor does not pick up on a fault. It makes sure that if there is supposed to be light, there actually is light.
Design
I had to use what I had at home to replicate this. I only had photodiodes when I started so used these instead of LDRs with a resistor in series. I used an Arduino to measure values from these. To get light levels similar to a lighthouse I used an actual lighthouse as reference. I live about 2 miles away from a lighthouse, and I have the software on the work laptop to check when lights turn on and off, so I aimed the photodiodes in roughly the same direction as the lighthouse LDR faces.
Using an Arduino to measure the values from the photodiodes, I connected this to a Raspberry Pi to log the values, and then referencing this with the times the actual lighthouse turned on and off, I was able to get some rough values for using.
Arduino Code:
const int Sensor1Pin = A3; const int Sensor2Pin = A4; const int Sensor3Pin = A5; int Sensor1Value = 0; int Sensor2Value = 0; int Sensor3Value = 0; void setup() { Serial.begin(9600); } void loop() { if(Serial.available()) { char ch=Serial.read(); if (ch=='a') { read1(); } if (ch=='b') { read2(); } if (ch=='c') { read3(); } } } void read1(){ Sensor1Value = analogRead(Sensor1Pin); delay(5); Sensor1Value = analogRead(Sensor1Pin); Serial.print("Raw Sensor Value \t 1: "); Serial.println(Sensor1Value); } void read2(){ Sensor2Value = analogRead(Sensor2Pin); delay(5); Sensor2Value = analogRead(Sensor2Pin); Serial.print("Raw Sensor Value \t 2: "); Serial.println(Sensor2Value); } void read3(){ Sensor3Value = analogRead(Sensor3Pin); delay(5); Sensor3Value = analogRead(Sensor3Pin); Serial.print("Raw Sensor Value \t 3: "); Serial.println(Sensor3Value); }
Raspberry Pi Code:
import datetime import serial import time sensor1 = [] sensor2 = [] sensor3 = [] arduino = serial.Serial('/dev/ttyACM0',9600) time.sleep(3) while True: ct = datetime.datetime.now() print("Time:-", ct) arduino.write('a') sensor1 = arduino.readline() print (str(sensor1)) arduino.write('b') sensor2 = arduino.readline() print (str(sensor2)) arduino.write('c') sensor3 = arduino.readline() print (str(sensor3)) results = open("sensorResults.txt","a") results.write(str(ct)) results.write('\n') results.write(sensor1) results.write(sensor2) results.write(sensor3) results.write('\n') results.close() time.sleep(10)
This was a sample of what the Raspberry Pi was logging and saving to a text file:
2020-11-15 09:02:33.792668
Raw Sensor Value 1: 754
Raw Sensor Value 2: 794
Raw Sensor Value 3: 781
2020-11-15 09:02:44.061484
Raw Sensor Value 1: 722
Raw Sensor Value 2: 761
Raw Sensor Value 3: 747
2020-11-15 09:02:54.323221
Raw Sensor Value 1: 693
Raw Sensor Value 2: 730
Raw Sensor Value 3: 717
2020-11-15 09:03:04.605418
Raw Sensor Value 1: 664
Raw Sensor Value 2: 701
Raw Sensor Value 3: 687
And these were the actual results at the same time as the lighthouse turned on. I had a bit of trouble remembering to set the clock time every time I powered on the Raspberry Pi which is why the second reading has the wrong time, but I just worked it out against the actual time. I left in my notes as it mentions forgetting again, the first time I did this there was a LOT of swearing involved:
2020-11-15 08:32:22.474197
Raw Sensor Value 1: 974
Raw Sensor Value 2: 911
Raw Sensor Value 3: 974
Forgot to set time again. Values calculated at actual time of 15.29.26
2020-11-15 10:30:49.190632
Raw Sensor Value 1: 321
Raw Sensor Value 2: 340
Raw Sensor Value 3: 336
I decided to use the Arduino with the photodiodes as the best way of sending an on/off signal to the PLC.
For the testing of the PLC I decided LEDs would replicate a lantern as well as anything. There would be three LEDs to turn on, Main Optic, Emergency Optic, and a Fault Indicator.
I also decided to use a single photodiode that would be next to the Main Optic LED to tell if it was actually outputting light as I only had one spare after using three in the voter circuit (not a circuit, Arduino doing the same thing).
For the current monitoring I used an Adafruit INA219 board. This was also connected to the Arduino and it was again doing the signal conditioning, and would send a signal to the PLC to say there was a current failure. I simply got the value form when the LED was on and chose a value less than the on value.
During the stages of trying to test this all out I found that although the PLC worked at 12Vdc, for it to get a HIGH signal, it had to be over 7V, therefore I couldn’t use the Arduino outputs straight into the PLC. I ended up using a few ideas to get this to work as I was going to need to go from the Arduino 5V to 12V for the signal inputs. I tried a switching IC first but could not get it to work, even though I had used it in a different project. I moved on to a relay shied for the Arduino which caused me problems. My board must be an old board, and it was designed poorly. I was having problems and while testing things out I realised one of the relay pins was actually sitting on top of the Ethernet connector on the Arduino. After shimming that it seemed to work and I could switch in 12V to the PLC.
The Arduino test code to go with the PLC was as follows:
#include <Wire.h> #include <Adafruit_INA219.h> Adafruit_INA219 ina219; const int Sensor1Pin = A1; const int Sensor2Pin = A2; const int Sensor3Pin = A3; const int Sensor4Pin = A0; int Sensor1Value = 0; int Sensor2Value = 0; int Sensor3Value = 0; int Sensor4Value = 0; int current = 6; int lantern = 7; int dusk = 5; int dawn = 4; void setup(void) { Serial.begin(9600); pinMode(current, OUTPUT); pinMode(lantern, OUTPUT); pinMode(dusk, OUTPUT); pinMode(dawn, OUTPUT); digitalWrite(current, HIGH); digitalWrite(lantern, HIGH); digitalWrite(dusk, HIGH); digitalWrite(dawn, HIGH); while (!Serial) { // will pause Zero, Leonardo, etc until serial console opens delay(1); } uint32_t currentFrequency; Serial.println("Hello!"); ina219.begin(); Serial.println("Measuring voltage and current with INA219 ..."); } void loop(void) { float shuntvoltage = 0; float busvoltage = 0; float current_mA = 0; float loadvoltage = 0; shuntvoltage = ina219.getShuntVoltage_mV(); busvoltage = ina219.getBusVoltage_V(); current_mA = ina219.getCurrent_mA(); loadvoltage = busvoltage + (shuntvoltage / 1000); Sensor1Value = analogRead(Sensor1Pin); delay(5); Sensor1Value = analogRead(Sensor1Pin); Sensor2Value = analogRead(Sensor2Pin); delay(5); Sensor2Value = analogRead(Sensor2Pin); Sensor3Value = analogRead(Sensor3Pin); delay(5); Sensor3Value = analogRead(Sensor3Pin); Sensor4Value = analogRead(Sensor4Pin); delay(5); Sensor4Value = analogRead(Sensor4Pin); Serial.print("Bus Voltage: "); Serial.print(busvoltage); Serial.println(" V"); Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV"); Serial.print("Load Voltage: "); Serial.print(loadvoltage); Serial.println(" V"); Serial.print("Current: "); Serial.print(current_mA); Serial.println(" mA"); Serial.println(""); Serial.println("Raw Sensor Value \t 1: "); Serial.println(Sensor1Value); Serial.println("Raw Sensor Value \t 2: "); Serial.println(Sensor2Value); Serial.println("Raw Sensor Value \t 3: "); Serial.println(Sensor3Value); Serial.println("Raw Sensor Value \t 4: "); Serial.println(Sensor4Value); if (current_mA <= 7) { Serial.println("Lantern Current FAIL"); digitalWrite(current, LOW); } else { digitalWrite(current, HIGH); } if (Sensor4Value <= 400) { Serial.println("Lantern Light Fail"); digitalWrite(lantern, LOW); } else { digitalWrite(lantern, HIGH); } if (Sensor1Value <= 340 && Sensor2Value <= 340 or Sensor2Value <= 340 && Sensor3Value <= 340 or Sensor1Value <= 340 && Sensor3Value <= 340){ Serial.println("After Dusk"); digitalWrite(dusk, LOW); } else { digitalWrite(dusk, HIGH); } if (Sensor1Value >= 900 && Sensor2Value >= 900 or Sensor2Value >= 900 && Sensor3Value >= 900 or Sensor1Value >= 900 && Sensor3Value >= 900){ Serial.println("After Dawn"); digitalWrite(dawn, LOW); } else { digitalWrite(dawn, HIGH); } delay(2000); }
PLC Code
The PLC then was to have 5 digital inputs and 3 outputs. The inputs were going to be:
Reset button
Light ON
Light OFF
Current OK
Light OK
The Outputs were going to be:
Main Optic
Reserve Optic
Fault Indicator
The code I designed using the Eaton software was as follows:
The first three rungs were alarms. The current alarm and the lantern alarm turning on a marker bit, each of which then turn on the Fault Indicator output. Both alarms would latch on until the reset button was pressed.
The two inputs from the Arduino to the PLC will only show a fault when the main light signal is first turned on and it counts to 60 seconds. This allows the normal bulb time to get up to temperature before declaring a fault.
The Light ON and Light OFF signals come from the Arduino which is measuring the light levels. The PLC has a 30 second timer so that fluctuations in light levels don’t turn on the lantern prematurely.
The Light Needed rung latches the lantern on until it gets the light off signal.
The Main Lantern rung turns on the main optic, with the fault markers bits locking off the lantern.
The Emergency Lantern rung should then turn on if the Main ON signal is active, but the Main Lantern is locked off.
The final rung was simply a way to keep track of the run hours. This is normally done with an analogue meter on sites.
Simulation
I did some simulation testing using the easySoft 7 software which helped smooth out a few issues.
This screenshot was what happened with the program when it got the low light level signal. This was taken while it was counting up to its 30 seconds before turning on the Light ON marker bit.
This is the program operating as it should be with the Light ON MB on, turning on the Main ON MB, which tells the PLC that a lantern needs to be on.
This was the simulation with both faults. It now shows the Main Lantern output as off, while the Emergency Lantern output is on.
The following is the Marker Bits tab, Digital Input tab and Digital Output tab under the fault conditions:
The simulation at this point looked good and I was happy to load it on the PLC for testing.
Testing
Once all parts were connected as I planned, the first part of testing was to lower the light level so that the LED representing the Main Optic would come on. This is what you can see in the following picture. Right next to the LED is the Photodiode that monitors the light output.
That part of the program looked to be working as I wanted. I could change the light level in the room to get the LED to turn on and off as expected. (Although during first tests I thought it wasn't working as I was forgetting the 30 second delay!)
The next part of the test was to check the two fault conditions. The current monitor test simply had the LED disconnected. To get the lantern failure I stuck a post-it between the LED and photodiode. The following picture shows this, along with the reserve lantern LED on and the red Fault Indicator LED just visible as on.
Everything worked as it should have during testing. The correct LEDs were coming on when they should, the two fault conditions worked separately from each other, the reset worked, overall it was operational and simple enough to achieve.
Roundup
There were a few things about this project that I had considered adding. The first was to add in a motor that would be able to turn an optic at a speed close to what is on an actual lighthouse, so say 1 flash every 30 seconds. The second was to have the reserve lantern flash rather than just be on all the time.
I was simply running out of time so neither of these were added, but I don’t think it would have been too difficult to add. The Easysoft7 software had the functions that should have allowed to build it with these controls.
I would have liked to set this up for a longer test, and as the E4 was a relay output it would have been possible to wire in mains, allowing a bulb to be used. Again I had plans, but due to time and it not really being important to the final outcome, this was left out.
I without doubt still over complicated things with the project that I put together.
The next project was going to be a step up from this one.
Top Comments