一昨日遊んだカメラ。今日はこれにETHERNET SHIELD 2を取り付けて遊んでみる。
- 間欠的に写真を撮り続ける。
- SDに保存する。
- ウェブアクセスがあると、一覧でサービスする。
まあ、これくらいで。サムネイル画像などハデに出したい気もするが、Arduinoはメモリも小さく、そんなに気の利いたウェブサービスはできない。
プロトタイピングシールドのブレッドボードに組み付ける。
まず、スケッチはこんなところだろう。
// // camera2Web.ino // 27.07.20(月) 0850~ // 佐藤俊夫 // Adafruit製小型TTLシリアルJPEGカメラ+ETHERNET SHIELD 2で // 間欠撮影をし、Webでダウンロードできるようにする。 // #include <Adafruit_VC0706.h> #include <SPI.h> #include <SD.h> #include <SoftwareSerial.h> #include <Ethernet2.h> #define CHIPSELECT 4 SoftwareSerial CAMCONNECTION(2, 3); Adafruit_VC0706 CAM = Adafruit_VC0706(&CAMCONNECTION); const unsigned long int INTERVAL = 30L * 1000L; byte MAC[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xF6, 0x74 }; IPAddress IP(192, 168, 1, 129); EthernetServer SERVER(80); EthernetClient CLIENT; void setup() { pinMode(10, OUTPUT); if(!SD.begin(CHIPSELECT)) return; if(!CAM.begin()) return; CAM.setImageSize(VC0706_320x240); Ethernet.begin(MAC, IP); SERVER.begin(); delay(1000); } void loop() { static unsigned long int prevtime = 0; char c; String rstr = ""; // INTERVALおきに写真を撮る if(millis() >= prevtime + INTERVAL){ prevtime = millis(); takePicture(); } // Webサーバ CLIENT = SERVER.available(); if(CLIENT) { while(CLIENT.connected()) { if(CLIENT.available()) { c = CLIENT.read(); rstr += c; if(rstr.endsWith("\r\n")){ break; } } } if(rstr.indexOf("IMG") >= 0){ String filename = "DCIM/"; char cfilename[17]; filename.concat(rstr.substring(rstr.indexOf("IMG"), rstr.indexOf("JPG") + 3)); filename.toCharArray(cfilename, 17); CLIENT.println("HTTP/1.1 200 OK"); CLIENT.println("Content-Type: image/jpg"); CLIENT.println("Connection: close"); CLIENT.println(); File img = SD.open(cfilename); while(img.available()){ CLIENT.write(img.read()); } img.close(); }else{ sendform(); } rstr = ""; delay(1); // close the connection: CLIENT.stop(); } delay(20); } void sendform(){ // フォームを送る。 CLIENT.println("HTTP/1.1 200 OK"); CLIENT.println("Content-Type: text/html"); CLIENT.println("Connection: close"); CLIENT.println(); CLIENT.println("<!DOCTYPE HTML>"); CLIENT.println("<html><head></head><body><center>"); File dcim = SD.open("/DCIM"); while(true) { File imgfile = dcim.openNextFile(); if(!imgfile){ dcim.rewindDirectory(); break; } CLIENT.write("<a href=\""); CLIENT.write(imgfile.name()); CLIENT.write("\">"); CLIENT.write(imgfile.name()); CLIENT.println("</a><br>"); imgfile.close(); } dcim.close(); CLIENT.println("</center></body></html>"); } void takePicture(){ static unsigned int pnum = 0; char filename[] = "DCIM/img0000.jpg"; CAM.takePicture(); filename[8] = '0' + pnum / 1000; filename[9] = '0' + (pnum / 100) % 10; filename[10] = '0' + (pnum / 10) % 10; filename[11] = '0' + pnum % 10; pnum ++; if(pnum > 9999) pnum = 0; if(SD.exists(filename)) return; File imgFile = SD.open(filename, FILE_WRITE); uint16_t jpglen = CAM.frameLength(); pinMode(8, OUTPUT); while (jpglen > 0) { uint8_t *buffer; uint8_t bytesToRead = min(32, jpglen); buffer = CAM.readPicture(bytesToRead); imgFile.write(buffer, bytesToRead); jpglen -= bytesToRead; } imgFile.close(); }
で、電源をつないで放置しておくと、写真が撮れるわけだ。既存のファイル名を避けるような芸コマなことはしてないけど、これはこれでけっこう面白い。
いつもの100円ショップのアクリル枠にねじ止めする。このカメラは上下が逆に映るので、こうすると丁度カメラが逆さまになって具合が良い。
それで、以前にWIZnetで紹介されて愉快だったアレのリベンジをやってみよう。携帯用のカメラホルダーに取り付け、ベランダに出して放置。