Showing posts with label Corona. Show all posts
Showing posts with label Corona. Show all posts

Wednesday, January 8, 2020

Arduino Project One: Secure communications through the firewall

Bad luck: I broke the camera connector on my Raspberry Pi Zero W, and then I think I zapped the Pi itself. It's dead, Jim. Fortunately, I have a Pi 3B lying around, waiting to be useful, so I think I'll press it into service.

My original plan was to set up a web page on the Pi, and to communicate with the Pi through a browser or a smartphone app. That would entail setting up port forwarding on my home network's router, or as they say, "punching a hole in the firewall." And that's always a network security risk.

Today, a co-worker gave me a better idea. It stems from the work I'm doing at FreeWave with MQTT.

Use MQTT to talk to the garage door

MQTT is a data communications protocol used widely in the Internet of Things (IoT) —the world of connected appliances, automobiles, doorbells, and so on. It's intended for sporadic communication of small amounts of data, perfect for this application.

MQTT follows a client-server model. However, the server doesn't really save the data: it just receives it from clients who send it data (that's called publishing), and distributes it to other clients that have asked to see the data (or subscribed to it). It doesn't actually save any data; it's just a go-between. For this reason, the server is more of a broker than a server.

A good, widely used, open-source MQTT broker is Mosquitto. Mosquitto is ridiculously simple to set up and run in the background. So I will set up Mosquitto to run on a cloud server somewhere.

The Raspberry Pi will subscribe to garage-door-opener messages received by the broker. It will publish a couple of messages of its own, in response to the messages it receives. I can use a Corona app, a webpage, or a Python or JavaScript script to publish messages to the broker.

By setting it up this way, I can totally bypass my router.

Messages to send to the Pi:
  • Request status of the garage door (closed, or not closed)
  • Push the button, Max.
Messages to be sent by the Pi:
  • Status of the garage door is closed, or not closed
    • ... including a camera image
  • The button has been pushed 
Data security is still a concern

MQTT transactions can be sent as binary data or as plain text. Anybody who knows the MQTT broker's IP address can snoop on the MQTT messages. Once they know the message tags, they can subscribe to those tags and intercept the data. If they can intercept the data, there's the chance that they can hack the system. At the very least, they can know the status of my garage door and maybe see what's in my garage. At worst, they can open and close the door at will.

An MQTT message can contain one or more metrics, the data items being transmitted. I can encrypt the data, and then send both the encrypted data and an encryption key, so the subscriber will have to utilize the key to decrypt the data. But if I do that for the "Push the button, Max" message, then a hacker can just copy the message and use it as is to push the button. I need a key that will change regularly, and that only the Raspberry Pi knows.

So another idea is to use a challenge-response algorithm, something like this.

Me: Hey, garage door. I want you to—
Pi: Wait wait wait, here's a randomly generated key. Use it to encode your message.

Me: Here's a huge number, which I created from your randomly generated key to prove that I'm me, and my request, which I encrypted using your randomly generated key.

Pi: Good, that's the right number. Now I know that you're you. Here's a response to your message, also encrypted using the randomly generated key.

Me: Thanks. We're done.

The idea of the Pi generating a random key, and both the Pi and the client using that key to generate an encryption key, has some holes in it. The NSA can hack something like that pretty quickly, if they can figure out the key-generation algorithm. But it might be enough to defeat neighborhood hackers. I think it's at least as secure as the mechanical lock-and-key on my front door.

Counting cards

Even if a hacker can't decrypt the messages, he might be able to deduce from the pattern of messages that someone is trying to operate the garage door opener. Since the normal state of the door is closed, if a hacker sees two clusters of messages a few minutes apart, for example, he can reasonably deduce that the garage door was opened and then closed. And if the hacker sees only one cluster of messages, with no other action for a while, he can reasonably deduce that the door's status was checked, but not changed.

It's like counting cards at the blackjack table.

So it might be a good idea to have the client and the Pi swap some bogus messages once in a while, encoded, of course, and the same size as real messages, to confuse any hackers monitoring the broker.


To read the other postings about this project, click here and scroll to the end.

Sunday, November 26, 2017

Arduino Project One: Lots of progress

Introduction

I got to put a lot of time into the project this weekend, and I got some cool stuff done. I ... well, here are two pictures for you, and then the details.

Things glowing in the dark

Lit by a desk lamp - I have to learn to take better pictures.

Hardware fully assembled

I put all the hardware pieces together. In the picture above, you will see the Arduino stack at the top. You've seen this before.

The breadboard has two new peripherals. First, at bottom center is a 16-by-2 liquid crystal display that I found while looking for jumper wires in the Sunfounder Project Super Starter Kit. This LCD can run with either a 4-bit or an 8-bit interface, plus 2 more digital pins for the RS and Enable signals. 

Second, the little red guy on the right is the Hall Effect sensor. When installed, this will be on the other end of a ten-foot long cable, mounted to the lintel.

