#include "WiFi.h" #include "esp_camera.h" #include "esp_timer.h" #include "img_converters.h" #include "Arduino.h" #include "soc/soc.h" // Disable brownour problems #include "soc/rtc_cntl_reg.h" // Disable brownour problems #include "driver/rtc_io.h" #include "FS.h" // SD Card ESP32 #include "SD_MMC.h" // SD Card ESP32 #include // read and write from flash memory #include #include #include // define the number of bytes you want to access #define EEPROM_SIZE 1 constexpr int kCameraPin_PWDN = 32; constexpr int kCameraPin_RESET = -1; // NC constexpr int kCameraPin_XCLK = 0; constexpr int kCameraPin_SIOD = 26; constexpr int kCameraPin_SIOC = 27; constexpr int kCameraPin_Y9 = 35; constexpr int kCameraPin_Y8 = 34; constexpr int kCameraPin_Y7 = 39; constexpr int kCameraPin_Y6 = 36; constexpr int kCameraPin_Y5 = 21; constexpr int kCameraPin_Y4 = 19; constexpr int kCameraPin_Y3 = 18; constexpr int kCameraPin_Y2 = 5; constexpr int kCameraPin_VSYNC = 25; constexpr int kCameraPin_HREF = 23; constexpr int kCameraPin_PCLK = 22; int pictureNumber = 0; const char* ssid = "FRITZ!Box 7530 MT"; const char* password = "14649735070293466500"; const char* mqtt_server = "mqtt.flespi.io"; const int mqtt_port = 1883; const char* mqtt_user = "Ydl9IsQMA5NqDfGWgQt98ebuHLbm1gsPkDNQTtqho2xP51CbHTaGX9YuIZEz3Xdd"; const char* mqtt_password = ""; const char* mqtt_TopicName = "esp32/birds"; framesize_t resolution_ = FRAMESIZE_QVGA; #define SLEEP_DELAY 0 #define FILE_PHOTO "/photo.jpg" // OV2640 相机模组的针脚定义 #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 #define CAMERA_MODEL_AI_THINKER WiFiClient mqttClient; PubSubClient client(mqttClient); const int LED_BUILTIN = 4; void setup_camera() { // OV2640 camera module camera_config_t config; config.pin_pwdn = kCameraPin_PWDN; config.pin_reset = kCameraPin_RESET; config.pin_xclk = kCameraPin_XCLK; config.pin_sscb_sda = kCameraPin_SIOD; config.pin_sscb_scl = kCameraPin_SIOC; config.pin_d7 = kCameraPin_Y9; config.pin_d6 = kCameraPin_Y8; config.pin_d5 = kCameraPin_Y7; config.pin_d4 = kCameraPin_Y6; config.pin_d3 = kCameraPin_Y5; config.pin_d2 = kCameraPin_Y4; config.pin_d1 = kCameraPin_Y3; config.pin_d0 = kCameraPin_Y2; config.pin_vsync = kCameraPin_VSYNC; config.pin_href = kCameraPin_HREF; config.pin_pclk = kCameraPin_PCLK; config.xclk_freq_hz = 20000000; config.ledc_timer = LEDC_TIMER_0; config.ledc_channel = LEDC_CHANNEL_0; config.pixel_format = PIXFORMAT_JPEG; config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 10; config.fb_count = 1; esp_err_t err = esp_camera_init(&config); Serial.printf("esp_camera_init: 0x%x\n", err); // sensor_t *s = esp_camera_sensor_get(); // s->set_framesize(s, FRAMESIZE_QVGA); } String msg; int timeCount = 0; void getimg(){//拍照分段发送到mqtt camera_fb_t *fb = esp_camera_fb_get(); if (fb){ Serial.printf("width: %d, height: %d, buf: 0x%x, len: %d\n", fb->width, fb->height, fb->buf, fb->len); char data[4104]; //client.publish(mqtt_TopicName, "0"); for (int i = 0; i < fb->len; i++){ sprintf(data, "%02X", *((fb->buf + i))); msg += data; // if (msg.length() == 4096){ // timeCount += 1; // client.beginPublish(mqtt_TopicName, msg.length(), 0); // client.print(msg); // client.endPublish(); // msg = ""; // } } if (msg.length() > 0){ client.beginPublish(mqtt_TopicName, msg.length(), 0); client.print(msg); client.endPublish(); msg = ""; } //client.publish(mqtt_TopicName, "1"); timeCount = 0; esp_camera_fb_return(fb); } } void setup_wifi() { delay(10); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.print("IP address : "); Serial.println(WiFi.localIP()); } void reconnect() { while (!client.connected()) { Serial.print("Attempting MQTT connection..."); if (client.connect("ESP32Client", mqtt_user, mqtt_password)) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } void setup() { Serial.begin(115200); Serial.setDebugOutput(true); Serial.println(); setup_camera(); setup_wifi(); client.setServer(mqtt_server, mqtt_port); if (client.connect("ESP32Client", mqtt_user, mqtt_password)) { Serial.println("mqtt connected"); } } void publishTelemetry(String data) { while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } boolean Status = client.publish_P( mqtt_TopicName, (const uint8_t*) data.c_str(), data.length(), true); Serial.println(String(Status ? "Successful" : "Error") ); } void capturePhoto( void ) { // Retrieve camera framebuffer camera_fb_t * fb = NULL; uint8_t* _jpg_buf = NULL; esp_err_t res = ESP_OK; size_t frame_size = 0; Serial.print("Capturing Image..."); digitalWrite(LED_BUILTIN, HIGH); // turn the LED on delay(1000); // wait for a second fb = esp_camera_fb_get(); digitalWrite(LED_BUILTIN, LOW); // turn the LED off delay(1000); // wait for a second if (!fb) { Serial.println("Camera capture failed"); res = ESP_FAIL; } else { Serial.println("Done!"); Serial.println(String("Size of the image...") + String(fb->len)); if (fb->format != PIXFORMAT_JPEG) { Serial.println("Compressing"); bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &frame_size); esp_camera_fb_return(fb); fb = NULL; if (!jpeg_converted) { Serial.println("JPEG compression failed"); res = ESP_FAIL; } } else { frame_size = fb->len; _jpg_buf = fb->buf; Serial.print("Publish photo..."); publishTelemetry(base64::encode(_jpg_buf, fb->len)); Serial.println("Done!"); esp_camera_fb_return(fb); } } if (res != ESP_OK) { return; } //Serial.println("Starting SD Card"); if(!SD_MMC.begin()){ Serial.println("SD Card Mount Failed"); return; } uint8_t cardType = SD_MMC.cardType(); if(cardType == CARD_NONE){ Serial.println("No SD Card attached"); return; } // initialize EEPROM with predefined size EEPROM.begin(EEPROM_SIZE); pictureNumber = EEPROM.read(0) + 1; // Path where new picture will be saved in SD Card String path = "/picture" + String(pictureNumber) +".jpg"; fs::FS &fs = SD_MMC; Serial.printf("Picture file name: %s\n", path.c_str()); File file = fs.open(path.c_str(), FILE_WRITE); if(!file){ Serial.println("Failed to open file in writing mode"); } else { file.write(fb->buf, fb->len); // payload (image), payload length Serial.printf("Saved file to path: %s\n", path.c_str()); EEPROM.write(0, pictureNumber); EEPROM.commit(); } file.close(); esp_camera_fb_return(fb); } void loop() { Serial.println("PSRAM found: " + String(psramFound())); if (!client.connected()) { reconnect(); } if (client.connected()) { capturePhoto(); } client.loop(); Serial.println("Going to sleep now"); if (SLEEP_DELAY == 0) { esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1); delay(1000); esp_deep_sleep_start(); } if (SLEEP_DELAY > 0) { delay(SLEEP_DELAY); delay(30000); } }