@lukecyca started off the ESP8266 project here:
I tried using the suggested tools but had no luck getting them installed on my Linux box. So I went looking for other options and was hoping for something Arduino IDE like as that is what I am used to using.
First I found that Adafruit had set up some libraries/hardware files that you could link to from your existing Arduno IDE: Using Arduino IDE | Adafruit HUZZAH ESP8266 breakout | Adafruit Learning System I tried this and while the code would compile, the upload would freeze.
Kept looking and found this: GitHub - esp8266/Arduino: ESP8266 core for Arduino I downloaded the Windows binary and it worked like a charm.
Out of the complete lack of creativity on my part I decided to port @lukecyca example onto the Arduino IDE. You can download it here: YAisVHSopen1.zip (2.6 KB)
The code basically monitors the vhs door api and lights LEDs as expected. I was having various issues so the serial monitor tracks various things. Keep in mind I am no programmer so I sort of cobbled together something from various places to parse the text from the site. Learned a bunch about control characters and such. I also added code to track various connection issues that I was (still) having. Handling errors and exceptions is more work than the prime taskā¦
Did run into a few issues:
-
While the average power draw of the module seems less than 100 mA it draws a lot more when the radio fires off. I was using a small Solarbotics Breadboard Power Supply and it seemed that because itās filter capacitor was small, it could not handle the spike in current draw. This didnāt seem to affect the processor but the radio would lose connectivity to my AP. Running off a larger power supply and adding larger filter caps seemed to solve this issue.
-
While I seemed to fix the above issues I find that the system will still lose itās connection to my AP and requires a reset. Again the serial monitor and processor seem fine but the program can no longer connect to the api site and I can no longer ping the unit on my network. Seems to happen randomly after several hours. Prior to moving to a better power supply it was happening every few minutes so perhaps it is related. One thing I tried to add was a reset through an API call but that feature is no yet working on the IDE. Another way to do it would be to use a GPIO pin to reset the module if once the connections start to fail. However Iād like to figure out why this is happening. Is it my AP (Apple AirPort), is it the type of WIFI connection Iām using (not sure if itās B, G or N), is it my carrier PCB (seems pretty solid), is it a bad batch of modules (same thing happens of 3 different one but they all came from AliExpress)
-
Even when I connect properly my parsing seems to fail a small percentage of times. Iād like to think itās the api host but manual testing from a browser never fails. More likely itās my code or possibly a glitch in the Arduino/ESP port. Again Iām no programmer so there may be much better ways to get what I want doneā¦
Here is the breadboard set up (note various extra caps):
Here is a crooked screenshot:
And here is the code (also in attached zip file), I tried to add lots of comments to help others figure out what I was doing:
// YA_isVHSopen_1.91 Bob Johnson May 8, 2015
// Test program using the Windows version (1.6.1-p1)of the Arduino based IDE for the ESP8266 module
// You can get it here: https://github.com/esp8266/Arduino
// Mashup of WiFiClient example and idea stolen from lukecyca: https://github.com/vhs/esp-isvhsopen
// Client goes to VHS api site and grabs isvhsopen result (either "open" or "closed")
// Code should leave no doubt that I am not a programmer
// Green OPEN LED connected to GPIO12 via 330 ohm resister
// Red CLOSED LED connected to GPIO13 via 330 ohm resister
// I used an ESP-07 from here:
// http://www.aliexpress.com/item/10pcs-ESP8266-serial-WIFI-model-ESP-07-Authenticity-Guaranteed-WIFI-module/32264981572.html
// I used a breakout board from here:
// https://www.tindie.com/products/Ba0sh1/esp8266-esp-0712-full-io-breadboard-adapter/
// Make sure you use a decent power supply, connections failing are an indication of power issues
// these are all the libraries, defines, constant declarations, etc
#include <ESP8266WiFi.h>
// this is where you put the SSID and PW for your AP
const char* ssid = "put your SSID here";
const char* password = "put your password here";
// this is the host and path to the data we want
const char* host = "api.vanhack.ca";
const char* url = "/s/vhs/data/door.txt";
// count for connnection fail reboot
float check_count; // # of times we check the web site
float fail_count; // # of times we didn't get get a http connection to server
float fail_percent; // used to calculate pertage times for open and closed
float open_count; // # of times VHS was open when we checked
float closed_count; // # of times VHS was closed when we checked
float open_percent; // used to calculate pertage times for open and closed
float closed_percent; // used to calculate pertage times for open and closed
float bad_data_percent; // used to calculate pertage times for open and closed
float bad_data_count; // used to calculate pertage times for open and closed
int flag; // flag to track if we got expected data
// these are the GPIO pins used to control the LEDs
#define OPEN_LED 12
#define CLOSED_LED 13
// this is the time delay in milliseconds in between checking the VHS API site.
// 60 seconds is good to avoid overloading it (cuz all the cool kids are makign one of these)
#define WAIT 58000
// this is the start of the setup section
void setup() {
// this sets up the pins as outputs
pinMode(OPEN_LED, OUTPUT); // set up green led output
pinMode(CLOSED_LED, OUTPUT); // set up red led output
// this initializes the serial port for monitoring
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println("####################################");
Serial.println(" YA_isVHSopen_1.91");
Serial.println("####################################");
Serial.print("Connecting To: ");
Serial.println(ssid);
// this starts up the WiFi network connection
WiFi.begin(ssid, password);
// this keeps trying until connected
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// this tells you your network connection information
Serial.println("");
Serial.println("WiFi Connected!!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("####################################");
Serial.println();
}
// this is the start of the main loop
void loop() {
//this sets up up the tcp connection to the server
WiFiClient client;
const int httpPort = 80;
delay(50); // delay to try to fix seemingly random freezes
// this tells you if it can't connect to the server
if (!client.connect(host, httpPort)) {
digitalWrite(OPEN_LED, LOW); // turn off any leds to avoid showing bad data
digitalWrite(CLOSED_LED, LOW);
fail_count++; // increment count to track how many times it fails
Serial.println();
Serial.println("####################################");
Serial.print("Connection Failed ");
Serial.print(fail_count, 0);
Serial.println(" Times... Crap");
Serial.println("####################################");
return;
}
delay(50); // delay to try to fix seemingly random freezes
check_count++; // increment check count
// this will send the http request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(50);
Serial.println("###################################################################");
Serial.print("Checking: ");
Serial.print(host);
Serial.print(url);
// this will grab text reply from server one line at a time
while (client.available()) {
delay(50);
String line = client.readStringUntil('\r');
delay(50);
// if the line starts with "Date" then it prints it cuz it's the server timestamp in GMT
if (line.startsWith("\nDate")) {
Serial.println(line); // this prints the date line
}
// this parses the line to see if it ends with "closed" and acts accordingly
if (line.endsWith("closed")) {
closed_count++; // increment closed count
closed_percent = 100 * (closed_count / check_count);
digitalWrite(OPEN_LED, LOW);
digitalWrite(CLOSED_LED, HIGH);
flag = 1; // set the flag so we know we got good data
Serial.println();
Serial.println("Sorry, the VHS is CLOSED right now :-(");
}
// this parses the line to see if it ends with "open" and acts accordingly
if (line.endsWith("open")) {
open_count++; // increment open count
open_percent = 100 * (open_count / check_count);
digitalWrite(OPEN_LED, HIGH);
digitalWrite(CLOSED_LED, LOW);
flag = 1; // set the flag so we know we got good data
Serial.println();
Serial.println("The VHS is OPEN right now, come on down!!");
}
}
// if we didn't get good data then print an error message and clear LEDs
if (flag == 0) {
bad_data_count++; //increment bad data count
bad_data_percent = 100 * (bad_data_count / check_count);
digitalWrite(OPEN_LED, LOW); // turn off any leds to avoid showing bad data
digitalWrite(CLOSED_LED, LOW);
Serial.println();
Serial.println("###################################################################");
Serial.println("Didn't get expected data from API... Crap");
Serial.println("Can't tell if VHS is OPEN or CLOSED!!");
}
bad_data_percent = 100 * (bad_data_count / check_count); // update % even if we don't call it
closed_percent = 100 * (closed_count / check_count);
open_percent = 100 * (open_count / check_count);
fail_percent = 100 * (fail_count / check_count);
flag = 0; // clear the flag for the next loop
Serial.println();
//Serial.print("You've been checking the VHS status for ");
Serial.print("I've checked the VHS status ");
Serial.print(check_count, 0);
Serial.print(" times in the last ");
Serial.print(check_count/60, 2);
Serial.println(" hours.");
Serial.print("It has been OPEN for ");
Serial.print(open_count, 0);
Serial.print(" minutes. [");
Serial.print(open_percent, 2);
Serial.println("% of the time]");
Serial.print("It has been CLOSED for ");
Serial.print(closed_count, 0);
Serial.print(" minutes. [");
Serial.print(closed_percent, 2);
Serial.println("% of the time]");
Serial.print("I couldn't get the data for ");
Serial.print(bad_data_count, 0);
Serial.print(" minutes. [");
Serial.print(bad_data_percent, 2);
Serial.println("% of the time]");
Serial.print("I couldn't get to the site for ");
Serial.print(fail_count, 0);
Serial.print(" minutes. [");
Serial.print(fail_percent, 2);
Serial.println("% of the time]");
Serial.println("###################################################################");
Serial.println();
Serial.println();
Serial.println();
Serial.println();
delay(WAIT); // wait 60 seconds to check again
}