You will notice a potentiometer on the left side of the breadboard. That's to control the contrast of the display. This is absolutely necessary with an LCD display. In the final enclosure, I'll use a trim pot that can be adjusted with a jeweler's screwdriver, through a hole in the enclosure.

Arduino software (almost) complete

The Arduino program is almost fully fleshed out. It searches for a Wifi router / access point, connects to it, and displays the SSID (the router's name) and its own IP address. Internally it has a list of access points, and cycles through them until it makes a connection.

In case of power failure, the Arduino program restarts, and with any luck the ESP8266 will have saved the connection information from before the power failure. If not, it will take several minutes for the router(s) to reboot, so the ESP8266 will count down 10 minutes on the display and then try again.

Once it has a connection, it starts a TCP server and opens a socket on an out-of-the-way port, to listen for clients. Every ten minutes it pings the router to make sure the Wifi connection is still good. 

That's where things stand right now.

When a client opens a connection to the server, well, that code is still in skeleton form. Before I can finish it, I have to write a client program in Python or C (or Corona!) to exercise the connection. That's one of the next steps.

The display

This was a bit of serendipity. I'd forgotten that Sunfounder kit came with an LCD. This is the standard 16x2 display based on the common ST7066/HD44780 parallel interface. This is a white-on-blue one with not very good contrast, so I'll buy a white-on-black or red-on-black one for the final product. I'd really like an old-fashioned, dot-matrix alphanumeric, 16x2 red LED display, but I haven't seen any of those for a while.

The display uses 4 digital pins for data, and one each for RS and Enable, so it fits within my pin budget.

Incorporating it into the code was a cinch, thanks to the Arduino LiquidCrystal library.

Detour: Who (or what) is "Eorlingas"?


For those of you who already looked it up on the Web, congratulations. For those of you who didn't even have to look it up ('cause you already knew!), I offer you my deepest regards.

For years, every new computer, callphone and game system in our family has borne the name of a fictional horse. When high-speed Internet finally made it to our neighborhood (yes, children, some of us first got our Internet through the phone line - at 2400 bits per second!), we needed a good name for our router, and we chose Rohirrim, the formal name for the Riders of Rohan, from The Lord of the Rings. Since that time, we have worn out or obsoleted four routers, and we're on our fifth one. It's the Fifth Detachment of the Rohirrim, or FifthRohirrim

