
From ESP32-CAM rookie to PRO
All the ESP32-CAM features exposed in in less than 10 lines of code.. Pictures, videos, Telegram notifications, motion detection, artificial intelligence... You name it!
This book is for you if:
You are a beginner and...
- you want to start learning from the basics. You are not comfortable with complex, convoluted code that makes you wonder which line is doing what
- you like to learn by doing. You want to see the code in action and see how it works
- you want features out-of-the-box (sd storage, cloud storage, Telegram notifications, motion detection...)
You are an expert and...
- you want to kickstart your projects by abstracting repetitive code
- you want to access advanced features like AI, multithreading, MQTT...
What's inside?
Quickstart
Configure the image sensor and take your first picture
Live streaming
View the camera feed in real-time from any web browser
Example: How to take picture
/** * Get started with the EloquentEsp32Cam library. * Configure camera and grab frames. * Turn on INFO logging in the Tools menu to see * debug messages. */ #include <eloquent_esp32cam3.h> eloquent::camera::Camera camera; void setup() { Serial.begin(115200); Serial.println("Take picture"); // configure hardware parts camera.hardware.brownout.disable(); camera.hardware.clock.fast(); camera.hardware.pinout.ask(); // configure frame camera.frame.pixformat.jpeg(); camera.frame.resolution.vga(); camera.frame.quality.high(); // you can still access the camera_config_t instance directly camera.config.fb_count = 2; camera.config.grab_mode = CAMERA_GRAB_LATEST; // initialize camera camera.begin(); // raise() will throw a std::runtime_error // only if something went wrong // useful for debugging // in production you should handle the exception // (see image.failed() later) camera.raise(); Serial.println("Init OK"); } void loop() { // grab a new frame auto image = camera.grab(); // frame grabbing may fail sometimes // since it is a recoverable error, // handle it instead of raising if (image.failed()) { Serial.println(image.error); delay(1000); return; } ESP_LOGI("App", "Frame size: %d bytes", image.size()); delay(1000); }
Example: Motion detection
/** * Motion detection example, simple case. * Includes events throttling. * * All configurations in the setup() method * for the motion detection are optional. * Feel free to delete the ones you don't need. * * Requires the JPEGDEC library * (https://github.com/bitbank2/JPEGDEC) */ #include <JPEGDEC.h> #include <eloquent_esp32cam3.h> #include <eloquent_esp32cam3/modules/motion.h> using eloquent::camera::Camera; using eloquent::camera::helpers::Throttle; using eloquent::camera::motion::Motion; using eloquent::camera::motion::dtypes::Result; Camera camera; Motion motion; Throttle throttle("3 seconds"); void setup() { Serial.begin(115200); delay(3000); Serial.println("Motion detection: simple case"); // see "GetStarted.ino" for more comments camera.hardware.brownout.disable(); camera.hardware.clock.fast(); camera.hardware.pinout.ask(); camera.frame.pixformat.jpeg(); camera.frame.resolution.vga(); camera.frame.quality.high(); // run motion detection on a 1/16th version // of the frame to make it faster and // use less resources // must be a power of 2 or a multiple of 8 motion.config.stride(16); // how much should two pixels differ // to be included into the motion count? motion.config.differBy(20); // how much to smooth pixels when updating // previous state. // 0 means no smooth at all (use latest frame as is) // 1 means no update al all (use first frame only) // 0.5 is the mean between current and prev motion.config.smoothBy(0.2); // while training, the background model is updated // but no motion detection is performed. // also, skip the first few frames while the camera stabilizes motion.config.trainFor(10); // decide which pixels to consider motion.config.consider([](size_t x, size_t y, uint8_t pixel) { // only consider pixels whose x is > 80 and y < 320 return x <= 160 && y <= 320; }); // you can register a function to call when // moving ratio is above a certain value motion.callbacks.onMotion(0.3, [](Result &result) { // ignore throttle, always print Serial.printf( "[callback] %.0f%% of the image changed (%d/%d)\n", result.ratio * 100, result.moving, result.total ); }); // init camera and discard first 2 frames camera.begin(); camera.raise(); camera.discard(2); // motion doesn't require init } void loop() { auto image = camera.grab(); if (image.failed()) { Serial.print("Camera error: "); Serial.println(image.error); return; } motion.update(image); if (motion.failed()) { Serial.print("Motion error: "); Serial.println(motion.error); return; } // check how much of the image changed // also, don't fire too many events (throttle) if (motion.result.ratio > 0.3 && throttle) { Serial.printf( "%.0f%% of the image changed (%d/%d)\n", motion.result.ratio * 100, motion.result.moving, motion.result.total ); Serial.printf( "Center of mass at x=%d, y=%d\n", motion.result.centerOfMass.x, motion.result.centerOfMass.y ); // start counting time from now // no event will trigger for the next 3 seconds throttle.touch(); } delay(100); }