Components and supplies
Arducam Mini OV2640
Arduino Ethernet Shield 2
standard pushbutton (normally open)
Arduino UNO
Amazon Echo
Apps and platforms
AWS Rekognition
AWS S3
Alexa Skills Kit
AWS API Gateway
AWS Lambda
Project description
Code
Smartcam Github Repository
Project Code + Setup Guide
Arduino Sketch
arduino
Sketch for Arduino Uno for controlling the Arducam and uploading the JPEG Picture to the AWS
1// Smart Camera, Alexa controlled face recognition door bell 2// 3// This demo can only work on OV2640_MINI_2MP platform. 4// 5// When switch is pressed, the camera caputures a JPG image. 6// The JPG data is read from the SPI bus in chunks and directly sent out using http put request 7// in order to avoid the need of storing it into ram or on SD Card. 8// 9// (C) 2018 Sebastian Enzinger & Markus Enzinger 10 11#include <Wire.h> // library for Arduino ports 12#include <ArduCAM.h> // library for Arducam 13#include <SPI.h> // library for SPI communications 14#include "memorysaver.h" // configures the camera type used 15#include <Ethernet.h> // library for ethernet shield 16#define switch 5 // GPIO pin for the door bell switch 17byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xF1, 0xED }; // Ethernet Mac Address to use for the ethernet shield 18char host[] = "d35xafoveji7v.cloudfront.net"; // Where to send the image by http post request 19 20const int CS = 7; // set pin 7 as the slave select for the cam module's spi port: 21bool is_header = false; 22int mode = 0; 23uint8_t start_capture = 0; 24ArduCAM myCAM( OV2640, CS ); 25uint8_t read_fifo_burst(ArduCAM myCAM); 26EthernetClient client; 27//------------------------------------------------------------------- setup() section ----------------------- 28void setup() { 29// put your setup code here, to run once: 30uint8_t vid, pid; 31uint8_t temp; 32IPAddress dnServer(192, 168, 3, 5); // the dns server ip 33IPAddress gateway(192, 168, 3, 5); // the router's gateway address 34IPAddress subnet(255, 255, 255, 0); // the subnet 35IPAddress ip(192, 168, 3, 251); //the IP address of our ethernet shield 36Ethernet.begin(mac, ip, dnServer, gateway, subnet); // Initialize Ethernet Shield 37Wire.begin(); 38Serial.begin(115200); // Initialize Serial Output for debug messages 39Serial.println(F("ArduCAM Start!")); 40// set the CS as an output: 41pinMode(CS, OUTPUT); // Chip select line to arducam 42pinMode(switch, INPUT_PULLUP); // Switch input: set pullup to read "high" when not pressed 43// initialize SPI: 44SPI.begin(); 45while(1){ 46 //Check if the ArduCAM SPI bus is OK 47 myCAM.write_reg(ARDUCHIP_TEST1, 0x55); 48 temp = myCAM.read_reg(ARDUCHIP_TEST1); 49 if (temp != 0x55){ 50 Serial.println(F("ACK CMD SPI interface Error!")); 51 delay(1000);continue; 52 }else{ 53 Serial.println(F("ACK CMD SPI interface OK."));break; 54 } 55} 56while(1){ //Check if the camera module type is OV2640 57 myCAM.wrSensorReg8_8(0xff, 0x01); 58 myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid); 59 myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid); 60 if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))){ 61 Serial.println(F("ACK CMD Can't find OV2640 module!")); 62 delay(1000);continue; 63 } 64 else{ 65 Serial.println(F("ACK CMD OV2640 detected."));break; 66 } 67} 68myCAM.set_format(JPEG); //Change to JPEG capture mode and initialize the OV2460 module 69myCAM.InitCAM(); 70delay(1000); 71myCAM.clear_fifo_flag(); 72} 73 74//------------------------------------------------------------------ LOOP section --------------------- 75void loop() { 76uint8_t temp = 0xff, temp_last = 0; 77uint32_t len; 78bool is_header = false, errorflag=false; 79int inChar; 80if (digitalRead(switch)) // Switch pressed? 81{ 82 myCAM.OV2640_set_JPEG_size(OV2640_800x600); // set image resolution in Arducam module 83 delay(1000); 84 Serial.println(F("ACK CMD switch to OV2640_800x600")); 85 temp = 0xff; 86 myCAM.flush_fifo(); 87 myCAM.clear_fifo_flag(); 88 myCAM.start_capture(); // start image capture 89 start_capture = 0; 90 while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)); // check if capture is finished 91 len = myCAM.read_fifo_length(); 92 Serial.println(len); 93 if ((len >= MAX_FIFO_SIZE) | (len == 0)) // check for invalid image size 94 { 95 myCAM.clear_fifo_flag(); 96 Serial.println(F("ERR wrong size")); 97 errorflag=1; 98 } 99 Serial.println(F("ACK CMD CAM Capture Done.")); 100 if (!client.connect(host, 80)) { // connect to host 101 Serial.println("ERR http connection failed"); 102 errorflag=1; 103 } 104 if (!errorflag) { 105 myCAM.CS_LOW(); // switch CS line of camera active 106 myCAM.set_fifo_burst();//Set fifo burst mode 107 SPI.transfer(0xFF); 108 myCAM.CS_HIGH(); // switch CS line of camera inactive to allow ethernet shield to use SPI bus 109 String response = "POST /prod/smartcamIdentifyPerson HTTP/1.1\ \ 110"; 111 response += "Host: d35xafoveji7v.cloudfront.net\ \ 112"; 113 response += "Content-Type: image/jpeg\ \ 114"; 115 response += "Content-Length: " + String(len) + "\ \ 116"; 117 Serial.println("connected to the server"); 118 client.println(response); 119 static const size_t bufferSize = 512; 120 static uint8_t buffer[bufferSize] = {0xFF}; 121 while (len) { // read chunks of 512 byte and send them out to host, because of memory constraints 122 size_t will_copy = (len < bufferSize) ? len : bufferSize; 123 myCAM.CS_LOW(); 124 myCAM.set_fifo_burst();//Set fifo burst mode 125 for (int bufptr=0; bufptr<will_copy; bufptr++) 126 buffer[bufptr]=SPI.transfer(0x00); 127 myCAM.CS_HIGH(); 128 if (client.connected()) 129 client.write(&buffer[0], will_copy); 130 len -= will_copy; 131 } 132 } 133 myCAM.CS_HIGH(); 134 int connectLoop=0; 135 while(client.connected()) // Sending complete, now read response from host and forward to serial monitor 136 { 137 while(client.available()) 138 { 139 inChar = client.read(); 140 Serial.write(inChar); 141 connectLoop = 0; // set connectLoop to zero if a packet arrives 142 } 143 connectLoop++; 144 if(connectLoop > 2000) // if more than 1000 milliseconds since the last packet 145 { 146 Serial.println(); 147 client.stop(); // then close the connection from this end. 148 } 149 delay(1); 150 } 151 } 152} 153
Smartcam Github Repository
Project Code + Setup Guide
Arduino Sketch
arduino
Sketch for Arduino Uno for controlling the Arducam and uploading the JPEG Picture to the AWS
1// Smart Camera, Alexa controlled face recognition door bell 2// 3// This demo can only work on OV2640_MINI_2MP platform. 4// 5// When switch is pressed, the camera caputures a JPG image. 6// The JPG data is read from the SPI bus in chunks and directly sent out using http put request 7// in order to avoid the need of storing it into ram or on SD Card. 8// 9// (C) 2018 Sebastian Enzinger & Markus Enzinger 10 11#include <Wire.h> // library for Arduino ports 12#include <ArduCAM.h> // library for Arducam 13#include <SPI.h> // library for SPI communications 14#include "memorysaver.h" // configures the camera type used 15#include <Ethernet.h> // library for ethernet shield 16#define switch 5 // GPIO pin for the door bell switch 17byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xF1, 0xED }; // Ethernet Mac Address to use for the ethernet shield 18char host[] = "d35xafoveji7v.cloudfront.net"; // Where to send the image by http post request 19 20const int CS = 7; // set pin 7 as the slave select for the cam module's spi port: 21bool is_header = false; 22int mode = 0; 23uint8_t start_capture = 0; 24ArduCAM myCAM( OV2640, CS ); 25uint8_t read_fifo_burst(ArduCAM myCAM); 26EthernetClient client; 27//------------------------------------------------------------------- setup() section ----------------------- 28void setup() { 29// put your setup code here, to run once: 30uint8_t vid, pid; 31uint8_t temp; 32IPAddress dnServer(192, 168, 3, 5); // the dns server ip 33IPAddress gateway(192, 168, 3, 5); // the router's gateway address 34IPAddress subnet(255, 255, 255, 0); // the subnet 35IPAddress ip(192, 168, 3, 251); //the IP address of our ethernet shield 36Ethernet.begin(mac, ip, dnServer, gateway, subnet); // Initialize Ethernet Shield 37Wire.begin(); 38Serial.begin(115200); // Initialize Serial Output for debug messages 39Serial.println(F("ArduCAM Start!")); 40// set the CS as an output: 41pinMode(CS, OUTPUT); // Chip select line to arducam 42pinMode(switch, INPUT_PULLUP); // Switch input: set pullup to read "high" when not pressed 43// initialize SPI: 44SPI.begin(); 45while(1){ 46 //Check if the ArduCAM SPI bus is OK 47 myCAM.write_reg(ARDUCHIP_TEST1, 0x55); 48 temp = myCAM.read_reg(ARDUCHIP_TEST1); 49 if (temp != 0x55){ 50 Serial.println(F("ACK CMD SPI interface Error!")); 51 delay(1000);continue; 52 }else{ 53 Serial.println(F("ACK CMD SPI interface OK."));break; 54 } 55} 56while(1){ //Check if the camera module type is OV2640 57 myCAM.wrSensorReg8_8(0xff, 0x01); 58 myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid); 59 myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid); 60 if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))){ 61 Serial.println(F("ACK CMD Can't find OV2640 module!")); 62 delay(1000);continue; 63 } 64 else{ 65 Serial.println(F("ACK CMD OV2640 detected."));break; 66 } 67} 68myCAM.set_format(JPEG); //Change to JPEG capture mode and initialize the OV2460 module 69myCAM.InitCAM(); 70delay(1000); 71myCAM.clear_fifo_flag(); 72} 73 74//------------------------------------------------------------------ LOOP section --------------------- 75void loop() { 76uint8_t temp = 0xff, temp_last = 0; 77uint32_t len; 78bool is_header = false, errorflag=false; 79int inChar; 80if (digitalRead(switch)) // Switch pressed? 81{ 82 myCAM.OV2640_set_JPEG_size(OV2640_800x600); // set image resolution in Arducam module 83 delay(1000); 84 Serial.println(F("ACK CMD switch to OV2640_800x600")); 85 temp = 0xff; 86 myCAM.flush_fifo(); 87 myCAM.clear_fifo_flag(); 88 myCAM.start_capture(); // start image capture 89 start_capture = 0; 90 while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)); // check if capture is finished 91 len = myCAM.read_fifo_length(); 92 Serial.println(len); 93 if ((len >= MAX_FIFO_SIZE) | (len == 0)) // check for invalid image size 94 { 95 myCAM.clear_fifo_flag(); 96 Serial.println(F("ERR wrong size")); 97 errorflag=1; 98 } 99 Serial.println(F("ACK CMD CAM Capture Done.")); 100 if (!client.connect(host, 80)) { // connect to host 101 Serial.println("ERR http connection failed"); 102 errorflag=1; 103 } 104 if (!errorflag) { 105 myCAM.CS_LOW(); // switch CS line of camera active 106 myCAM.set_fifo_burst();//Set fifo burst mode 107 SPI.transfer(0xFF); 108 myCAM.CS_HIGH(); // switch CS line of camera inactive to allow ethernet shield to use SPI bus 109 String response = "POST /prod/smartcamIdentifyPerson HTTP/1.1\ \ 110"; 111 response += "Host: d35xafoveji7v.cloudfront.net\ \ 112"; 113 response += "Content-Type: image/jpeg\ \ 114"; 115 response += "Content-Length: " + String(len) + "\ \ 116"; 117 Serial.println("connected to the server"); 118 client.println(response); 119 static const size_t bufferSize = 512; 120 static uint8_t buffer[bufferSize] = {0xFF}; 121 while (len) { // read chunks of 512 byte and send them out to host, because of memory constraints 122 size_t will_copy = (len < bufferSize) ? len : bufferSize; 123 myCAM.CS_LOW(); 124 myCAM.set_fifo_burst();//Set fifo burst mode 125 for (int bufptr=0; bufptr<will_copy; bufptr++) 126 buffer[bufptr]=SPI.transfer(0x00); 127 myCAM.CS_HIGH(); 128 if (client.connected()) 129 client.write(&buffer[0], will_copy); 130 len -= will_copy; 131 } 132 } 133 myCAM.CS_HIGH(); 134 int connectLoop=0; 135 while(client.connected()) // Sending complete, now read response from host and forward to serial monitor 136 { 137 while(client.available()) 138 { 139 inChar = client.read(); 140 Serial.write(inChar); 141 connectLoop = 0; // set connectLoop to zero if a packet arrives 142 } 143 connectLoop++; 144 if(connectLoop > 2000) // if more than 1000 milliseconds since the last packet 145 { 146 Serial.println(); 147 client.stop(); // then close the connection from this end. 148 } 149 delay(1); 150 } 151 } 152} 153
Downloadable files
Arduino Uno / Camera Wiring
Schematic how the Arduino and Arducam are connected
Arduino Uno / Camera Wiring
Comments
Only logged in users can leave comments