The architecture of our house is such that the back rooms don't always receive a good signal from the router. I want the router to be hard-wired into our Xbox and our TV, so I can't move it. So, I installed a Wifi repeater in the back of the house. (By sheer coincidence, although I'd love to claim clever planning, this repeater is located about six feet above the garage door opener.) The repeater can't be named after a horse, since it's part of the infrastructure, not a computing device.

"Rohirrim" is an ancient Gondor word. The Rohirrim didn't use that word to identify themselves. In the ancient language of Rohan, they were descended from a king named Eorl, hence they were the Sons of Eorl — the Eorlingas.

I will claim clever planning for that one.

Back on the main road: the Hall effect sensor

I decided to try the ACS712 dev board first, because it has built-in trim pots for Vref and gain. I only had to connect it to 5V, ground, and an analog input on the Arduino. I wasn't happy with its performance at first. The voltage level drifted all around. I finally got it to settle down, but I can't have it drifting like that in real life.

When I finally got it settled down, I used a refrigerator magnet to manipulate it. I got the Vref and gain pots adjusted so that it pegged at 0.0 V without the magnet, and at 5.0 V with the magnet touching the chip.

Some voltage level in the circuit is floating. I don't understand the circuit well enough to fix it yet. Maybe I need to put a load (you know, a resistor) between the two current input pins.

Other than that, the sensor just works without complaint or fuss. Clearly, I have more homework to do before I can use it in real life, but this weekend's results were promising.

It needs a case, an enclosure

I've been thinking about this for a while. I'm going to have to put the Arduino in a case.

All of the Arduino Uno R3 enclosures I've found so far are for just the Arduino Uno R3 board. Once you add a shield to your Arduino, it outgrows the enclosure.

A generic project box might be okay, but it can't be metal, because of the Wifi.

I thought of 3D printing one. I don't know SolidWorks, which I think is what everyone uses, so I'd have to learn SolidWorks. I looked for ready-made 3D printable designs, and the first one I found was, I'm really sorry to say this, ugly

Okay, I just looked again, and there are some better-looking ones out there. None of them solve my height issue, but if I can get their source and manipulate it in SolidWorks or something, then I can take care of that myself.

I also need to include openings for: the LCD, the contrast adjustment for the LCD, and any LEDs I want to make visible.

I think that making the enclosure, and fitting everything in it, is going to be more work than the hardware and software parts of the project. Maybe I'll just use a cardboard box, an X-Acto knife, and clear packing tape. I'm only half-kidding.

The sensor needs an enclosure too

I can't just nail the Hall effect sensor to the beam in the garage. It will be exposed to a rather harsh environment. I may need to 3D print a case for it as well.

Alternatively, I could encapsulate it in potting compound. That would be just as good - but I'd have to find a way to include mounting holes. And whatever I do has to be nonmetallic, or at least nonmagnetic or nonferrous. Hmm. That will take more thinking.

What's next

I've made good progress so far. Here's what I still need to do

  1. Write a TCP client in Python or C, to exercise the server.
  2. Port that TCP client to an Android app, using Corona SDK.
  3. Finish the Arduino code:
    1. Hall effect sensor
    2. Debug the TCP client-handling code
  4. Finish the Android app as well.
  5. Get a real LCD display.
  6. Design and fabricate enclosures for the Arduino stack and the sensor.
  7. Assemble the whole thing.
Other items that come to mind:
  1. Try the breadboard design in the garage before I commit to a final design.
  2. Run Wireshark while the server is running, to see who tries to call my Arduino.
  3. Configure my router to allow passthrough only on the designated port, or from designated clients.
  4. Exercise the challenge-and-response algorithm.
  5. Document the whole thing.


To read the other postings about this project, click here and scroll to the end.

Wednesday, November 22, 2017

Arduino Project One: The Arduino program takes shape

Introduction

This week, I created the skeleton of the program for the Arduino stack. I'm not ready to share my source code yet. Let me get the rest of the meat on the skeleton first.

Security

I listed some ideas for my cybersecurity scheme last week. I have incorporated all of the measure I listed into my program. I'm sure there's a hacker out there somewhere who will figure it out. My description here isn't meant as a challenge to them. It's just to inform you of some simple things that worked for me.
  1. I've chosen a port number, out of the 65,535 available, that's easy to remember.
  2. The server will only accept client requests from specified devices, and not from the world at large. Although MAC address spoofing is a thing, this will stop all but the most determined hackers.
  3. The server will use TCP instead of HTTP, trading long and legible transactions for short and incomprehensible ones.
  4. The router autoforward will be tweaked so that only TCP requests via the specified port can get through to the Arduino.
  5. The server uses a challenge-and-response mechanism, like two spies swapping passwords. When a socket is opened and the client's authorization is verified, the server sends the client a randomly-generated numeric sequence. The client must reply with the proper numeric sequence. I intend to keep the details of this algorithm proprietary. Sorry, folks.
  6. It may be necessary to have the server go through the challenge-and-response several times in the life of a connection.

Robustness and Reliability

The terms "robust" and "reliable" are not synonymous. "Reliable" means that the system will not fail during regular operation as a result of stupidity — my stupidity, to be specific. "Robust" means that the system can recover from power failures and loss of Wifi signal all by itself, without any human intervention.

When the Arduino is first powered up, or when it recovers from a power failure, it looks through its list of available Wifi routers and tries each one in turn, until it gets a connection. If it doesn't get a connection at all, then it sets a timer for 10 minutes and tries again. This is because it can take DSL modems and Wifi routers a while to recover from a power failure too, so if it doesn't catch one the first time, it gives it time to reboot.

After it gets a Wifi connection, it sets up a permanent TCP socket to listen for client requests. Although client requests are the whole reason for its existence, they're not very frequent, so it will spend most of its time being idle.

Every 10 minutes or so, it will ping the Wifi router, to verify that it still has the connection. If the ping fails, then the Arduino has lost the connection, so it goes through the power-up sequence again.

When a client requests a connection, the Arduino opens a temporary TCP socket for that client. It will be up to the client to send a TCP query every second or so, unless it's sending a button-push command. It's up to the client, whether it's a webpage or an Android app, to politely say goodbye and close the socket when it exits. (I'm sure that Corona SDK and JavaScript include onExit() event servers, or something similar.)

But it's possible for the remote client to just drop the connection - battery dies, phone gets run over, computer blue-screens, that sort of thing. So the Arduino will set a watchdog timer when it opens the temporary socket. Any query from the client resets the watchdog timer (that's called "kicking the watchdog" in Embedded Programming Land). If the client doesn't send a query for a long time, the watchdog timer expires, the Arduino says goodbye to the client in case the client is listening, and then the Arduino closes the socket.

TCP/IP

I haven't decided whether to allow multiple clients yet. Normally, only my wife and I will be using the app, and very seldom at the same time. It would be crazily rare to have three people trying to control the garage door at once. Still, it would be annoying for one person to open the app on their phone, and the other person try to open it on theirs, and get the equivalent of a busy signal. So I'll probably have to allow multiple clients.

I haven't put in the actual TCP/IP commands yet. That's for later. 

Sensor and Actuator

I haven't wired up the Hall effect sensor, and I haven't written any code for it. And although I haven't actually connected the relay to the garage door opener yet, I have written the relay code, and I've verified that the relay shield plays nicely with the ESP8266 shield.

