Time Laps z wykorzystaniem taniego ESP32 CAM już opisywałem jakiś czas temu tu „ESP32 CAM – TimeLaps” jednak był to zapis na kartę SD. Tym razem opiszę co i jak gdy chcemy wysyłać materiał na nasz serwer www np. zainstalowany na malinie. Ja w swoim przypadku wgrywam pliki na jeden ze swoich serwów w DC.
Wymagane komponenty:
- ESP32-CAM z OV2640
- Karta mikoSD np. 32GB w formacie FAT32
- Arduino IDE zainstalowaną obsługą ESP32
- konwerter TTL
- przewody żeńskie
Pamiętać trzeba aby karta pamięci, była w formacie FAT32 innego formatu ESP32 Cam nie rozpozna prawidłowo. Ze swoich testów wiem, że mimo zapisu w specyfikacji jest podane max 4GB bez problemu pracuje z kartą 32GB.
Połączenie ESP32 CAM z TTL
Poniżej opis połączenia w celu wgrana oprogramowania, należy pamiętać, że trzeba połączyć GPIO0 do GND inaczej nie wgracie swojego programu. Do późniejszej pracy nie jest ona potrzebna.
ESP32-CAM | UART |
GND | GND |
5V | VCC (5V) |
U0R | TX |
U0T | RX |
GPIO 0 | GND |
Kod jest autorstwa Robotzero1 i został udostępniony na GITHub.
Potrzebny będzie nam plik który przyjmie dane. W tym celu na swoim serwerze tworzymy plik np post.php i wprowadzamy poniższy kod w jego wnętrzu. Nazwą post.php będę posługiwał się dalej w celu opisania co i jak.
<?php
$received = file_get_contents('php://input');
$fileToWrite = "upload - ".time().".jpg";
file_put_contents($fileToWrite, $received);
?>
Sekcję $fileToWrite możemy zdefiniować pod jaką nazwą będą zapisywane nasze pliki powyższy zapis „upload – „.time().”.jpg” spowoduje wygenerowanie nazwy „upload – 1590436649.jpg”
Dobra czas przejść do samego kodu do naszego ESP32 CAM, ważne linijki zamieszczam poniżej.
const char* ssid = „tranzystor.pl”; // nazwa sieci WiFi
const char* password = „password”; //hasło do sieci
int capture_interval = 30000; // co ile ma być wykonywane zdjęcie milisekundach
const char *post_url = „http://tranzystor.pl/sciezka_do_pliku/post.php”; // lokalizacja pliku na serwerze
Kod programu
#include "esp_http_client.h"
#include "esp_camera.h"
#include <WiFi.h>
#include "Arduino.h"
const char* ssid = "tranzystor.pl"; // nazwa sieci WiFi
const char* password = "password"; //hasło do sieci
int capture_interval = 30000; // co ile ma być wykonywane zdjęcie milisekundach
const char *post_url = "http://tranzystor.pl/sciezka_do_pliku/post.php"; // lokalizacja pliku na serwerze
bool internet_connected = false;
long current_millis;
long last_capture_millis = 0;
// 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
void setup()
{
Serial.begin(115200);
if (init_wifi()) { // Connected to WiFi
internet_connected = true;
Serial.println("Internet connected");
}
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;
//init with high specs to pre-allocate larger buffers
if (psramFound()) {
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
}
bool init_wifi()
{
int connAttempts = 0;
Serial.println("\r\nConnecting to: " + String(ssid));
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED ) {
delay(500);
Serial.print(".");
if (connAttempts > 10) return false;
connAttempts++;
}
return true;
}
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
switch (evt->event_id) {
case HTTP_EVENT_ERROR:
Serial.println("HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED:
Serial.println("HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT:
Serial.println("HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER:
Serial.println();
Serial.printf("HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_DATA:
Serial.println();
Serial.printf("HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
if (!esp_http_client_is_chunked_response(evt->client)) {
// Write out data
// printf("%.*s", evt->data_len, (char*)evt->data);
}
break;
case HTTP_EVENT_ON_FINISH:
Serial.println("");
Serial.println("HTTP_EVENT_ON_FINISH");
break;
case HTTP_EVENT_DISCONNECTED:
Serial.println("HTTP_EVENT_DISCONNECTED");
break;
}
return ESP_OK;
}
static esp_err_t take_send_photo()
{
Serial.println("Taking picture...");
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
return ESP_FAIL;
}
esp_http_client_handle_t http_client;
esp_http_client_config_t config_client = {0};
config_client.url = post_url;
config_client.event_handler = _http_event_handler;
config_client.method = HTTP_METHOD_POST;
http_client = esp_http_client_init(&config_client);
esp_http_client_set_post_field(http_client, (const char *)fb->buf, fb->len);
esp_http_client_set_header(http_client, "Content-Type", "image/jpg");
esp_err_t err = esp_http_client_perform(http_client);
if (err == ESP_OK) {
Serial.print("esp_http_client_get_status_code: ");
Serial.println(esp_http_client_get_status_code(http_client));
}
esp_http_client_cleanup(http_client);
esp_camera_fb_return(fb);
}
void loop()
{
// TODO check Wifi and reconnect if needed
current_millis = millis();
if (current_millis - last_capture_millis > capture_interval) { // Take another picture
last_capture_millis = millis();
take_send_photo();
}
}
Kod do pobrania klik
Aby przesłać kod, wykonaj następujące kroki:
1) Przejdź do Narzędzia > Płyta i wybierz AI-Thinker ESP32-CAM .
2) Przejdź do Narzędzia > Port i wybierz port COM, do którego podłączony jest ESP32 CAM.
3) Następnie kliknij przycisk .
Gry program wgra się prawidłowo, zobaczysz poniższy obrazek.
Po chwili prac ESP32 CAM na karcie pamięci znajdziecie zdjęcia które zostały wykonane, ilość zdjęć zależy od czasu jaki ustawiliście w interwale.
Wlozylem karte MicroSD 32GB sformatowana na FAT32 i katalogiem DATA ale system wysyla komunikat ze nie moze utworzyc na karcie formatu VFAT Co moze byc przyczyna?
Spotkałem się, u mnie jeden moduł nie widział większej niż 16GB a 2 widział 32 ale tylko z goodram.