hello
I am having issues with Arduino wifi Rev2 when enabling wifi, the system becomes very unstable and hangs from time to time. It is hard to predict when, sometimes after few minutes sometimes after hours, but I need a way to reset the MCU as it is controlling my aquarium (lights, co2, etc).
I configured a watchdog and noticed that the controller is reset very often, at least 3/4 times per hour, sometimes even more...can this be considered normal?
here the updated code
#include "arduino_secrets.h"
#include <Wire.h> // enable I2C.
#include <RCSwitch.h> // enable RF transmission.
#include "rgb_lcd.h" // enable LCD.
#include <avr/wdt.h>
#include <SPI.h>
#include <Time.h>
#include "RTClib.h"
#include "DHT.h" // enable DHT Temperature sensor.
#include <WiFiNINA.h> // change to #include <WiFi101.h> for MKR1000
#define LED 3 //connect LED to digital pin2
#define TOTAL_CIRCUITS 3 // <-- CHANGE THIS | set how many I2C circuits are attached to the Tentacle
#define DHTPIN A0 // what pin we're connected to
#define DHTTYPE DHT11 // DHT 11
#define WDTO_8S 9 // watchdog
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 rtc;
// Enter your sensitive data in arduino_secrets.h
const char ssid[] = SECRET_SSID;
const char pass[] = SECRET_PASS;
// Network / Wifi settings
int status = WL_IDLE_STATUS;
WiFiClient client;
// Influx code
byte host[] = {192, 168, 1, 120};
int port = 8086;
char buff[256];
// Atlas code
char sensordata[30]; // A 30 byte character array to hold incoming data from the sensors
byte sensor_bytes_received = 0; // We need to know how many characters bytes have been received
byte code = 0; // used to hold the I2C response code.
byte in_char = 0; // used as a 1 byte buffer to store in bound bytes from the I2C Circuit.
int channel_ids[] = {100, 101, 102}; // <-- CHANGE THIS. A list of I2C ids that you set your circuits to.
char *channel_names[] = {"PH", "EC", "Temp"}; // <-- CHANGE THIS. A list of channel names (must be the same order as in channel_ids[]) - only used to designate the readings in serial communications
// variables & stuff
float pH, temp, ec, t, h;
rgb_lcd lcd;
const int colorR = 0;
const int colorG = 100;
const int colorB = 255;
String data;
int lights, ph_status;
int wdt_reset = 0;
// RF code
RCSwitch mySwitch = RCSwitch();
void setup()
{
Serial.begin(9600); // Set the hardware serial port.
Wire.begin(); // enable I2C port.
// RF init
mySwitch.enableTransmit(2);
mySwitch.setPulseLength(166);
mySwitch.setRepeatTransmit(4);
// LCD init
lcd.display();
lcd.begin(16, 2);
// Temp sensor init
dht.begin();
// initialize rtc
rtc.begin();
//connect to wifi
wifiConnect();
// Setup watchdog
Serial.println("Starting watchdog");
watchdogSetup();
}
void loop()
{
// reset watchdog
Serial.println("Resetting watchdog");
wdt_reset();
// Run readings
for (int channel = 0; channel < TOTAL_CIRCUITS; channel++) { // loop through all the sensors
Wire.beginTransmission(channel_ids[channel]); // call the circuit by its ID number.
Wire.write('r'); // request a reading by sending 'r'
Wire.endTransmission(); // end the I2C data transmission.
delay(1000); // AS circuits need a 1 second before the reading is ready
sensor_bytes_received = 0; // reset data counter
memset(sensordata, 0, sizeof(sensordata)); // clear sensordata array;
Wire.requestFrom(channel_ids[channel], 48, 1); // call the circuit and request 48 bytes (this is more then we need).
code = Wire.read();
while (Wire.available()) { // are there bytes to receive?
in_char = Wire.read(); // receive a byte.
if (in_char == 0) { // null character indicates end of command
Wire.endTransmission(); // end the I2C data transmission.
break; // exit the while loop, we're done here
}
else {
sensordata[sensor_bytes_received] = in_char; // append this byte to the sensor data array.
sensor_bytes_received++;
}
}
if (channel_names[channel] == "PH")
{ //sensore PH
pH = atof(sensordata); //convert the string to a floating point number so it can be evaluated by the Arduino
if (pH >= 6.7)
{ //if the pH is greater than or equal to 6.7, activate co2 supply via RF link
Serial.print("pH is basic, activating CO2 : ");
ph_status = 1;
digitalWrite(LED, HIGH);
Serial.println(pH, 3);
mySwitch.send(5330227, 24);
}
if (pH < 6.7)
{ //if the pH is less than or equal to 6.7, power off co2 supply via RF link
Serial.print("pH is ok, turning off CO2 : ");
ph_status = 0;
digitalWrite(LED, LOW);
Serial.println(pH, 3);
mySwitch.send(5330236, 24);
}
}
if (channel_names[channel] == "Temp")
{ //sensore temperatura
temp = atof(sensordata); //convert the string to a floating point number so it can be evaluated by the Arduino
}
if (channel_names[channel] == "EC")
{ //sensore conduttività
ec = atof(sensordata); //convert the string to a floating point number so it can be evaluated by the Arduino
}
Serial.print(channel_names[channel]); // print channel name
Serial.print(':');
switch (code) { // switch case based on what the response code is.
case 1: // decimal 1 means the command was successful.
Serial.println(sensordata); // print the actual reading
break; // exits the switch case.
case 2: // decimal 2 means the command has failed.
Serial.println("command failed"); // print the error
break; // exits the switch case.
case 254: // decimal 254 means the command has not yet been finished calculating.
Serial.println("circuit not ready"); // print the error
break; // exits the switch case.
case 255: // decimal 255 means there is no further data to send.
Serial.println("no data"); // print the error
break; // exits the switch case.
}
}
// Do other stuff here (Update a display, etc)
//delay(2500); // service the alarm timers once per second
lcd.setRGB(colorR, colorG, colorB);
lcd.setCursor(0, 0);
lcd.print("pH:");
lcd.print(pH);
lcd.print(" ");
lcd.print("uS:");
lcd.print(ec);
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(temp);
h = dht.readHumidity();
t = dht.readTemperature();
if (isnan(t) || isnan(h))
{
Serial.println("Failed to read from DHT");
}
wifiConnect();
influx();
ptime(); // print time and check whether lights need to be turned on/off
DateTime now = rtc.now();
// if (now.hour() == 22 && now.minute() == 15)
if (now.hour() >= 13 && now.hour() < 21) {
LedOn();
} else {
LedOff();
}
}
void LedOn()
{
Serial.println("Turning on LED Lights");
lights = 1;
mySwitch.send(5330371, 24);
}
void LedOff()
{
Serial.println("Turning off LED Lights, good night :)");
lights = 0;
mySwitch.send(5330380, 24);
}
void influx()
{
// Send data to Influx
if (client.connect(host, port))
{
Serial.println("##########################");
Serial.println("connected to Influx server");
sprintf(buff, "aquarium ph=%.2f,temp_int=%.2f,temp_ext=%.2f,µS=%.2f,lights=%d,ph_status=%d,wdt_reset=%i", pH, temp, t, ec, lights, ph_status, wdt_reset);
Serial.print("String being posted to Influx: ");
Serial.println(buff);
// send the HTTP POST request:
client.println("POST /write?db=aquarium HTTP/1.1");
client.println("User-Agent: Arduino/1.0");
client.println("Host: arduino");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Content-Length: " + String(strlen(buff)));
client.println("Connection: close");
client.println();
client.println(buff);
client.println();
// flush all connections
client.stop();
Serial.println("client disconnected");
Serial.println("##########################");
delay(500);
}
else
{
// if you couldn't make a connection:
Serial.println("EEEEEEEEEEEEEEEEEEEEEEEEE");
Serial.println("connection failed");
Serial.println();
Serial.println("disconnecting from server.");
Serial.println("EEEEEEEEEEEEEEEEEEEEEEEEE");
client.stop();
}
}
void ptime() {
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" - ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
}
void wifiConnect() {
// Return to loop() if already connected to the WLAN router
if (WiFi.status() == WL_CONNECTED)
{
Serial.println("-----------------------------------------------");
Serial.println("We are alredy connected to network, skipping...");
Serial.println("-----------------------------------------------");
return;
}
// Wifi connect
status = WiFi.disconnect();
Serial.println("+++++++++++++++++++++++++++++++++++++++");
Serial.println("Attempting to connect to WPA network...");
Serial.println("+++++++++++++++++++++++++++++++++++++++");
status = WiFi.begin(ssid, pass);
// if unable to connect, halt
if (status != WL_CONNECTED)
{
Serial.println("Couldn't get a WiFi connection");
while (true);
}
// if the conneciton succeeded, print network info
else {
Serial.println("Connected to network");
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
String fv = WiFi.firmwareVersion();
Serial.print("Firmware version: ");
Serial.println(fv);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
// wait 10 seconds for connection:
delay(3500);
}
void watchdogSetup() {
#ifdef ARDUINO_ARCH_MEGAAVR
if (RSTCTRL.RSTFR & RSTCTRL_WDRF_bm) {
Serial.println("EEEEEEEEEEEEEEEEEEEEEEEEE");
Serial.println(F("It was a watchdog reset."));
Serial.println("EEEEEEEEEEEEEEEEEEEEEEEEE");
wdt_reset = 1;
influx();
wdt_reset = 0;
}
RSTCTRL.RSTFR |= RSTCTRL_WDRF_bm ;
wdt_enable(WDT_PERIOD_8KCLK_gc);
#endif
}