├── readme └── CAT_DetectorV3 ├── credentials_Example.h ├── CAT_DetectorV3.ino ├── helpers.h └── camera_pins.h /readme: -------------------------------------------------------------------------------- 1 | Code for video: https://youtu.be/Y6Scr5Ago9g 2 | 3 | Still work in progress -------------------------------------------------------------------------------- /CAT_DetectorV3/credentials_Example.h: -------------------------------------------------------------------------------- 1 | // WiFi credentials 2 | const char* ssid = "***"; 3 | const char* password = "***"; 4 | 5 | // MQTT broker details 6 | const char* mqttServer = "192.168.0.203"; 7 | const char* apiKey = "***"; -------------------------------------------------------------------------------- /CAT_DetectorV3/CAT_DetectorV3.ino: -------------------------------------------------------------------------------- 1 | #define CAMERA_MODEL_AI_THINKER 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "esp_camera.h" 9 | #include 10 | #include // this file contains SSID, password, and ChatGPT key 11 | #include "camera_pins.h" 12 | #include "helpers.h" 13 | 14 | const char* openai_api_url = "https://api.openai.com/v1/chat/completions"; 15 | const char* openai_api_key = apiKey; 16 | 17 | 18 | String response = ""; 19 | 20 | #define PICTURELEN 10000 21 | 22 | // Pin definitions 23 | #define RELAY_PIN 2 24 | 25 | 26 | String captureImage() { 27 | digitalWrite(LAMP_PIN, HIGH); // Turn on LED 28 | delay(100); 29 | camera_fb_t* fb = esp_camera_fb_get(); 30 | if (!fb) { 31 | Serial.println("Camera capture failed"); 32 | debugMQTT("No picture"); 33 | digitalWrite(LAMP_PIN, LOW); // Turn off LED 34 | delay(200); 35 | esp_restart(); // Trigger a software reset 36 | } 37 | String _imageBase64 = base64::encode((const uint8_t*)fb->buf, fb->len); 38 | esp_camera_fb_return(fb); 39 | Serial.println("captured"); 40 | // Serial.println(_imageBase64); 41 | digitalWrite(LAMP_PIN, LOW); // Turn off LED 42 | return _imageBase64; 43 | } 44 | 45 | String sendQuestionToChatGPT(char question[], String imageBase64) { 46 | HTTPClient http; 47 | // Create JSON payload 48 | DynamicJsonDocument doc(PICTURELEN); 49 | doc["model"] = "gpt-4o"; 50 | JsonArray messages = doc.createNestedArray("messages"); 51 | 52 | JsonObject message = messages.createNestedObject(); 53 | message["role"] = "user"; 54 | 55 | JsonArray content = message.createNestedArray("content"); 56 | 57 | JsonObject textObject = content.createNestedObject(); 58 | textObject["type"] = "text"; 59 | textObject["text"] = question; 60 | 61 | JsonObject imageObject = content.createNestedObject(); 62 | imageObject["type"] = "image_url"; 63 | 64 | JsonObject imageUrl = imageObject.createNestedObject("image_url"); 65 | imageUrl["url"] = "data:image/jpeg;base64," + imageBase64 + "\""; 66 | 67 | doc["max_tokens"] = 300; 68 | 69 | String payload; 70 | serializeJson(doc, payload); 71 | doc.clear(); 72 | 73 | http.begin(openai_api_url); 74 | http.addHeader("Content-Type", "application/json"); 75 | http.addHeader("Authorization", String("Bearer ") + openai_api_key); 76 | 77 | // Send the POST request 78 | int httpResponseCode = http.POST(payload); 79 | 80 | // Handle the response 81 | String GPTresponse; 82 | if (httpResponseCode > 0) { 83 | GPTresponse = http.getString(); 84 | //Serial.println("GPTResponse:"); 85 | //Serial.println(GPTresponse); 86 | } else { 87 | Serial.print("Error on sending POST: "); 88 | Serial.println(httpResponseCode); 89 | debugMQTT("Error sending POST"); 90 | GPTresponse = "0"; // in case of error water is on 91 | } 92 | http.end(); 93 | DynamicJsonDocument responseBody(4096); 94 | DeserializationError error = deserializeJson(responseBody, GPTresponse); 95 | 96 | if (error) { 97 | Serial.print("JSON parse failed: "); 98 | Serial.println(error.c_str()); 99 | debugMQTT("JSON not decoded"); 100 | return ""; // Assume no cat detected on error 101 | } 102 | 103 | String answer = responseBody["choices"][0]["message"]["content"]; 104 | answer.toLowerCase(); 105 | Serial.print("Answer from API: "); 106 | debugMQTT(answer); 107 | Serial.println(answer); 108 | return (answer); 109 | } 110 | 111 | void setup() { 112 | Serial.begin(115200); 113 | pinMode(RELAY_PIN, OUTPUT); 114 | digitalWrite(RELAY_PIN, LOW); 115 | pinMode(LAMP_PIN, OUTPUT); 116 | digitalWrite(LAMP_PIN, LOW); 117 | 118 | connectWiFi(); 119 | setupCamera(); 120 | defineMACaddress(); 121 | client.setCallback(callback); 122 | setupOTA(); 123 | connectMQTT(); 124 | HA_auto_discovery(); 125 | Serial.print("stateTopic"); 126 | Serial.println(stateTopicName); 127 | debugMQTT("Connected"); 128 | 129 | String imageBase64 = captureImage(); 130 | if (imageBase64.isEmpty()) { 131 | debugMQTT("no image"); 132 | delay(200); 133 | esp_restart(); 134 | } 135 | debugMQTT("Image taken"); 136 | Serial.println("1st Question-----------"); 137 | debugMQTT("1st question"); 138 | response = sendQuestionToChatGPT("what do you see on the image?", imageBase64); 139 | Serial.println("2nd Question-----------"); 140 | debugMQTT("2nd question"); 141 | response = sendQuestionToChatGPT("Do you recognize a cat on the image? Please answer only with yes or no", imageBase64); 142 | if (response != "") { 143 | if (response.indexOf("yes") != -1) { 144 | Serial.println("Cat detected!"); 145 | client.publish(stateTopicName.c_str(), "ON"); 146 | } else { 147 | Serial.println("No cat detected!"); 148 | client.publish(stateTopicName.c_str(), "OFF"); 149 | } 150 | } else { 151 | client.publish(stateTopicName.c_str(), "No response"); 152 | client.publish(stateTopicName.c_str(), "ON"); 153 | } 154 | } 155 | 156 | void loop() { 157 | ArduinoOTA.handle(); 158 | if (!client.connected()) { 159 | connectMQTT(); 160 | } 161 | client.loop(); 162 | } 163 | -------------------------------------------------------------------------------- /CAT_DetectorV3/helpers.h: -------------------------------------------------------------------------------- 1 | const int mqttPort = 1883; 2 | const char* mqttUser = "admin"; 3 | const char* mqttPassword = "admin"; 4 | 5 | String macAddr; 6 | String uniqueID; 7 | 8 | String stateTopicName; 9 | String discoveryTopicName; 10 | 11 | #define receiveTopic "Cat_PIR" 12 | #define MESSAGELENGTH 600 13 | 14 | WiFiClient espClient; 15 | PubSubClient client(espClient); 16 | 17 | void setupCamera() { 18 | camera_config_t config; 19 | config.ledc_channel = LEDC_CHANNEL_0; 20 | config.ledc_timer = LEDC_TIMER_0; 21 | config.pin_d0 = Y2_GPIO_NUM; 22 | config.pin_d1 = Y3_GPIO_NUM; 23 | config.pin_d2 = Y4_GPIO_NUM; 24 | config.pin_d3 = Y5_GPIO_NUM; 25 | config.pin_d4 = Y6_GPIO_NUM; 26 | config.pin_d5 = Y7_GPIO_NUM; 27 | config.pin_d6 = Y8_GPIO_NUM; 28 | config.pin_d7 = Y9_GPIO_NUM; 29 | config.pin_xclk = XCLK_GPIO_NUM; 30 | config.pin_pclk = PCLK_GPIO_NUM; 31 | config.pin_vsync = VSYNC_GPIO_NUM; 32 | config.pin_href = HREF_GPIO_NUM; 33 | config.pin_sccb_sda = SIOD_GPIO_NUM; 34 | config.pin_sccb_scl = SIOC_GPIO_NUM; 35 | config.pin_pwdn = PWDN_GPIO_NUM; 36 | config.pin_reset = RESET_GPIO_NUM; 37 | config.xclk_freq_hz = 20000000; 38 | config.frame_size = FRAMESIZE_SVGA; 39 | config.pixel_format = PIXFORMAT_JPEG; // for streaming 40 | //config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition 41 | config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; 42 | config.fb_location = CAMERA_FB_IN_PSRAM; 43 | config.jpeg_quality = 12; 44 | config.fb_count = 1; 45 | 46 | // if PSRAM IC present, init with UXGA resolution and higher JPEG quality 47 | // for larger pre-allocated frame buffer. 48 | if (config.pixel_format == PIXFORMAT_JPEG) { 49 | if (psramFound()) { 50 | config.jpeg_quality = 10; 51 | config.fb_count = 2; 52 | config.grab_mode = CAMERA_GRAB_LATEST; 53 | } else { 54 | // Limit the frame size when PSRAM is not available 55 | Serial.println("Please switch PSRAM on in configuration"); 56 | while (1) 57 | config.frame_size = FRAMESIZE_SVGA; 58 | config.fb_location = CAMERA_FB_IN_DRAM; 59 | } 60 | } else { 61 | // Best option for face detection/recognition 62 | config.frame_size = FRAMESIZE_240X240; 63 | #if CONFIG_IDF_TARGET_ESP32S3 64 | config.fb_count = 2; 65 | #endif 66 | } 67 | 68 | #if defined(CAMERA_MODEL_ESP_EYE) 69 | pinMode(13, INPUT_PULLUP); 70 | pinMode(14, INPUT_PULLUP); 71 | #endif 72 | 73 | // camera init 74 | esp_err_t err = esp_camera_init(&config); 75 | if (err != ESP_OK) { 76 | Serial.printf("Camera init failed with error 0x%x", err); 77 | return; 78 | } 79 | 80 | sensor_t* s = esp_camera_sensor_get(); 81 | // initial sensors are flipped vertically and colors are a bit saturated 82 | if (s->id.PID == OV3660_PID) { 83 | s->set_vflip(s, 1); // flip it back 84 | s->set_brightness(s, 1); // up the brightness just a bit 85 | s->set_saturation(s, -2); // lower the saturation 86 | } 87 | // drop down frame size for higher initial frame rate 88 | if (config.pixel_format == PIXFORMAT_JPEG) { 89 | s->set_framesize(s, FRAMESIZE_QVGA); 90 | } 91 | 92 | #if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM) 93 | s->set_vflip(s, 1); 94 | s->set_hmirror(s, 1); 95 | #endif 96 | 97 | #if defined(CAMERA_MODEL_ESP32S3_EYE) 98 | s->set_vflip(s, 1); 99 | #endif 100 | 101 | // Setup LED FLash if LED pin is defined in camera_pins.h 102 | #if defined(LED_GPIO_NUM) 103 | setupLedFlash(LED_GPIO_NUM); 104 | #endif 105 | } 106 | 107 | void connectWiFi() { 108 | WiFi.begin(ssid, password); 109 | while (WiFi.status() != WL_CONNECTED) { 110 | delay(1000); 111 | Serial.println("Connecting to WiFi..."); 112 | } 113 | Serial.println("WiFi Connected!"); 114 | } 115 | 116 | void connectMQTT() { 117 | client.setServer(mqttServer, mqttPort); 118 | while (!client.connected()) { 119 | Serial.println("Connecting to MQTT..."); 120 | if (client.connect("ESP32Client", mqttUser, mqttPassword)) { 121 | Serial.println("Connected to MQTT"); 122 | client.subscribe(receiveTopic); 123 | } else { 124 | Serial.print("MQTT connection failed. Reset."); 125 | esp_restart(); 126 | } 127 | } 128 | } 129 | 130 | void debugMQTT(String _message) { 131 | Serial.print("------------"); 132 | Serial.println(_message); 133 | client.publish(stateTopicName.c_str(), _message.c_str()); 134 | } 135 | 136 | void setupOTA() { 137 | ArduinoOTA.setHostname("Cat-Discoverer"); // Set the OTA device name 138 | ArduinoOTA.setPassword("admin"); // Optional: Set an OTA password 139 | ArduinoOTA.onStart([]() { 140 | String type; 141 | if (ArduinoOTA.getCommand() == U_FLASH) { 142 | type = "sketch"; 143 | } else { // U_SPIFFS 144 | type = "filesystem"; 145 | } 146 | Serial.println("Start updating " + type); 147 | }); 148 | 149 | ArduinoOTA.onEnd([]() { 150 | Serial.println("\nEnd"); 151 | }); 152 | 153 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { 154 | Serial.printf("Progress: %u%%\r", (progress / (total / 100))); 155 | }); 156 | 157 | ArduinoOTA.onError([](ota_error_t error) { 158 | Serial.printf("Error[%u]: ", error); 159 | if (error == OTA_AUTH_ERROR) { 160 | Serial.println("Auth Failed"); 161 | } else if (error == OTA_BEGIN_ERROR) { 162 | Serial.println("Begin Failed"); 163 | } else if (error == OTA_CONNECT_ERROR) { 164 | Serial.println("Connect Failed"); 165 | } else if (error == OTA_RECEIVE_ERROR) { 166 | Serial.println("Receive Failed"); 167 | } else if (error == OTA_END_ERROR) { 168 | Serial.println("End Failed"); 169 | } 170 | }); 171 | 172 | ArduinoOTA.begin(); 173 | Serial.println("OTA Ready"); 174 | } 175 | 176 | 177 | void HA_auto_discovery() { 178 | // Construct the autodiscovery message for the binary sensor 179 | StaticJsonDocument doc; // Allocate memory for the JSON document 180 | doc["name"] = "Cat-Discover"; 181 | doc["device_class"] = "occupancy"; 182 | doc["qos"] = 0; 183 | doc["unique_id"] = uniqueID; // Use MAC-based unique ID 184 | doc["payload_on"] = "ON"; 185 | doc["payload_off"] = "OFF"; 186 | doc["state_topic"] = stateTopicName; 187 | /* 188 | // Create a nested array for availability 189 | JsonArray availability = doc.createNestedArray("availability"); 190 | JsonObject availability_0 = availability.createNestedObject(); 191 | availability_0["topic"] = String(stateTopicName) + "/availability"; 192 | availability_0["payload_available"] = "online"; 193 | availability_0["payload_not_available"] = "offline"; 194 | */ 195 | JsonObject device = doc.createNestedObject("device"); 196 | device["ids"] = macAddr; // Use the full MAC address as identifier 197 | device["name"] = "Cat-Discover"; // Device name 198 | device["mf"] = "Sensorsiot"; // Include supplier info 199 | device["mdl"] = "Notifier"; 200 | device["sw"] = "1.0"; 201 | device["hw"] = "0.9"; 202 | 203 | char buffer[MESSAGELENGTH]; 204 | serializeJson(doc, buffer); // Serialize JSON object to buffer 205 | 206 | Serial.println(discoveryTopicName.c_str()); 207 | Serial.print("AutodiscoveryMessage: "); 208 | Serial.println(buffer); // Print the JSON payload to Serial Monitor 209 | Serial.print("Length of buffer: "); 210 | Serial.println(strlen(buffer)); 211 | client.publish(discoveryTopicName.c_str(), buffer, true); // Publish to MQTT with retain flag set 212 | } 213 | 214 | void callback(char* topic, byte* payload, unsigned int length) { 215 | String message = ""; 216 | for (unsigned int i = 0; i < length; i++) { 217 | message += (char)payload[i]; 218 | } 219 | 220 | Serial.print("Message received on topic "); 221 | Serial.print(topic); 222 | Serial.print(": "); 223 | Serial.println(message); 224 | 225 | if (String(topic) == receiveTopic && message == "occupied") { 226 | Serial.println("Motion detected! Capturing image..."); 227 | // detect(); 228 | } 229 | } 230 | 231 | void defineMACaddress(){ 232 | // Get the MAC address of the board 233 | macAddr = WiFi.macAddress(); 234 | Serial.println(macAddr); 235 | String hi = macAddr; 236 | hi.toLowerCase(); 237 | hi.replace(":", ""); // Remove colons from MAC address to make it topic-friendly 238 | // Extract the last 6 characters of the MAC address (ignoring colons) 239 | uniqueID = "catNotifier-" + hi.substring(hi.length() - 4); // Use last 4 byte 240 | stateTopicName = "homeassistant/binary_sensor/" + uniqueID + "/state"; 241 | discoveryTopicName = "homeassistant/binary_sensor/" + uniqueID + "/config"; 242 | 243 | Serial.print("uniqueID: "); 244 | Serial.println(uniqueID); 245 | Serial.print("stateTopicName: "); 246 | Serial.println(stateTopicName); 247 | Serial.print("discoveryTopicName: "); 248 | Serial.println(discoveryTopicName); 249 | } -------------------------------------------------------------------------------- /CAT_DetectorV3/camera_pins.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Pin definitions for some common ESP-CAM modules 3 | * 4 | * Select the module to use in myconfig.h 5 | * Defaults to AI-THINKER CAM module 6 | * 7 | */ 8 | #if defined(CAMERA_MODEL_AI_THINKER) 9 | // 10 | // AI Thinker 11 | // https://github.com/SeeedDocument/forum_doc/raw/master/reg/ESP32_CAM_V1.6.pdf 12 | // 13 | #define PWDN_GPIO_NUM 32 14 | #define RESET_GPIO_NUM -1 15 | #define XCLK_GPIO_NUM 0 16 | #define SIOD_GPIO_NUM 26 17 | #define SIOC_GPIO_NUM 27 18 | #define Y9_GPIO_NUM 35 19 | #define Y8_GPIO_NUM 34 20 | #define Y7_GPIO_NUM 39 21 | #define Y6_GPIO_NUM 36 22 | #define Y5_GPIO_NUM 21 23 | #define Y4_GPIO_NUM 19 24 | #define Y3_GPIO_NUM 18 25 | #define Y2_GPIO_NUM 5 26 | #define VSYNC_GPIO_NUM 25 27 | #define HREF_GPIO_NUM 23 28 | #define PCLK_GPIO_NUM 22 29 | #define LED_PIN 33 // Status led 30 | #define LED_ON LOW // - Pin is inverted. 31 | #define LED_OFF HIGH // 32 | #define LAMP_PIN 4 // LED FloodLamp. 33 | 34 | #elif defined(CAMERA_MODEL_WROVER_KIT) 35 | // 36 | // ESP WROVER 37 | // https://dl.espressif.com/dl/schematics/ESP-WROVER-KIT_SCH-2.pdf 38 | // 39 | #define PWDN_GPIO_NUM -1 40 | #define RESET_GPIO_NUM -1 41 | #define XCLK_GPIO_NUM 21 42 | #define SIOD_GPIO_NUM 26 43 | #define SIOC_GPIO_NUM 27 44 | #define Y9_GPIO_NUM 35 45 | #define Y8_GPIO_NUM 34 46 | #define Y7_GPIO_NUM 39 47 | #define Y6_GPIO_NUM 36 48 | #define Y5_GPIO_NUM 19 49 | #define Y4_GPIO_NUM 18 50 | #define Y3_GPIO_NUM 5 51 | #define Y2_GPIO_NUM 4 52 | #define VSYNC_GPIO_NUM 25 53 | #define HREF_GPIO_NUM 23 54 | #define PCLK_GPIO_NUM 22 55 | #define LED_PIN 2 // A status led on the RGB; could also use pin 0 or 4 56 | #define LED_ON HIGH // 57 | #define LED_OFF LOW // 58 | // #define LAMP_PIN x // No LED FloodLamp. 59 | 60 | #elif defined(CAMERA_MODEL_ESP_EYE) 61 | // 62 | // ESP-EYE 63 | // https://twitter.com/esp32net/status/1085488403460882437 64 | #define PWDN_GPIO_NUM -1 65 | #define RESET_GPIO_NUM -1 66 | #define XCLK_GPIO_NUM 4 67 | #define SIOD_GPIO_NUM 18 68 | #define SIOC_GPIO_NUM 23 69 | #define Y9_GPIO_NUM 36 70 | #define Y8_GPIO_NUM 37 71 | #define Y7_GPIO_NUM 38 72 | #define Y6_GPIO_NUM 39 73 | #define Y5_GPIO_NUM 35 74 | #define Y4_GPIO_NUM 14 75 | #define Y3_GPIO_NUM 13 76 | #define Y2_GPIO_NUM 34 77 | #define VSYNC_GPIO_NUM 5 78 | #define HREF_GPIO_NUM 27 79 | #define PCLK_GPIO_NUM 25 80 | #define LED_PIN 21 // Status led 81 | #define LED_ON HIGH // 82 | #define LED_OFF LOW // 83 | // #define LAMP_PIN x // No LED FloodLamp. 84 | 85 | #elif defined(CAMERA_MODEL_M5STACK_PSRAM) 86 | // 87 | // ESP32 M5STACK 88 | // 89 | #define PWDN_GPIO_NUM -1 90 | #define RESET_GPIO_NUM 15 91 | #define XCLK_GPIO_NUM 27 92 | #define SIOD_GPIO_NUM 25 93 | #define SIOC_GPIO_NUM 23 94 | #define Y9_GPIO_NUM 19 95 | #define Y8_GPIO_NUM 36 96 | #define Y7_GPIO_NUM 18 97 | #define Y6_GPIO_NUM 39 98 | #define Y5_GPIO_NUM 5 99 | #define Y4_GPIO_NUM 34 100 | #define Y3_GPIO_NUM 35 101 | #define Y2_GPIO_NUM 32 102 | #define VSYNC_GPIO_NUM 22 103 | #define HREF_GPIO_NUM 26 104 | #define PCLK_GPIO_NUM 21 105 | // M5 Stack status/illumination LED details unknown/unclear 106 | // #define LED_PIN x // Status led 107 | // #define LED_ON HIGH // 108 | // #define LED_OFF LOW // 109 | // #define LAMP_PIN x // LED FloodLamp. 110 | 111 | #elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM) 112 | // 113 | // ESP32 M5STACK V2 114 | // 115 | #define PWDN_GPIO_NUM -1 116 | #define RESET_GPIO_NUM 15 117 | #define XCLK_GPIO_NUM 27 118 | #define SIOD_GPIO_NUM 22 119 | #define SIOC_GPIO_NUM 23 120 | #define Y9_GPIO_NUM 19 121 | #define Y8_GPIO_NUM 36 122 | #define Y7_GPIO_NUM 18 123 | #define Y6_GPIO_NUM 39 124 | #define Y5_GPIO_NUM 5 125 | #define Y4_GPIO_NUM 34 126 | #define Y3_GPIO_NUM 35 127 | #define Y2_GPIO_NUM 32 128 | #define VSYNC_GPIO_NUM 25 129 | #define HREF_GPIO_NUM 26 130 | #define PCLK_GPIO_NUM 21 131 | // M5 Stack status/illumination LED details unknown/unclear 132 | // #define LED_PIN x // Status led 133 | // #define LED_ON HIGH // 134 | // #define LED_OFF LOW // 135 | // #define LAMP_PIN x // LED FloodLamp. 136 | 137 | #elif defined(CAMERA_MODEL_M5STACK_WIDE) 138 | // 139 | // ESP32 M5STACK WIDE 140 | // 141 | #define PWDN_GPIO_NUM -1 142 | #define RESET_GPIO_NUM 15 143 | #define XCLK_GPIO_NUM 27 144 | #define SIOD_GPIO_NUM 22 145 | #define SIOC_GPIO_NUM 23 146 | #define Y9_GPIO_NUM 19 147 | #define Y8_GPIO_NUM 36 148 | #define Y7_GPIO_NUM 18 149 | #define Y6_GPIO_NUM 39 150 | #define Y5_GPIO_NUM 5 151 | #define Y4_GPIO_NUM 34 152 | #define Y3_GPIO_NUM 35 153 | #define Y2_GPIO_NUM 32 154 | #define VSYNC_GPIO_NUM 25 155 | #define HREF_GPIO_NUM 26 156 | #define PCLK_GPIO_NUM 21 157 | // M5 Stack status/illumination LED details unknown/unclear 158 | // #define LED_PIN x // Status led 159 | // #define LED_ON HIGH // 160 | // #define LED_OFF LOW // 161 | // #define LAMP_PIN x // LED FloodLamp. 162 | 163 | #elif defined(CAMERA_MODEL_M5STACK_ESP32CAM) 164 | // 165 | // Common M5 Stack without PSRAM 166 | // 167 | #define PWDN_GPIO_NUM -1 168 | #define RESET_GPIO_NUM 15 169 | #define XCLK_GPIO_NUM 27 170 | #define SIOD_GPIO_NUM 25 171 | #define SIOC_GPIO_NUM 23 172 | #define Y9_GPIO_NUM 19 173 | #define Y8_GPIO_NUM 36 174 | #define Y7_GPIO_NUM 18 175 | #define Y6_GPIO_NUM 39 176 | #define Y5_GPIO_NUM 5 177 | #define Y4_GPIO_NUM 34 178 | #define Y3_GPIO_NUM 35 179 | #define Y2_GPIO_NUM 17 180 | #define VSYNC_GPIO_NUM 22 181 | #define HREF_GPIO_NUM 26 182 | #define PCLK_GPIO_NUM 21 183 | // Note NO PSRAM,; so maximum working resolution is XGA 1024×768 184 | // M5 Stack status/illumination LED details unknown/unclear 185 | // #define LED_PIN x // Status led 186 | // #define LED_ON HIGH // 187 | // #define LED_OFF LOW // 188 | // #define LAMP_PIN x // LED FloodLamp. 189 | 190 | #elif defined(CAMERA_MODEL_TTGO_T_JOURNAL) 191 | // 192 | // LilyGO TTGO T-Journal ESP32; with OLED! but not used here.. :-( 193 | #define PWDN_GPIO_NUM 0 194 | #define RESET_GPIO_NUM 15 195 | #define XCLK_GPIO_NUM 27 196 | #define SIOD_GPIO_NUM 25 197 | #define SIOC_GPIO_NUM 23 198 | #define Y9_GPIO_NUM 19 199 | #define Y8_GPIO_NUM 36 200 | #define Y7_GPIO_NUM 18 201 | #define Y6_GPIO_NUM 39 202 | #define Y5_GPIO_NUM 5 203 | #define Y4_GPIO_NUM 34 204 | #define Y3_GPIO_NUM 35 205 | #define Y2_GPIO_NUM 17 206 | #define VSYNC_GPIO_NUM 22 207 | #define HREF_GPIO_NUM 26 208 | #define PCLK_GPIO_NUM 21 209 | // TTGO T Journal status/illumination LED details unknown/unclear 210 | // #define LED_PIN 33 // Status led 211 | // #define LED_ON LOW // - Pin is inverted. 212 | // #define LED_OFF HIGH // 213 | // #define LAMP_PIN 4 // LED FloodLamp. 214 | 215 | #elif defined(CAMERA_MODEL_ARDUCAM_ESP32S_UNO) 216 | // Pins from user @rdragonrydr 217 | // https://github.com/ArduCAM/ArduCAM_ESP32S_UNO/ 218 | // Based on AI-THINKER definitions 219 | #define PWDN_GPIO_NUM 32 220 | #define RESET_GPIO_NUM -1 221 | #define XCLK_GPIO_NUM 0 222 | #define SIOD_GPIO_NUM 26 223 | #define SIOC_GPIO_NUM 27 224 | #define Y9_GPIO_NUM 35 225 | #define Y8_GPIO_NUM 34 226 | #define Y7_GPIO_NUM 39 227 | #define Y6_GPIO_NUM 36 228 | #define Y5_GPIO_NUM 21 229 | #define Y4_GPIO_NUM 19 230 | #define Y3_GPIO_NUM 18 231 | #define Y2_GPIO_NUM 5 232 | #define VSYNC_GPIO_NUM 25 233 | #define HREF_GPIO_NUM 23 234 | #define PCLK_GPIO_NUM 22 235 | #define LED_PIN 2 // Status led 236 | #define LED_ON HIGH // - Pin is not inverted. 237 | #define LED_OFF LOW // 238 | //#define LAMP_PIN x // No LED FloodLamp. 239 | 240 | #else 241 | // Well. 242 | // that went badly... 243 | #error "Camera model not selected, did you forget to uncomment it in myconfig?" 244 | #endif 245 | --------------------------------------------------------------------------------