What's Next

I'll stick with this program until it's finished. Then I'll need to write a server in plain vanilla C, or maybe Python, to test it. Once the program is finished and it works, I'll post the source code.


To read the other postings about this project, click here and scroll to the end.

Thursday, November 16, 2017

Arduino Project One: Moving right along

I have a lot to report this time. Good things have been happening.

No Corona app yet: More Arduino programming

I didn't write the app on yet. I thought I'd better characterize the Arduino hardware stack a little more.

First, I wrote a little relay demo that turns the relay on and off every second. I needed to find out how easy it was. It's ridiculously easy.

Then I wrote a webserver for the Arduino/ESP8266. I let the thing run open-loop. I tried to access the Arduino's webpage from both my phone and my PC. I was only successful part of the time. I read some online reviews of the ESP8266 shield, and some people complained that it worked once, and never again. Others complained that it didn't have the advertised range. I took two different approaches to this problem.

  1. I modified the SparkFun ESP8266 libraries to print out more information about the clients it was connecting with. I need to know the client's IP address, because other than my own phone and maybe a JavaScript TCP client on my website, nobody should be monkeying with this IoT gadget. I know that full-PC webservers always snoop clients' IP addresses. So I had the Arduino send a command AT+CIPSTATUS to the ESP8266 every time it got a client request, and  log the text of the client request on its serial output.

    After I was finished testing the webserver using the browsers on my phone and my PC, I left the logger running while I did other stuff. HOLY COW! I think that the passthrough is enabled by default on my router. My little Arduino was fielding requests from all over the world. I never did see any IP addresses, but good grief, there's a bunch of nosy machines out there. I couldn't tell if they were humans, spiders, or bad guys. I'll definitely need to use a proprietary port number on my webserver, and I'll definitely need to put restrictions on the passthrough.
  2. I dug up a Coredy E300 repeater/AP/router I've had sitting around for a year or longer, and configured it as a repeater. I plugged it into a wall outlet in the bedroom, almost exactly six feet above the garage door opener. Bonus! This also gives me better Wifi reception in the bedroom and the loft.

Don't give up on the Electric Imp yet

I should mention that this week I got an automated email from SparkFun asking me how I liked my Electric Imp purchase, and reminding me that they were available for tech support and troubleshooting. If I didn't know it was automated, I would have thought they were reading my mind. Or my blog. I will follow up with them on the Electric Imp. It would be cool to get it working.

HTTP vs. TCP

I noticed a lot of dropped bytes in the Arduino's webserver log. I don't know whether they were dropped between the client and the ESP8266, the ESP8266 and the Arduino, or the Arduino's serial port and my PC's Arduino terminal window. I should try using puTTY for my serial I/O and see if it has the same problem.

In the meantime, that got me to thinking: maybe I don't need a full-blown webserver on this project. I mean, Rick S. wrote an awesome webserver for RLE's products, and I learned a lot from working on those projects, but if the user interface is going to reside on an app or on a protected page at my own website, then all I'll need between the Arduino and the client are as follows:

From the client:
  • connection request
  • response to the Arduino's security challenge
  • garage door status query
  • button push
  • response to the watchdog signal ("Yes, I'm still here")
From the Arduino:
  • security challenge in response to connection request
  • garage door status, either in response to a query or initiated by the Arduino
  • acknowledgement of button push
  • a watchdog signal ("Are you still there?")
I don't need HTTP for that. TCP will work just fine.

Security

I am paranoid about a hacker getting into the Arduino, figuring out what it's doing, and using it to burgle my house. I thought of somehow incorporating a public/private key into the interface, but I don't know if the Arduino supports that. So I'll be taking these other security measures:
  • Using a proprietary port number. There's only 65,535 to choose from.
  • Using TCP instead of HTTP, making for shorter messages which will be unintelligible to anyone else.
  • Only accepting client requests from specified devices, and not from the world at large.
  • Tuning the router settings so that it only passes through requests using that port, and from those devices.
  • Incorporating a challenge-and-response feature. When a socket is opened and the client's authorization is verified, the server sends the client a randomly-generated numeric sequence. The client uses the numeric sequence to compute and send the server a numeric sequence in response. If the client's response isn't what the server expected, then the server closes the socket.
The challenge-and-response feature isn't very sophisticated, and it may not even be necessary, given all the other precautions. We'll see.

The system will still be vulnerable to DDoS attacks. There's not much I can do about that. Everything connected to the Internet is vulnerable to DDoS attacks.

A short hardware update

This week I stopped at Home Depot and bought 20 feet of shielded, round, 28 gauge 4-conductor cable, suitable for this project and others. The final installation of the Hall effect sensor will only need 10 feet.

I'm considering what kind of enclosure to get (or make) for the Arduino stack. It will need to be plastic, or at least transparent to Wifi signals. I'd like to have some status LEDs visible through it. 

