Rozhodli jsme se postavit jednoduchou online fotopast, která na signál z PIR čidla pořídí fotku a tu následně pošle přes WiFi na Google disk. Snímky z této fotopasti budou tedy k dispozici ihned po pořízení a dostupné prakticky odkudkoli. Z toho vyplývá, že pro správné fungování je nutný signál WiFi a Google účet. Taková fotopast bude tedy vhodná k zabezpečení objektů, kde je tento signál dostupný.
Hardware který budeme potřebovat
Společnost LilyGo vyrábí zajímavé vývojové desky LILYGO® TTGO T-Camera ESP32 WROVER. Na desce je integrován dvoujádrový mikrokontroler ESP32-WROVER-B, 0,96“ I2C OLED displej s rozlišením 128×64, OV2640 2Mpx kamera, PIR senzor AS312, nabíjecí čip IP5306 pro možnost napájení z Li-Ion baterie a konektor pro připojení přídavných modulů komunikujících po sběrnici I2C. Obsahuje též USB-UART převodník pro datovou komunikaci a programování a dvě tlačítka – RESET a IO15(IO34), které lze využít ve vlastním programu. Modul existuje ve dvou variantách – s I2S mikrofonem a bez. Jinak se varianty liší jen vnitřním zapojením, rozložení součástek a konektorů je stejné.
Díky této desce kde máme prakticky vše v jednom nám zbývá vymyslet pouze napájení a zapouzdření do nějaké vhodné krabičky. Desku lze napájet buď z baterie, microUSB, nebo 5V na konektoru pro přídavné moduly. My v konečné konstrukci použijeme variantu s mikrofonem a napájení 5V z konektoru pro přídavné moduly, protože máme k dispozici trvalé napájení a nebudeme žádné přídavné moduly používat. Musíme ještě upozornit na trochu nepříjemný fakt u varianty s mikrofonem – tato varianta má z nějakého důvodu zapojeno PIR čidlo na jiný pin mikrokontroleru než varianta bez mikrofonu. Konkrétně na pin IO19. Na tomto pinu bohužel není možné zprovoznit probouzení mikrokontroleru ze spánku, a tak je tento modul v tomto případě vhodný jen pro napájení z trvalého zdroje.
Zapouzdření do krabičky si každý zpracuje podle svých možností a plánovaného umístění.
Připojíme desku USB kabelem do počítače a nainstalujeme ovladače USB převodníku CP2102. Jak na to si můžete přešít v článku o zapojení ovladače převodníku USB.
Software a programování Arduino
Programovat budeme ve vývojovém prostředí Arduino IDE. Jak jsme psali, tato varianta neumožňuje PIR čidlem probouzet mikrokontroler a tak použijeme testování signálu z PIR čidla za běhu programu.
Budeme potřebovat podporu pro vývojové desky ESP32 pro Arduino, knihovnu ESP8266 and ESP32 OLED driver for SSD1306 displays od ThingPulse a knihovnu arduino-base64.
Vytvoříme nový projekt a pojmenujeme ho např. fotopast. Knihovnu arduino-base64 rozbalíme a nakopírujeme soubory Base64.h a Base64.cpp do stejné složky se souborem projektu. Ve stejné složce vytvoříme soubor wifikeys.h a uložíme do něho následující dva řádky:
const char *ssid = "nazev_vasi_wifi_site";
const char *password = "heslo_k_wifi_siti";
Tím je příprava na samotné programování hotová. Nyní musíme na straně Googlu vytvořit skript, který nám přijme data obrázku z pasti a uloží ho na Google disk.
Přejdeme na stránku https://script.google.com/home a přihlásíme se do Google účtu. Potom vytvoříme nový skript klepnutím na tlačítko Nový projekt. Klepneme na název projektu, který je nyní automaticky pojmenován jako „Projekt bez názvu“ a pojmenujeme ho jako např. „Fotopast“.
V poli pro zadávání kódu vše smažeme a vložíme následující kód:
function doPost(e) { // Funkce google scriptu prijimajici data metodou HTTPS POST
var data = Utilities.base64Decode(e.parameters.data); // Dekoduje prichozi data
var timeZone = Session.getScriptTimeZone(); // Nastavi se casove pasmo
var nazevSouboru = Utilities.formatDate(new Date(), timeZone, "yyyyMMdd_HHmmss")+".jpg"; // Sestavi se nazev souboru
var blob = Utilities.newBlob(data, e.parameters.mimetype, nazevSouboru ); // Vytvori se soubor obrazku
// Ulozi obrazek na Google Disk
var folder, folders = DriveApp.getFoldersByName("Fotopast"); // Nazev slozky, do ktere se budou obrazky ukladat
if (folders.hasNext()) { // Pokud slozka existuje
folder = folders.next(); // Pouzije se existujici slozka
} else { // Pokud slozka neexistuje
folder = DriveApp.createFolder("Fotopast"); // Slozka se vytvori
}
var file = folder.createFile(blob); // Ulozi obrazek do slozky
return ContentService.createTextOutput('Ulozeno') // Vrati odesilateli text "Ulozeno"
}
Uložíme! Potom klikneme vpravo nahoře na tlačítko „Implementovat“ a vybereme možnost „Nová implementace“. Jako typ implementace vybereme možnost „Webová aplikace“. V rozbalovacím poli „Kdo má přístup“ vybereme položku „Kdokoli“ a klepneme na tlačítko „Implementovat“. Na dalším okně si zkopírujeme „ID implementace“ a uložíme si ho do nějakého textového souboru. Toto ID budeme pak zadávat do kódu v Arduino IDE. Klepneme na tlačítko „Hotovo“ a máme hotovo.
Do otevřeného souboru projektu v Arduino IDE vložíme následující kód:
#include <WiFiClientSecure.h>
#include <Wire.h>
#include "esp_camera.h"
#include "wifikeys.h"
#include "SSD1306.h"
#include "Base64.h"
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 4
#define SIOD_GPIO_NUM 18
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 36
#define Y8_GPIO_NUM 37
#define Y7_GPIO_NUM 38
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 35
#define Y4_GPIO_NUM 14
#define Y3_GPIO_NUM 13
#define Y2_GPIO_NUM 34
#define VSYNC_GPIO_NUM 5
#define HREF_GPIO_NUM 27
#define PCLK_GPIO_NUM 25
#define I2C_SDA 21
#define I2C_SCL 22
#define SSD1306_MODE_TYPE 0 // 0 : GEOMETRY_128_64 // 1: GEOMETRY_128_32
#define SSD1306_ADDRESS 0x3c
#define AS312_PIN 19
// Promenne pro pouzite při odesilani dat na server
const char* myDomain = "script.google.com";
String myScript = "/macros/s/xxxxxxxxxxx/exec"; //Sem se místo xxx vlozi kod google skriptu
String myFilename = "filename=capture.jpg";
String mimeType = "&mimetype=image/jpeg";
String myImage = "&data=";
int waitingTime = 30000; // Doba pro odeslani obrazku na server, pokud bude pomale pripojeni, lze v pripade problemu s prenosem zvetsit
SSD1306 oled(SSD1306_ADDRESS, I2C_SDA, I2C_SCL, (OLEDDISPLAY_GEOMETRY)SSD1306_MODE_TYPE);
bool deviceProbe(uint8_t addr){ // Testuje, zda je pritomno I2C zarizeni na dane adrese
Wire.beginTransmission(addr);
return Wire.endTransmission() == 0;
}
bool setupDisplay(){ // Nastaveni displeje
if (!deviceProbe(SSD1306_ADDRESS))return false;
oled.init();
return true;
}
bool setupCamera(){ // Nastaveni kamery
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_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x\n", err);
return false;
}
sensor_t *s = esp_camera_sensor_get();
if (s->id.PID == OV3660_PID) {
s->set_vflip(s, 1);
s->set_brightness(s, 1);
s->set_saturation(s, -2);
}
s->set_framesize(s, FRAMESIZE_QVGA);
s->set_vflip(s, 1);
s->set_hmirror(s, 1);
return true;
}
void setupNetwork(){ // Nastaveni a pripojeni k WiFi
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
}
bool saveCapturedImage() { // Vyfoceni a odeslani obrazku na server
Serial.println("Connect to " + String(myDomain));
WiFiClientSecure client;
if (client.connect(myDomain, 443)) {
Serial.println("Connection successful");
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Camera capture failed");
return false;
}
char *input = (char *)fb->buf;
char output[base64_enc_len(3)];
String imageFile = "";
for (int i=0;i<fb->len;i++) {
base64_encode(output, (input++), 3);
if (i%3==0) imageFile += urlencode(String(output));
}
String Data = myFilename+mimeType+myImage;
esp_camera_fb_return(fb);
Serial.println("Send a captured image to Google Drive.");
client.println("POST " + myScript + " HTTP/1.1");
client.println("Host: " + String(myDomain));
client.println("Content-Length: " + String(Data.length()+imageFile.length()));
client.println("Content-Type: application/x-www-form-urlencoded");
client.println();
client.print(Data);
int Index;
for (Index = 0; Index < imageFile.length(); Index = Index+1000) {
client.print(imageFile.substring(Index, Index+1000));
}
Serial.println("Waiting for response.");
long int StartTime=millis();
while (!client.available()) {
Serial.print(".");
delay(100);
if ((StartTime+waitingTime) < millis()) {
Serial.println();
Serial.println("No response.");
//If you have no response, maybe need a greater value of waitingTime
break;
}
}
Serial.println();
if (client.find("302")){
Serial.println("Data send OK.");
}else{
Serial.println("Data send FAIL!");
return false;
}
} else {
Serial.println("Connected to " + String(myDomain) + " failed.");
}
client.stop();
return true;
}
// Prevod binarniho obrazku na textovou variantu pro posilani na webove stranky
//https://github.com/zenmanenergy/ESP8266-Arduino-Examples/
String urlencode(String str){
String encodedString="";
char c;
char code0;
char code1;
char code2;
for (int i =0; i < str.length(); i++){
c=str.charAt(i);
if (c == ' '){
encodedString+= '+';
} else if (isalnum(c)){
encodedString+=c;
} else{
code1=(c & 0xf)+'0';
if ((c & 0xf) >9){
code1=(c & 0xf) - 10 + 'A';
}
c=(c>>4)&0xf;
code0=c+'0';
if (c > 9){
code0=c - 10 + 'A';
}
code2='#include <WiFiClientSecure.h>
#include <Wire.h>
#include "esp_camera.h"
#include "wifikeys.h"
#include "SSD1306.h"
#include "Base64.h"
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 4
#define SIOD_GPIO_NUM 18
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 36
#define Y8_GPIO_NUM 37
#define Y7_GPIO_NUM 38
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 35
#define Y4_GPIO_NUM 14
#define Y3_GPIO_NUM 13
#define Y2_GPIO_NUM 34
#define VSYNC_GPIO_NUM 5
#define HREF_GPIO_NUM 27
#define PCLK_GPIO_NUM 25
#define I2C_SDA 21
#define I2C_SCL 22
#define SSD1306_MODE_TYPE 0 // 0 : GEOMETRY_128_64 // 1: GEOMETRY_128_32
#define SSD1306_ADDRESS 0x3c
#define AS312_PIN 19
// Promenne pro pouzite při odesilani dat na server
const char* myDomain = "script.google.com";
String myScript = "/macros/s/xxxxxxxxxxx/exec"; //Sem se místo xxx vlozi kod google skriptu
String myFilename = "filename=capture.jpg";
String mimeType = "&mimetype=image/jpeg";
String myImage = "&data=";
int waitingTime = 30000; // Doba pro odeslani obrazku na server, pokud bude pomale pripojeni, lze v pripade problemu s prenosem zvetsit
SSD1306 oled(SSD1306_ADDRESS, I2C_SDA, I2C_SCL, (OLEDDISPLAY_GEOMETRY)SSD1306_MODE_TYPE);
bool deviceProbe(uint8_t addr){ // Testuje, zda je pritomno I2C zarizeni na dane adrese
Wire.beginTransmission(addr);
return Wire.endTransmission() == 0;
}
bool setupDisplay(){ // Nastaveni displeje
if (!deviceProbe(SSD1306_ADDRESS))return false;
oled.init();
return true;
}
bool setupCamera(){ // Nastaveni kamery
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_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x\n", err);
return false;
}
sensor_t *s = esp_camera_sensor_get();
if (s->id.PID == OV3660_PID) {
s->set_vflip(s, 1);
s->set_brightness(s, 1);
s->set_saturation(s, -2);
}
s->set_framesize(s, FRAMESIZE_QVGA);
s->set_vflip(s, 1);
s->set_hmirror(s, 1);
return true;
}
void setupNetwork(){ // Nastaveni a pripojeni k WiFi
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
}
bool saveCapturedImage() { // Vyfoceni a odeslani obrazku na server
Serial.println("Connect to " + String(myDomain));
WiFiClientSecure client;
if (client.connect(myDomain, 443)) {
Serial.println("Connection successful");
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Camera capture failed");
return false;
}
char *input = (char *)fb->buf;
char output[base64_enc_len(3)];
String imageFile = "";
for (int i=0;i<fb->len;i++) {
base64_encode(output, (input++), 3);
if (i%3==0) imageFile += urlencode(String(output));
}
String Data = myFilename+mimeType+myImage;
esp_camera_fb_return(fb);
Serial.println("Send a captured image to Google Drive.");
client.println("POST " + myScript + " HTTP/1.1");
client.println("Host: " + String(myDomain));
client.println("Content-Length: " + String(Data.length()+imageFile.length()));
client.println("Content-Type: application/x-www-form-urlencoded");
client.println();
client.print(Data);
int Index;
for (Index = 0; Index < imageFile.length(); Index = Index+1000) {
client.print(imageFile.substring(Index, Index+1000));
}
Serial.println("Waiting for response.");
long int StartTime=millis();
while (!client.available()) {
Serial.print(".");
delay(100);
if ((StartTime+waitingTime) < millis()) {
Serial.println();
Serial.println("No response.");
//If you have no response, maybe need a greater value of waitingTime
break;
}
}
Serial.println();
if (client.find("302")){
Serial.println("Data send OK.");
}else{
Serial.println("Data send FAIL!");
return false;
}
} else {
Serial.println("Connected to " + String(myDomain) + " failed.");
}
client.stop();
return true;
}
// Prevod binarniho obrazku na textovou variantu pro posilani na webove stranky
//https://github.com/zenmanenergy/ESP8266-Arduino-Examples/
String urlencode(String str){
String encodedString="";
char c;
char code0;
char code1;
char code2;
for (int i =0; i < str.length(); i++){
c=str.charAt(i);
if (c == ' '){
encodedString+= '+';
} else if (isalnum(c)){
encodedString+=c;
} else{
code1=(c & 0xf)+'0';
if ((c & 0xf) >9){
code1=(c & 0xf) - 10 + 'A';
}
c=(c>>4)&0xf;
code0=c+'0';
if (c > 9){
code0=c - 10 + 'A';
}
code2='\0';
encodedString+='%';
encodedString+=code0;
encodedString+=code1;
//encodedString+=code2;
}
yield();
}
return encodedString;
}
void displayText(String text, int d){ // Zobrazeni textu na displeji
int len = text.length();
oled.clear();
oled.drawString( oled.getWidth() / 2, oled.getHeight() / 2 - len, text);
oled.display();
if (d > 0){
delay(d);
oled.clear();
oled.display();
}
}
void setup(){
Serial.begin(115200);
Wire.begin(I2C_SDA, I2C_SCL);
bool statusd, statusc;
statusd = setupDisplay(); // Nastaveni displeje
Serial.print("setupDisplay status "); (statusd)? Serial.println("OK") : Serial.println("Fail");
statusc = setupCamera(); // Nastaveni kamery
Serial.print("setupCamera status "); (statusc)? Serial.println("OK") : Serial.println("Fail");
if (!statusd || !statusc) { // Pokud se vyskytla chyba v nastaveni, zrestartuje se ESP32
Serial.println("Initializing error, restarting...");
delay(10000); esp_restart();
}
oled.setFont(ArialMT_Plain_16);
oled.setTextAlignment(TEXT_ALIGN_CENTER);
displayText("Starting...", 0);
setupNetwork(); // Nastaveni a pripojeni k WiFi
Serial.println("Ready...");
displayText("Ready...", 1000);
}
void loop(){
if(digitalRead(AS312_PIN)){ // Pokud je detekovan pohyb
Serial.println("Camera capture and send...");
displayText("Capture and send", 0);
// Odesle se obrazek na Google
if (saveCapturedImage()){ // Pokud odeslani obrazku probehlo v poradku
displayText("Send OK", 1000);
}else{
displayText("Send FAIL!", 1000);
}
}
}
';
encodedString+='%';
encodedString+=code0;
encodedString+=code1;
//encodedString+=code2;
}
yield();
}
return encodedString;
}
void displayText(String text, int d){ // Zobrazeni textu na displeji
int len = text.length();
oled.clear();
oled.drawString( oled.getWidth() / 2, oled.getHeight() / 2 - len, text);
oled.display();
if (d > 0){
delay(d);
oled.clear();
oled.display();
}
}
void setup(){
Serial.begin(115200);
Wire.begin(I2C_SDA, I2C_SCL);
bool statusd, statusc;
statusd = setupDisplay(); // Nastaveni displeje
Serial.print("setupDisplay status "); (statusd)? Serial.println("OK") : Serial.println("Fail");
statusc = setupCamera(); // Nastaveni kamery
Serial.print("setupCamera status "); (statusc)? Serial.println("OK") : Serial.println("Fail");
if (!statusd || !statusc) { // Pokud se vyskytla chyba v nastaveni, zrestartuje se ESP32
Serial.println("Initializing error, restarting...");
delay(10000); esp_restart();
}
oled.setFont(ArialMT_Plain_16);
oled.setTextAlignment(TEXT_ALIGN_CENTER);
displayText("Starting...", 0);
setupNetwork(); // Nastaveni a pripojeni k WiFi
Serial.println("Ready...");
displayText("Ready...", 1000);
}
void loop(){
if(digitalRead(AS312_PIN)){ // Pokud je detekovan pohyb
Serial.println("Camera capture and send...");
displayText("Capture and send", 0);
// Odesle se obrazek na Google
if (saveCapturedImage()){ // Pokud odeslani obrazku probehlo v poradku
displayText("Send OK", 1000);
}else{
displayText("Send FAIL!", 1000);
}
}
}
V menu Nástroje – Vývojová deska vybereme ESP32 Arduino – ESP32 Wrover Module a v Nástroje – Port vybereme sériový port, na který se nám nainstaloval USB převodník desky. Např. COM3.
Klepnutím na tlačítko se šipkou doprava – Nahrát se provede kompilace programu a pokud proběhla bez chyb dojde k nahrání programu do desky.
Pokud vše proběhlo bez problémů, tak by deska měla po detekování pohybu PIR čidlem vyfotit obrázek a poslat jej na Google disk.
Zda vše probíhá v pořádku lze sledovat na sériové konzoli a na displeji. Na displeji se však nezobrazují všechny informace jako v sériové konzoli, ale pouze základní informace – Startuji, Připraven, Vyfoceno a posílám, Posláno/Neposláno.
Jak si někteří mohli povšimnout, tak se v textu nikde nepíše o provozu v noci. Jelikož vývojová deska nedisponuje žádným infračerveným přisvěcováním, je nutné pro noční provoz toto přisvěcování přidat zvlášť.
14 Responses
kam to posílá fotky abych si stáhl program/aplikaci děkuji.
Dobrý den, odpověď na Vaši otázku naleznete hned v první větě: Rozhodli jsme se postavit jednoduchou online fotopast, která na signál z PIR čidla pořídí fotku a tu následně pošle přes WiFi na Google disk.
Dobrý den, mohl bych se zeptat?? píše mi to že má problém s tím že WiFi.begin (ssid, password); není deklarováno. Je to možné?
Dobrý den, to se stává, když máte vabraný špatný typ mikrokontroleru v Arduino IDE. Zde je nutné mít vybrán: ESP32 Wrover Module.
Dobrý den
mám problém při nahrávání mi píše chybu
base64_enc_len‘ was not declared in this scope
nějaký nápad třeba jiná knihovna nebo tak něco ?
Dobrý den, máte soubory Base64.h a Base64.cpp nakopírovány do stejné složky, jako soubor ino?
Ano a soubor wifikeys.h s vyplněnými řádky podle návodu. A soubory jsou stažené z arduino stránek myslím ty base.
Dobrý den, možná se bude jednat o novou nekompatibilní verzi knihovny. Zašleme Vám do mailu soubory Base64.h a Base64.cpp, se kterými jsme článek psali.
už nechci rušit ale jak se mohu zbavit tohoto (prosím o stručnou ukázku nebo video). Děkuji VH.
že ssid není deklarováno
Nemáte tento krok vyplněný :
: Ve stejné složce vytvoříme soubor wifikeys.h a uložíme do něho následující dva řádky:
Sám jsem vyráběl jednoduchou fotopast Chce to nějakou levnou kameru, Já mám sencor 3cam 2000W.Kamera je kloubové připojena ke krabičce. V krabičce mám 2akumulatory 18650,vypínač akumulátorů, nabíjecí automatika
TP4056, step-down měnič 5V/3A s 1x USB, (ovládání kamery), modul zvyšování napětí M406A a PIR čidlo T379.
Funguje to tak baterie jsou zapojeny paralelně dávají 4.2voltu max. Napětí jde přes nabíjecí obvod do měniče na 12v pro PIR čidlo. Toto přes step-down měnič 5V/3A s 1x USB a odsud se napájí nebo nenapaji kamera, podle toho se spustí a natáčí. Záběry lze provádět pouze vedne, ale i tak je to zábava.
Dobrý den,pomohl by mi prosim s tim někdo?
Děkuji
Zdravím, s čím konkrétně?