177 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "WebServer.h"
 | |
| #include "WiFi.h"
 | |
| #include "esp_camera.h"
 | |
| #include "esp_timer.h"
 | |
| #include "img_converters.h"
 | |
| #include "Arduino.h"
 | |
| #include "soc/soc.h"           // Disable brownout problems
 | |
| #include "soc/rtc_cntl_reg.h"  // Disable brownout problems
 | |
| #include "driver/rtc_io.h"
 | |
| #include <LittleFS.h>
 | |
| 
 | |
| // OV2640 camera module pins (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
 | |
| 
 | |
| // Replace with your network credentials
 | |
| const char* ssid = "...";
 | |
| const char* password = "...";
 | |
| 
 | |
| // Create AsyncWebServer object on port 80
 | |
| WebServer server(80);
 | |
| 
 | |
| // Photo File Name to save in LittleFS
 | |
| #define FILE_PHOTO "/photo.jpg"
 | |
| 
 | |
| //LED flash setup parameters - the LED flash illuminates the meter when the photo is taken
 | |
| const int freq = 5000;
 | |
| const int ledChannel = 2;  // Timer 0 is used to generate the camera pixel clock
 | |
|                            //    so use a different Timer for the LED flash. Use Timer 1 (Channel 2 / Channel 3).
 | |
| const int res = 8;         // select 8-bit resolution
 | |
| const int ledPin = 4;      // the flash LED is connected to pin 4
 | |
| const int brightness = 255; // set the led PWM ( 0 - 255 )
 | |
| 
 | |
| void captureAndSave( void ) {
 | |
|   camera_fb_t * fb = NULL;
 | |
|   bool ok = 0;
 | |
| 
 | |
|   do {
 | |
|     // Take a photo with the camera
 | |
|     Serial.println("Taking a photo...");
 | |
| 
 | |
|     // Dump first frame
 | |
|     fb = esp_camera_fb_get();
 | |
|     esp_camera_fb_return(fb);
 | |
|     fb = NULL;
 | |
| 
 | |
|     // Configure and turn on the LED flash
 | |
|     ledcAttachPin(ledPin, ledChannel);
 | |
|     ledcSetup(ledChannel, freq, res);  
 | |
|     ledcWrite(ledChannel, brightness);
 | |
|     delay(1);
 | |
| 
 | |
|     fb = esp_camera_fb_get();
 | |
| 
 | |
|     // Turn off the LED flash
 | |
|     ledcWrite(ledChannel, 0);
 | |
|     ledcDetachPin(ledPin);
 | |
| 
 | |
|     if (!fb) {
 | |
|       Serial.println("Camera capture failed");
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     // Photo file name
 | |
|     File file = LittleFS.open(FILE_PHOTO, FILE_WRITE);
 | |
| 
 | |
|     // Insert the data in the photo file
 | |
|     if (!file) {
 | |
|       Serial.println("Failed to open file in writing mode");
 | |
|     }
 | |
|     else {
 | |
|       file.write(fb->buf, fb->len); // payload (image), payload length
 | |
|       Serial.println("Photo saved");
 | |
|     }
 | |
|     // Close the file
 | |
|     file.close();
 | |
|     esp_camera_fb_return(fb);
 | |
| 
 | |
|     // check if file has been correctly saved in LittleFS
 | |
|     File f_pic = LittleFS.open( FILE_PHOTO );
 | |
|     unsigned int pic_sz = f_pic.size();
 | |
|     Serial.print("Saved file is ");
 | |
|     Serial.print(pic_sz);
 | |
|     Serial.println(" bytes");
 | |
|     pic_sz > 100 ? ok = true : ok = false;
 | |
|   } while ( !ok );
 | |
| }
 | |
| 
 | |
| void setup() {
 | |
|   Serial.begin(115200);
 | |
| 
 | |
|   // Connect to Wi-Fi
 | |
|   WiFi.begin(ssid, password);
 | |
|   while (WiFi.status() != WL_CONNECTED) {
 | |
|     delay(1000);
 | |
|     Serial.println("Connecting to WiFi...");
 | |
|   }
 | |
|   if (!LittleFS.begin(true)) {
 | |
|     Serial.println("An Error has occurred while mounting LittleFS");
 | |
|     ESP.restart();
 | |
|   }
 | |
|   else {
 | |
|     delay(500);
 | |
|     Serial.println("LittleFS mounted successfully");
 | |
|   }
 | |
| 
 | |
|   // Print ESP32 Local IP Address
 | |
|   Serial.print("IP Address: http://");
 | |
|   Serial.println(WiFi.localIP());
 | |
| 
 | |
|   // Turn off the 'brownout detector'
 | |
|   WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
 | |
| 
 | |
|   // OV2640 camera module
 | |
|   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;
 | |
| 
 | |
|   config.frame_size = FRAMESIZE_HD;
 | |
|   config.jpeg_quality = 10;
 | |
|   config.fb_count = 1;
 | |
| 
 | |
|   // Camera init
 | |
|   esp_err_t err = esp_camera_init(&config);
 | |
|   if (err != ESP_OK) {
 | |
|     Serial.printf("Camera init failed with error 0x%x", err);
 | |
|     ESP.restart();
 | |
|   }
 | |
| 
 | |
|   server.on("/", HTTP_GET, []() {
 | |
|     captureAndSave();
 | |
|     File file = LittleFS.open(FILE_PHOTO);
 | |
|     server.streamFile(file, "image/jpeg");
 | |
|     file.close();
 | |
|   });
 | |
| 
 | |
|   // Start server
 | |
|   server.begin();
 | |
| }
 | |
| 
 | |
| void loop() {
 | |
|   server.handleClient();
 | |
|   delay(1);
 | |
| }
 |