Hello!
I’m working on a project that involves an ESP32CAM (AI-THINKER) taking a picture and then displaying it in the Blynk Image Gallery widget.
I’m having issues getting the image to update in the app everytime I take a new picture and I could use some help. I can go into the widget settings and manually refresh the image but I’m having issues getting blynk.setProperty working the way I want it to.
I’ve attached my code at the bottom, but is there a way to connect setProperty to a flag or condition as opposed to a pin?
Description of program and problem:
- Image Gallery widget pointing to fileserver url.
- Button widget in BLYNK connected to V5 which triggers the ESP32CAM to take and send a photo over ftp. (everything works to this point, image file shows up in the fireserver).
- Update ImageGallery to display new image once uploaded (problem here, image does not update).
I think what is happening is the setProperty is running before the image has been uploaded to the server, so it updates to the image it already has. It would be nice if I could run setProperty periodically as opposed to via a virtual pin, that way the widget would update the image displayed every “x” seconds and catch the new image whenever it shows up at the url.
Notes: Image quality is not super important, this is taking pictures of the inside of a chicken coop to confirm number of chickens inside for the user. If we think this is a filesize upload issue I’m willing to reduce the image quality. Current size of image showing up in the fileserver @ SVGA is generally under 20kb so I doubt that is the problem.
Thanks in advance for any help offered!
// #define BLYNK_PRINT Serial
#define BUTTON V5
#define LED 4
#define DOORUP V7
#define DOORDOWN V6
// #define BLYNK_TEMPLATE_ID "TMPLQjB7UkPG" //Clone or comment out for other deployments
// #define BLYNK_DEVICE_NAME "CoopCommand"
#include "esp_camera.h"
#include "SPI.h"
#include "driver/rtc_io.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include <FS.h>
#include <WiFiUdp.h>
#include <ESPmDNS.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <ESP32_FTPClient.h>
// #include <ArduinoOTA.h>
char ftp_server[] = "files.000webhost.com";
char ftp_user[] = "xxxxxxx";
char ftp_pass[] ="xxxxxxx";
String pic_url = "xxxxxxxx/";
WiFiClient client;
ESP32_FTPClient ftp (ftp_server,ftp_user,ftp_pass, 5000, 2);
// BLYNK Widgets
WidgetLED led1(V1);
WidgetLED led2(V2);
WidgetLED led3(V3);
WidgetLED led4(V4);
// Your WiFi credentials & Authentication Code from Blynk
// Set password to "" for open networks.
const char* ssid = "xxxxxxx";
const char* password = "xxxxxxx";
char auth[] = "xxxxxx"; //sent by Blynk
// Serial Communication Variables
char coopRx; // Info received from CoopCommand
bool newDataRx = false; //has CoopCam received new data from CoopCommand
bool takePhoto = false; //Did the Blynk App request a photo?
// Timers
unsigned long photoTimer = 500; // Time to run flash before taking photo
unsigned long lastPhotoTimer = 0; // Last time the flash timer was checked
unsigned long wifiTimer = 30000; // How often to try re-connecting if WIFI lost
unsigned long lastWifiTimer = 0; // Last time the WIFI re-connect timer was checked
BlynkTimer timer;
#define CAMERA_MODEL_AI_THINKER
#if defined(CAMERA_MODEL_AI_THINKER)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#else
#error "Camera model not selected"
#endif
void setup() {
// ArduinoOTA.begin();
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
pinMode(LED, OUTPUT);
// Serial, WI-FI & Blynk Communication
Serial.begin(115200);
Blynk.begin(auth, ssid, password);
WiFi.begin( ssid, password );
Blynk.setProperty(V8, "url", 1, pic_url);
// You can also specify server:
//Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
//Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
if (psramFound()) {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_CIF;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Initialize camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
ESP.restart();
}
}
String sendPhoto() {
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
delay(100);
if(!fb) {
Serial.println("Camera capture failed");
// delay(1000);
ESP.restart();
}
ftp.OpenConnection();
// Create a file and write the image data to it;
ftp.ChangeWorkDir("/public_html/uploads/"); // change it to reflect your directory
ftp.InitFile("Type I");
ftp.NewFile("1.jpg");
ftp.WriteData(fb->buf, fb->len);
ftp.CloseFile();
ftp.CloseConnection();
}
void coopCom ( void ) {
if (WiFi.status() == WL_CONNECTED) {
lastWifiTimer = millis();
}
else if (WiFi.status() != WL_CONNECTED) {
if ((unsigned long)(millis() - lastWifiTimer) >= wifiTimer) {
ESP.restart();
}
}
if (Serial.available() > 0) {
coopRx = Serial.read();
newDataRx = true;
}
if (newDataRx == true) {
if (coopRx == 'O') { //If CoopCommand says the door is up
led1.on();
led2.off();
led3.off();
led4.off();
newDataRx = false;
}
if (coopRx == 'S') { //If CoopCommand says the door is down
led1.off();
led2.on();
led3.off();
led4.off();
newDataRx = false;
}
if (coopRx == 'U') { //If CoopCommand says the door is opening
led1.off();
led2.off();
led3.on();
led4.off();
newDataRx = false;
}
if (coopRx == 'D') { //If CoopCommand says the door is closing
led1.off();
led2.off();
led3.off();
led4.on();
newDataRx = false;
}
}
}
BLYNK_WRITE(DOORUP) {
Serial.print('U');
}
BLYNK_WRITE(DOORDOWN) {
Serial.print('D');
}
void flashOff ( void ) {
digitalWrite(LED, LOW);
sendPhoto();
takePhoto = false;
Serial.print('N');
delay(100);
Blynk.setProperty(V5, "urls", 1, pic_url);
}
void flashOn (void) {
digitalWrite(LED, HIGH);
Serial.print('L');
}
BLYNK_WRITE(V5) {
flashOn();
timer.setTimeout(500L, flashOff);
}
void loop() {
// ArduinoOTA.handle();
coopCom();
Blynk.run();
timer.run();
}