What Works:

– the VC0706 camera works just fine. It’s not HD, it’s not video, and at 38400 bps serial readout it’s downright slow. If you have a USB capable micro, like a Raspberry Pi, go with a nice webcam. But this was sitting in my parts bin, obsolete when I decided to use cheap webcams on the rover. It uses the Adafruit_VC0706 library and softwareserial; no issues.

– the ESP-01 works just fine. The camera uses the TX/RX pins, plus there are a couple of I/O lines for expansion… not sure if I need to complicate this much more, but I have a PIR sensor that I might add. This uses the ESP8266HTTPClient and ESP8266WebServer (and ESP8266WiFi) libraries. Again, just works… for what I’m doing.

– Node.js – using http and express, the node server sits on a mac (for now) and simply grabs images at regular intervals. The image is letterboxed and the filename and timestamp text are added in the letterbox areas (the ‘jimp’ module for graphics, ‘moment’ for time/date stuff). A copy is stored locally, and a generic named copy is ftp’d up to an internet host as a ‘most recent image’… the reasoning for this to follow at the end of this post.

A couple of magic URL’s on the server (the ‘express’ module) cause it to send an image update request to the camera, or just grab the latest image. This means that in true Rube-Goldberg fashion, I can send a curl request based on seeing an email containing a known string… in other words – from anywhere I can send a plain email and cause the camera to take an image ‘now’, and ftp it somewhere useful.

Conversely the cam has a magic URL that simply refreshes the image buffer, but doesn’t serve it back in a web page. Once the image is read out of serial the cam sends a GET to a URL on nodejs to let it know the image is ready, which it then fetches from the camera…. because….

What doesn’t work:

HTTP POST’s longer than 2-3kb on the ESP8266. So I can’t just send a POST to nodejs with the latest image. This seems to be a known issue, and with no codebase stability I decided to skip using POST to ship images from the cam to a web server. Instead, I send a GET to nodejs, which causes nodejs to do a subsequent GET of the image. Dumb, but I won’t get bit with any bugs. I did spend a few hours on chunking out data, which I think may have been working – save for one typo I discovered the following day. At any rate, it was a hacky workaround for a bug that shouldn’t exist.


As a proof of concept I can trigger an image refresh, or let the timer in nodejs do it for me. When ready, the image is grabbed from the camera (via wifi), massaged and timestamped, then uploaded where it’s useful.

Next Steps:

Encapsulate the client side of this in an app for the Fitbit Versa; send a refresh request (probably NOT an email…), and then fetch image and display it on the watch face.


Camera URL’s:
/img returns just the image (no html wrapper)
/imgs sets 160×120, refreshes the image buffer, hits /ready on nodejs
/imgm sets 320×240, refreshes the image buffer, hits /ready on nodejs
/reset sets up the camera (again)
/test serves up a known-good test jpeg from memory
/pics takes a small image, returns it in a web page with a time stamp
/picm takes a medium image, returns it in a web page with a time stamp

nodejs URL’s:
/ready informs nodejs to GET /img on the cam, to get the latest image
/refresh informs nodejs to GET /imgm on the cam

NOTE: UDP logging and timestamps are still served from another mac running timetest.go – this is working so I’m not sure if it’s worth going back over the Go code to convert to nodejs or not. Probably not.

NOTE to self: This post was supposed to document the API structure that’s ready to go… but with half in Arduino for the ESP, and half in nodejs, I decided to this quick-and-dirty, with trigger url’s on both ends, so remember to go back and cover the 8 slot / 4 byte JSON encapsulated command array stuff.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.