Hi everybody,
My setup is made by 2 arduino uno wifi ver2. One read sensors and send data to a webserver.
The second just ask to webserver what to do and turn on or off the relay.
i have a problem with my arduino controlling 8 relay channels.
After few hours it freeze and there is no way to resume it.. try to reset button, to swich off power for hours to move it to another room connected to the laptop...
Until I reprogram nothing restart to work... after the reprogramming restart working normally for few hours.. maybe 1 day...
I really don't know that can I do...
When that happen I don't see arduino conected (in the router), that mean it do not make the setup() where it open connection...
here is the code:
#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoJson.h>
//#################################################################################
// ONLY RELAY MANAGER
#include "multi_channel_relay.h"
////////////////////////////
// BOOLEAN VALUES ACTIVE STATE
// That Bool Var determine the switch on or off about the relay
//Last operation in Loop check that values and change relay state
Multi_Channel_Relay relay;
Multi_Channel_Relay relay2;
//**************************************************
// ARDUINO SETUP TO LINK AT HYDROPONYX SYSTEM ONLINE
//**************************************************
//*** ***
int ArduinoId = 21;
String HostRoot = "arduino";
char HostName[] = "192.168.1.116";
//*** ***
//**************************************************
//**************************************************
//////////////////////////////////////////////////////////////////////////////////////////
// WIFI
char ssid[] = "newnyxnet"; // your network SSID (name)
char pass[] = "000sfh000"; // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS; // the WiFi radio's status
// END WIFI
////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// VARIABLES
WiFiClient client;
String readString;
int SendDataMinutes = 1;
int NextSendMinute = 0;
int RebootSeconds = 1000;
long LoopTimeSeconds = 10;
int nowM = 0;
int nowH = 0;
int nowS = 0;
// END VARIABLES
//////////////////////////////////////////////////////////////////////////////////////////
DynamicJsonDocument getRequest(String HostPage,String HostCommand, String Parameters = "");
bool HumActive = false;
bool DripActive = false;
bool FanMainActive = false;
bool FanAuxActive = false;
bool AirInActive = false;
bool HotActive = false;
// JUST TO LOG
int ActiveTemperature = 0;
int ActiveHumidity = 0;
//
//////////////////////////
//#################################################################################
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
relay.begin(0x11);
relay2.begin(0x21);
//dht.begin();
//dht2.begin();
Serial.println("****** BEGIN HYDROPONIY******");
// *** WIFI ***
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
// you're connected now, so print out the data:
Serial.print("You're connected to the network");
printCurrentNet();
printWifiData();
// *** END WIFI ***
//**********************************
WakeUp();
timeUpdate();
setConfigVariables();
NextSendMinute = nowM;
relayBegin();
}
void(* resetFunc) (void) = 0; //declare reset function @ address 0
//###########################################################################################################
//###########################################################################################################
void loop() {
HeartBeat();
if(NextSendMinute < nowM)
{
//Va bene solo nel caso NextSendMinute = 0 e nowM 59
if(NextSendMinute == 0 && nowM == 59){NextSendMinute = 0;}
//Negli altri casi reimpostare NextSendMinute a nowM
else{NextSendMinute = nowM;}
}
String logg = "NextSendMinute:" + String(NextSendMinute);
sysLog(logg);
delay(500);
Serial.println("***** START LOOP SECTION *****");
setConfigVariables();
timeUpdate();
if(getStartedSeconds() > RebootSeconds){resetFunc();}
setRelayStatus();
deployRelay();
if(isLogTime()){ logRelayStatus(); }
isArduinoToReboot();
Serial.println();
String str = "***** DELAY " + String(LoopTimeSeconds) + " SECONDS *****";
Serial.print(str);
Serial.println();
delay(getLoopTime());
Serial.println("***** END LOOP SECTION *****");
}
//###########################################################################################################
//###########################################################################################################
void WakeUp() //client function to send/receive GET request data.
{
String Param = "&arduinoId=" + String(ArduinoId);// + "&ip=" + IpAddress + "&mac=" + MacAddress;
sendRequest("logger","wakeUp",Param);
}
void HeartBeat() //client function to send/receive GET request data.
{
String Param = "&arduinoId=" + String(ArduinoId);// + "&ip=" + IpAddress + "&mac=" + MacAddress;
sendRequest("logger","heartbeat",Param);
}
void logEnvironment(float t1,float t2, float h1, float h2) //client function to send/receive GET request data.
{
int st = getStartedSeconds();
String Param = "&arduinoId=" + String(ArduinoId) + "&t1=" + String(t1) + "&h1=" + String(h1) + "&t2=" + String(t2) + "&h2=" + String(h2) + "&ss=" + String(st);
sendRequest("logger","logEnvironment",Param);
}
void logRelayStatus()
{
int st = getStartedSeconds();
int at = ActiveTemperature;
int ah = ActiveHumidity;
String Param = "&arduinoId=" + String(ArduinoId) + "&hum=" + String(HumActive) + "&airIn=" + String(AirInActive) + "&fanMain=" + String(FanMainActive) + "&fanAux=" + String(FanAuxActive) + "&drip=" + String(DripActive) + "&hot=" + String(HotActive) + "&ss=" + String(st) + "&at=" + String(at) + "&ah=" + String(ah);
sendRequest("logger","setRelayStatus",Param);
}
void timeUpdate()
{
DynamicJsonDocument doc = getRequest("logger","getTime");
Serial.println("Response:");
nowM = doc["getTimeMinutes"].as<int>();
nowH = doc["getTimeHours"].as<int>();
nowS = doc["getTimeSeconds"].as<int>();
String str = String(nowH) + ":" + String(nowM) + ":" + String(nowS) + " - Updated Time!";
Serial.println();
Serial.print(str);
Serial.println();
}
void setConfigVariables()
{
String Param = "&arduinoId=" + String(ArduinoId);
DynamicJsonDocument doc = getRequest("logger","getConfigs",Param);
// Extract values
Serial.println(F("Response:"));
Serial.print("SendDataMinutes: ");Serial.println(doc["SendDataMinutes"].as<int>());
Serial.print("RebootSeconds: ");Serial.println(doc["RebootSeconds"].as<int>());
Serial.print("LoopTimeSeconds: ");Serial.println(doc["LoopTimeSeconds"].as<int>());
SendDataMinutes = doc["SendDataMinutes"].as<int>();
RebootSeconds = doc["RebootSeconds"].as<int>();
LoopTimeSeconds = doc["LoopTimeSeconds"].as<int>();
// Disconnect
client.stop();
}
void sysLog(String text)
{
String Param = "&arduinoId=" + String(ArduinoId) + "&logText=" + text;
sendRequest("logger","log",Param);
}
bool isLogTime()
{
//se NOW m uguale al prossimo send minute torno true e rivalorizzo NextSendMinute con + minuti in base a var
Serial.println();
Serial.print("---Check next log time:");
Serial.print(NextSendMinute);
if(NextSendMinute > 59) {NextSendMinute -= 60;}
if(nowM == NextSendMinute)
{
Serial.print(" Add time for next");
NextSendMinute += SendDataMinutes;
if(NextSendMinute > 59){NextSendMinute -= 60;}
return true;
}
return false;
}
void isArduinoToReboot()
{
Serial.println();
Serial.print("---- Check if Arduino Logger need a reboot ------");
Serial.println();
String Param = "&arduinoId=1";
DynamicJsonDocument doc = getRequest("logger","RebootPending",Param);
int RebootArd = doc["RebootPending"].as<int>();
if(RebootArd == 1){ Serial.print("Reboot needed!");Serial.println();sysLog("ArduinoLoggerNeedReboot.StartRebootChannel7"); resetArduinoLogger();}
else{Serial.print("Reboot not needed");Serial.println();}
}
///////////////////////////////////////////////////////////////
// TOOLS
String getTimeFormatted()
{
String tt = String(nowH) + ":" + String(nowM) + ":" + String(nowS);
return tt;
}
int getStartedSeconds()
{
long m = millis();
int s = m/1000;
return s;
}
long getLoopTime()
{
return LoopTimeSeconds * 1000;
}
/////////////////////////////////////////
// LOGS METHODS
void WriteLog() {
delay(20);
Serial.println();
Serial.flush();
}
void WriteLogText(String str)
{
delay(20);
Serial.print(str);
Serial.print(" ");
Serial.flush();
}
void WriteLogText(int str)
{
delay(20);
Serial.print(str);
Serial.print(" ");
Serial.flush();
}
// END LOG METHODS
/////////////////////////////////////////////////
//*****************************************************************************
//********************************************************************************
//** WIFI
void printWifiData() {
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
Serial.println(ip);
// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}
void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
void printMacAddress(byte mac[]) {
for (int i = 5; i >= 0; i--) {
if (mac[i] < 16) {
Serial.print("0");
}
Serial.print(mac[i], HEX);
if (i > 0) {
Serial.print(":");
}
}
Serial.println();
}
////////////////////////////////////////////////////////////
// HTTP REQUEST
void sendRequest(String HostPage,String HostCommand, String Parameters)
{
Serial.println();
Serial.print("--- SEND REQUEST ---");
Serial.println();
//************
// *** FIXED
String Host = "Host: " + String(HostName);
//************
HostRoot = "/" + HostRoot;
HostPage = "/" + HostPage + ".php";
HostCommand = "?" + HostCommand;
String GET = HostRoot + HostPage + HostCommand; //"/arduino/logger.php?logEnvironment";
String ToSend = "GET " + GET + Parameters + " HTTP/1.1";
//************
Serial.println();Serial.print("ToSend: ");Serial.print(ToSend);
if (client.connect(HostName, 80)) { //starts client connection, checks for connection
Serial.println("connected");
client.println(ToSend); //download text
client.println(Host);
client.println("Connection: close"); //close 1.1 persistent connection
client.println(); //end of get request
}
else {Serial.println("connection failed"); Serial.println();}
while (client.connected() && !client.available()) delay(1); //waits for data
while (client.connected() || client.available()) { //connected or data available
char c = client.read(); //gets byte from ethernet buffer
readString += c; //places captured byte in readString
}
client.stop(); //stop client
Serial.println("client disconnected."); Serial.println(); Serial.print(readString);
readString = ""; //clear readString variable
Serial.println();Serial.print("Data Logged to Server!");Serial.println();
Serial.println();
Serial.print("--- END SEND REQUEST ---");
Serial.println();
}
DynamicJsonDocument getRequest(String HostPage,String HostCommand, String Parameters)
{
Serial.println();
Serial.print("--- SEND GET REQUEST ---");
Serial.println();
//************
// *** FIXED
String Host = "Host: " + String(HostName);
//************
HostRoot = "/" + HostRoot;
HostPage = "/" + HostPage + ".php";
HostCommand = "?" + HostCommand;
String GET = HostRoot + HostPage + HostCommand; //"/arduino/logger.php?logEnvironment"; E
String ToSend = "GET " + GET + Parameters + " HTTP/1.1";
//************
Serial.println();Serial.print("ToSend: ");Serial.print(ToSend);
if (client.connect(HostName, 80)) { //starts client connection, checks for connection
Serial.println("connected");
client.println(ToSend); //download text
client.println(Host);
client.println("Connection: close"); //close 1.1 persistent connection
client.println(); //end of get request
}
else {Serial.println("connection failed"); Serial.println();resetFunc(); }
// Check HTTP status
char status[32] = {0};
client.readBytesUntil('\r', status, sizeof(status));
// It should be "HTTP/1.0 200 OK" or "HTTP/1.1 200 OK"
if (strcmp(status + 9, "200 OK") != 0) {
Serial.print(F("Unexpected response: "));
Serial.println(status);
client.stop();
resetFunc();
return;
}
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!client.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
client.stop();
resetFunc();
return;
}
// Allocate the JSON document
// Use https://arduinojson.org/v6/assistant to compute the capacity.
const size_t capacity = 512;//JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60;
DynamicJsonDocument doc(capacity);
// Parse JSON object
DeserializationError error = deserializeJson(doc, client);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
client.stop();
resetFunc();
return;
}
client.stop();
Serial.println();
Serial.print("--- END SEND GET REQUEST ---");
Serial.println();
return doc;
}
// HTTP REQUEST
////////////////////////////////////////////////////////////
//#########################################################################################################################################################################
//#########################################################################################################################################################################
// START SECTION ONLY RELAY MANAGER
//#########################################################################################################################################################################
//#########################################################################################################################################################################
void setRelayStatus()
{
String Param = "&arduinoId=" + String(ArduinoId);
DynamicJsonDocument doc = getRequest("logger","getRelayStatus",Param);
// Extract values
Serial.println(F("Response:"));
Serial.print("HumiState: ");Serial.println(doc["Hum"].as<int>());
Serial.print("AirInState: ");Serial.println(doc["AirIn"].as<int>());
Serial.print("FanMainState: ");Serial.println(doc["FanMain"].as<int>());
Serial.print("FanAuxState: ");Serial.println(doc["FanAux"].as<int>());
Serial.print("DripState: ");Serial.println(doc["Drip"].as<int>());
Serial.print("HotState: ");Serial.println(doc["Hot"].as<int>());
Serial.print("ActiveTemperature(0=ok,1=down,2=up): ");Serial.println(doc["ActiveTemperature"].as<int>());
Serial.print("ActiveHumidity(0=ok,1=down,2=up): ");Serial.println(doc["ActiveHumidity"].as<int>());
HumActive = doc["Hum"].as<int>();
AirInActive = doc["AirIn"].as<int>();
FanMainActive = doc["FanMain"].as<int>();
FanAuxActive = doc["FanAux"].as<int>();
DripActive = doc["Drip"].as<int>();
HotActive = doc["Hot"].as<int>();
ActiveTemperature = doc["ActiveTemperature"].as<int>();
ActiveHumidity = doc["ActiveHumidity"].as<int>();
// Disconnect
client.stop();
}
void deployRelay()
{
WriteLog(); WriteLogText("----- Start Deploy Relay channels -----");
//HUMIDIFIER
if (HumActive)turnOn(1);
else turnOff(1);
WriteLog(); WriteLogText("Humidifier"); WriteLogText(HumActive);
//AIR IN
if (AirInActive) turnOn(2);
else turnOff(2);
WriteLog(); WriteLogText("AirIN"); WriteLogText(AirInActive);
//FAN MAIN
if (FanMainActive) turnOn(3);
else turnOff(3);
WriteLog(); WriteLogText("FanMain"); WriteLogText(FanMainActive);
//DRIP
if (DripActive) turnOn(4);
else turnOff(4);
WriteLog(); WriteLogText("Drip"); WriteLogText(DripActive);
//HOT
if (HotActive) turnOn(5);
else turnOff(5);
WriteLog(); WriteLogText("Hot"); WriteLogText(HotActive);
//FAN AUX
if (FanAuxActive) turnOn(6);
else turnOff(6);
WriteLog(); WriteLogText("FanAux"); WriteLogText(FanAuxActive);
WriteLog(); WriteLogText("----- END Deploy Relay Channels ------");
}
/////////////////////////////////////////////////
//RELAY METHODS
void turnOn(int i)
{
int index = i;
if (i > 4)
{
index = i - 4;
relay2.turn_on_channel(index);
}
else
{
relay.turn_on_channel(index);
}
}
void turnOff(int i)
{
int index = i;
if (i > 4)
{
index = i - 4;
relay2.turn_off_channel(index);
}
else
{
relay.turn_off_channel(index);
}
}
void relayBegin()
{
WriteLog();WriteLogText("----- START BEGIN RELAY -----");
turnOff(1);
turnOff(2);
turnOff(3);
turnOff(4);
turnOff(5);
turnOff(6);
//turnOff(7);
WriteLog();WriteLogText("Set all channel to OFF 1-7");
WriteLog();WriteLogText("----- END BEGIN RELAY -----");
}
void resetArduinoLogger()
{
Serial.println();
Serial.print("------ REBOOT ARDUINO -------");
Serial.println();
Serial.print("TurnOff Relay 7");
turnOn(7);
delay(5000);
Serial.print("Turn on Relay 7");
//NextSendMinute += 2;
turnOff(7);
delay(55000);
}
void selfReboot()
{
sysLog("Perform a HardReset , shut down my own relay 2 channel 4 (ch 8)");
turnOn(8);
}
Thanks a lot
Bye
Nyk