#ifndef PLC_h
#define PLC_h
// struct CLOCK declaration
struct ClockStruct {bool Q; bool Q_Rtrig; bool Q_Ntrig;};
ClockStruct ClockReturn; // instance of CLOCK struct
// struct TIMER declaration
struct TimerStruct {bool Q; int ET;};
TimerStruct TON_Return; // instance of TON struct
TimerStruct TOF_Return; // instance of TOF struct
TimerStruct TP_Return; // instance of TP struct
/*
----------------------------------------------------------
--------------- CLASS DECLARATIONS ---------------
----------------------------------------------------------
*/
//
// Class CLOCK (Clock generator with Edge Trig)
//
class CLOCK{
private:
long unsigned CpuTimeOLD;
bool OUT;
bool OUT_Old;
public:
ClockStruct Q(long unsigned IN_CpuTime, int IN_Period_2);
};
//
// Class R_TRIG (Detects a positive signal edge of a boolean signal)
//
class R_TRIG{
private:
bool IN_Old;
bool OUT;
public:
bool Q(bool IN_Signal);
};
//
// Class N_TRIG (Detects a negative signal edge of a boolean signal)
//
class N_TRIG{
private:
bool IN_Old;
bool OUT;
public:
bool Q(bool IN_Signal);
};
//
// Class TON (ON delay timer)
//
class TON{
private:
long unsigned CpuTimeOLD;
long unsigned ElapsedTime;
public:
TimerStruct EXE(long unsigned IN_CpuTime, bool IN_Signal, int IN_PT);
};
//
// Class TOF (OFF delay timer)
//
class TOF{
private:
long unsigned CpuTimeOLD;
long unsigned ElapsedTime;
public:
TimerStruct EXE(long unsigned IN_CpuTime, bool IN_Signal, int IN_PT);
};
//
// Class TP (Pulse timer)
//
class TP{
private:
long unsigned CpuTimeOLD;
long unsigned ElapsedTime;
bool IN_Old1;
bool Start_TP;
public:
TimerStruct EXE(long unsigned IN_CpuTime, bool IN_Signal, int IN_PT);
};
/*
----------------------------------------------------------
------------------ CLASS METHODS -----------------
----------------------------------------------------------
*/
//
// Function CLOCK (Clock generator with Edge Trig)
//
ClockStruct CLOCK::Q(long unsigned IN_CpuTime, int IN_Period_2){
if (IN_CpuTime - CpuTimeOLD > (IN_Period_2)) {
OUT = !OUT;
CpuTimeOLD = IN_CpuTime;
}
// gestione fronti salita e discesa di Clock
if (OUT && !OUT_Old ) {ClockReturn.Q_Rtrig = HIGH;}
else {ClockReturn.Q_Rtrig = LOW;}
if (!OUT && OUT_Old ) {ClockReturn.Q_Ntrig = HIGH;}
else {ClockReturn.Q_Ntrig = LOW;}
OUT_Old = OUT;
ClockReturn.Q = OUT;
return ClockReturn;
}
//
// Function R_TRIG (Detects a positive signal edge of a boolean signal)
//
bool R_TRIG::Q(bool IN_Signal){
if (IN_Signal && !IN_Old) {OUT = HIGH;}
else {OUT = LOW;}
IN_Old = IN_Signal;
return OUT;
}
//
// Function N_TRIG (Detects a negative signal edge of a boolean signal)
//
bool N_TRIG::Q(bool IN_Signal){
if (!IN_Signal && IN_Old) {OUT = HIGH;}
else {OUT = LOW;}
IN_Old = IN_Signal;
return OUT;
}
//
// Function Timer TON (ON delay timer)
//
TimerStruct TON::EXE(long unsigned IN_CpuTime, bool IN_Signal, int IN_PT){
if (IN_Signal) {
ElapsedTime = IN_CpuTime - CpuTimeOLD;
if (ElapsedTime >= IN_PT) {TON_Return.Q = HIGH;}
else {TON_Return.ET = ElapsedTime;}
}
else
{
TON_Return.Q = LOW;
TON_Return.ET = 0;
CpuTimeOLD = IN_CpuTime;
}
return TON_Return;
}
//
// Function Timer TOF (OFF delay timer)
//
TimerStruct TOF::EXE(long unsigned IN_CpuTime, bool IN_Signal, int IN_PT){
if (IN_Signal) {
TOF_Return.Q = HIGH;
TOF_Return.ET = 0;
CpuTimeOLD = IN_CpuTime;
}
else
{
ElapsedTime = IN_CpuTime - CpuTimeOLD;
if (ElapsedTime >= IN_PT) {TOF_Return.Q = LOW;}
else {TOF_Return.ET = ElapsedTime;}
}
return TOF_Return;
}
//
// Function Timer TP (Pulse timer)
//
TimerStruct TP::EXE(long unsigned IN_CpuTime, bool IN_Signal, int IN_PT){
if (IN_Signal && !IN_Old1) {
Start_TP = HIGH;
CpuTimeOLD = IN_CpuTime;
}
ElapsedTime = IN_CpuTime - CpuTimeOLD;
if (Start_TP && (ElapsedTime >= IN_PT)) {
Start_TP = LOW;
CpuTimeOLD = IN_CpuTime;
}
IN_Old1 = IN_Signal;
TP_Return.Q = Start_TP;
//Serial.println(Start_TP); // print value on serial
return TP_Return;
}
#endif
/*
----------------------------------------------------------
------------------ SKETCH -----------------
----------------------------------------------------------
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 7, 6, 5, 4);
//
// dichiarazione variabili globali
//
// istanza 1 classe CLOCK
CLOCK CLOCK_01 = CLOCK();
ClockStruct Clock_01_Ret;
// istanza 2 classe CLOCK
CLOCK CLOCK_02 = CLOCK();
ClockStruct Clock_02_Ret;
// istanza 1 classe TON
TON TON_01 = TON();
TimerStruct TON_01_Ret;
// istanza 1 classe TOF
TOF TOF_01 = TOF();
TimerStruct TOF_01_Ret;
// istanza 1 classe TP
TP TP_01 = TP();
TimerStruct TP_01_Ret;
// istanze 1 classi R_TRIG e N_TRIG
R_TRIG R_TRIG_01 = R_TRIG();
N_TRIG N_TRIG_01 = N_TRIG();
// istanze 2 classi R_TRIG e N_TRIG
R_TRIG R_TRIG_02 = R_TRIG();
N_TRIG N_TRIG_02 = N_TRIG();
int DigIn2;
int DigIn3;
bool DigIn2_Rtrig;
bool DigIn2_Ntrig;
bool DigIn3_Rtrig;
bool DigIn3_Ntrig;
//
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(9600); // inizializzo la seriale integrata a 9600 baud
pinMode(2, INPUT); // dichiaro il PIN2 come Input
pinMode(3, INPUT); // dichiaro il PIN3 come Input
pinMode(8, OUTPUT); // dichiaro il PIN8 come Ouput
pinMode(9, OUTPUT); // dichiaro il PIN9 come Ouput
pinMode(10, OUTPUT); // dichiaro il PIN10 come Ouput
pinMode(11, OUTPUT); // dichiaro il PIN11 come Ouput
pinMode(LED_BUILTIN, OUTPUT); // dichiaro l'uscita del led integrato LED_BUILTIN che corrisponde al PIN13 come output
lcd.begin(16, 2);
lcd.print("-- PLC04 --");
}
//
// the loop function runs over and over again forever
void loop() {
DigIn2 = digitalRead(2); // leggo lo stato dell'ingresso del PIN2
DigIn3 = digitalRead(3); // leggo lo stato dell'ingresso del PIN3
Clock_01_Ret = CLOCK_01.Q(millis(), 1000); // chiamata classe CLOCK
Clock_02_Ret = CLOCK_02.Q(millis(), 4000); // chiamata classe CLOCK
DigIn2_Rtrig = R_TRIG_01.Q(DigIn2);
DigIn2_Ntrig = N_TRIG_01.Q(DigIn2);
TON_01_Ret = TON_01.EXE(millis(), DigIn2, 1000);
TP_01_Ret = TP_01.EXE(millis(), DigIn2, 1000);
DigIn3_Rtrig = R_TRIG_02.Q(DigIn3);
DigIn3_Ntrig = N_TRIG_02.Q(DigIn3);
TOF_01_Ret = TOF_01.EXE(millis(), DigIn3, 500);
//
// USCITA PIN 8
//
if (DigIn2_Rtrig) {
digitalWrite(8, HIGH); // accendo il led
//Serial.println("on"); // print value on serial
}
if (DigIn2_Ntrig) {
digitalWrite(8, LOW); // spengo il led
//Serial.println("off"); // print value on serial
}
//
// USCITA PIN 9
//
if (TP_01_Ret.Q) {
digitalWrite(9, HIGH); // accendo il led
//lcd.setCursor(0, 1); // (lcd.setCursor(column, row))
//lcd.print("-- TP --");
//Serial.println("on"); // print value on serial
}
if (!TP_01_Ret.Q) {
digitalWrite(9, LOW); // spengo il led
//Serial.println("off"); // print value on serial
}
//
// USCITA PIN 10
//
if (DigIn3_Rtrig) {
digitalWrite(10, HIGH); // accendo il led
//Serial.println("on"); // print value on serial
}
if (DigIn3_Ntrig) {
digitalWrite(10, LOW); // spengo il led
//Serial.println("off"); // print value on serial
}
//
// USCITA PIN 11
//
if (TOF_01_Ret.Q) {
digitalWrite(11, HIGH); // accendo il led
//Serial.println("on"); // print value on serial
}
if (!TOF_01_Ret.Q) {
digitalWrite(11, LOW); // spengo il led
//Serial.println("off"); // print value on serial
}
lcd.setCursor(0, 0); // (lcd.setCursor(column, row))
lcd.print("TOF.Q : ");
lcd.print(TOF_01_Ret.Q);
lcd.print(" ");
lcd.setCursor(0, 1); // (lcd.setCursor(column, row))
lcd.print("TOF.ET : ");
lcd.print(TOF_01_Ret.ET);
lcd.print(" ");
//
// USCITA LED integrato
//
if (Clock_01_Ret.Q_Rtrig) {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
//Serial.println("on2"); // print value on serial
}
if (Clock_01_Ret.Q_Ntrig) {
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
//Serial.println("off2"); // print value on serial
}
}