Created
July 18, 2016 13:13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ESP8266WiFi.h> | |
#include <WiFiClient.h> | |
#include <ESP8266WebServer.h> | |
#include <ESP8266mDNS.h> | |
#include <Adafruit_VC0706.h> | |
#include <SPI.h> | |
#include <SD.h> | |
#include <SoftwareSerial.h> | |
#define DBG_PORT Serial | |
const char* ssid = "SSID"; | |
const char* password = "PASSWORD"; | |
const char* host = "ESP8266"; | |
ESP8266WebServer server = ESP8266WebServer(80); | |
SoftwareSerial cameraconnection = SoftwareSerial(4, 5); | |
Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection); | |
static bool hasSD = false; | |
File imgFile; | |
void returnOK() { | |
server.send(200, "text/plain", ""); | |
} | |
void returnFail(String msg) { | |
server.send(500, "text/plain", msg + "\r\n"); | |
} | |
bool loadFromSdCard(String path) { | |
String dataType = "text/plain"; | |
if (path.endsWith("/")) path += "index.htm"; | |
if (path.endsWith(".src")) path = path.substring(0, path.lastIndexOf(".")); | |
else if (path.endsWith(".htm")) dataType = "text/html"; | |
else if (path.endsWith(".css")) dataType = "text/css"; | |
else if (path.endsWith(".js")) dataType = "application/javascript"; | |
else if (path.endsWith(".png")) dataType = "image/png"; | |
else if (path.endsWith(".gif")) dataType = "image/gif"; | |
else if (path.endsWith(".jpg")) dataType = "image/jpeg"; | |
else if (path.endsWith(".ico")) dataType = "image/x-icon"; | |
else if (path.endsWith(".xml")) dataType = "text/xml"; | |
else if (path.endsWith(".pdf")) dataType = "application/pdf"; | |
else if (path.endsWith(".zip")) dataType = "application/zip"; | |
File dataFile = SD.open(path.c_str()); | |
if (dataFile.isDirectory()) { | |
path += "/index.htm"; | |
dataType = "text/html"; | |
dataFile = SD.open(path.c_str()); | |
} | |
if (!dataFile) | |
return false; | |
if (server.hasArg("download")) dataType = "application/octet-stream"; | |
if (server.streamFile(dataFile, dataType) != dataFile.size()) { | |
DBG_PORT.println("Sent less data than expected!"); | |
} | |
dataFile.close(); | |
return true; | |
} | |
void handleFileUpload() { | |
if (server.uri() != "/edit") return; | |
HTTPUpload& upload = server.upload(); | |
if (upload.status == UPLOAD_FILE_START) { | |
if (SD.exists((char *)upload.filename.c_str())) SD.remove((char *)upload.filename.c_str()); | |
imgFile = SD.open(upload.filename.c_str(), FILE_WRITE); | |
DBG_PORT.print("Upload: START, filename: "); DBG_PORT.println(upload.filename); | |
} | |
else if (upload.status == UPLOAD_FILE_WRITE) { | |
if (imgFile) imgFile.write(upload.buf, upload.currentSize); | |
DBG_PORT.print("Upload: WRITE, Bytes: "); DBG_PORT.println(upload.currentSize); | |
} | |
else if (upload.status == UPLOAD_FILE_END) { | |
if (imgFile) imgFile.close(); | |
DBG_PORT.print("Upload: END, Size: "); DBG_PORT.println(upload.totalSize); | |
} | |
} | |
void deleteRecursive(String path) { | |
File file = SD.open((char *)path.c_str()); | |
if (!file.isDirectory()) { | |
file.close(); | |
SD.remove((char *)path.c_str()); | |
return; | |
} | |
file.rewindDirectory(); | |
while (true) { | |
File entry = file.openNextFile(); | |
if (!entry) break; | |
String entryPath = path + "/" + entry.name(); | |
if (entry.isDirectory()) { | |
entry.close(); | |
deleteRecursive(entryPath); | |
} | |
else { | |
entry.close(); | |
SD.remove((char *)entryPath.c_str()); | |
} | |
yield(); | |
} | |
SD.rmdir((char *)path.c_str()); | |
file.close(); | |
} | |
void handleDelete() { | |
if (server.args() == 0) return returnFail("BAD ARGS"); | |
String path = server.arg(0); | |
if (path == "/" || !SD.exists((char *)path.c_str())) { | |
returnFail("BAD PATH"); | |
return; | |
} | |
deleteRecursive(path); | |
returnOK(); | |
} | |
void handleCreate() { | |
if (server.args() == 0) return returnFail("BAD ARGS"); | |
String path = server.arg(0); | |
if (path == "/" || SD.exists((char *)path.c_str())) { | |
returnFail("BAD PATH"); | |
return; | |
} | |
if (path.indexOf('.') > 0) { | |
File file = SD.open((char *)path.c_str(), FILE_WRITE); | |
if (file) { | |
file.write((const char *)0); | |
file.close(); | |
} | |
} | |
else { | |
SD.mkdir((char *)path.c_str()); | |
} | |
returnOK(); | |
} | |
void printDirectory() { | |
if (!server.hasArg("dir")) return returnFail("BAD ARGS"); | |
String path = server.arg("dir"); | |
if (path != "/" && !SD.exists((char *)path.c_str())) return returnFail("BAD PATH"); | |
File dir = SD.open((char *)path.c_str()); | |
path = String(); | |
if (!dir.isDirectory()) { | |
dir.close(); | |
return returnFail("NOT DIR"); | |
} | |
dir.rewindDirectory(); | |
server.setContentLength(CONTENT_LENGTH_UNKNOWN); | |
server.send(200, "text/json", ""); | |
WiFiClient client = server.client(); | |
server.sendContent("["); | |
for (int cnt = 0; true; ++cnt) { | |
File entry = dir.openNextFile(); | |
if (!entry) | |
break; | |
String output; | |
if (cnt > 0) | |
output = ","; | |
output += "{\"type\":\""; | |
output += (entry.isDirectory()) ? "dir" : "file"; | |
output += "\",\"name\":\""; | |
output += entry.name(); | |
output += "\""; | |
output += "}"; | |
server.sendContent(output); | |
entry.close(); | |
} | |
server.sendContent("]"); | |
dir.close(); | |
} | |
void handleNotFound() { | |
if (hasSD && loadFromSdCard(server.uri())) return; | |
String message = "SDCARD Not Detected\n\n"; | |
message += "URI: "; | |
message += server.uri(); | |
message += "\nMethod: "; | |
message += (server.method() == HTTP_GET) ? "GET" : "POST"; | |
message += "\nArguments: "; | |
message += server.args(); | |
message += "\n"; | |
for (uint8_t i = 0; i<server.args(); i++) { | |
message += " NAME:" + server.argName(i) + "\n VALUE:" + server.arg(i) + "\n"; | |
} | |
server.send(404, "text/plain", message); | |
DBG_PORT.print(message); | |
} | |
void setup() { | |
DBG_PORT.begin(115200); | |
DBG_PORT.println("VC0706 Camera test"); | |
pinMode(SS, OUTPUT); | |
if (!SD.begin(SS)) { | |
DBG_PORT.println("Card failed, or not present"); | |
return; | |
} | |
else { | |
hasSD = true; | |
} | |
WiFi.begin(ssid, password); | |
DBG_PORT.print("Connecting to "); | |
DBG_PORT.println(ssid); | |
uint8_t i = 0; | |
while (WiFi.status() != WL_CONNECTED && i++ < 20) { | |
delay(500); | |
} | |
if (i == 21) { | |
DBG_PORT.print("Could not connect to"); | |
DBG_PORT.println(ssid); | |
while (1) delay(500); | |
} | |
DBG_PORT.print("Connected! IP address: "); | |
DBG_PORT.println(WiFi.localIP()); | |
if (MDNS.begin(host)) { | |
MDNS.addService("http", "tcp", 80); | |
DBG_PORT.println("MDNS responder started"); | |
DBG_PORT.print("You can now connect to http://"); | |
DBG_PORT.print(host); | |
DBG_PORT.println(".local"); | |
} | |
server.on("/list", HTTP_GET, printDirectory); | |
server.on("/edit", HTTP_DELETE, handleDelete); | |
server.on("/edit", HTTP_PUT, handleCreate); | |
server.on("/edit", HTTP_POST, []() { returnOK(); }, handleFileUpload); | |
server.onNotFound(handleNotFound); | |
server.begin(); | |
DBG_PORT.println("HTTP server started"); | |
if (cam.begin()) { | |
DBG_PORT.println("Camera Found:"); | |
} | |
else { | |
DBG_PORT.println("No camera found?"); | |
return; | |
} | |
char *reply = cam.getVersion(); | |
if (reply == 0) { | |
Serial.print("Failed to get version"); | |
} | |
else { | |
Serial.println("-----------------"); | |
Serial.print(reply); | |
Serial.println("-----------------"); | |
} | |
//cam.setImageSize(VC0706_640x480); // biggest | |
cam.setImageSize(VC0706_320x240); // medium | |
//cam.setImageSize(VC0706_160x120); // small | |
uint8_t imgsize = cam.getImageSize(); | |
Serial.print("Image size: "); | |
if (imgsize == VC0706_640x480) Serial.println("640x480"); | |
if (imgsize == VC0706_320x240) Serial.println("320x240"); | |
if (imgsize == VC0706_160x120) Serial.println("160x120"); | |
cam.setMotionDetect(true); | |
Serial.print("Motion detection is "); | |
if (cam.getMotionDetect()) | |
Serial.println("ON"); | |
else | |
Serial.println("OFF"); | |
} | |
void loop() { | |
server.handleClient(); | |
if (cam.motionDetected()) { | |
Serial.println("Motion!"); | |
cam.setMotionDetect(false); | |
if (!cam.takePicture()) | |
Serial.println("Failed to snap!"); | |
else | |
Serial.println("Picture taken!"); | |
char filename[13]; | |
strcpy(filename, "IMAGE00.JPG"); | |
SD.remove(filename); | |
File imgFile = SD.open(filename, FILE_WRITE); | |
uint16_t jpglen = cam.frameLength(); | |
Serial.print(jpglen, DEC); | |
Serial.println(" byte image"); | |
Serial.print("Writing image to "); Serial.print(filename); | |
while (jpglen > 0) { | |
uint8_t *buffer; | |
uint8_t bytesToRead; | |
if (jpglen < 32) | |
bytesToRead = jpglen; | |
else | |
bytesToRead = 32; | |
buffer = cam.readPicture(bytesToRead); | |
imgFile.write(buffer, bytesToRead); | |
jpglen -= bytesToRead; | |
} | |
imgFile.close(); | |
Serial.println("...Done!"); | |
cam.resumeVideo(); | |
cam.setMotionDetect(true); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment