Hey all,
I'm building a garage door controller that exposes an HTTP UI for status and control. I'm having a few issues, which I think might be related either to the board or (more likely) my implementation of the code using WiFi.
Issue #1: WiFi seems to disconnect from the AP after a period of time, sometimes a few hours, but often mostly around 15 minutes
Issue #2: While operational, sending "too many" connections to the board (i.e. reloading the browser page more than about once every 3-4 seconds) will cause it to 'hang'.
My first and major issue is #1; it's largely useless as a garage door controller if I have to keep power-cycling the board every 15 minutes.
The code is below; note I had to remove code comments/truncate some functions for brevity to avoid hitting the maximum character limit for a post. Appreciate any pointers/tips you have for trying to get this to work more reliably!
(Oh, probably worth mentioning I've just updated the board firmware and the WiFi firmware, still no joy)
Thanks.
#include <WiFi101.h>
// ArduinoCloud - Version: Latest
#include <ArduinoCloud.h>
#include <ArduinoCloudThing.h>
#include <ArduinoCloudThingBase.h>
// Arduino Cloud settings and credentials
const char userName[] = "XXX";
const char thingName[] = "XXX";
const char thingId[] = "XXX";
const char thingPsw[] = "XXX";
WiFiSSLClient sslClient;
ArduinoCloudThing GDC;
// Configuration
int RELAY_PIN = 7;
int SWITCH_SENSOR_PIN = 8;
int SWITCH_POWER_PIN = 9;
int RELAY_DURATION_MS = 750;
char SSID[] = SECRET_SSID;
char PASSWORD[] = SECRET_PASSWORD;
// Global variables
int relayTriggering = 0;
int errorState = 0;
const int OPEN = HIGH;
const int CLOSED = LOW;
int status = WL_IDLE_STATUS;
String doorState = "UNKNOWN";
String lastDoorState = "UNKNOWN";
int wifiStatus;
// Objects
WiFiServer server(80);
void setup() {
configurePins();
Serial.begin(9600);
delay(3500);
initialiseWifi();
initialiseServer();
//Arduino cloud
GDC.begin(thingName, userName, thingId, thingPsw, sslClient);
GDC.enableDebug();
GDC.addProperty("garageDoorStatus", CHARSTRING, R);
GDC.addProperty("sensorPinValue", INT, R);
initialiseSensorSwitch();
digitalWrite(6, HIGH);
}
void loop() {
listenHttpServer();
getDoorState();
checkAndReconnectWifi();
}
void configurePins() {
pinMode(RELAY_PIN, OUTPUT);
pinMode(SWITCH_SENSOR_PIN, INPUT_PULLUP);
pinMode(SWITCH_POWER_PIN, OUTPUT);
pinMode(6, OUTPUT);
}
void initialiseSensorSwitch() {
digitalWrite(SWITCH_POWER_PIN, HIGH);
digitalWrite(SWITCH_SENSOR_PIN, HIGH);
doorState = getDoorState();
Serial.println("Writing door state to Arduino cloud...");
GDC.writeProperty("garageDoorStatus", doorState);
GDC.writeProperty("sensorPinValue", digitalRead(SWITCH_SENSOR_PIN));
}
String getDoorState() {
int state = digitalRead(SWITCH_SENSOR_PIN);
digitalWrite(6, !state);
if (state == LOW) {
doorState = "CLOSED";
} else {
doorState = "OPEN";
}
if (doorState != lastDoorState) {
lastDoorState = doorState;
GDC.writeProperty("garageDoorStatus", doorState);
}
return doorState;
}
void initialiseServer() {
server.begin();
}
// Create an HTTP Server to listen for connections and return pages.
void listenHttpServer() {
WiFiClient client = server.available();
if (client) {
//Serial.println("new client");
String currentLine = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
//Serial.write(c);
if (c == '\n') {
if (currentLine.length() == 0) {
String hdrs = "";
String page = indexPage();
hdrs += "HTTP/1.1 200 OK\n";
hdrs += "Content-type:text/html\n";
hdrs += "Server: GDC, by Richard Parker\n";
hdrs += "Connection: close\n";
hdrs += "Content-Length: " + page.length();
hdrs += "\n";
hdrs += "\n\n";
client.print(hdrs);
client.print(page);
client.print("\n\n");
break;
}
else {
currentLine = "";
}
}
else if (c != '\r') {
currentLine += c;
}
if (currentLine.endsWith("GET /PUSH")) {
pulseRelay();
}
}
}
client.stop();
Serial.println("disconnected client");
}
}
String indexPage() {
String response = "";
response += "<html>\n";
response += "<head>\n";
// Truncated for brevity
// The HTTP response ends with another blank line:
response += "</div>\n";
response += "</body></html>\n";
return response;
}
String getDoorStateHtml() {
// Truncated for brevity
}
// Initialise and turn ON WiFi...
void initialiseWifi() {
Serial.println("BOOT: Initialising WiFi... ");
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("ERROR: WiFi chip not present.");
errorState = 1;
}
else {
Serial.println("BOOT: WiFi chip OK!");
Serial.print("WIFI: Attempting to connect to SSID: ");
Serial.println(SSID);
while (wifiStatus != WL_CONNECTED) {
wifiStatus = WiFi.begin(SSID, PASSWORD);
delay(5000);
}
Serial.print("WIFI: ");
Serial.print(SSID);
Serial.println(" connected!");
printWifiStatus();
}
}
void checkAndReconnectWifi() {
if (WiFi.status() != WL_CONNECTED) {
while (status != WL_CONNECTED) {
Serial.println("WIFI: Disconnected. Reconnecting...");
status = WiFi.begin(SSID, PASSWORD);
delay(5000);
}
Serial.println("WIFI: Reconnected!");
printWifiStatus();
}
}
void printWifiStatus() {
// Truncated for brevity
}
void pulseRelay() {
if (relayTriggering == true) { exit; } // This is effectively a "de-bounce" for relay-triggering.
relayTriggering = true;
Serial.print("Triggering relay... ");
digitalWrite(RELAY_PIN, OPEN);
delay(RELAY_DURATION_MS);
digitalWrite(RELAY_PIN, CLOSED);
Serial.println("Finished.");
relayTriggering = false;
}