I try mostly every examples and tutorial. I defined the pin like below, but I can initialize the SPI (failed at Check SPI bus in setup) Code: #include <WiFi.h> #include <Wire.h> #include <SPI.h> #include <WebServer.h> #include <ArduCAM.h> // Replace with your Wi-Fi credentials const char* ssid = "ssdi"; const char* password = "password"; // SPI Settings for Arducam #define CS 15 // SPI Chip Select #define SPI_SCK 14 // SPI Clock #define SPI_MISO 35 // SPI MISO #define SPI_MOSI 12 // SPI MOSI // Create WebServer object WebServer server(80); // Camera object ArduCAM myCAM(OV2640, CS); // Initialize the SPI and camera pins void setup() { Serial.begin(115200); // Connect to Wi-Fi WiFi.begin(ssid, password); Serial.print("Connecting to WiFi..."); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("Connected!"); Serial.print("Camera Feed: http://"); Serial.println(WiFi.localIP()); // Initialize SPI SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI, CS); // Initialize Camera Wire.begin(); delay(1000); //pinMode(CS, OUTPUT); //digitalWrite(CS, HIGH); // Reset the CPLD myCAM.write_reg(0x07, 0x80); delay(100); myCAM.write_reg(0x07, 0x00); delay(100); // Check SPI bus uint8_t temp = myCAM.read_reg(ARDUCHIP_TEST1); if (temp != 0x55) { Serial.println(F("SPI interface error!")); return; } else { Serial.println(F("SPI interface OK")); } // Initialize camera myCAM.set_format(JPEG); myCAM.InitCAM(); myCAM.OV2640_set_JPEG_size(OV2640_320x240); // Set resolution to 320x240 delay(1000); myCAM.clear_fifo_flag(); // Define server routes server.on("/", HTTP_GET, handleRoot); server.on("/capture", HTTP_GET, handleCapture); server.begin(); } void loop() { server.handleClient(); } // Serve Home Page void handleRoot() { server.send(200, "text/html", "<h1>ESP32 Camera</h1><img src='/capture' />"); } // Capture and send an image void handleCapture() { // Start the capture process myCAM.start_capture(); // Wait until the capture is done while (!myCAM.read_fifo()) { delay(10); // Check periodically if capture is finished } // Get the length of the captured image in the FIFO buffer uint32_t imageSize = myCAM.read_fifo_length(); if (imageSize > 0) { // Allocate buffer for the image data uint8_t *imageBuffer = (uint8_t*) malloc(imageSize); if (imageBuffer != NULL) { // Read the image data from the FIFO buffer byte-by-byte uint32_t index = 0; while (index < imageSize) { imageBuffer[index] = myCAM.read_fifo(); index++; } // Send the captured image as JPEG over HTTP server.send_P(200, "image/jpeg", (const char*) imageBuffer, imageSize); // Free the allocated memory after sending the image free(imageBuffer); } } // Clear the FIFO flag for the next capture myCAM.clear_fifo_flag(); }
Code: #include <WiFi.h> #include <Wire.h> #include <SPI.h> #include <WebServer.h> #include <ArduCAM.h> #include "memorysaver.h" //you can change the value of wifiType to select Station or AP mode. //Default is AP mode. int wifiType = 0; // 0:Station 1:AP //AP mode configuration //Default is arducam_esp8266.If you want,you can change the AP_ssid to your favorite name const char *AP_ssid = "arducam_udooKey"; //Default is no password.If you want to set password,put your password here const char *AP_password = "arducam_udooKey"; // Replace with your Wi-Fi credentials const char* ssid = "SSID"; const char* password = "PASSWORD"; WebServer server(80); static const size_t bufferSize = 4096; static uint8_t buffer[bufferSize] = {0xFF}; uint8_t temp = 0, temp_last = 0, vid, pid; int i = 0; bool is_header = false; // SPI Settings for ArduCAM ArduCAM myCAM(OV2640, 15); void start_capture(){ myCAM.clear_fifo_flag(); myCAM.start_capture(); } void serverRoot(){ server.send(200, "text/html", "<h1>ESP32 Camera</h1><img src='/capture' /><br><a href='/stream'>Live Stream</a>"); } void camCapture(ArduCAM myCAM){ WiFiClient client = server.client(); uint32_t len = myCAM.read_fifo_length(); if (len >= MAX_FIFO_SIZE) //8M { Serial.println(F("Over size.")); } if (len == 0 ) //0 kb { Serial.println(F("Size is 0.")); } myCAM.CS_LOW(); myCAM.set_fifo_burst(); if (!client.connected()) return; String response = "HTTP/1.1 200 OK\r\n"; response += "Content-Type: image/jpeg\r\n"; response += "Content-len: " + String(len) + "\r\n\r\n"; server.sendContent(response); i = 0; while ( len-- ) { temp_last = temp; temp = SPI.transfer(0x00); //Read JPEG data from FIFO if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while, { buffer[i++] = temp; //save the last 0XD9 //Write the remain bytes in the buffer if (!client.connected()) break; client.write(&buffer[0], i); is_header = false; i = 0; myCAM.CS_HIGH(); break; } if (is_header == true) { //Write image data to buffer if not full if (i < bufferSize) buffer[i++] = temp; else { //Write bufferSize bytes image data to file if (!client.connected()) break; client.write(&buffer[0], bufferSize); i = 0; buffer[i++] = temp; } } else if ((temp == 0xD8) & (temp_last == 0xFF)) { is_header = true; buffer[i++] = temp_last; buffer[i++] = temp; } } } void serverCapture(){ start_capture(); Serial.println(F("CAM Capturing")); int total_time = 0; total_time = millis(); while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)); total_time = millis() - total_time; Serial.print(F("capture total_time used (in miliseconds):")); Serial.println(total_time, DEC); total_time = 0; Serial.println(F("CAM Capture Done.")); total_time = millis(); camCapture(myCAM); total_time = millis() - total_time; Serial.print(F("send total_time used (in miliseconds):")); Serial.println(total_time, DEC); Serial.println(F("CAM send Done.")); } void serverStream(){ WiFiClient client = server.client(); String response = "HTTP/1.1 200 OK\r\n"; response += "Content-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n"; server.sendContent(response); while (1){ start_capture(); while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)); size_t len = myCAM.read_fifo_length(); if (len >= MAX_FIFO_SIZE) //8M { Serial.println(F("Over size.")); continue; } if (len == 0 ) //0 kb { Serial.println(F("Size is 0.")); continue; } myCAM.CS_LOW(); myCAM.set_fifo_burst(); if (!client.connected()) break; response = "--frame\r\n"; response += "Content-Type: image/jpeg\r\n\r\n"; server.sendContent(response); while ( len-- ) { temp_last = temp; temp = SPI.transfer(0x00); //Read JPEG data from FIFO if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while, { buffer[i++] = temp; //save the last 0XD9 //Write the remain bytes in the buffer myCAM.CS_HIGH();; if (!client.connected()) break; client.write(&buffer[0], i); is_header = false; i = 0; } if (is_header == true) { //Write image data to buffer if not full if (i < bufferSize) buffer[i++] = temp; else { //Write bufferSize bytes image data to file myCAM.CS_HIGH(); if (!client.connected()) break; client.write(&buffer[0], bufferSize); i = 0; buffer[i++] = temp; myCAM.CS_LOW(); myCAM.set_fifo_burst(); } } else if ((temp == 0xD8) & (temp_last == 0xFF)) { is_header = true; buffer[i++] = temp_last; buffer[i++] = temp; } } if (!client.connected()) break; } } 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); if (server.hasArg("ql")){ int ql = server.arg("ql").toInt(); #if defined (OV2640_MINI_2MP) || defined (OV2640_CAM) myCAM.OV2640_set_JPEG_size(ql); #elif defined (OV5640_MINI_5MP_PLUS) || defined (OV5640_CAM) myCAM.OV5640_set_JPEG_size(ql); #elif defined (OV5642_MINI_5MP_PLUS) || defined (OV5642_MINI_5MP_BIT_ROTATION_FIXED) ||(defined (OV5642_CAM)) myCAM.OV5642_set_JPEG_size(ql); #endif delay(1000); Serial.println("QL change to: " + server.arg("ql")); } } void setup() { uint8_t vid, pid; uint8_t temp; Wire.begin(18,21,400000); Serial.begin(115200); Serial.println(F("ArduCAM Start!")); // set the CS as an output: pinMode(15, OUTPUT); digitalWrite(15,HIGH); // initialize SPI: SPI.begin(14,35,12,15); //Check if the ArduCAM SPI bus is OK myCAM.write_reg(ARDUCHIP_TEST1, 0x55); temp = myCAM.read_reg(ARDUCHIP_TEST1); if (temp != 0x55){ Serial.println(F("SPI1 interface Error!")); while(1); } //Check if the camera module type is OV2640 myCAM.wrSensorReg8_8(0xff, 0x01); myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid); myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid); if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))){ Serial.println(F("Can't find OV2640 module!")); Serial.println(vid); Serial.println(pid); } else { Serial.println(F("OV2640 detected.")); } //Change to JPEG capture mode and initialize the OV2640 module myCAM.set_format(JPEG); myCAM.InitCAM(); myCAM.OV2640_set_JPEG_size(OV2640_320x240); myCAM.clear_fifo_flag(); if (wifiType == 0){ if(!strcmp(ssid,"SSID")){ Serial.println(F("Please set your SSID")); while(1); } if(!strcmp(password,"PASSWORD")){ Serial.println(F("Please set your PASSWORD")); while(1); } // Connect to WiFi network Serial.println(); Serial.println(); Serial.print(F("Connecting to ")); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print(F(".")); } Serial.println(F("WiFi connected")); Serial.println(""); Serial.println(WiFi.localIP()); }else if (wifiType == 1){ Serial.println(); Serial.println(); Serial.print(F("Share AP: ")); Serial.println(AP_ssid); Serial.print(F("The password is: ")); Serial.println(AP_password); WiFi.mode(WIFI_AP); WiFi.softAP(AP_ssid, AP_password); Serial.println(""); Serial.println(WiFi.softAPIP()); } // Start the server server.on("/",HTTP_GET, serverRoot); server.on("/capture", HTTP_GET, serverCapture); server.on("/stream", HTTP_GET, serverStream); server.onNotFound(handleNotFound); server.begin(); Serial.println(F("Server started")); } void loop() { server.handleClient(); } Finally get it working by specifiying the pin in the Wire.begin() and SPI.begin() call