I have en ESP32 CAM rotated by a stepper motor which it controls. It receives requests over a TCP socket to rotate a certain number of degrees and take a photo which it then sends back over the socket. Everything works well BUT the photo is being taken before the rotation. Here is the code that handles the client
void doMove(int targetDegrees){
targetDegrees = targetDegrees % 3600;
// convert target degrees to position, targetDegrees is degrees x 10
long target = circle*targetDegrees/3600.0+.5;
long current = stepper.currentPosition()% circle;
long positionDiff = target-current;
Serial.print(“targetDegrees: “);Serial.println(targetDegrees);
Serial.print(“target: “);Serial.println(target);
Serial.print(“current: “);Serial.println(current);
Serial.print(“positionDiff: “);Serial.println(positionDiff);
// go to the position via the shortest route
if (positionDiff> halfCircle){
positionDiff-=circle;
}
else if(positionDiff<-halfCircle){
positionDiff +=circle;
}
Serial.print(“New positionDiff: “);Serial.println(positionDiff);
stepper.move(positionDiff);
while(stepper.distanceToGo()!=0){
stepper.run();
}
Serial.println(“completed move”);
Serial.print(“current Position = “);Serial.println(stepper.currentPosition()% circle);
Serial.print(“target: “);Serial.println(target);
}
// handle client
void handleClient(WiFiClient client) {
Serial.println(“Client connected “);
Serial.println(“Receiving data…”);
std::vector<uint8_t> data;
while (true) {
size_t available = client.available();
if (available == 0) {
delay(1);
continue;
}
std::vector<uint8_t> chunk(available);
size_t read = client.read(chunk.data(), available);
if (read == 0) {
break;
}
chunk.resize(read);
data.insert(data.end(), chunk.begin(), chunk.end());
if (read < chunkSize) {
break;
}
}
if (data.size() != sizeof(int)) {
Serial.println(“Invalid request”);
return;
}
int angle = *reinterpret_cast<const int*>(data.data());
Serial.print(“Received request for angle “);
Serial.println(angle);
doMove(angle);
Serial.println(“About to take picture”);
camera_fb_t* fb = esp_camera_fb_get();
if(!fb) {
Serial.println(“Camera capture failed”);
return;
}
size_t size = fb->len;
Serial.print(“Sending photo of size “);
Serial.print(size);
Serial.println(” bytes”);
client.write(reinterpret_cast<const uint8_t*>(&size), sizeof(size));
client.write(fb->buf, size);
// release the buffer
esp_camera_fb_return(fb);
Serial.println(“Closing connection…”);
client.stop();
}
Either I do not understand the Accelstepper operation or I do not understand the camera. All the copious print statements in the doMove function indicate that it is actually doing the move before it returns. So it seems that the statement
camera_fb_t* fb = esp_camera_fb_get();
is sending a photo it had previously taken.
Can anybody tell me what to change or direct me to the reference for the camera software.
Alan
Hi.
Due to an update of the ESP32 core, the ESP32-CAM now saves four pictures in the frame buffer by default.
So, you’ll get the next picture in the buffer when you try to get a picture, which is four pictures old.
- How we resolve this issue:
- set config.grab_mode = CAMERA_GRAB_LATEST; to show the latest picture in the buffer
- set config.fb_count = 1; to get only one picture in the buffer – with this workaround it will display a picture that is one picture old.
- to solve this issue, we added the following when taking a picture—basically getting the latest picture, clearing the buffer, and taking a new picture again. This ensures we always get the latest picture in the buffer:
// Take a photo with the camera
fb = esp_camera_fb_get();
esp_camera_fb_return(fb); // dispose the buffered image
fb = NULL; // reset to capture errors
// Get fresh image
Serial.println("Taking a photo...");
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
return;
}
I hope this helps.
Regards,
Sara
Fantastic, I had thought of taking 2 pictures but iI never thought of needing to clear out 4 !
You are a life saver.
Alan
Hi
Unfortunately, there isn’t a place for official documentation.
Here you’ll find the Arduino core for the ESP32: https://github.com/espressif/arduino-esp32
Regards,
Sara