My first Arduino Sketch

A while ago I read an article about the Adafruit Feather HUZZAH with ESP8266 in Hackerspace magazine. I had to buy one to play with! It’s been on a shelf for a month and finally it’s time for me to get it out and get it working! I had to program it using the Arduino IDE and I haven’t done C or C++ in years so it’s going to be a nice challenge.

I already have a Raspberry PI Zero setup with a PIR sensor and a Unicorn hat. This acts as a night light – giving me a nice red glow to see my way to the loo when I get up at night. It also acts as an alarm clock gently waking me up each morning, then flashing madly if it is ignored! As you would expect from any integration professional it’s controllable by REST based services and the alarm set off with cron!

(Tweet with pic of the nightlight when I first put it up https://twitter.com/metcarob/status/902607076203134978 )

When I read about the HUZZAH I thought that it would make a good flyout light for this system. It has a wifi chip and can be battery powered. This way I can make it into a hallway night light controlled by my main Raspberry Pi Zero based light server.

Most people use online services like IFTTT for this kind of thing but I don’t want my setup to be reliant on internet service being up so instead I will make them talk directly to each other. Despite that they are both on my home wifi I am going to be using HTTPS so I can learn how it is setupe. These days everything should be secure and it will give me an added benefit of learning how HTTPS works in IOT type devices.

I don't make these projects easy for myself - features I need:
- It has to make HTTPS requests (To tell my light.lan server what it's IP address is.)
- It has to accept HTTPS requests (So my light.lan server can tell it to turn on and off)
- It has to have a timer
- It has to drive a ring of NeoPixels

(Stretch goals for the future will involve making it run on a battery, this will mean learning about the processor's sleep modes and power optimizing my code.

My code for the sketch is here: https://gitlab.com/rmetcalf9/python_rest_pi_light/tree/master/flyouts/h…

I started with the WiFi HTTPS server example and tweaked it from there to a working example. The rest of this article consists of the most interesting/challenging tweaks.
(Example I used https://github.com/esp8266/Arduino/blob/e954022b94e28e2039b4aac31097035… )

Keeping secrets out of git

This wasn't obvious at first - to me at least. When you use the save as dialog in the Arduino IDE it will create a folder for your sketch. You can place other files in this directory. .h files can be included. So I took the sample SecureWiFI server and created a Secrets.h file and moved the WIFI credentials and certificate and key into that file. (Secret.h can then be in .gitignore)

It has to be included with quotes rather than chevrons otherwise the file isn't found:

  1. #include <Secrets.h> //won't work
  2. #include "Secrets.h" //works

Making HTTPS Post requests

This was reasonably easy in the end. In order to correctly follow HTTPSRedirects I had to include HTTPSRedirect.h and HTTPSRedirect.cpp from https://github.com/rgrokett/ESP8266_PIR/tree/master/ESP8266_PIR.

Verfying the certificate meant capturing the cert's fingerprint and storing it in my secrets.h file:

  1. openssl s_client -servername maker.ifttt.com -connect maker.ifttt.com:443 | openssl x509 -fingerprint -noout

I found my python server I was making the requests to crashed after a number of requests. I think this was because I didn't have the client.flush and client.stop commands but I am not completely sure. Finally I am building the HTTP requests manually myself; in my use case I do not need to interpret the response but in future I plan to investigate further and see if I can get an example using a http library working. I decided not to here because my sketch is also a HTTPS server and used different libraries and I wasn't sure if they conflicted.

  1.   HTTPSRedirect client(light_server_port);
  2.   if (!client.connect(light_server_host, light_server_port)) {
  3.     Serial.println("connection failed");
  4.     return;
  5.   }
  6.   Serial.println("Connection established");
  7.  
  8.   if (!client.verify(light_server_SHA1Fingerprint, light_server_host)) {
  9.       Serial.println("certificate doesn't match. will not send message.");
  10.       return;
  11.   }
  12.  
  13.   String postData = "{";
  14.   postData += "\"secret\":\""; postData += SECRET_LIGHTSERVER_SECRET; postData += "\",";
  15.   postData += "\"externalSystemID\": \"HUZZAHFlyout001\",";
  16.   postData += "\"externalID\": \"001\",";
  17.   postData += "\"notificationName\": \"lightChange\",";
  18.   postData += "\"targetGETURL\": \"https://"; postData += WiFi.localIP().toString(); postData += "/lightchange\"";
  19.   postData += "}";
  20.  
  21.   client.print("POST "); client.print(light_server_notifier_url); client.println(" HTTP/1.1");
  22.   client.print("Host: "); client.println(light_server_host);
  23.   client.println("Cache-Control: no-cache");
  24.   client.println("Content-Type: application/json");
  25.   client.print("Content-Length: "); client.println(postData.length());
  26.   client.println();
  27.   client.println(postData);
  28.  
  29.   Serial.println("Read response");
  30.  
  31.   while (client.connected())
  32.   {
  33.     if ( client.available() )
  34.     {
  35.       char str=client.read();
  36.      Serial.print(str);
  37.     }      
  38.   }
  39.   Serial.println("");
  40.   Serial.println("End of response");
  41.  
  42.   client.flush();
  43.   client.stop();

I did not have to call my webserver with this project but my next project will. This gives an interesting problem since my web server is secured by lets encrypt and the HTTPS certificates will expire every 90 days. I don’t want to re-flash the devices with new fingerprints. I am going to have to look into this further.

Making a HTTPS server

HTTPS in general gives interesting problems to Arduino devices. I want to make a device once and leave it in place for years, handling certificate expire is going to be tricky. In this project I have created my own certificate authority and issue my own certificates so I can set an expiry a long time in the future, I just need to get the light server (which is on a Raspberry Pi) to trust my own CA which shouldn’t be difficult.
In order to get the HTTPS server example working I had to supply a cert and a private key as a string of bytes. I have put these in my Secret.h file. Instructions on how to do this are in the standard example.

Timer based activation

I found a good reference on timer based activation here - https://www.forward.com.au/pfod/ArduinoProgramming/TimingDelaysInArduin…

Having an event run on a timer poses even more interesting questions. The device should stay on for a long time, what happens when the hardware timer wraps around from the maximum value back to zero? Arduino’s don’t have real time clocks but they are able to give you the number of seconds since power up. I think this is because the hardware clock is based on the frequency of the CPU but I am not sure of this. The millis() function gives values in milliseconds. I don’t have to know time in any greater detail than that for this project.

Useful links

Arduino libries come with samples. These are accessible in the Arduino IDE but it is helpful to know where they come from on github:
https://github.com/esp8266/Arduino/tree/e954022b94e28e2039b4aac31097035…

Summary

There were way more interesting questions involved in this project than I thought there would be. Even basic things like timing, HTTPS, and storing passwords required some research and digging in to. A lot of the solutions I have are ok for this project but I will have to delve into them more in future.

Power management might be a big issue. The WiFi doesn’t have to be on and connected all the time, plus there are even possibilities of having external wake up boards (I don’t know the exact term for these) which turn on your device on a button press.
I have a second project already lined up and I am ordering more HUZZAH feathers!

Published Date