|
| 1 | +#include "esp_camera.h" |
| 2 | +#include <WiFi.h> |
| 3 | + |
| 4 | +// |
| 5 | +// WARNING!!! Make sure that you have either selected ESP32 Wrover Module, |
| 6 | +// or another board which has PSRAM enabled |
| 7 | +// |
| 8 | + |
| 9 | +// Select camera board model |
| 10 | +//#define CAMERA_MODEL_WROVER_KIT |
| 11 | +//#define CAMERA_MODEL_ESP_EYE |
| 12 | +//#define CAMERA_MODEL_M5STACK_PSRAM |
| 13 | +//#define CAMERA_MODEL_M5STACK_WIDE |
| 14 | +#define CAMERA_MODEL_AI_THINKER |
| 15 | + |
| 16 | +// Select camera module used on the board |
| 17 | +#define CAMERA_MODULE_OV2640 |
| 18 | +//#define CAMERA_MODULE_OV3660 |
| 19 | + |
| 20 | +#if __has_include("mywifi.h") |
| 21 | + // I keep my settings in a seperate header file that is in my .gitignore file |
| 22 | + #include "mywifi.h" |
| 23 | +#else |
| 24 | + // OWEN: todo |
| 25 | + // Leave as is to create the default accesspoint, or comment out ACCESSPOINT |
| 26 | + // line and supply your own network SSID and PASSWORD. |
| 27 | + //bool accessPoint = true; |
| 28 | + //const char ap_ssid[] = "ESP-CAM-SERVER"; |
| 29 | + //const char ap_password[] = "ESP-CAM-DEMO"; |
| 30 | + const char* ssid = "my-access-point-ssid"; |
| 31 | + const char* password = "my-access-point-password"; |
| 32 | +#endif |
| 33 | + |
| 34 | +#include "camera_pins.h" |
| 35 | + |
| 36 | +#ifdef LED_PIN // Do we have a LED pin? |
| 37 | + const int ledPin = LED_PIN; |
| 38 | +#else |
| 39 | + const int ledPin = -1; |
| 40 | +#endif |
| 41 | +long int ledVal = 10; // Start with LED dim |
| 42 | +const int ledChannel = 8; // chose a free PWM channel (some channels apparently used by camera) |
| 43 | +const int pwmfreq = 50000; // 5Khz was very audible on my PSU, 50K better. |
| 44 | +const int pwmresolution = 8; // duty cycle has 8 bit range |
| 45 | + |
| 46 | +void startCameraServer(); |
| 47 | + |
| 48 | +void setup() { |
| 49 | + Serial.begin(115200); |
| 50 | + Serial.setDebugOutput(true); // OWEN: Change? ProperDebug with #ifdef & stuff..? |
| 51 | + Serial.println(); |
| 52 | + |
| 53 | + if (ledPin != -1) { |
| 54 | + ledcSetup(ledChannel, pwmfreq, pwmresolution); // configure LED PWM channel |
| 55 | + ledcAttachPin(LED_PIN, ledChannel); // attach the GPIO pin to the channel |
| 56 | + ledcWrite(ledChannel, ledVal); // set initial value |
| 57 | + } |
| 58 | + |
| 59 | + camera_config_t config; |
| 60 | + config.ledc_channel = LEDC_CHANNEL_0; |
| 61 | + config.ledc_timer = LEDC_TIMER_0; |
| 62 | + config.pin_d0 = Y2_GPIO_NUM; |
| 63 | + config.pin_d1 = Y3_GPIO_NUM; |
| 64 | + config.pin_d2 = Y4_GPIO_NUM; |
| 65 | + config.pin_d3 = Y5_GPIO_NUM; |
| 66 | + config.pin_d4 = Y6_GPIO_NUM; |
| 67 | + config.pin_d5 = Y7_GPIO_NUM; |
| 68 | + config.pin_d6 = Y8_GPIO_NUM; |
| 69 | + config.pin_d7 = Y9_GPIO_NUM; |
| 70 | + config.pin_xclk = XCLK_GPIO_NUM; |
| 71 | + config.pin_pclk = PCLK_GPIO_NUM; |
| 72 | + config.pin_vsync = VSYNC_GPIO_NUM; |
| 73 | + config.pin_href = HREF_GPIO_NUM; |
| 74 | + config.pin_sscb_sda = SIOD_GPIO_NUM; |
| 75 | + config.pin_sscb_scl = SIOC_GPIO_NUM; |
| 76 | + config.pin_pwdn = PWDN_GPIO_NUM; |
| 77 | + config.pin_reset = RESET_GPIO_NUM; |
| 78 | + config.xclk_freq_hz = 20000000; |
| 79 | + config.pixel_format = PIXFORMAT_JPEG; |
| 80 | + //init with high specs to pre-allocate larger buffers |
| 81 | + if(psramFound()){ |
| 82 | + config.frame_size = FRAMESIZE_UXGA; |
| 83 | + config.jpeg_quality = 10; |
| 84 | + config.fb_count = 2; |
| 85 | + } else { |
| 86 | + config.frame_size = FRAMESIZE_SVGA; |
| 87 | + config.jpeg_quality = 12; |
| 88 | + config.fb_count = 1; |
| 89 | + } |
| 90 | + |
| 91 | +#if defined(CAMERA_MODEL_ESP_EYE) |
| 92 | + pinMode(13, INPUT_PULLUP); |
| 93 | + pinMode(14, INPUT_PULLUP); |
| 94 | +#endif |
| 95 | + |
| 96 | + // camera init |
| 97 | + esp_err_t err = esp_camera_init(&config); |
| 98 | + if (err != ESP_OK) { |
| 99 | + Serial.printf("Camera init failed with error 0x%x", err); |
| 100 | + return; |
| 101 | + } |
| 102 | + |
| 103 | + sensor_t * s = esp_camera_sensor_get(); |
| 104 | + //initial sensors are flipped vertically and colors are a bit saturated |
| 105 | + if (s->id.PID == OV3660_PID) { |
| 106 | + s->set_vflip(s, 1);//flip it back |
| 107 | + s->set_brightness(s, 1);//up the blightness just a bit |
| 108 | + s->set_saturation(s, -2);//lower the saturation |
| 109 | + } |
| 110 | + //drop down frame size for higher initial frame rate |
| 111 | + s->set_framesize(s, FRAMESIZE_QVGA); |
| 112 | + |
| 113 | +#if defined(CAMERA_MODEL_M5STACK_WIDE) |
| 114 | + s->set_vflip(s, 1); |
| 115 | + s->set_hmirror(s, 1); |
| 116 | +#endif |
| 117 | + |
| 118 | + WiFi.begin(ssid, password); |
| 119 | + |
| 120 | + while (WiFi.status() != WL_CONNECTED) { |
| 121 | + delay(500); |
| 122 | + Serial.print("."); |
| 123 | + } |
| 124 | + Serial.println(""); |
| 125 | + Serial.println("WiFi connected"); |
| 126 | + |
| 127 | + startCameraServer(); |
| 128 | + |
| 129 | + Serial.print("Camera Ready! Use 'http://"); |
| 130 | + Serial.print(WiFi.localIP()); |
| 131 | + Serial.println("' to connect"); |
| 132 | +} |
| 133 | + |
| 134 | +void flashLED(int power) |
| 135 | +{ |
| 136 | + if (ledPin == -1) return; // no led. |
| 137 | + if (ledVal < 64) { // Only flash at power if dim |
| 138 | + ledcWrite(ledChannel, power); // A flash at requested power. |
| 139 | + delay(5); // small delay |
| 140 | + ledcWrite(ledChannel, ledVal); // turn the LED back to set power |
| 141 | + } else { // otherwise blink off |
| 142 | + ledcWrite(ledChannel, 0); // blink off |
| 143 | + delay(5); // small delay |
| 144 | + ledcWrite(ledChannel, ledVal); // turn the LED back to set power |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | +void loop() { |
| 149 | + // put your main code here, to run repeatedly: |
| 150 | + delay(10000); |
| 151 | +} |
0 commit comments