Red-on-black LCD display from Sparkfun
Red-on-black LCD display from Sparkfun

I got a wild-hair idea this evening, that it would be good to have a small LCD or LED display on the enclosure, always displaying short status messages. I can start without it, and it's not really necessary, but it would be a nice touch.


To read the other postings about this project, click here and scroll to the end.

Saturday, November 11, 2017

Arduino Project One: Corona hits a roadblock

This project has many different facets, and a lot of new things to learn. Development is definitely not linear. It can go in many different directions simultaneously — and that's a good thing, because some of those different directions run into roadblocks.

The Corona Roadblock

For example, there's nothing that says I have to have the webserver running on the Arduino stack before I start working on the Android app. With that in mind, I concentrated on learning Corona this week. Since I once ran a game programming company, I'm familiar with this genre of software. So it seemed like a safe and comfortable place to go.

I downloaded the Corona SDK and worked through the Getting Started tutorial. The last step was to do a live build, installing a development version of your app on your Android device.

Sadly, it was not to be. When I selected File > Build > Android from the Corona Simulator, I got this error message:
Stupid error message.


I selected Yes, and I ended up downloading and installing Java SE Development Kit 9.0.1 for Windows, 64-bit. (It doesn't give you much choice.) After it was installed, I ran Corona and selected File > Build > Android again. Same error message.

I went to the Corona community forums and found this recent thread, which says that Corona SDK 2017.3135 doesn't support the 64-bit JDK. But a fix is coming, and in the meantime, the awesome Corona staff posted a link to the older, 32-bit, Java SE Development Kit 8u151. The word on the Web is that multiple JDKs can exist on my computer at once, so I'll leave 9.0.1 installed.

Corona's not the only game in town. But I'm comfortable with it, with my gaming background. My son has used it successfully and speaks highly of it. And I really don't feel like downloading, installing, and learning yet another development kit. I already have enough new tools to learn. But I went ahead, and downloaded and installed 8u151.

It works! Back in Corona, File > Build > Android built a .apk file for me.

Then I needed to practice installing it on my phone. The Corona Signing and Building page says that if I don't have the Android SDK installed, I can upload the .apk file to a webserver, then download it to my phone, go to the Downloads directory, and simply tap on the .apk file to install it. However, the Signing and Building page also says that I can use the adp install command to install the .apk file directly.

Two problems arose. First, the debug version of the app was so big that it exceeded (what was left of) my daily limit on my webserver, so detouring through the webserver was out of the question for the day. Second, adb is the Android Debug Bridge, which is part of the official Android SDK, and I inferred from the Corona documentation that adb is rather important.

So even though I didn't want to "download, install and learn yet another development kit," that's exactly what I did. First, I mistakenly downloaded and installed the Android Studio IDE. If adb was part of Android Studio IDE, it was hidden very well. I couldn't find it. Then I looked on the Corona debugging page, and it gave some clues on how to download the command-line-only Android SDK tools. That was a relief — if I had to download the entire Android Studio IDE, why was I even bothering with Corona? So I happily uninstalled Android Studio IDE.

According to the debugging page, I needed to install at least the Android SDK Tools (I had to scroll down to the bottom of the page to find them) and Android SDK Platform Tools. It took some sleuthing to find those links. The adb tool is in the Platform Tools, so I had to make sure I had that one.

I unzipped the downloaded files and stored them in C:\Program Files\Android\sdk-tools, in the subdirectories tools and platform-tools.

For a test, I tried installing the StarExplorer app from the Corona SDK "Getting Started" tutorial. It took a couple of tries to execute the adb install command:
C:\Program Files\Android\sdk-tools\platform-tools>adb install -r "\Users\Ray\Documents\Corona Built Apps\StarExplorer.apk"\Users\Ray\Documents\Corona Built Apps...d. 2.8 MB/s (27069109 bytes in 9.069s)        pkg: /data/local/tmp/StarExplorer.apkSuccess
C:\Program Files\Android\sdk-tools\platform-tools>
Finally it was successful - but then I couldn't find the app on the phone. I looked in the Apps pages, but StarExplorer wasn't there. Then I looked for the /data/local/tmp directory using the My Files app and I couldn't find it.

It turned out that I was being impatient. It just took a while for the phone to update its files. After about 20 minutes, I went back to the Apps pages and I found it. The app ran perfectly on my phone.

To make it a little easier the next time I install an app, I added the paths C:\Program Files\Android\sdk-tools\tools\bin and C:\Program Files\Android\sdk-tools\platform-tools to my PATH environmental variable. Now I don't have to type in adb's entire pathname to run it.

So even though it was a real trip down the rabbit hole, collecting and installing all the tools to build and install the app on the phone, it finally worked.

Corona Does Networking!

On the bright side, I did find out this week that Corona has a network library. Reading the API documentation and looking at some examples, I'd say that this will do the trick nicely. 

So What's Next?

Now I can write the app. Once it's completed, I'll go back to the Arduino. I have to do the following:
  1. get the relay clicking
  2. try out those Hall effect sensors
  3. write the webserver and exercise it from my home network
  4. get my DSL modem / Wifi router to passthrough HTTP requests to the Arduino webserver.
  5. exercise the Arduino webserver from outside my home network

What about Internet privacy?

One thing that I haven't thought about until now: I need to research privacy / security measures for the Arduino webserver. I don't want the whole world to know when my garage door is up or down, and I definitely don't want strangers activating it. Moreover, I don't want someone in Uzbekistan hijacking my Android, turning it into a bot, and using it to mount a DDoS attack on an embassy somewhere.


To read the other postings about this project, click here and scroll to the end.

Sunday, November 5, 2017

Arduino Project One: (Not really a ) Progress Report

For a project with no timetable or deadline, this one is progressing nicely.

Hardware

I've collected all of the electronics I will need. Here's a picture of them:
The stack in the center includes: the Arduino (this one's an Elegoo Uno R3) on the bottom; the Sparkfun ESP9266 Wifi shield in the middle; and the Evil Mad Scientist relay shield on top. In front of the stack are two ACS712-based Hall effect sensor boards. The one on the lower left is just the sensor. The one on the lower right includes an amplifier and a couple of adjustment potentiometers.

I will need to enclose the sensor in either a block of potting compound, or a 3D-printed plastic case. It will be in a place rather exposed to the elements, and I don't need it to break down at critical moments.

I'll need to either make a 3D-printed case for the Arduino stack, or find a project box that fits it. Since it will be mounted next to the garage door opener motor, it won't need environmental protection, but it will need to be protected from vibration, and it will have to be able to connect wirelessly to my router.

I'll also need to get a power supply (a wall wart) for the Arduino stack, and about 20 feet of 4-conductor 28AWG or 24AWG wire for the Hall effect sensor.

Finally, I'll need to verify that none of the signals used on the Wifi or Relay shields overlap. I fear I may already have a collision with the software serial interface on the ESP8266 and a relay control pin.

Software

The code for the Hall effect sensor, while not exactly trivial, is stuff I already know how to do. I've been doing this sort of thing for years.

I ran through the ESP8266 tutorial, and I can set up the ESP8266/Arduino combo as a very rudimentary webserver. I've successfully communicated with it via a browser. That's all I need on that end.

I found a webpage that tells how to connect the ESP8266/Arduino combo to the Internet, including the critical step (new knowledge!) of setting up forwarding through my DSL router/Wifi access point.

I found another webpage that expands on that, using JQUERY and HTML to control a servo - or in my case,  a relay.

I've installed Corona on my computer, but I haven't played with it yet. I hope there's a tutorial in there that gives me hints on how to create an app that can communicate with the ESP9266/Arduino's webserver.

I need to find something about installing public/private keys on the Arduino to keep this tiny part of the Internet of Things from getting hacked.

That's it for now

By next time, I should have the web server running on the hardware stack, and I should have some preliminary testing completed on the sensors.


To read the other postings about this project, click here and scroll to the end.

Wednesday, October 25, 2017

Arduino Project One: A long-distance garage door remote

Want to keep updated on this project? See the end of this article for a list of all progress reports.



Introduction

I've enjoyed "hobby computers" for a long time. I have more than one each of Raspberry Pi, C.H.I.P., and Arduino. There are many others out there, but I don't spend enough time with the ones that I have. I have worked through the tutorials, and I have done some breadboard constructions that are rather fun, but I haven't done any serious work with any of them.

Our garage door opener has given us a scare a couple of times in the eleven years that we've lived in this house. Twice, we have come home to find that it was open when we thought it was closed. The first time, a large lime against the door frame on one side caused the door opener to reverse, lest the closing door squish the lime. The second time, the door forgot where "closed" was, touched the ground, and opened again. Why did it forget? It could have been the house settling, the concrete heaving, or something slipping in the door opener mechanism.

After the incident with the lime, I started getting paranoid about the garage door. Don't tell anybody this, but I have driven two miles back to the house, just to drive past and make sure the garage door was really closed.

Finally! I have a great idea for a hobby computer project! I will build a web-based garage door sensor and actuator. I'm sure it's never been done before! I'll commercialize it and make millions!

Research on the State of the Art

Actually, in the world of hobby computers, I'm a few years behind. A Web search for "Arduino garage door" shows how many people have already done it.

Moreover, in the world of commercial, web-based, garage door sensors and actuators, I'm way behind. Here's a kit for only $120 from Overhead Door (or Genie).

I don't care. I'm going to do it anyway, just because it's fun.

Basic Design

So here's a basic design. TODO: Insert a graphic, a block diagram of the system.

Sensor
Actuator
Computer
- Arduino
- Wifi shield
Either a tiny webserver on the Arduino, or some executable code on a private webserver
Browser-based interface
Android app

Now for the details:

Sensor

A garage door can have three states: fully open, fully closed, or moving.

No, a garage door can have five states: fully open, fully closed, opening, closing, or stopped in the middle.

That's too much work. How are you going to keep track of all of that? You could put a shaft encoder on one of the rotating parts of the opener. That would let you tell if it was opening, closing, or stopped — but not whether it was fully open or fully closed. That's three states, but not the two that matter most.

One solution online was to use two powerful magnets and a Hall effect sensor, with the magnets positioned on the drive chain exactly where "fully opened" and "fully closed" should be. That allows the garage door to have three states: fully open, fully closed, or somewhere in the middle and presumably moving.

A one-button controller for a garage door opener works like this: press the button to start it moving. Press it a second time to stop it moving. Press it a third time to start it moving in the opposite direction. The door opener stops automatically at the fully open and fully closed settings. This takes us back to the five states.

How about we simplify the problem? I only care whether the door is or isn't fully closed. If it's not fully closed, then it's moving up, moving down, fully open, or stuck in the middle, and I don't care. Those all count as not fully closed — or open.

I already know that a photosensor and reflector wouldn't work reliably at our house. The photosensor might get confused by the sun's glare on summer mornings.

I could mount some kind of sensor (magnetic, photovoltaic, pressure) flat on the concrete, and the door would come down flat on top of it. This might not work in the winter, when we get a layer of ice on top of it.

I could mount a 3D linear accelerometer on the top panel of the door. When that panel goes completely vertical and stops moving, then the door is closed. I like this idea! But the accelerometer has to have some way to communicate with the computer, and it's attached to a moving door. 

Reed switches. Mercury switches. Mechanical things wear out. What if there were a mechanical switch that doesn't wear out? My pilot son had a great idea.

Aircraft have a switch built into the landing gear, called a squat switch, or a weight-on-wheels switch, which tells them when the aircraft is solidly on the ground. Some things in the aircraft, you don't want to have happen until the plane or helicopter cannot fall out of the sky. These switches are, by necessity, extremely robust. A squat switch will tell you whether the airplane is or isn't on the ground.

Where to mount the switch? Well, when a garage door closes, the top of the door is pressed flat across the lintel of the door frame. (The lintel is the horizontal part across the top. The vertical parts on the sides are called the posts.) When the door starts opening, the top of the door is pulled away from the lintel, and no other part of the door touches the lintel. So the lintel seems like a good place to mount a squat switch.

Now I just have to get one. My son, the pilot, is finding a source for me.

After thinking about it overnight (no wonder I didn't sleep well!) I realized that the location for the squat switch — top of the door, top center of the lintel — is also an ideal place for a magnet and Hall effect sensor. So if the squat switch ends up being expensive, I'll go back to SparkFun for one of their ACS712-based Hall effect sensor boards.

Actuator

The garage door opener is an Overhead Door SilentMax 4040. Installed by Yours Truly eleven years ago, it works as well as the day I put it in. Its rubber belt drive is almost completely silent, especially after I lubricated the belt with a thin spray of white grease a few years back.

The SilentMax 4040 has a wired remote on the wall of the garage, with two buttons: one for the door, and one for the light. Only two wires go into the opener itself, so the wired remote must do something to differentiate between the DOOR button and the LIGHT button. And it does. Here are the pertinent details:

  • With no buttons pushed, a 4.1Vdc difference exists between the terminals on the opener.
  • Pushing the DOOR button shorts the two terminals, so there's a 0.0Vdc difference for around 200 ms.
  • Pushing the LIGHT button doesn't short the terminals, but engages a voltage divider, so there's a 2.76Vdc difference between them.
Since I don't care about the light, I can just have the computer switch a relay. 
Anyway, I'll need to attach a relay to the same terminals used by the wired remote. The computer will switch the relay, which will duplicate the action of the remotes.

Computer

A Raspberry Pi or a C.H.I.P. would be overkill for this project. You don't need Linux to open and close a garage door. I'll use an Arduino. In fact, I'm going to go really old-school and use an Arduino Uno. I have two to choose from: a Redboard from SparkFun; and an Uno R3 from Elegoo. I should be able to run the same program on both boards. I'll try the Elegoo first. It's brand new, and I want to try it out.

The Arduino has general-purpose digital inputs and outputs that will work just fine for the sensor and the relay. I'll need to add a transistor to the relay output, and perhaps an op amp or other buffer to the sensor input.

For Wifi capability, I have two choices from SparkFun: either the Electric Imp, or the  ESP8266. Both solutions are versatile enough that someone smarter than me could figure out how to use the Electric Imp or ESP8266 by itself, without the Arduino, to do this project. I'm not that smart. Both solutions come in either an Arduino R3 shield form factor, which is ideal for my Arduino Uno boards, or in a smaller "breakout" board. I ended up buying both.

I tried the ESP8266 shield first. It worked the first time I powered it up.

I tried the Electric Imp next. It didn't work. That is, I couldn't get it to connect to my Wifi router. The setup requires you to download an app to your tablet or smartphone, power up the Electric Imp, hold it next to the phone screen, and run a function on the app which transmits your Wifi router information to the Electric Imp by strobing the phone screen into a light sensor on the Electric Imp. When the strobing is completed, you're supposed to wait up to 90 seconds for the Electric Imp to connect to the Wifi router.

Wouldn't it be simpler just to set up a serial connection to the Electric Imp and type in the SSID and password manually? It would certainly make troubleshooting easier. The concept of the Electric Imp is intriguing, but if I can't make it work, what use is it?

Since I'll be using an Arduino and a Wifi shield, and one can stack an infinite number of shields on an Arduino (as long as the pin assignments don't conflict), I bought the Relay Shield from SparkFun. I will stack it on top of the Wifi shield - or maybe the Wifi shield should be on top. We'll experiment.

The hardware as of 26 Oct 2017 (rawr)

Webserver

My first implementation will use a webserver. This could be a mini-webserver on the Arduino, or on the Wifi board (like I said, they're both versatile enough to handle it), or on a private server. All three are viable options right now.

I should probably use a port, for a couple of reasons — the main one being that it gives me some security, however weak. How many low-level hackers are going to be trying different ports?

For the sake of security, the webserver will require some kind of authentication. This is important so that some random hacker doesn't spend all day running my garage door up and down for his own amusement. This could be as simple as a login and password. 

In the long term, I'll also want some kind of security between the webserver (if it's remote) and the Wifi. One of the prior implementations used a dual challenge and response: the server sent the host a hashed number, and the host then replied with the unhashed number. If the number was correct, then the host sent the server a hashed number, and the server had to unhash it and check it. I dunno yet. I'll figure this part out later.

The basic procedure will go like this:
  1. Requester sends authentication; host accepts or rejects it.
  2. Host queries the Arduino for the current status of the door.
  3. Arduino checks the sensor and replies to the Host.
  4. Host tells door status to the requester.
  5. Requester pushes the button to start or stop the door. (Or exits, if they're satisfied with the status.)
  6. Host sends the Arduino the "button" command.
  7. Arduino energizes the relay for 200 ms.
  8. Host queries Arduino once per second, for as long as the requester is logged in or the app is open.
  9. Requester exits the app, Host and Arduino go idle.

Browser-based interface / Webpage

The browser-based interface will be as follows:
  1. Welcome screen: login, password
  2. Main screen
    1. Status indicator: green and "open" or red and "closed".
    2. A big button, labeled "Push this button" or something like that.
    3. A smaller "Exit" button.
    4. An even smaller "setup" button - to specify the Wifi's IP address.
  3. Under the hood
    1. Queries the Arduino once a second.
    2. Sends button pushes to the Arduino.

Android app

The Android app would do basically the same thing as the browser-based interface, without the need to login. Well, maybe - as a security precaution, in case the phone is stolen.

Software Tools

The Arduino is programmed in its own dialect of C. The ESP8266 is controlled using good ol' AT commands. The Electric Imp is programmed in a C-like language called Squirrel. The webserver could be JavaScript, perl, or who knows what else?

For the Android app, I considered using Xamarin, but I didn't want to get trapped in the Microsoft tar baby, so I'm going with Corona. It's advertised as a 2D game engine, but it's much more powerful than that. I've used game engines before, and I know what they can do. Besides, I can get some expert help with Corona.

Proposed Enhancements

I've seen people connect spy cameras to hobby computers. I'd like to connect a camera to the Arduino or the ESP8266, and have a tiny picture of the garage door on the main screen.

I need to measure the time it takes for the garage door to close. If the door status is "not closed" and someone pushes the button, the door status should changed to "closed" in a reasonable amount of time. If it doesn't, then the status should change to "there's a problem".

I'm not afraid of a more complicated state machine. With the right sensors, I could incorporate all five states. I'll try other sensors, if I can figure out how to make them work &mdash and if they're reliable.

Not that it affects the basic functionality of the machine, but I'm going to have to do some graphics work to create the objects that make up the app. Call me old-fashioned or steampunk if you will, but I still enjoy the skeuomorphic user interfaces that Apple and Microsoft used to use and have since abandoned. My app is going to have a couple of old-fashioned indicator lights mounted in chrome or bronze bezels, a 3D push button bigger than a fingertip, and a black leather (or black crackle-finish or black powder-coated metal) background.

Project Timetable

There isn't any timetable. This is a hobby, a just-for-fun DIY project. But here's a list of milestones as they occur.

25 Oct 2017 First draft of this project plan is written. Happy birthday!
26 Oct 2017 Added details about the Wifi shield and relay shield from SparkFun.. Added details about the wired remote.

Updates

I ended up posting each update as a separate article. Here are the rest of them.