error found the Framebuffer fb was being freed before the SSLClient could finish writing hence the corrupted drive image.
Posts made by nemsys
-
RE: SSL Socket errors
-
SSL Socket errors
Greetings and thank-you for your time.
I am trying to send camera images from my ESP32 (M5 Stack PoECAM) to my personal google drive.
following this tutorial :
https://hobby-it.com/m5timer_gdrive-2/I have setup SSLClient with the EthernetLarge library the jpgs arrive and but they are corrupted/incomplete. Any ideas why this might be happening, I have tried different chunk sizes no effect ?
I don't believe its hardware as the example sketches all work as intended
errors/warnings
SSLClient)(SSL_WARN)(connected): Socket was dropped unexpectedly (this can be an alternative to closing the connection) (SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_WRITE_FAIL (SSLClient)(SSL_ERROR)(available): Cannot operate if the write error is not reset:
The project is on github (https://gitlab.com/ArchNemsys/esp32-poe-cam) the code for the relevant function (sensitive data removed) is posted below apologies I was halfway through refactoring it to use char bufs rather than strings:
#include <SSLClient.h> #include "gdrive_trust.h" #define WRITE_SIZE_MAX 1024 // //#define API_PORT 443 //#define API_PATH_TOKEN "/oauth2/v4/token" const char* refreshServer = "oauth2.googleapis.com"; const char* refreshUri = "/token"; const char* apiServer = "www.googleapis.com"; const char* apiUri = "/upload/drive/v3/files?uploadType=multipart"; char accessToken[2048]; // ethClient is declared elsewhere but works perfectly outside this funciton SSLClient httpsClient(ethClient, gdriveTAs, 1, 25); // SSLClient::write, is buffered does not actually write to the network. you must call SSLClient::available or SSLClient::flush, int waitingTime = 10000; // Wait 10 seconds to google response. // Send JPEG by Http POST void postGoogleDriveByAPI() { Serial.println("Connect to " + String(apiServer)); if (httpsClient.connect(apiServer, 443)) { Serial.println("Connection successful"); // Get Time for save file name struct tm timeinfo; if(!getLocalTime(&timeinfo)){ Serial.println("Failed to obtain time 1"); return; } char saveFilename[64]; /* char metadata[256]; const char* startBoundry = "--foo_bar_baz\r\n" "Content-Type:image/jpeg\r\n\r\n"; const char* endBoundry = "\r\n--foo_bar_baz--"; */ strftime (saveFilename,64,"ALERT_%A_%B_%d_%Y_%Hh%Mm%Ss.jpg",&timeinfo); Serial.println(saveFilename); /* snprintf( metadata, 256, "--foo_bar_baz\r\n" "Content-Type: application/json; charset=UTF-8\r\n\r\n" "{\"name\":\"%s\",\"parents\":[\"%s\"]}\r\n\r\n" , saveFilename, PARENT_ID ); unsigned long contentsLength = strlen(metadata) + strlen(startBoundry) + fb->len + strlen(endBoundry); snprintf(header,256, "POST %s HTTP/1.1\r\n" "HOST: %s \r\n" "Connection: close\r\n" "content-type: multipart/related; boundary=foo_bar_baz\r\n" "content-length: %u \r\n" "authorization: Bearer %s \r\n\r\n", apiUri, apiServer, contentsLength, accessToken); */ String metadata = "--foo_bar_baz\r\n" "Content-Type: application/json; charset=UTF-8\r\n\r\n" "{\"name\":\"" + String(saveFilename) + "\",\"parents\":[\"" + String(PARENT_ID) + "\"]}\r\n\r\n"; // parents:save folder //"{\"name\":\"" + saveFilename + "\"}\r\n\r\n"; // parerents is Optional String startBoundry = "--foo_bar_baz\r\n" "Content-Type:image/jpeg\r\n\r\n"; String endBoundry = "\r\n--foo_bar_baz--"; unsigned long contentsLength = metadata.length() + startBoundry.length() + fb->len + endBoundry.length(); String header = "POST " + String(apiUri) + " HTTP/1.1\r\n" + "HOST: " + String(apiServer) + "\r\n" + "Connection: close\r\n" + "content-type: multipart/related; boundary=foo_bar_baz\r\n" + "content-length: " + String(contentsLength) + "\r\n" + "authorization: Bearer " + accessToken + "\r\n\r\n"; Serial.println("Send JPEG DATA by API"); httpsClient.print(header); httpsClient.print(metadata); httpsClient.print(startBoundry); // JPEG data is separated into 1000 bytes and POST int chunk = 1000; unsigned long dataLength = fb->len; uint8_t* bufAddr = fb->buf; for(unsigned long i = 0; i < dataLength ;i=i+chunk) { if ( (i + chunk) < dataLength ) { httpsClient.write(( bufAddr + i ), chunk); } else if (dataLength%chunk != 0) { httpsClient.write(( bufAddr + i ), dataLength%chunk); } } httpsClient.print(endBoundry); Serial.println("Waiting for response."); long int StartTime=millis(); while (!httpsClient.available()) { Serial.print("."); delay(100); if ((StartTime+waitingTime) < millis()) { Serial.println(); Serial.println("No response."); break; } } } else { Serial.println("Connected to " + String(refreshServer) + " failed."); } httpsClient.stop(); }
-
PoECAM - Building Examples
Just a heads up for anyone trying to build the PoeCAM examples or the Ethernet examples.
Ensure the board is set to M5Stack-Timer-CAM not PoE CAM.
Additionally the Ethernet-Stream example needs the network.h header lines 16-17 altered as below else it will not compile
static ip4_addr_t ip_addr; // For platform = espressif32@ ^3.5.0 //static esp_ip4_addr_t ip_addr; // For platform = espressif32@ ^5.1.0
Ardunio Studio v2 (linux)
boards package
esp32 v1.06 boardslibs
PoECam lib v0.0.2
PoECAM ethernet lib v3Ext_PIN_1 is at GPIO 33 a simple example of polling a PIR sensor is below :
#include <Arduino.h> void setup() { pinMode(33, INPUT_PULLUP); Serial.begin(115200); } void loop() { Serial.println(digitalRead(33)); delay(1000); }
not a 100% sure about the pull-up resistor but I have a vague feeling I read it somewhere, and well it works.
If anyone knows any other helpful tips, links to examples etc please reply to this thread I am by no means an expert !
maybe we can get it stickyed or add to the documentation
-
RE: POECAM and PIR sensor
HI @felmue ,
Thankyou for your reply :)
I had already striped the LCD code its the M5Stack header (and includes) itself that doesn't want to compile.
The only samples that compile are the factory test and Ethernet stream which leads me to believe their isn't a board specific header as such.
digging through the platform library there is a pin_header
#ifndef Pins_Arduino_h #define Pins_Arduino_h #include <stdint.h> #define EXTERNAL_NUM_INTERRUPTS 16 #define NUM_DIGITAL_PINS 40 #define NUM_ANALOG_INPUTS 16 #define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1) #define digitalPinToInterrupt(p) (((p)<40)?(p):-1) #define digitalPinHasPWM(p) (p < 34) static const uint8_t TX = 1; static const uint8_t RX = 3; static const uint8_t SDA = 25; static const uint8_t SCL = 33; static const uint8_t G23 = 23; static const uint8_t G25 = 25; static const uint8_t G27 = 27; static const uint8_t G22 = 22; static const uint8_t G26 = 26; static const uint8_t G21 = 21; static const uint8_t G32 = 32; static const uint8_t G35 = 35; static const uint8_t G34 = 34; static const uint8_t G5 = 5; static const uint8_t G39 = 39; static const uint8_t G18 = 18; static const uint8_t G36 = 36; static const uint8_t G19 = 19; static const uint8_t G15 = 15; static const uint8_t G2 = 2; static const uint8_t G33 = 33; static const uint8_t G13 = 13; static const uint8_t G4 = 4; static const uint8_t G0 = 0; static const uint8_t DAC1 = 25; static const uint8_t DAC2 = 26; static const uint8_t ADC1 = 35; static const uint8_t ADC2 = 36; #endif /* Pins_Arduino_h */
which of course is one of the many reasons why the example library doesn't compile,my device simply has different pins.
In the factory test I see the references to UART Ext_PIN_1 and Ext_PIN_2 :
Serial.println("UART INIT"); uart_init(Ext_PIN_1, Ext_PIN_2);
which is defiend in timer_cam_config.h
#define Ext_PIN_1 33 #define Ext_PIN_2 25
So lets strip off the header and run it with the pure Arduino.
#include <Arduino.h> void setup() { pinMode(33, INPUT_PULLUP); Serial.begin(115200); } void loop() { Serial.println(digitalRead(33)); delay(1000); }
It works but only if I set the board to M5Stack-Timer-CAM.
Additionally the Ethernet-Stream example needs the network.h header lines 16-17 altered as below else it will not compile
static ip4_addr_t ip_addr; // For platform = espressif32@ ^3.5.0 //static esp_ip4_addr_t ip_addr; // For platform = espressif32@ ^5.1.0
I will post this in the modules forum for other users trying to build the examples, apologies for putting this in FAQ (it was late/early)
-
RE: POECAM and PIR sensor
hi @felmue
I had tried to compile the PIR example sketch after installing the libraries but I get the following compile error
Arduino/libraries/M5Stack/src/M5Stack.h:112, Projects/ESP32/M5Stack/examples/Unit/PIR/PIR.ino:16: .arduino15/packages/m5stack/hardware/esp32/2.0.7/libraries/SD/src/SD.h:31:30: error: 'SS' was not declared in this scope bool begin(uint8_t ssPin=SS, SPIClass &spi=SPI, uint32_t frequency=4000000, const char * mountpoint="/sd", uint8_t max_files=5, bool format_if_empty=false); ^~ .arduino15/packages/m5stack/hardware/esp32/2.0.7/libraries/SD/src/SD.h:31:30: note: suggested alternative: 'FS' bool begin(uint8_t ssPin=SS, SPIClass &spi=SPI, uint32_t frequency=4000000, const char * mountpoint="/sd", uint8_t max_files=5, bool format_if_empty=false); ^~ FS Multiple libraries were found for "SD.h" Used: .arduino15/packages/m5stack/hardware/esp32/2.0.7/libraries/SD Not used: .arduino15/libraries/SD
Do we know if the stock M5Stack headers are compatabile with this board ?
the ethernet example for the cam-timer board compiles and runs without issue but notably it doesn't make use of the M5Stack header
ethernetStream sketch headers
#include <WiFi.h> #include "esp_task_wdt.h" #include "esp_camera.h" #include "PoE_CAM.h" #include <esp_heap_caps.h>
PoE_Cam.h
#include "./utility/camera_index.h" #include "./utility/w5500_image.h" #include "./utility/uart_frame.h" #include "./utility/timer_cam_config.h" #include "./utility/cam_cmd.h" #include "./utility/protocol.h" #include "./utility/app_httpd.h" #include "./utility/network.h" #include "./utility/image_post.h"
I'm not being foolish the wiring is as simple as (ignore the solder) :
-
POECAM and PIR sensor
Apologies for what will probably be a very basic question.
I have recently got my POECAM working with Arduino IDE and an trying to read the sensor value from a [PIR sensor] (https://shop.m5stack.com/products/pir-module).
I have read through the scare documention that is available for this device and am at a lose where to start I tried dumping the GPIO pins to serial as I hold my hand over the sensor and inferring which pin was the sensor; but I am guessing that a pin needs to be powered or in read mode as no change occurs ?
void setup() { Serial.begin(115200); } void loop() { for(int i=0;i<40;i++) { int pin = digitalRead(i); Serial.print(i); Serial.print(':'); Serial.print(pin); Serial.print('|'); } Serial.println(' '); }