Hi All,
First of all, here is my complete code, it's not small but i've learned before in this forum that shouldnn't be an issue. To explain the setup : i'm running a MDuino 57R+ (arduino mega clone) that is connected trough ethernet over a router to a windows computer . On that computer i have a delphi program running that connects to the PLC every 1000ms, sends a / separated string , The plc recieves the string, and sends back a simular string with all data from sensors and status.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <ModbusRTUMaster.h>
#include <RS485.h>
#include "Adafruit_FONA.h"
#define FONA_RST 2
// GSM Module
HardwareSerial *fonaSerial = &Serial1;
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
// Modbus
ModbusRTUMaster master(RS485);
#define UDP_TX_PACKET_MAX_SIZE 1024
unsigned int localPort = 8001; // local port to listen on
const uint32_t baudrate = 19200UL;
// Modbusdata :
#define MasterModbusAdd 0
#define Cel1ModbusSensor 1 // TVOC Sensor , info here : https://www.sentera.eu/en/productdetails/outdoor-temperature--humidity--tvoc-sensor-pom/147254
#define Cel1ModbusFan 5 // VFD , info here : https://www.sentera.eu/en/productdetails/ac-fan-speed-controller-0-10-v-din-rail-15-a/119383
// Ethernet
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 200);
EthernetUDP Udp;
// DS18B20 sensors data :
OneWire oneWire(3);
DallasTemperature sensors(&oneWire);
DeviceAddress DST1 = {0x28, 0x1A, 0x6F, 0xA5, 0x13, 0x21, 0x01, 0x29}; // Temperature boiler HOT
DeviceAddress DST2 = {0x28, 0x7E, 0x65, 0x8E, 0x13, 0x21, 0x01, 0x6F}; // Temperature boiler COLD
DeviceAddress DST3 = {0x28, 0x99, 0x09, 0xD5, 0x13, 0x21, 0x01, 0xBF}; // Temperature heat exchanger IN
DeviceAddress DST4 = {0x28, 0x07, 0xBF, 0x99, 0x13, 0x21, 0x01, 0x3C}; // Temperature heat exchanger OUT
// Declare variables :
int Cel1Active,Cel1Running,Cel1Prior;
String result,tmp,ch;
char caracter;
uint16_t au16data[16];
uint16_t au16dataw[16];
uint8_t u8state,ModbusFunction,CurrentModbusFunction;
int TVOCTemp,NewTVOCTemp, TVOCHum,TVOCValue,TVOCStatus,TVOCLight,SetTemp,SetHum,SetFan,FanSetting,SetTDiff,SetHDiff,SetHeatDelay,SetVatTemp,SetVatTempDiff,SetEvaporatorDiff,MaxVatT,MinVatT,PressDelay,slave,AlarmCount,LowTemp,HighTemp,LowHum,HighHum;;
String SetTempSTR,SetHumSTR,SetFanSTR,SetTempDiff,SetHumDiff,SetHeatDelaySTR,VatTempSTR,VatTempDiffSTR,EvaporatorDiffSTR,MaxVatTSTR,MinVatTSTR,PressDelaySTR,LowTempSTR,HighTempSTR,LowHumSTR,HighHumSTR;
int temp1,temp2,temp3,temp4,Signal;
bool R01,R02,R03,R04,R05,R06,R07,R08,R11,R27,AlarmActive,SimUnlocked; // relay override statusses
bool TOk, ColdQ, HotQ,HeatDelayActive,DeHumidActive,HumidActive, Heating,Cooling,MagValve;
unsigned long HeatDelayTime, PressTime;
unsigned long u32wait;
unsigned long target_time = 0L ;
const unsigned long PERIOD = 10*1000UL;
int numReadings = 5;
int currentReading = 0;
int Deviation = 2; // 4 = 40% deviation readings are ignored
unsigned long AvgTemp1,AvgTemp2,AvgTemp3,AvgTemp4;
unsigned long AlarmDelayTime = 0; // in mS
unsigned long AlarmInterval = 10000; // in mS
int ActiveAlarmCode =0;
char ReceiveString[UDP_TX_PACKET_MAX_SIZE]; // buffer to hold incoming packet,
char SendString[] ="";
String SendStr ;
uint32_t lastSentTime = 0UL;
uint32_t lastGSMTime = 0UL;
uint32_t AlarmResendTime = 0UL;
long previousMillis = 0;
long ModbusInterval = 1000;
long TVOCInterval = 0;
char PIN[5];
const int Cel1SensorTempAdd = 0;
const int Cel1SensorHumAdd = 9;
const int Cel1SensorTVOCAdd = 25;
const int Cel1SensorState = 29;
const int Cel1SensorLightAdd= 40;
const int Cel1FanSetFanAdd = 30;
const int Cel1FanGetFanAdd = 1;
const char* pinchar="0000";
const char* phonenumber="************";
String phonenr;
bool SMSSent = false;
void setup() {
Serial.begin(9600);
// start the Ethernet
Ethernet.begin(mac, ip);
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// start UDP
Udp.begin(localPort);
Serial.println("Connecting to RS485 ");
RS485.begin(baudrate, HALFDUPLEX, SERIAL_8E1);
master.begin(baudrate);
u32wait = millis() + 2000;
u8state = 0;
slave=1;
ModbusFunction=0;
AlarmCount =0;
HeatDelayActive = false;
DeHumidActive = false;
HumidActive = false;
Heating = false;
Cooling = false;
MagValve = false;
Cel1Active = 0;
Cel1Running = false;
pinMode(I0_2, INPUT); // Pressostat
pinMode(I0_4, INPUT); // Analog humidity sensor
pinMode(R0_1, OUTPUT); // Magnetic valve
pinMode(R0_2, OUTPUT); // Compressor
pinMode(R0_3, OUTPUT); // Pump cold water
pinMode(R0_4, OUTPUT); // Pump hot water
pinMode(R0_5, OUTPUT); // Valve cold water
pinMode(R0_6, OUTPUT); // Valve hot water
pinMode(R0_7, OUTPUT); // Heat resistor boiler
pinMode(R0_8, OUTPUT); // Steam humidifeir
pinMode(R1_1, OUTPUT); // Resistor heat exchanger
pinMode(R2_7, OUTPUT); // Alarm relay
R01 = false;
R02 = false;
R03 = false;
R04 = false;
R05 = false;
R06 = false;
R07 = false;
R08 = false;
R11 = false;
R27 = false;
// Start Temp Sensors
sensors.begin();
sensors.setResolution(11);
fonaSerial->begin(4800);
Serial.println(F("Initializing @ 4800 baud..."));
if (! fona.begin(*fonaSerial)) {
Serial.println(F("Couldn't find FONA"));
while(1);
}
Serial.println(F("FONA is OK"));
}
void loop() {
if (millis() - lastGSMTime > 15000) {
// Unlock PINCODE
if (SimUnlocked==false)
{
if (!fona.unlockSIM(pinchar)) {
Serial.println(F("SIM Unlock Failed"));
Serial.println(pinchar);
} else {
Serial.println(F("SIM Unlock OK!"));
SimUnlocked=true;
Serial.println(pinchar);
}
}
// Get the signal strength
Signal = fona.getRSSI();
// check once every 15s
lastGSMTime = millis();
}
// Request Modbus data , every 5,5s :
if (millis() - lastSentTime > 5500) {
if (ModbusFunction==0)
{
CurrentModbusFunction = ModbusFunction;
// get Temperature
if (!master.readInputRegisters(1, 0, 1)) {
// Failure treatment
}
}
if (ModbusFunction==1)
{
CurrentModbusFunction = ModbusFunction;
// get Hum
if (!master.readInputRegisters(1, 9, 1)) {
// Failure treatment
}
}
if (ModbusFunction==2)
{
CurrentModbusFunction = ModbusFunction;
if (TVOCInterval==0) // So we get a reading immediatly, then ignore this reading 20 times , to prevent the TVOC sensor from overloading.
{
// get TVOC
if (!master.readInputRegisters(1, 25, 1)) {
// Failure treatment
}
}
TVOCInterval++;
if (TVOCInterval>20) { TVOCInterval=0; }
}
if (ModbusFunction==3)
{
CurrentModbusFunction = ModbusFunction;
// get Sensor Status
if (!master.readInputRegisters(1, 29, 1)) {
// Failure treatment
}
}
if (ModbusFunction==4)
{
CurrentModbusFunction = ModbusFunction;
// get Light Sensor Status
if (!master.readInputRegisters(1, 40, 1)) {
// Failure treatment
}
}
if (ModbusFunction==5)
{
CurrentModbusFunction = ModbusFunction;
// get fan setting
if (!master.readInputRegisters(5, 1, 1)) {
// Failure treatment
}
}
if (ModbusFunction==6)
{
CurrentModbusFunction = ModbusFunction;
// Set fan setting
if (!master.writeSingleRegister(5, 30, SetFan))
{
// Failure treatment
}
}
ModbusFunction++;
if (ModbusFunction>6) { ModbusFunction=0; }
lastSentTime = millis();
}
// Read Modbus data
if (master.isWaitingResponse()) {
ModbusResponse response = master.available();
if (response) {
if (response.hasError()) {
// Response failure treatment. You can use response.getErrorCode()
// to get the error code.
Serial.print("Error ");
Serial.println(response.getErrorCode());
} else {
// Get the discrete inputs values from the response
if (response.hasError()) {
// Response failure treatment. You can use response.getErrorCode()
// to get the error code.
Serial.print("Error ");
Serial.println(response.getErrorCode());
} else {
if (CurrentModbusFunction==0) { TVOCTemp = response.getRegister(0); }
if (CurrentModbusFunction==1) { TVOCHum = response.getRegister(0); }
if (CurrentModbusFunction==2) { TVOCValue = response.getRegister(0); }
if (CurrentModbusFunction==3) { TVOCStatus = response.getRegister(0); }
if (CurrentModbusFunction==4) { TVOCLight = response.getRegister(0); }
if (CurrentModbusFunction==5) { FanSetting = response.getRegister(0); }
}
}
}
}
// Build a string that we will send back to the computer over UDP.
// It contains every data of the sensors and state of the relays.
SendStr="";
SendStr = SendStr + digitalRead(R0_1)+"/"; //0
SendStr = SendStr + digitalRead(R0_2)+"/"; //1
SendStr = SendStr + digitalRead(R0_3)+"/"; //2
SendStr = SendStr + digitalRead(R0_4)+"/"; //3
SendStr = SendStr + digitalRead(R0_5)+"/"; //4
SendStr = SendStr + digitalRead(R0_6)+"/"; //5
SendStr = SendStr + digitalRead(R0_7)+"/"; //6
SendStr = SendStr + digitalRead(R0_8)+"/"; //7
SendStr = SendStr + digitalRead(R1_1)+"/"; //8
SendStr = SendStr + digitalRead(R2_7)+"/"; //9
SendStr = SendStr + digitalRead(I0_2)+"/"; //10
SendStr = SendStr + TVOCTemp + "/"; //11
SendStr = SendStr + TVOCHum + "/"; //12
SendStr = SendStr + TVOCValue + "/"; //13
SendStr = SendStr + TVOCStatus+ "/"; //14
SendStr = SendStr + TVOCLight + "/"; //15
SendStr = SendStr + FanSetting+ "/"; //16
SendStr = SendStr + temp1+ "/"; //17
SendStr = SendStr + temp2+ "/"; //18
SendStr = SendStr + temp3+ "/"; //19
SendStr = SendStr + temp4+ "/"; //20
SendStr = SendStr + Cel1Active+ "/"; //21
SendStr = SendStr + Cel1Prior +"/" ; //22
SendStr = SendStr + ActiveAlarmCode+ "/" ; //23
SendStr = SendStr + Signal; //24
// Serial.println(SendStr); // For debug purpose
char SendString[SendStr.length()+1];
SendStr.toCharArray(SendString, SendStr.length()+1);
// check incoming UDP data.
int packetSize = Udp.parsePacket();
if (packetSize) {
Udp.read(ReceiveString, UDP_TX_PACKET_MAX_SIZE);
// send a reply to the IP address and port that sent us the packet we received
// does this not need a delay in between ?
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(SendString);
Udp.endPacket();
}
delay(10);
// convert the recieved data . Set the settings and switch the relays in case of manual mode
ConvertReceivedData(ReceiveString);
// All data is recieved and ready, go to the celcontrol procedure
ControlCel1();
}
// END LOOP
void ConvertReceivedData(String inputdata)
{
// The PC sends a string to the PLC, starting with ST and ending with E . That way i can make sure the string is complete by checking if E is present at the end;
if(inputdata.indexOf("E") > 0) // check if we have complete data
{
// remove the leading and end strings
inputdata.replace("ST","");
inputdata.replace("E","");
// Set Vars with the data of the string
if (getIntValue(inputdata, ':', 10)!=0){
SetTemp = getIntValue(inputdata, ':', 10);
}
if (getIntValue(inputdata, ':', 11)!=0){
SetHum = getIntValue(inputdata, ':', 11);
}
if (getIntValue(inputdata, ':', 12)!=0){
SetFan = getIntValue(inputdata, ':', 12);
}
if (getIntValue(inputdata, ':', 13)!=0){
SetTDiff = getIntValue(inputdata, ':', 13);
}
if (getIntValue(inputdata, ':', 14)!=0){
SetHDiff = getIntValue(inputdata, ':', 14);
}
if (getIntValue(inputdata, ':', 15)!=0){
SetHeatDelay = getIntValue(inputdata, ':', 15);
}
if (getIntValue(inputdata, ':', 16)!=0){
SetVatTemp = getIntValue(inputdata, ':', 16);
}
if (getIntValue(inputdata, ':', 17)!=0){
SetVatTempDiff = getIntValue(inputdata, ':', 17);
}
if (getIntValue(inputdata, ':', 18)!=0){
SetEvaporatorDiff = getIntValue(inputdata, ':', 18);
}
if (getIntValue(inputdata, ':', 19)!=0){
MaxVatT = getIntValue(inputdata, ':', 19);
}
if (getIntValue(inputdata, ':', 20)!=0){
MinVatT = getIntValue(inputdata, ':', 20);
}
if (getIntValue(inputdata, ':', 21)!=0){
PressDelay = getIntValue(inputdata, ':', 21);
}
if (getIntValue(inputdata, ':', 22)!=0){
LowTemp = getIntValue(inputdata, ':', 22);
}
if (getIntValue(inputdata, ':', 23)!=0){
HighTemp = getIntValue(inputdata, ':', 23);
}
if (getIntValue(inputdata, ':', 24)!=0){
LowHum = getIntValue(inputdata, ':', 24);
}
if (getIntValue(inputdata, ':', 25)>0){
HighHum = getIntValue(inputdata, ':', 25);
}
if (getIntValue(inputdata, ':', 26)==0){
Cel1Active = 0;
}
else{
Cel1Active = 1;
}
if (getIntValue(inputdata, ':', 27)>0){
Cel1Prior = 1; // PRIOR HUM
}
else{
Cel1Prior = 0; // PRIOR TEMP
}
// phone number
if (getIntValue(inputdata, ':', 28)>0){
phonenr = String(getValue(inputdata, ':', 28));
phonenumber = phonenr.c_str();
}
// Set Relays :
// Only if the cel running process is pauzed, we can switch the relays manually.
if ( Cel1Active==0)
{
// Relay 1 , magnet ventil
if (getValue(inputdata, ':', 0).equals("1"))
{
digitalWrite(R0_1, HIGH);
R01 = true;
}
else
{
digitalWrite(R0_1, LOW);
R01= false;
}
// Relay 2 : Compressor
if (getValue(inputdata, ':', 1).equals("1"))
{
digitalWrite(R0_2, HIGH);
R02 = true;
}
else
{
digitalWrite(R0_2, LOW);
R02 = false;
}
// Relay 3 :
if (getValue(inputdata, ':', 2).equals("1"))
{
digitalWrite(R0_3, HIGH);
R03 = true;
}
else
{
digitalWrite(R0_3, LOW);
R03 = false;
}
// Relay 4 :
if (getValue(inputdata, ':', 3).equals("1"))
{
digitalWrite(R0_4, HIGH);
R04 = true;
}
else
{
digitalWrite(R0_4, LOW);
R04 = false;
}
// Relay 5 :
if (getValue(inputdata, ':', 4).equals("1"))
{
digitalWrite(R0_5, HIGH);
R05 = true;
}
else
{
digitalWrite(R0_5, LOW);
R05 = false;
}
// Relay 6 :
if (getValue(inputdata, ':',5).equals("1"))
{
digitalWrite(R0_6, HIGH);
R06 = true;
}
else
{
digitalWrite(R0_6, LOW);
R06 = false;
}
// Relay 7 :
if (getValue(inputdata, ':',6 ).equals("1"))
{
digitalWrite(R0_7, HIGH);
R07 = true;
}
else
{
digitalWrite(R0_7, LOW);
R07 = false;
}
// Relay 8 :
if (getValue(inputdata, ':', 7).equals("1"))
{
digitalWrite(R0_8, HIGH);
R08 = true;
}
else
{
digitalWrite(R0_8, LOW);
R08 = false;
}
// Relay 9 :
if (getValue(inputdata, ':', 8).equals("1"))
{
digitalWrite(R1_1, HIGH);
R11 = true;
}
else
{
digitalWrite(R1_1, LOW);
R11 = false;
}
// Relay 9 , ALARM :
if (getValue(inputdata, ':', 27).equals("1"))
{
digitalWrite(R2_7, HIGH);
R27 = true;
}
else
{
digitalWrite(R2_7, LOW);
R27 = false;
}
}
}
}
void ControlCel1()
{
//Check Temp Every 10s
if (millis () - target_time >= PERIOD)
{
target_time += PERIOD ; // change scheduled time exactly, no slippage will happen
sensors.requestTemperatures();
sensors.setWaitForConversion(false);
int ttemp1 = sensors.getTempC(DST1)*10;
int ttemp2 = sensors.getTempC(DST2)*10;
int ttemp3 = sensors.getTempC(DST3)*10;
int ttemp4 = sensors.getTempC(DST4)*10;
if (ttemp1>-1000)
{
temp1 = ttemp1;
}
if (ttemp2>-1000)
{
temp2 = ttemp2;
}
if (ttemp3>-1000)
{
temp3 = ttemp3;
}
if (ttemp4>-1000)
{
temp4 = ttemp4;
}
sensors.setWaitForConversion(true);
}
// All relays OUT
if (Cel1Active==0 && Cel1Running==true)
{
if (R01 == false) {
digitalWrite(R0_1, LOW);
}
if (R02 == false) {
digitalWrite(R0_2, LOW);
}
if (R03 == false) {
digitalWrite(R0_3, LOW);
}
// Pomp warm water uit
if (R04 == false) {
digitalWrite(R0_4, LOW);
}
// Ventiel koud water dicht
if (R05 == false) {
digitalWrite(R0_5, LOW);
}
// Ventiel warm water dicht
if (R06 == false) {
digitalWrite(R0_6, LOW);
}
// Weerstand vat uit
if (R07 == false) {
digitalWrite(R0_7, LOW);
}
// Stoombevochtiger uit
if (R08 == false) {
digitalWrite(R0_8, LOW);
}
if (R11 == false) {
digitalWrite(R1_1, LOW);
}
if (R27 == false) {
digitalWrite(R2_7, LOW);
}
delay (250);
Cel1Running = false;
}
// here starts the actual controlling process.
if (TVOCTemp>0 && SetTemp>0 && TVOCHum>0 && SetHum>0 && SetHDiff>0 and SetTDiff>0 && Cel1Active>0) // Make sure we have a reading
{
Cel1Running=true;
// Temperature Controlling :
// 1. Stop Cooling :
if (TVOCTemp<SetTemp && Cooling==true)
{
Cooling = false;
//pomp koud water uit , enkel indien compressor niet draait.
if (R03 == false && digitalRead(R0_2) == LOW && DeHumidActive==false )
{
digitalWrite(R0_3, LOW);
}
// Ventiel koud water dicht
if (R05 == false && DeHumidActive==false) {
digitalWrite(R0_5, LOW);
}
}
// Temperature Controlling :
// 2: Stop Heating
if (TVOCTemp>SetTemp && Heating==true)
{
Serial.println("--Stop Heating");
HeatDelayActive = false;
Heating = false;
// Pomp warm water uit, enkel indien compressor uit
if (R04 == false && digitalRead(R0_2) == LOW && DeHumidActive==false) {
digitalWrite(R0_4, LOW);
}
// Ventiel warm water dicht
if (R06 == false && DeHumidActive==false) {
digitalWrite(R0_6, LOW);
}
// Weerstand batterij uit
if (R11 == false && DeHumidActive==false) {
digitalWrite(R1_1, LOW);
}
}
// Temperature Controlling :
// 3 : Start Cooling , only when Temperature is Prior OR Humididity is OK
if ((TVOCTemp>(SetTemp+SetTDiff)) && ( Cel1Prior == 0 || (Cel1Prior == 1 && HumidActive == false && DeHumidActive == false)))
{
if (Cel1Prior == 0 && HumidActive==true)
{
digitalWrite(R0_8, LOW);
}
if (Cel1Prior == 0 && DeHumidActive==true)
{
digitalWrite(R0_6, LOW); // warm water ventiel dicht
}
Serial.println("--Start Cooling");
Cooling = true;
// Pomp koud water aan
digitalWrite(R0_3, HIGH);
// Koud water ventiel open
digitalWrite(R0_5, HIGH);
}
// Temperature Controlling :
// 4: Start Heating , only when Temperature is Prior OR Humididity is OK
if ((TVOCTemp<(SetTemp-SetTDiff)) && ( Cel1Prior == 0 || (Cel1Prior == 1 && HumidActive == false && HumidActive == false)))
{
if (Cel1Prior == 0 && HumidActive==true)
{
// Stoombevochtiger UIT
digitalWrite(R0_8, LOW);
}
if (Cel1Prior == 0 && DeHumidActive==true)
{
// koud water ventiel UIT
digitalWrite(R0_5, LOW);
}
Serial.println("--Start Heating");
Heating = true;
if (HeatDelayActive == false)
{
HeatDelayTime = millis();
HeatDelayActive = true;
}
if (((millis() - HeatDelayTime) >= (SetHeatDelay*60000)) && HeatDelayActive == true)
{
// Activeer weerstand batterij
digitalWrite(R1_1, HIGH); // tijdelijk uit
}
// Pomp warm water aan
digitalWrite(R0_4, HIGH);
// Warm water ventiel open
digitalWrite(R0_6, HIGH);
}
// Humidity Controlling :
// 1: Stop Drying :
if (TVOCHum<SetHum && DeHumidActive==true)
{
Serial.println("--Drying Stopped");
DeHumidActive = false ;
HeatDelayActive = false;
//pomp koud water uit , enkel indien compressor niet draait.
if (R03 == false && digitalRead(R0_2) == LOW ) {
digitalWrite(R0_3, LOW);
}
// Pomp warm water uit
if (R04 == false && digitalRead(R0_2) == LOW ) {
digitalWrite(R0_4, LOW);
}
// Ventiel koud water dicht
if (R05 == false) {
digitalWrite(R0_5, LOW);
}
// Ventiel warm water dicht
if (R06 == false) {
digitalWrite(R0_6, LOW);
}
// Weerstand batterij uit
if (R11 == false) {
digitalWrite(R1_1, LOW);
}
}
// 2: Stop Humiding
if (TVOCHum>SetHum && HumidActive==true)
{
HumidActive = false;
// Stoombevochtiger uit
if (R08 == false) {
digitalWrite(R0_8, LOW);
}
}
// 3: Start Drying
if ((TVOCHum>(SetHum+SetHDiff)) && ( Cel1Prior == 1 || (Cel1Prior == 0 && Heating ==false && Cooling== false)))
{
Serial.println("--Drying");
DeHumidActive = true;
if (temp4>temp3) // Uitgaande temperatuur van de batterij word te hoog, stop bijwarmen
{
// Pomp warm water UIT, enkel indien compressor uit
if (digitalRead(R0_2) == LOW) {
digitalWrite(R0_4, LOW);
}
// Ventiel warm water DICHT
digitalWrite(R0_6, LOW);
// Weerstand Batterij UIT
digitalWrite(R1_1, LOW);
}
if (temp4<temp3-10)
{
// Pomp warm water AAN
digitalWrite(R0_4, HIGH);
// Ventiel warm water OPEN
digitalWrite(R0_6, HIGH);
if (HeatDelayActive == false)
{
HeatDelayTime = millis();
HeatDelayActive = true;
}
if (((millis() - HeatDelayTime) >= (SetHeatDelay*60000)) && HeatDelayActive == true)
{
// Weerstand Batterij AAN
digitalWrite(R1_1, HIGH);
}
}
// pomp Koud Water AAN
digitalWrite(R0_3, HIGH);
// Ventiel Koud Water OPEN
digitalWrite(R0_5, HIGH);
// Pomp en ventiel warm water worden hierboven geregeld.
// bevochtigen uit
digitalWrite(R0_8, LOW);
}
// 4 : Start Humiding
if ( (TVOCHum<(SetHum-SetHDiff)) && ( Cel1Prior == 1 || (Cel1Prior == 0 && Heating ==false && Cooling== false)) )
{
Serial.println("--Humiding");
HumidActive = true;
digitalWrite(R0_8, HIGH);
}
//Compressor controlling
// 1: When temp in boiler is too high , start compressor
if ((temp2 - SetVatTempDiff)>SetVatTemp)
{
Serial.println("--Chiller sturing AAN");
// Magneetventiel AAN
Serial.println("--Magneetventiel AAN");
digitalWrite(R0_1, HIGH);
if (MagValve == false)
{
MagValve = true;
PressTime = millis();
}
if ( (millis() - PressTime) >= (PressDelay*1000))
{
if (digitalRead(R0_1) == HIGH && digitalRead(I0_2) == LOW )
{
// Alarm motor won't start , disabled for now
// SendAlarm(10);
// AlarmCount++;
}
}
// When Pressostat is HIGH is , start compressor , start pumps
if (digitalRead(I0_2)==HIGH)
{
Serial.println("--Pressostat HIGH = Compressor ON , pumps ON");
digitalWrite(R0_2, HIGH);
digitalWrite(R0_3, HIGH);
digitalWrite(R0_4, HIGH);
}
// When Pressostat is LOW, stop compressor :
if (digitalRead(I0_2)==LOW)
{
Serial.println("--Pressostat LOW = Compressor OFF , pumps OFF");
//Compressor uit
digitalWrite(R0_2, LOW);
}
}
// Stop compressor when temp is reached
if (temp2<=SetVatTemp)
{
//Magnet valve OFF
MagValve = false;
Serial.println("--Magnet ventil OFF");
digitalWrite(R0_1, LOW);
digitalWrite(R0_2, LOW);
if (Cooling==false && Heating==false && HumidActive==false && DeHumidActive==false)
{
digitalWrite(R0_3, LOW);
digitalWrite(R0_4, LOW);
}
// If Pressostat LOW , compressor OFF :
if (digitalRead(I0_2)==LOW)
{
Serial.println("--Pressostat LOW = Compressor OFF");
if (R02 == false) {
// Compressor UIT
digitalWrite(R0_2, LOW);
}
}
}
} // End main controlling LOOP
AlarmCount = 0;
// Set Alarms :
if ((LowTemp>0) && TVOCTemp>0 && (LowTemp)>TVOCTemp) // Temp te laag
{
SendAlarm(20);
AlarmCount++;
}
if (HighTemp>0 && TVOCTemp>0 && (HighTemp)<TVOCTemp) // Temp te hoog
{
SendAlarm(21);
ActiveAlarmCode=21;
AlarmCount++;
}
if (LowHum>0 && TVOCHum>0 && LowHum>TVOCHum) // Hum te laag
{
SendAlarm(22);
AlarmCount++;
}
if (HighHum>0 && TVOCHum>0 && HighHum<TVOCHum) // Hum te hoog
{
SendAlarm(23);
AlarmCount++;
}
// Als koud water vat te koud is
if (temp1<10 && temp1< MinVatT)
{
SendAlarm(24);
AlarmCount++;
}
// Als warm water vat te warm is
if (temp2>0 && temp2> MaxVatT)
{
SendAlarm(25);
AlarmCount++;
}
if ( AlarmCount == 0 )
{
// AlarmDelay.stop();
ActiveAlarmCode = 0;
}
}
void SendAlarm(int AlarmCode)
{
ActiveAlarmCode = AlarmCode;
/* Disabled for now
if (millis() - AlarmResendTime > 600000) {
char message[141] = "Alarm, controleer cel";
if (AlarmCode==20) { char message[141] = "Temperatuur cel te hoog"; }
if (AlarmCode==21) { char message[141] = "Temperatuur cel te laag"; }
if (AlarmCode==22) { char message[141] = "Luchtvochtigheid te laag"; }
if (AlarmCode==23) { char message[141] = "Luchtvochtigheid te hoog"; }
if (AlarmCode==24) { char message[141] = "Koud vat temperatuur te laag"; }
if (AlarmCode==25) { char message[141] = "Warm vat temperatuur te hoog"; }
if (!fona.sendSMS(phonenumber, message)) {
Serial.println(F("SMS Failed"));
} else {
Serial.println(F("SMS Sent!"));
}
AlarmResendTime=millis();
}
else
{
//Serial.println(F("Don't send yet"));
}*/
}
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = { 0, -1 };
int maxIndex = data.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++) {
if (data.charAt(i) == separator || i == maxIndex) {
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}
int getIntValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = { 0, -1 };
int maxIndex = data.length() - 1;
String result;
for (int i = 0; i <= maxIndex && found <= index; i++) {
if (data.charAt(i) == separator || i == maxIndex) {
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
result = found > index ? data.substring(strIndex[0], strIndex[1]) : "";
return result.toInt();
}
void ResetAlarm()
{
// Reset alarm relay , not used for now
if (R27 == false) {
digitalWrite(R2_7, LOW);
}
AlarmActive = false;
AlarmDelayTime = 0; // Set it to 0 to make the next alarm trigger immediatly
}
void flushSerial() {
while (Serial.available())
Serial.read();
}
char readBlocking() {
while (!Serial.available());
return Serial.read();
}
Anyway, for some reason, my code seems to make my MDuino freeze. Here in the test location at home i had never any issues. In the live situation it happens anywhere from every 2 hours to every 2 days. The communication seems to stop , and most of the time so does the PLC (code freezes). I tried to add a watchdog but the PLC became very unstable.
Do i need to check the packets before sending / recieving? or do i miss something?
Any help is very much appreciated . Thanks !