Closed FBMinis closed 3 years ago
I've tried a few things with this today but not had any success. I noticed if you took the imageFile variable at line 227
if (i%3==0) imageFile += urlencode(String(output));
and printed it to the serial monitor and then ran it through this: https://codebeautify.org/url-decode-string followed by this: https://base64.guru/converter/decode/image when you have a higher resolution the bottom of the picture was missing.
So somewhere there's no enough space to store the whole base64 string to send it to Google.
I tried creating and sending the buffer as base64 in chunks with and without urlencoding it but I couldn't get it to work. Maybe someone has a script for this somewhere else but I imagine it's not necessary on normal systems with more resources.
In desperation I tried splitting the base64 string into two parts to send. It worked once and then I just got SSL errors in the serial monitor (with debug verbose set) so I think it's just too much data for the ESP32. Maybe with a different partition structure or writing the base64 string to SPIFFs it could work.
String SendCapturedImage2GoogleDrive() {
const char* myDomain = "script.google.com";
String getAll = "", getBody = "";
String partOutput;
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
delay(1000);
ESP.restart();
return "Camera capture failed";
}
Serial.println("Connect to " + String(myDomain));
WiFiClientSecure client_tcp;
if (client_tcp.connect(myDomain, 443)) {
Serial.println("Connection successful");
char *input = (char *)fb->buf;
char output[base64_enc_len(3)];
String imageFile = "data:image/jpeg;base64,";
String imageFile2 = "";
for (int i = 0; i < fb->len / 2; i++) {
base64_encode(output, (input++), 3);
if (i % 3 == 0) imageFile += urlencode(String(output));
}
for (int i = 0; i < fb->len / 2; i++) {
base64_encode(output, (input++), 3);
if (i % 3 == 0) imageFile2 += urlencode(String(output));
}
String Data = myFoldername + myFilename + myImage;
Serial.print("image file length: ");
Serial.println(imageFile.length());
Serial.print("image file 2 length: ");
Serial.println(imageFile2.length());
client_tcp.println("POST " + myScript + " HTTP/1.1");
client_tcp.println("Host: " + String(myDomain));
client_tcp.println("Content-Length: " + String(Data.length() + imageFile.length() + imageFile2.length()));
client_tcp.println("Content-Type: application/x-www-form-urlencoded");
client_tcp.println("Connection: keep-alive");
client_tcp.println();
client_tcp.print(Data);
int Index;
for (Index = 0; Index < imageFile.length(); Index = Index + 1000) {
client_tcp.print(imageFile.substring(Index, Index + 1000));
client_tcp.flush();
}
for (Index = 0; Index < imageFile2.length(); Index = Index + 1000) {
client_tcp.print(imageFile2.substring(Index, Index + 1000));
client_tcp.flush();
}
esp_camera_fb_return(fb);
int waitTime = 10000; // timeout 10 seconds
long startTime = millis();
boolean state = false;
while ((startTime + waitTime) > millis())
{
Serial.print(".");
delay(100);
while (client_tcp.available())
{
char c = client_tcp.read();
if (state == true) getBody += String(c);
if (c == '\n')
{
if (getAll.length() == 0) state = true;
getAll = "";
}
else if (c != '\r')
getAll += String(c);
startTime = millis();
}
if (getBody.length() > 0) break;
}
client_tcp.stop();
Serial.println(getBody);
}
else {
getBody = "Connected to " + String(myDomain) + " failed.";
Serial.println("Connected to " + String(myDomain) + " failed.");
}
return getBody;
}
Thank you for investing your time into it. It is clear now that this is something above my skills. I have been reading about google apps scripts to try to understand how this works:
https://developers.google.com/apps-script/guides/web https://github.com/tanaikech/taking-advantage-of-Web-Apps-with-google-apps-script
I have been using the following code but using any resolution over VGA results in photos with gray lines:
https://github.com/fustyles/Arduino/tree/master/ESP32-CAM_PIR_GoogleDrive
Some time ago, before finding your repository, I was following the tutorial in Random Nerds Tutorial website to send photos to Telegram periodically. Sometimes the HTTP request would timeout and I would not receive a photo. Then I found your sketches and the "send by binary" routine allows me to send UXGA with quality=10!
So, maybe you can find a way to send to Google Drive in a decent quality.
Here are some photos I have been collecting as a test. Having them in Google Drive allows me to check what's going on everywhere but also to download and make a timelapse with VirtualDub.
https://drive.google.com/drive/folders/156cK59hy2A9GHn?usp=sharing
I have attached the code I use to take a photo and send to Telegram. It uses an external RTC to cut power until it's time to send it. workingESP32CAMds3231rtclibAlarmTelegramVBatOnly.txt