Cześć, ostatnio zamówiłem esp32 cam z zamiarem rozpoznawania tablic rejestracyjnych.
Skończyło się na:
- integracji esp32 z rejestratorem dahua który wysyła powiadomienie o przekroczeniu linii na kamerze, czyli pojawieniu się nowego obiektu przed bramą,
- esp32 nasłuchuje tego komunikatu i kiedy coś pojawia się przed bramą:
- esp32 wtedy ustawia virtualRelay na ON przez 2s
- na ten ON virtualRelay-a reaguje esp32 cam i robi zdjęcie które następnie wysyła do gemini AI z odpowiednim promptem
- gemini odsyła odpowiedź do esp32cam i jeśli pasuje numer rejestracyjny, marka, model i kolor samochodu...
- esp32cam otwiera z pomocą Supli bramę wjazdową
- wszystko trwa 2-3 sekundy
- i działa...
Jutro dalszy ciąg z kodami i zdjęciami.
Supla+AI, rozpoznawanie tablic rejestracyjnych i kur na podwórku
-
SOYER
- Posts: 1623
- Joined: Wed Aug 10, 2022 12:29 pm
- Location: Kryry
- Been thanked: 2 times
Last edited by SOYER on Sat Mar 14, 2026 3:16 pm, edited 1 time in total.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
Fajnie! Czekam na ciąg dalszy.
Ale z tytułem to "pojechałeś"
Ale z tytułem to "pojechałeś"
Wiesz, że Supla obsługuje Zigbee? Wstąp do Klubu Promila: https://forum.supla.org/viewtopic.php?t=18018
Szukasz nowego GG? Jest tutaj: https://forum.supla.org/viewtopic.php?t=18036-
malarz
- Posts: 506
- Joined: Wed Jan 27, 2021 4:04 pm
- Been thanked: 2 times
Oczywiście: Supla+rozpoznawanieSamochodu+inegracjaZrejestratoremDahua+reakcjaNaPrzekroczenieLini+otwarcieBramyPoPodjechaniuAuta+Kody+Zdjęcia
Próbuję przerobić pomysły na działające projekty w ArduinoIDE.
I następny nowy temat:malarz wrote: Sat Mar 14, 2026 10:35 amOczywiście: Supla+rozpoznawanieSamochodu+inegracjaZrejestratoremDahua+reakcjaNaPrzekroczenieLini+otwarcieBramyPoPodjechaniuAuta+Kody+Zdjęcia
![]()
Supla+rozpoznawanieSamochodu+inegracjaZrejestratoremDahua+reakcjaNaPrzekroczenieLini+otwarcieBramyPoPodjechaniuAuta+Kody+Zdjęcia+Opis
Wiesz, że Supla obsługuje Zigbee? Wstąp do Klubu Promila: https://forum.supla.org/viewtopic.php?t=18018
Szukasz nowego GG? Jest tutaj: https://forum.supla.org/viewtopic.php?t=18036-
Robert Błaszczak
- Posts: 5222
- Joined: Sat Dec 22, 2018 8:55 pm
- Location: Zielona Góra
- Has thanked: 37 times
- Been thanked: 27 times
Zibi_007 wrote: Sat Mar 14, 2026 1:03 pm I następny nowy temat:
Supla+rozpoznawanieSamochodu+inegracjaZrejestratoremDahua+reakcjaNaPrzekroczenieLini+otwarcieBramyPoPodjechaniuAuta+Kody+Zdjęcia+Opis![]()
A tak poważnie to prośba do @klew o skrócenie tego tematu. Taki temat nie jest czytelny, a rozwala Forum.
Propozycja: Otwarcie bramy na podstawie tablicy rejestracyjnej
Pozdrawiam
Robert Błaszczak
Moja prywatna strona: www.blaszczak.pl
Robert Błaszczak
Moja prywatna strona: www.blaszczak.pl
-
SOYER
- Posts: 1623
- Joined: Wed Aug 10, 2022 12:29 pm
- Location: Kryry
- Been thanked: 2 times
Hej, widzę, że temat budzi duże zainteresowanie
Aktualnie mam 2 urządzenia: esp32u(było c3 ale nie dawało rady) i esp32 cam.
Esp32u działa na dwóch wątkach, jeden obsługuje suplę i pojedynczy kanał wirtualnego przekaźnika, a na drugim wątku łaczy się poprzez API z rejestratorem Dahua i nasłuchuje informacji o przekroczeniu linii(wirtualnej) na kamerze która patrzy przed bramę. W momencie przekroczenia linii, esp włącza vr na 2 sekundy i tutaj kończy się jego praca,
a zaczyna robota esp32 cam, który przez MQTT nasłuchuje powyższy vr i kiedy ten jest włączony, esp wykonuje zdjęcie i wysyła je do AI gemini z prośbą o podanie numeru tablicy rejestracyjnej i marki samochodu. AI odpowiada, esp porównuje odpowiedź z bazą samochodów, jeśli pasuje marka i numer, przez MQTT otwiera bramę.
Skrótowo: jedno esp nasłuchuje rejestratora i kiedy ten mówi "coś wjechało przed bramę" esp włącza na moment virtualrelay. Na tą informację czeka już esp cam który robi zdjęcie i jeśli pasuje marka i numer otwiera bramę.
Kod dla esp32 cam:
Dodatkowo jest tam jeszcze lokalny podgląd w przeglądarce na zrobione zdjęcie, potrzebne do testów.
Kod dla obsługi zdarzeń rejestratora:
Potestuję jeszcze kilka dni, a potem muszę tą kamerkę jakoś zainstalować.
Trzeba oczywiście też zmienić prompt tak by gemini odrzucał wszelkie "zdjęcia ze zdjęciem". W aktualnym prompcie wystarczy pokazać zdjęcie naszego auta i już brama się otwiera:).
Bawiąc się z rejestratorem, coś naknociłem bo już nie dostaję na moim telefonie powiadomień push z apki Dahua, pewnie będę musiał ją przeinstalować
.
Projekt powstał z chęci zrobienia czegoś ciekawego. Przy jego powstawaniu ogromnie korzystałem z pomocy AI(również gemini). Potwierdza się pogląd, że z AI krótko piszesz ale długo debugujesz:).
Jeszcze jedna informacja, od pojawienia się na podjeździe do momentu włączenia otwierania bramy mija maksymalnie 5 sekund. Także dość użyteczne. Będę tego używał chyba tylko dla zabawy bo wolę otwierać bramę wcześniej, a nie czekać aż się otworzy.
Jednak projekt dość rozwojowy bo przecież AI może rozpoznawać wszystko, czy pada deszcz(zamknij okna dachowe), jest ciemno(włącz światło), kury uciekły z kurnika i biegają po podwórku(wyślij powiadomienie push z Supli) i wiele innych....
P.S. już zmieniam temat:)
Aktualnie mam 2 urządzenia: esp32u(było c3 ale nie dawało rady) i esp32 cam.
Esp32u działa na dwóch wątkach, jeden obsługuje suplę i pojedynczy kanał wirtualnego przekaźnika, a na drugim wątku łaczy się poprzez API z rejestratorem Dahua i nasłuchuje informacji o przekroczeniu linii(wirtualnej) na kamerze która patrzy przed bramę. W momencie przekroczenia linii, esp włącza vr na 2 sekundy i tutaj kończy się jego praca,
a zaczyna robota esp32 cam, który przez MQTT nasłuchuje powyższy vr i kiedy ten jest włączony, esp wykonuje zdjęcie i wysyła je do AI gemini z prośbą o podanie numeru tablicy rejestracyjnej i marki samochodu. AI odpowiada, esp porównuje odpowiedź z bazą samochodów, jeśli pasuje marka i numer, przez MQTT otwiera bramę.
Skrótowo: jedno esp nasłuchuje rejestratora i kiedy ten mówi "coś wjechało przed bramę" esp włącza na moment virtualrelay. Na tą informację czeka już esp cam który robi zdjęcie i jeśli pasuje marka i numer otwiera bramę.
Kod dla esp32 cam:
Code: Select all
//płytka AI Thinker ESP32-CAM
#include "esp_camera.h"
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include "Base64.h"
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include <WebServer.h>
WebServer server(80);
uint8_t* last_photo_buf = NULL;
size_t last_photo_len = 0;
void handleRoot() {
if (last_photo_buf != NULL && last_photo_len > 0) {
server.setContentLength(last_photo_len);
server.send(200, "image/jpeg", ""); // Wysyła tylko nagłówek
server.client().write(last_photo_buf, last_photo_len); // Wysyła czyste bajty
} else {
server.send(200, "text/plain; charset=UTF-8", "Brak zdjęcia. Wyzwol analize MQTT.");
}
}
// --- WIFI CONFIGURATION ---
const char* ssid = "x";
const char* password = "x";
// --- GEMINI CONFIGURATION ---
const char* apiKey = "x";
// --- MQTT SUPLA CONFIGURATION ---
const char* mqtt_server = "mqttx.supla.org";
const int mqtt_port = 8883;
const char* mqtt_user = "x";
const char* mqtt_pass = "x";
// LISTENING TOPIC (Trigger)
const char* topic_sub = "supla/x/devices/x/channels/x/state/on";
// SENDING TOPIC (Opening the gate )
const char* topic_pub = "supla/x/devices/x/channels/x/execute_action";
WiFiClientSecure espClient;
PubSubClient client(espClient);
bool triggerPhoto = false;
struct Samochod {
String tablica;
String marka;
};
// Twoja lista uprawnionych pojazdów
Samochod baza[] = {
{"SPS xxx", "VOLVO"},
{"SPS xxx", "OPEL"}
};
int ileWBazie = 2;
// --- PINS ESP32-CAM 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 callback(char* topic, byte* payload, unsigned int length) {
String message = "";
for (int i = 0; i < length; i++) message += (char)payload[i];
// In Supla, the ON state is usually "1"
if (message == "true") {
Serial.println(">>> ON signal received via MQTT! Starting analysis...");
triggerPhoto = true;
}
}
void reconnect() {
while (!client.connected()) {
Serial.print("Connecting to MQTT...");
if (client.connect("ESP32_CAM_LPR_Node", mqtt_user, mqtt_pass)) {
Serial.println("Connected!");
client.subscribe(topic_sub);
} else {
Serial.print("Error: ");
Serial.print(client.state());
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
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 = 10000000; config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_VGA; // Optimal for RAM
config.jpeg_quality = 12;
config.fb_count = 1;
esp_camera_init(&config);
sensor_t * s = esp_camera_sensor_get();
s->set_vflip(s, 1);
s->set_hmirror(s, 0);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println("\nWiFi OK");
Serial.println("MQTT config...");
espClient.setInsecure();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
server.on("/", handleRoot);
server.begin();
Serial.print("Podglad pod: http://");
Serial.println(WiFi.localIP());
}
void loop() {
if (!client.connected()) reconnect();
client.loop();
server.handleClient();
if (triggerPhoto) {
triggerPhoto = false;
analyzeWithGemini();
}
}
void analyzeWithGemini() {
camera_fb_t * fb_warmup = esp_camera_fb_get();
if (fb_warmup) esp_camera_fb_return(fb_warmup);
delay(500);
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) { Serial.println("Camera error"); return; }
// --- KOPIOWANIE DLA PODGLĄDU ---
if (last_photo_buf) free(last_photo_buf);
last_photo_buf = (uint8_t*)malloc(fb->len);
if (last_photo_buf) {
memcpy(last_photo_buf, fb->buf, fb->len);
last_photo_len = fb->len;
}
String base64Image = base64::encode(fb->buf, fb->len);
esp_camera_fb_return(fb);
HTTPClient http;
http.setTimeout(30000);
String url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=" + String(apiKey);
http.begin(url);
http.addHeader("Content-Type", "application/json");
String prompt = "Analyze this image. Return ONLY a JSON object with fields: plate, brand. Format: {\\\"plate\\\":\\\"...\\\", \\\"brand\\\":\\\"...\\\"}. Do not add any extra text or markdown.";
String payload = "{\"contents\":[{\"parts\":[{\"text\":\"" + prompt + "\"},{\"inline_data\":{\"mime_type\":\"image/jpeg\",\"data\":\"" + base64Image + "\"}}]}]}";
int httpResponseCode = http.POST(payload);
if (httpResponseCode == 200) {
String response = http.getString();
DynamicJsonDocument doc(8192);
deserializeJson(doc, response);
String rawJson = doc["candidates"][0]["content"]["parts"][0]["text"];
Serial.print("ODPOWIEDŹ GEMINI: ");
Serial.println(rawJson);
rawJson.replace("```json", "");
rawJson.replace("```", "");
rawJson.trim();
DynamicJsonDocument car(1024);
deserializeJson(car, rawJson);
String odczytanaTablica = car["plate"];
String odczytanaMarka = car["brand"];
Serial.println("\n--- WYNIK ANALIZY ---");
Serial.printf("TABLICA: %s | %s %s (%s)\n", odczytanaTablica.c_str(), odczytanaMarka.c_str());
bool znaleziono = false;
for (int i = 0; i < ileWBazie; i++) {
// 1. Przygotowanie tablic (bez spacji, wielkie litery)
String t1 = odczytanaTablica; t1.replace(" ", ""); t1.toUpperCase();
String t2 = baza[i].tablica; t2.replace(" ", ""); t2.toUpperCase();
// 2. Przygotowanie marek (wielkie litery, usunięcie zbędnych spacji)
String m1 = odczytanaMarka; m1.trim(); m1.toUpperCase();
String m2 = baza[i].marka; m2.trim(); m2.toUpperCase();
// WARUNEK: Musi zgadzać się tablica ORAZ marka musi pasować do odczytu
if (t1 == t2 && (m1.indexOf(m2) != -1 || m2.indexOf(m1) != -1)) {
Serial.println(">>> DOSTĘP PRZYZNANY: " + baza[i].marka + " [" + baza[i].tablica + "]");
client.publish(topic_pub, "OPEN");//_CLOSE
Serial.println("Wysłano MQTT: Otwieram bramę");
znaleziono = true;
break;
}
}
if (!znaleziono) {
Serial.println("XXX POJAZD NIEZGODNY LUB NIEZNANY XXX");
}
} else {
Serial.printf("HTTP error: %d\n", httpResponseCode);
}
http.end();
}Kod dla obsługi zdarzeń rejestratora:
Code: Select all
//curl -g --digest -u xx:xxx "http://192.x.x.x/cgi-bin/eventManager.cgi?action=attach&codes=[CrossLineDetection]"
//płytka esp32 dev module
#include <WiFi.h>
#include <MD5Builder.h>
#define SUPLA_LOG_LEVEL 3
#include <SuplaDevice.h>
#include <supla/network/esp_wifi.h>
#include <supla/control/virtual_relay.h>
// --- KONFIGURACJA ---
const char* ssid = "x";
const char* password = "x";
const char* host = "x";
const char* user = "x";
const char* pass = "x";
const char* url = "/cgi-bin/eventManager.cgi?action=attach&codes=[CrossLineDetection]&channel=2&heartbeat=5";
char GUID[16] = {x};
char AUTHKEY[16] = {x};
WiFiClient d_client;
Supla::ESPWifi supla_wifi(ssid, password);
auto vRelay = new Supla::Control::VirtualRelay();
unsigned long lastEventTime = 0;
unsigned long lastDataTime = 0;
// --- FUNKCJE POMOCNICZE ---
String md5(String payload) {
MD5Builder _md5; _md5.begin(); _md5.add(payload); _md5.calculate();
return _md5.toString();
}
String getDigestAuth(String header) {
auto getParam = [&](String param) {
int start = header.indexOf(param + "=\"");
if (start == -1) return String("");
start += param.length() + 2;
return header.substring(start, header.indexOf("\"", start));
};
String realm = getParam("realm"), nonce = getParam("nonce"), qop = "auth", nc = "00000001", cnonce = "abcdefgh";
String ha1 = md5(String(user) + ":" + realm + ":" + String(pass));
String ha2 = md5("GET:" + String(url));
String resp = md5(ha1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + ha2);
return "Digest username=\"" + String(user) + "\", realm=\"" + realm + "\", nonce=\"" + nonce +
"\", uri=\"" + url + "\", qop=" + qop + ", nc=" + nc + ", cnonce=\"" + cnonce +
"\", response=\"" + resp + "\", algorithm=MD5";
}
// --- WĄTEK DAHUA (URUCHAMIANY NA RDZENIU 0) ---
void dahuaTask(void * pvParameters) {
Serial.println("[Dahua] Wątek wystartował na Core 0.");
while(1) {
if (WiFi.status() == WL_CONNECTED) {
if (!d_client.connected()) {
Serial.println("[Dahua] Próba połączenia (Krok 1/2)...");
if (d_client.connect(host, 80)) {
// Wysłanie zapytania o Digest (udajemy curl dla stabilności)
d_client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"User-Agent: curl/7.68.0\r\n" +
"Accept: */*\r\n" +
"Connection: close\r\n\r\n");
String response = "";
unsigned long t = millis();
// Czekamy na wyzwanie Digest max 3s
while ((d_client.connected() || d_client.available()) && (millis() - t < 3000)) {
if (d_client.available()) {
char c = d_client.read();
response += c;
if (response.indexOf("\r\n\r\n") != -1) break;
}
vTaskDelay(1 / portTICK_PERIOD_MS);
}
int authPos = response.indexOf("WWW-Authenticate: Digest");
if (authPos != -1) {
String authLine = response.substring(authPos, response.indexOf("\r", authPos));
Serial.println("[Dahua] Logowanie (Krok 2/2)...");
d_client.stop();
vTaskDelay(150 / portTICK_PERIOD_MS);
if (d_client.connect(host, 80)) {
d_client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Authorization: " + getDigestAuth(authLine) + "\r\n" +
"User-Agent: curl/7.68.0\r\n" +
"Accept: */*\r\n" +
"Connection: keep-alive\r\n\r\n");
Serial.println("[Dahua] POŁĄCZONO I NASŁUCHUJĘ!");
lastDataTime = millis();
}
} else {
Serial.println("[Dahua] BŁĄD: Brak autoryzacji Digest w odpowiedzi.");
d_client.stop();
}
}
if (!d_client.connected()) vTaskDelay(5000 / portTICK_PERIOD_MS);
}
// --- STABILNY ODBIÓR STRUMIENIA ZNAK PO ZNAKU ---
String currentLine = "";
currentLine.reserve(256); // Optymalizacja pamięci
while (d_client.connected()) {
if (d_client.available()) {
char c = d_client.read();
lastDataTime = millis(); // Reset timeoutu - coś przyszło!
// Opcjonalne: Serial.print(c); // Odkomentuj, by widzieć "surowy" zrzut danych
if (c == '\n') {
// Analiza kompletnej linii
if (currentLine.indexOf("Code=CrossLineDetection") != -1) {
if (currentLine.indexOf("action=Start") != -1) {
Serial.println("\n>>> [DAHUA] !!! ALARM PRZEKROCZENIA LINII !!! <<<");
vRelay->turnOn();
lastEventTime = millis();
} else if (currentLine.indexOf("action=Stop") != -1) {
Serial.println("\n[Dahua] Koniec zdarzenia.");
}
}
currentLine = ""; // Czyścimy bufor po znaku nowej linii
}
else if (c != '\r') {
currentLine += c;
}
// Zabezpieczenie przed zbyt długą linią (brak znaku \n)
if (currentLine.length() > 512) currentLine = "";
}
// Timeout: Dahua milczy (brak ruchu). Restart po 2 minutach ciszy.
if (millis() - lastDataTime > 120000) {
Serial.println("\n[Dahua] Timeout (2 min) - restart połączenia...");
d_client.stop();
break;
}
vTaskDelay(1 / portTICK_PERIOD_MS); // Kluczowe dla stabilności WiFi/Supla
}
} else {
vTaskDelay(1000 / portTICK_PERIOD_MS); // Czekaj na WiFi
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
void setup() {
Serial.begin(115200);
// Start Supli na domyślnym rdzeniu (1)
SuplaDevice.begin(GUID, "svrx.supla.org", "[email protected]", AUTHKEY);
// Uruchomienie wątku Dahua na rdzeniu 0
xTaskCreatePinnedToCore(dahuaTask, "DahuaTask", 8192, NULL, 1, NULL, 0);
Serial.println("System gotowy (Dual Core).");
}
void loop() {
SuplaDevice.iterate();
if (vRelay->isOn() && (millis() - lastEventTime > 2000)) {
vRelay->turnOff();
Serial.println("[Supla] OFF.");
}
}Trzeba oczywiście też zmienić prompt tak by gemini odrzucał wszelkie "zdjęcia ze zdjęciem". W aktualnym prompcie wystarczy pokazać zdjęcie naszego auta i już brama się otwiera:).
Bawiąc się z rejestratorem, coś naknociłem bo już nie dostaję na moim telefonie powiadomień push z apki Dahua, pewnie będę musiał ją przeinstalować
Projekt powstał z chęci zrobienia czegoś ciekawego. Przy jego powstawaniu ogromnie korzystałem z pomocy AI(również gemini). Potwierdza się pogląd, że z AI krótko piszesz ale długo debugujesz:).
Jeszcze jedna informacja, od pojawienia się na podjeździe do momentu włączenia otwierania bramy mija maksymalnie 5 sekund. Także dość użyteczne. Będę tego używał chyba tylko dla zabawy bo wolę otwierać bramę wcześniej, a nie czekać aż się otworzy.
Jednak projekt dość rozwojowy bo przecież AI może rozpoznawać wszystko, czy pada deszcz(zamknij okna dachowe), jest ciemno(włącz światło), kury uciekły z kurnika i biegają po podwórku(wyślij powiadomienie push z Supli) i wiele innych....
P.S. już zmieniam temat:)
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
Sam pomysł ciekawy, warty gratulacji. Jakieś wyzwanie, realizacja, efekty. Samo otwieranie bramy można oczywiście rozwiązać na wiele innych prostszych sposobów. Nawet dzisiaj rano na rolkach w FB pokazał mi się filmik jak gościu połączył mikrokontroler do świateł w aucie i sekwencja trzech mignięć uruchamiała mu bramę. Ale Twój pomysł z tą kamerką w połączeniu z AI to ciekawa sprawa. Np. może ostrzegać jak żona idzie. A jak np. koledzy to milczy albo uruchamia większe mrożenie w lodówce
A tak na poważnie to podobają mi się takie różne nietypowe pomysły 
-
SOYER
- Posts: 1623
- Joined: Wed Aug 10, 2022 12:29 pm
- Location: Kryry
- Been thanked: 2 times
Mam jeszcze prośbę, jakby mi ktoś powiedział jak ograniczyć logi supli w czasie działania programu. Wiem(?), że jest kilka „poziomów” dla logów, ale z moim kolegą ejajem poległem na tym.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
Używasz ArduinoIDE czy PlatformIO? To robi różnicę jeśli chodzi o Twoje pytanie.SOYER wrote: Sat Mar 14, 2026 7:26 pm Mam jeszcze prośbę, jakby mi ktoś powiedział jak ograniczyć logi supli w czasie działania programu. Wiem(?), że jest kilka „poziomów” dla logów, ale z moim kolegą ejajem poległem na tym.
