The code is long, so I only put the code in for the IP address, which is the original post. I can post the whole sketch, though.
#include "srcOV2640.h"
#include <WiFi.h>
#include <WebServer.h>
#include <WiFiClient.h>
#include "Arduino.h" // General functionality
#include "esp_camera.h" // Camera
#include <SD.h> // SD Card
#include "FS.h" // File System
#include "soc/soc.h" // System settings (e.g. brownout)
#include "soc/rtc_cntl_reg.h"
#include "driver/rtc_io.h"
#include <EEPROM.h> // EEPROM flash memory
#include "time.h" // Time functions
// "ESP Mail Client" by Mobizt, tested with v1.6.4
#include "ESP_Mail_Client.h" // e-Mail
// DEFINES
//#define USE_INCREMENTAL_FILE_NUMBERING //Uses EEPROM to store latest file stored
#define USE_TIMESTAMP // Uses Wi-Fi to retrieve current time value
#define SEND_EMAIL // Uses Wi-Fi to email photo attachment
#define TRIGGER_MODE // Photo capture triggered by GPIO pin rising/falling
//#define TIMED_MODE // Photo capture automated according to regular delay
// Select camera model
//#define CAMERA_MODEL_WROVER_KIT
//#define CAMERA_MODEL_ESP_EYE
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE
#define CAMERA_MODEL_AI_THINKER
#include "camera_pins.h"
// Wi-Fi settings
#define SSID1 ""
#define PWD1 ""
OV2640 cam;
WebServer server(80);
const char HEADER[] = "HTTP/1.1 200 OK\r\n" \
"Access-Control-Allow-Origin: *\r\n" \
"Content-Type: multipart/x-mixed-replace; boundary=123456789000000000000987654321\r\n";
const char BOUNDARY[] = "\r\n--123456789000000000000987654321\r\n";
const char CTNTTYPE[] = "Content-Type: image/jpeg\r\nContent-Length: ";
const int hdrLen = strlen(HEADER);
const int bdrLen = strlen(BOUNDARY);
const int cntLen = strlen(CTNTTYPE);
void handle_jpg_stream(void)
{
char buf[32];
int s;
WiFiClient client = server.client();
client.write(HEADER, hdrLen);
client.write(BOUNDARY, bdrLen);
while (true)
{
if (!client.connected()) break;
cam.run();
s = cam.getSize();
client.write(CTNTTYPE, cntLen);
sprintf( buf, "%d\r\n\r\n", s );
client.write(buf, strlen(buf));
client.write((char *)cam.getfb(), s);
client.write(BOUNDARY, bdrLen);
}
}
const char JHEADER[] = "HTTP/1.1 200 OK\r\n" \
"Content-disposition: inline; filename=capture.jpg\r\n" \
"Content-type: image/jpeg\r\n\r\n";
const int jhdLen = strlen(JHEADER);
void handle_jpg(void)
{
WiFiClient client = server.client();
cam.run();
if (!client.connected()) return;
client.write(JHEADER, jhdLen);
client.write((char *)cam.getfb(), cam.getSize());
}
void handleNotFound()
{
String message = "Server is running!\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
server.send(200, "text / plain", message);
}
#define SMTP_HOST "smtp.office365.com"
#define SMTP_PORT 25
#define AUTHOR_EMAIL ""
#define AUTHOR_PASSWORD ""
// CONSTANTS
// GPIO Pin 33 is small red LED near to RESET button on the back of the board
const byte ledPin = GPIO_NUM_33;
// GPIO Pin 4 is bright white front-facing LED
const byte flashPin = GPIO_NUM_4;
// When using TRIGGER_MODE, this pin will be used to initiate photo capture
const byte triggerPin = GPIO_NUM_13;
// Flash strength (0=Off, 255=Max Brightness)
// Setting a low flash value can provide a useful visual indicator of when a photo is being taken
const byte flashPower = 1;
#ifdef TIMED_MODE
//const int timeLapseInterval = 30; // seconds between successive shots in TIMELAPSE mode
#endif
const int startupDelayMillis = 3000; // time to wait after initialising camera before taking photo
// GLOBALS
// Keep track of number of pictures taken for incremental file naming
int pictureNumber = 0;
// Full path of filename of the last photo saved
String path;
#ifdef SEND_EMAIL
// SMTP session used for eMail sending
SMTPSession smtp;
// Function fired on email success/failure
void smtpCallback(SMTP_Status status);
// Callback function after eMail sending
void smtpCallback(SMTP_Status status) {
// Print the current status
Serial.println(status.info());
// Show details of successful delivery
if (status.success()) {
Serial.println("----------------");
Serial.printf("Message sent success: %d\n", status.completedCount());
Serial.printf("Message sent failed: %d\n", status.failedCount());
Serial.println("----------------\n");
struct tm dt;
for (size_t i=0; i<smtp.sendingResult.size(); i++) {
SMTP_Result result = smtp.sendingResult.getItem(i);
time_t ts = (time_t)result.timestamp;
localtime_r(&ts, &dt);
Serial.printf("Message No: %d\n", i + 1);
Serial.printf("Status: %s\n", result.completed ? "success" : "failed");
Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);
Serial.printf("Recipient: %s\n", result.recipients);
Serial.printf("Subject: %s\n", result.subject);
}
Serial.println("----------------");
}
}
#endif
void sleep() {
// IMPORTANT - we define pin mode for the trigger pin at the end of setup, because most pins on the ESP32-CAM
// have dual functions, and may have previously been used by the camera or SD card access. So we overwrite them here
pinMode(triggerPin, INPUT_PULLDOWN);
// Ensure the flash stays off while we sleep
rtc_gpio_hold_en(GPIO_NUM_4);
// Turn off the LED
digitalWrite(ledPin, HIGH);
delay(1000);
#ifdef TRIGGER_MODE
// Use this to wakeup when trigger pin goes HIGH
esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1);
// Use this to wakeup when trigger pin goes LOW
// esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0);
//#elif defined(TIMED_MODE)
// Or, use this to wakeup after a certain amount of time has elapsed (parameter specified in uS, so multiply secs by 1000000)
//esp_sleep_enable_timer_wakeup(timeLapseInterval * 1000000);
#endif
Serial.println(" Going to sleep now");
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void setup()
{
// Light up the discrete red LED on the back of the board to show the device is active
pinMode(ledPin, OUTPUT);
// It's an active low pin, so we write a LOW value to turn it on
digitalWrite(ledPin, LOW);
// CAUTION - We'll disable the brownout detection
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
// Start serial connection for debugging purposes
Serial.begin(115200);
//while (!Serial); //wait for serial connection.
Serial.println(__FILE__ __DATE__);
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
// Frame parameters
// config.frame_size = FRAMESIZE_UXGA;
if(psramFound()){
config.frame_size = FRAMESIZE_QVGA;
config.jpeg_quality = 12;
config.fb_count = 2;
}
else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
#if defined(CAMERA_MODEL_ESP_EYE)
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
#endif
cam.init(config);
// Disable any hold on pin 4 that was placed before ESP32 went to sleep
rtc_gpio_hold_dis(GPIO_NUM_4);
// Use PWM channel 7 to control the white on-board LED (flash) connected to GPIO 4
ledcSetup(7, 5000, 8);
ledcAttachPin(4, 7);
// Turn the LED on at specified power
ledcWrite(7, flashPower);
// Initialise the camera
// Short pause helps to ensure the I2C interface has initialised properly before attempting to detect the camera
delay(250);
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
sleep();
}
// Image settings
sensor_t * s = esp_camera_sensor_get();
// Gain
s->set_gain_ctrl(s, 1); // Auto-Gain Control 0 = disable , 1 = enable
s->set_agc_gain(s, 0); // Manual Gain 0 to 30
s->set_gainceiling(s, (gainceiling_t)0); // 0 to 6
// Exposure
s->set_exposure_ctrl(s, 1); // Auto-Exposure Control 0 = disable , 1 = enable
s->set_aec_value(s, 300); // Manual Exposure 0 to 1200
// Exposure Correction
s->set_aec2(s, 0); // Automatic Exposure Correction 0 = disable , 1 = enable
s->set_ae_level(s, 0); // Manual Exposure Correction -2 to 2
// White Balance
s->set_awb_gain(s, 1); // Auto White Balance 0 = disable , 1 = enable
s->set_wb_mode(s, 0); // White Balance Mode 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
s->set_whitebal(s, 1); // White Balance 0 = disable , 1 = enable
s->set_bpc(s, 0); // Black Pixel Correction 0 = disable , 1 = enable
s->set_wpc(s, 1); // White Pixel Correction 0 = disable , 1 = enable
s->set_brightness(s, 0); // Brightness -2 to 2
s->set_contrast(s, 0); // Contrast -2 to 2
s->set_saturation(s, 0); // Saturation -2 to 2
s->set_special_effect(s, 0); // (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
// Additional settings
s->set_lenc(s, 1); // Lens correction 0 = disable , 1 = enable
s->set_hmirror(s, 0); // Horizontal flip image 0 = disable , 1 = enable
s->set_vflip(s, 0); // Vertical flip image 0 = disable , 1 = enable
s->set_colorbar(s, 0); // Colour Testbar 0 = disable , 1 = enable
s->set_raw_gma(s, 1); // 0 = disable , 1 = enable
s->set_dcw(s, 1); // 0 = disable , 1 = enable
// We want to take the picture as soon as possible after the sensor has been triggered, so we'll do that first, before
// setting up the SD card, Wifi etc.
// Initialise a framebuffer
camera_fb_t *fb = NULL;
// But... we still need to give the camera a few seconds to adjust the auto-exposure before taking the picture
// Otherwise you get a green-tinged image as per https://github.com/espressif/esp32-camera/issues/55
// Two seconds should be enough
delay(startupDelayMillis);
// Take picture
fb = esp_camera_fb_get();
// Check it was captured ok
if(!fb) {
Serial.println("Camera capture failed");
sleep();
}
// Turn flash off after taking picture
ledcWrite(7, 0);
// Build up the string of the filename we'll use to save the file
path = "/pic";
// Following section creates filename based on increment value saved in EEPROM
#ifdef USE_INCREMENTAL_FILE_NUMBERING
// We only need 2 bytes of EEPROM to hold a single int value, but according to
// https://arduino-esp8266.readthedocs.io/en/latest/libraries.html#eeprom
// Minimum reserved size is 4 bytes, so we'll use that
EEPROM.begin(4);
// Read the value from the EEPROM cache
EEPROM.get(0, pictureNumber);
pictureNumber += 1;
// Path where new picture will be saved in SD Card
path += String(pictureNumber) + "_";
// Update the EEPROM cache
EEPROM.put(0, pictureNumber);
// And then actually write the modified cache values back to EEPROM
EEPROM.commit();
#endif
// Connect to Wi-Fi if required
#if defined(SEND_EMAIL) || defined(USE_TIMESTAMP)
WiFi.mode(WIFI_STA);
WiFi.setHostname("");
int connAttempts = 0;
IPAddress ip;
WiFi.mode(WIFI_STA);
WiFi.begin(SSID1, PWD1);
WiFi.setHostname("");
while (WiFi.status() != WL_CONNECTED);
{
delay(500);
Serial.print(F("."));
connAttempts++;
}
{
ip = WiFi.localIP();
Serial.println(F("WiFi connected"));
Serial.println("");
Serial.println(ip);
Serial.print("Stream Link: http://");
Serial.print(ip);
Serial.println("/mjpeg/1");
server.on("/mjpeg/1", HTTP_GET, handle_jpg_stream);
server.on("/jpg", HTTP_GET, handle_jpg);
server.onNotFound(handleNotFound);
server.begin();
}
if(WiFi.isConnected()){
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.print(" Signal Level: ");
Serial.println(WiFi.RSSI());
Serial.println();
}
else {
Serial.println(F("Failed to connect to Wi-Fi"));
sleep();
}
#endif
#ifdef USE_TIMESTAMP
// Following section creates filename based on timestamp
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 0;
// Synchronise time from specified NTP server - e.g. "pool.ntp.org", "time.windows.com", "time.nist.gov"
// From https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Time/SimpleTime/SimpleTime.ino
configTime(gmtOffset_sec, daylightOffset_sec, "pool.ntp.org");
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
sleep();
}
else {
Serial.print("Current time is ");
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
char timeStringBuff[50]; //50 chars should be enough
strftime(timeStringBuff, sizeof(timeStringBuff), "%Y%m%d_%H%M%S", &timeinfo);
path += (String)timeStringBuff;
}
#endif
// Add the file extension
path += ".jpg";
// Next, we need to start the SD card
Serial.println("Starting SD Card");
if(!MailClient.sdBegin(14, 2, 15, 13)) {
Serial.println("SD Card Mount Failed");
sleep();
}
// Access the file system on the SD card
fs::FS &fs = SD;
// Attempt to save the image to the specified path
File file = fs.open(path.c_str(), FILE_WRITE);
if(!file){
Serial.printf("Failed to save to path: %s\n", path.c_str());
sleep();
}
else {
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.printf("Saved file to path: %s\n", path.c_str());
}
file.close();
// Now that we've written the file to SD card, we can release the framebuffer memory of the camera
esp_camera_fb_return(fb);
// And breathe for a moment...
delay(1000);
#ifdef SEND_EMAIL
// Get verbose output of emailing process
smtp.debug(1);
// Assign the callback function called after sending
smtp.callback(smtpCallback);
// Define the session config data which used to store the TCP session configuration
ESP_Mail_Session session;
session.server.host_name = SMTP_HOST;
session.server.port = SMTP_PORT;
session.login.email = AUTHOR_EMAIL;
session.login.password = AUTHOR_PASSWORD;
session.login.user_domain = "mydomain.net";
// Define the SMTP_Message class variable to hold the config of the eMail itself
SMTP_Message message;
//message.enable.chunking = true; // Enable chunked data transfer for large messages if server supported
message.sender.name = "ESP32-CAM";
message.sender.email = AUTHOR_EMAIL;
message.subject = "Motion Detected - ESP32-CAM";
message.addRecipient("", "");
//message.addRecipient("", "");
//message.addCc("email3");
//message.addBcc("email4");
// Set the message content
message.text.content = "Motion has been detected, and you are receiving a Pest Memo. Please take a look inside of it.";
message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64;
// Now define the attachment properties
SMTP_Attachment att;
att.descr.filename = "photo.jpg";
att.descr.mime = "application/octet-stream"; //binary data
att.file.path = path.c_str();
att.file.storage_type = esp_mail_file_storage_type_sd;
att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;
// Add attachment to the message
message.addAttachment(att);
// Connect to server with the session config
Serial.println("Connecting to SMTP");
if(!smtp.connect(&session)) {
Serial.println("Couldn't connect");
sleep();
}
// Start sending Email and close the session
Serial.println("Sending Mail");
if(!MailClient.sendMail(&smtp, &message)) {
Serial.println("Error sending Email, " + smtp.errorReason());
sleep();
}
#endif
// Now that email is sent, we can turn the Wi-Fi off
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
// And go to bed until the next time we are triggered to take a photo
sleep();
}
void loop()
{
server.handleClient();
}
OV2640.h
#ifndef OV2640_H_
#define OV2640_H_
#include <Arduino.h>
#include <pgmspace.h>
#include <stdio.h>
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_camera.h"
extern camera_config_t esp32cam_config, esp32cam_aithinker_config, esp32cam_ttgo_t_config;
class OV2640
{
public:
OV2640(){
fb = NULL;
};
~OV2640(){
};
esp_err_t init(camera_config_t config);
void run(void);
size_t getSize(void);
uint8_t *getfb(void);
int getWidth(void);
int getHeight(void);
framesize_t getFrameSize(void);
pixformat_t getPixelFormat(void);
void setFrameSize(framesize_t size);
void setPixelFormat(pixformat_t format);
private:
void runIfNeeded(); // grab a frame if we don't already have one
// camera_framesize_t _frame_size;
// camera_pixelformat_t _pixel_format;
camera_config_t _cam_config;
camera_fb_t *fb;
};
#endif //OV2640_H_
camera_pins.h
#if defined(CAMERA_MODEL_WROVER_KIT)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 21
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 19
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 5
#define Y2_GPIO_NUM 4
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#elif defined(CAMERA_MODEL_ESP_EYE)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 4
#define SIOD_GPIO_NUM 18
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 36
#define Y8_GPIO_NUM 37
#define Y7_GPIO_NUM 38
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 35
#define Y4_GPIO_NUM 14
#define Y3_GPIO_NUM 13
#define Y2_GPIO_NUM 34
#define VSYNC_GPIO_NUM 5
#define HREF_GPIO_NUM 27
#define PCLK_GPIO_NUM 25
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_M5STACK_WIDE)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 22
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_AI_THINKER)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#else
#error "Camera model not selected"
#endif
srcOV2640.h
#include "OV2640.h"
#define TAG "OV2640"
// definitions appropriate for the ESP32-CAM devboard (and most clones)
camera_config_t esp32cam_config{
.pin_pwdn = -1, // FIXME: on the TTGO T-Journal I think this is GPIO 0
.pin_reset = 15,
.pin_xclk = 27,
.pin_sscb_sda = 25,
.pin_sscb_scl = 23,
.pin_d7 = 19,
.pin_d6 = 36,
.pin_d5 = 18,
.pin_d4 = 39,
.pin_d3 = 5,
.pin_d2 = 34,
.pin_d1 = 35,
.pin_d0 = 17,
.pin_vsync = 22,
.pin_href = 26,
.pin_pclk = 21,
.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_JPEG,
// .frame_size = FRAMESIZE_UXGA, // needs 234K of framebuffer space
// .frame_size = FRAMESIZE_SXGA, // needs 160K for framebuffer
// .frame_size = FRAMESIZE_XGA, // needs 96K or even smaller FRAMESIZE_SVGA - can work if using only 1 fb
.frame_size = FRAMESIZE_SVGA,
.jpeg_quality = 12, //0-63 lower numbers are higher quality
.fb_count = 2 // if more than one i2s runs in continous mode. Use only with jpeg
};
camera_config_t esp32cam_aithinker_config{
.pin_pwdn = 32,
.pin_reset = -1,
.pin_xclk = 0,
.pin_sscb_sda = 26,
.pin_sscb_scl = 27,
// Note: LED GPIO is apparently 4 not sure where that goes
// per https://github.com/donny681/ESP32_CAMERA_QR/blob/e4ef44549876457cd841f33a0892c82a71f35358/main/led.c
.pin_d7 = 35,
.pin_d6 = 34,
.pin_d5 = 39,
.pin_d4 = 36,
.pin_d3 = 21,
.pin_d2 = 19,
.pin_d1 = 18,
.pin_d0 = 5,
.pin_vsync = 25,
.pin_href = 23,
.pin_pclk = 22,
.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_1,
.ledc_channel = LEDC_CHANNEL_1,
.pixel_format = PIXFORMAT_JPEG,
// .frame_size = FRAMESIZE_UXGA, // needs 234K of framebuffer space
// .frame_size = FRAMESIZE_SXGA, // needs 160K for framebuffer
// .frame_size = FRAMESIZE_XGA, // needs 96K or even smaller FRAMESIZE_SVGA - can work if using only 1 fb
.frame_size = FRAMESIZE_SVGA,
.jpeg_quality = 12, //0-63 lower numbers are higher quality
.fb_count = 2 // if more than one i2s runs in continous mode. Use only with jpeg
};
camera_config_t esp32cam_ttgo_t_config{
.pin_pwdn = 26,
.pin_reset = -1,
.pin_xclk = 32,
.pin_sscb_sda = 13,
.pin_sscb_scl = 12,
.pin_d7 = 39,
.pin_d6 = 36,
.pin_d5 = 23,
.pin_d4 = 18,
.pin_d3 = 15,
.pin_d2 = 4,
.pin_d1 = 14,
.pin_d0 = 5,
.pin_vsync = 27,
.pin_href = 25,
.pin_pclk = 19,
.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_JPEG,
.frame_size = FRAMESIZE_SVGA,
.jpeg_quality = 12, //0-63 lower numbers are higher quality
.fb_count = 2 // if more than one i2s runs in continous mode. Use only with jpeg
};
void OV2640::run(void)
{
if (fb)
//return the frame buffer back to the driver for reuse
esp_camera_fb_return(fb);
fb = esp_camera_fb_get();
}
void OV2640::runIfNeeded(void)
{
if (!fb)
run();
}
int OV2640::getWidth(void)
{
runIfNeeded();
return fb->width;
}
int OV2640::getHeight(void)
{
runIfNeeded();
return fb->height;
}
size_t OV2640::getSize(void)
{
runIfNeeded();
if (!fb)
return 0; // FIXME - this shouldn't be possible but apparently the new cam board returns null sometimes?
return fb->len;
}
uint8_t *OV2640::getfb(void)
{
runIfNeeded();
if (!fb)
return NULL; // FIXME - this shouldn't be possible but apparently the new cam board returns null sometimes?
return fb->buf;
}
framesize_t OV2640::getFrameSize(void)
{
return _cam_config.frame_size;
}
void OV2640::setFrameSize(framesize_t size)
{
_cam_config.frame_size = size;
}
pixformat_t OV2640::getPixelFormat(void)
{
return _cam_config.pixel_format;
}
void OV2640::setPixelFormat(pixformat_t format)
{
switch (format)
{
case PIXFORMAT_RGB565:
case PIXFORMAT_YUV422:
case PIXFORMAT_GRAYSCALE:
case PIXFORMAT_JPEG:
_cam_config.pixel_format = format;
break;
default:
_cam_config.pixel_format = PIXFORMAT_GRAYSCALE;
break;
}
}
esp_err_t OV2640::init(camera_config_t config)
{
memset(&_cam_config, 0, sizeof(_cam_config));
memcpy(&_cam_config, &config, sizeof(config));
esp_err_t err = esp_camera_init(&_cam_config);
if (err != ESP_OK)
{
printf("Camera probe failed with error 0x%x", err);
return err;
}
// ESP_ERROR_CHECK(gpio_install_isr_service(0));
return ESP_OK;
}
What I will be trying to add in for my fan is:
int speedPin=5;
int dir1=4;
int dir2=3;
int mSpeed=255;
void setup() {
pinMode (speedPin, OUTPUT);
pinMode (dir1, OUTPUT);
pinMode (dir2, OUTPUT);
Serial.begin (115200);
void loop() {
digitalWrite (dir1, HIGH);
digitalWrite (dir2, LOW);
analogWrite (speedPin, mSpeed);
}
I am hoping that I can have the fan turn on for 3 seconds then sleep for 30 minutes then repeat. I would like to use code like this:
#define TIMED_MODE
const int timelapseinterval = 1800 seconds //seconds between 3 second burst
void sleep() {
pinMode(triggerPin, INPUT_PULLUP);
esp_sleep_enable_enable_ext0_wakeup(GPIO_NUM_14, 0);
#elif defined(TIMED_MODE)
esp_sleep_enable_timer_wakeup(timelapseInterval * 1800000000)