Skocz do zawartości

Pomocna odpowiedź

Dobra. Zaczynamy opis aktualnej wersji alarmu od opisu funkcji ESP32-CAM.

W tej chwili system składa się z panelu na moim serwerze (dostępnego w sieci, po zalogowaniu), komunikacji za pośrednictwem protokołu MQTT pomiędzy serwerem a Pico i poszczególnymi ESP32. Całość sterowana jest z mojego serwerka w chmurze Oracle, a nie, jak w poprzedniej wersji z Pico.

Zaczynamy od kodu dla ESP-32-CAM, który można pobrać z githuba. ponieważ dopiero zaczynam poznawać C, jestem z niego bardzo dumny, i szeroko otwarty na wszelką krytykę. Najważniejsze możliwości: komunikacja dwukierunkowa za pośrednictwem trzech kanałów MQTT (zdjęcia, kody sterujące, komunikaty o pracy), zmiana wybranych parametrów kamery z panelu (między innymi rozdzielczość, kompresja, ISO), możliwość miękkiego resetowania ESP32 albo samego modułu kamery, możliwość załadowania nowej wersji oprogramowania z serwera (OTA), możliwość zdalnego sprawdzenia siły sygnału WiFi z którego korzysta kamera (RSSI). Komunikacja obywa się z zabezpieczeniem certyfikatem PEM (opcjonalnie bez, ale nie w pełni to przetestowałem). Jest tu pewien słaby punkt: certyfikat na sztywno wpisany jest w kodzie, i aby go zmienić, trzeba zrobić upgrade oprogramowania. A darmowe certyfikaty Certbota mają ograniczony czas ważności. Jeśli ktoś ma pomysł, jak to rozwiązać inaczej, chętnie go poznam.

W skrócie, ESP32-CAM po uruchomieniu ustawia aktualny czas, pobiera ustawienia z pamięci nieulotnej i wysyła na jednym z kanałów zdjęcia. Nasłuchuje na innym kanale, co pozwala mu uruchamiać opcje diagnostyczne i update oprogramowania.

Na serwerze pobierane zdjęcia mogą być strumieniowane do panelu webowego i jednocześnie zapisywane w archiwum (czyszczonego po 48 godzinach), przy czym archiwizowanie zdjęć nie jest na razie dostępne na githubie, działa w oparciu o basha odpalanego z CRON'a:

#!/bin/bash

a=$"mosquitto_sub -h localhost -t cam1/out -p 1883 -u user -P password
b=$"jest"

while read -r line;
do
    echo $line | base64 --decode > /home/www/asm/obrazek1.jpg
    echo $b > /home/www/asm/o1.txt
done < <($a 2>&1)

Poza tym każde zdjęcie jest na serwerze analizowane, ale to temat na innego, obszernego, posta. W razie potrzeby wysyłany jest mail z powiadomieniem. Przyznam się bez bicia, że analiza ruchu na zdjęciach jest jeszcze w powijakach (ale działa, choć jeszcze nie tak dobrze, jak chciałbym).

Działa to naprawdę szybko, chociaż im wyższa rozdzielczość, tym wolniej. Niedługo sprawdzę, czy dodatkowe anteny poprawią sytuację.

To maksimum możliwej wydajności teraz: https://movies.metricsmaster.eu/w/4yUX7ZYtHdkFsKFKbyyPFb

Pamiętajcie, że mówimy tu o module za 33,97 PLN.

W następnym wpisie: Co w takim razie robi Pico?, ale to już raczej jutro.

(edytowany)

Testuję właśnie zewnętrzne anteny do ESP32-CAM.

anteny.thumb.png.3058de3180ac9a0f1ec06c8e27cac1d0.png

Zgadnijcie, która sprawuje się najlepiej? 😄

Testowane w mieszkaniu w bloku, gdzie jest wiele sieci, więc poziom zakłóceń jest bardzo wysoki.

Routerem jest telefon Blackberry, w odległości ok,. 2 metrów.

Wyniki (RSSI, miara pomocnicza; wskaźnik siły odbieranego sygnału włącznie z zakłóceniami, im mniej tym lepiej):

wbudowana antena - 84-93 dBm

antena płytkowa (pierwsza z lewej) - 62-63 dBm

antena modelarska (pierwsza z prawej) - 68-71 dBm

antena łamana (w środku) - 63-65 dBm

Trochę zaskakujące, ale najlepiej sprawuje się płytka.

 

Edytowano przez Szern
3 minuty temu, _LM_ napisał:

Środkowa? 

Też tak myślałem, dlatego kupiłem ich więcej, a pozostałych po jednej dla testów. 😄

1 minutę temu, _LM_ napisał:

Płytkowa nie ma czasem charakterystyki kierunkowej? 

Jeszcze nie jestem pewien, sprawdzam. Środkowa ma na pewno i wyniki podałem dla najlepszej uzyskanej pozycji.

(edytowany)

W mieszkaniu ciężko będzie stwierdzić ze względu na odbicia i interferencje sygnału, czasem warto testować na różnych kanałach wifi, w każdym razie ciekawy temat 

Edytowano przez _LM_
(edytowany)

W ogóle, to trzeba mieć świadomość, że to bardzo tani, chiński produkt. Płytki kupowane w dłuższym odstępie czasu różnią się znacząco parametrami (na przykład rozmiar pamięci flash i parametry odbiornika WiFi). Dodatkowo, po pewnym czasie użytkowania (u mnie ok. rok) pogorszeniu ulegają parametry WiFi i niektóre kamery "wychodzą" z zasięgu mojej sieci, stąd moje zainteresowanie antenami.

Testy dla starej kamerki, która pracowała ponad rok i ma 2 MB flasha: RSSI 84-93 dBm, natomiast do nowej, właśnie kupionej (inny wygląd obiektywu, 4 MB flasha): RSSI 74-88 dBm (porównanie dla anten wbudowanych).

Powyższe testy anten zrobiłem na "starej" kamerze, później zrobię to samo dla "nowej".

Nie mam możliwości zmiany kanału w tej chwili, konkretne testy w terenie może zrobię za około tydzień, a może dopiero na wiosnę.

Dla mnie hardcore'owe jest przelutowywanie opornika zerówki SMD, ale na razie udaje mi się jakimś cudem to zrobić.

Edytowano przez Szern
(edytowany)
21 minut temu, Szern napisał:

Dla mnie hardcore'owe jest przelutowywanie opornika zerówki SMD, ale na razie udaje mi się jakimś cudem to zrobić.

Pod mikroskopem nie ma z tym żadnych problemów (to chyba 0402, więc nawet bez mikroskopu się da, tylko potrzebujesz dobrej pęsety - ja mam jakąś tytanową z "łapkami" 0.15mm)

Edytowano przez H1M4W4R1
  • Lubię! 1
34 minuty temu, H1M4W4R1 napisał:

Pod mikroskopem nie ma z tym żadnych problemów (to chyba 0402, więc nawet bez mikroskopu się da, tylko potrzebujesz dobrej pęsety - ja mam jakąś tytanową z "łapkami" 0.15mm)

Masz na myśli "normalny" mikroskop (np. x100) i taką pęsetę?

  • 9 miesiące później...

Kolejny sezon minął bez włamania. System alarmowy przechodzi tylko niewielki tuning. Brak czasu i kasy. Wiele się na nim uczę.

Kluczową zmianą jest poprawione oprogramowanie centrali, które spowodowało, że Pico stało się najbardziej niezawodnym elementem systemu. Obecnie jest wykorzystywane nawet do restartu routera, kiedy zawiedzie (to wprawdzie Netgear, ale kilkunastoletni).

Tak wygląda obecnie schemat centralki (niestety wszystko na płytce uniwersalnej):

centrala.thumb.png.edc6e045195d1d1a827344a2fb92c21d.png

A tak wygląda aktualna wersja oprogramowania, która na nim chodzi:

// centrala asm v.09
// websocket
//
// sterowanie przekaźnikami (ESP32-CAM, syreny, światło, router)
// bezpośrednie zasilanie lampy diodowej
// czujnik AHT-10
// sygnał odstraszacza do wzmacniacza
// resetowanie kamer
// 

#include <Arduino.h>
#include <pico/stdlib.h>

#include <WiFi.h>
#include <SocketIOclient.h>
#include <MQTTPubSubClient.h>

#include <pico/time.h>
#include <pico/util/datetime.h>
// #include <hardware/watchdog.h>

#include <Adafruit_AHTX0.h>

#define DEBUG_SERIAL 0         // 0 - off, 1 - init & frame, 2 - detailed
#define DEBUG_MQTT 1           // 0 - off, 1 - on

const char * ssid = "nazwa_sieci_WiFi";
const char * pass = "hasło_sieci_WiFi";

// GPIO
// lewa od góry 0,1,2,3,4,5,6,7 odpowiednio zaciski: 1, 2, 3, 4, 5, 6, 7, wzmacniacz
// prawa od dołu 8,9,10,11,12,13,14,3V3 OUT
// prawa od dołu 8,9,10,26 (A0 IN) dzielnik napięcia,27 (A1 IN) dzielnik napięcia,28,12V IN to amplifier,3V3 OUT <-

const uint kam[2] = {0,1}; // esp32-cam (aktywowane stanem niskim, przy wyłączonym Pico działają) {0,1}
const uint s[2] = {2,3}; // na 2 dwie syreny w kamerach, na 3 duża syrena 220V (aktywowane stanem niskim - a powinny wysokim) {2,3}
// GPIO4 i GPIO5 - AHT-10 connected
const uint l[3] = {8,9,6}; // światło na zewnątrz, na parterze i na strychu
const uint b[1] = {7}; // brzęczyk odstraszacza myszy na strychu
const uint se[2] = {26,27}; // czujniki światła
const uint r[1] = {10}; // router

const uint klick[7] {0,1,2,3,8,9,6}; // for status check
// state0 to state6 - return state of pin as above (LOW or HIGH)
// klick0 to klick6 - change state of pin as above (LOW to HIGH, or HIGH to LOW)

const char* mqttServer = "adres.serwerw.mqtt.pl";
const long mqttPort = 8083;
const char* mqttUser = "użytkownik_MQTT";
const char* mqttPass = "hasło_MQTT";
const char* mqttId = "pico-centrala";
const char* mqttTopicIn = "pico/in";
const char* mqttTopicTemp = "pico/temp";
const char* mqttTopicHum = "pico/hum";
const char* mqttTopicLight1 = "pico/light1";
const char* mqttTopicLight2 = "pico/light2";
const char* mqttTopicDebug = "pico/debug";
const char* mqttTopicKam1 = "kam1/debug";
const char* mqttTopicKam2 = "kam2/debug";
const char* mqttTopicPing = "ping";
const char* mqtt_pong = "pong";
const char* mqtt_time = "time"; // return current time of Pico
const char* mqtt_stime = "stime"; // force take time from timeserver
const char* mqtt_knock = "knock, knock"; // doing nothing, need to prevent froze ESP32-CAM
const char* mqtt_signal = "signal"; // return strench of WiFI signal in dBm
const char* mqtt_echo = "echo"; // return text defined in line below
const char* mqtt_echo_return = "echo, echo, echo!";
const char* mqtt_pins = "pins"; // return current states connected pins of Pico
const char* mqtt_buzz = "buzz"; // return current minutes to run mouse buzzer in this hour
const char* mqtt_restart = "res"; // restart Pico
const char* mqtt_mouseOff = "mof"; // mouse buzzer off
const char* mqtt_mouseOn = "mon"; // mouse buzzer on

const char* ntpServer1 = "tempus1.gum.gov.pl";
const char* ntpServer2 = "tempus2.gum.gov.pl";
const long gmtOffset_sec = 3600;   // GMT offset (seconds)
const int daylightOffset_sec = -3600;  // daylight offset (seconds)
time_t t;

bool  mqtt_status = 0, // status of connection with mqtt
      mqtt_initialised = 0, // initialisation mqtt
      sensors = 0, // sensors results sending - on or off
      rndset[2] = {0,0}, // ability to generate random mouse sound parameters
      silence = 1, // status of mouse buzzer
      kamstat[2] = {0,1}, // cameras status: on (0) or off (1)
      ping = 0, pong = 0, // ping mqtt server
      mouse = 1, // mouse buzzer working or not
      timeset = 0; // time from server is set 
uint  minuty[5] = {10, 12, 27, 35, 48},
      strenght[2],
      freq,
      kamtest[2] = {0,0},
      blink = 100;
int   tt;
unsigned long 
      duration,
      wifi_counter = 0UL,
      now = 0UL,
      last[5] = {0UL,0UL,0UL,0UL,0UL},
      wc1 = 1UL,
      wc2 = 1UL,
      wc3 = 1UL;
sensors_event_t 
      humidity,
      temp;
char 
      te[10],
      hu[10];

IPAddress ip(192,168,1,145); // Pico2 145, Pico1 141
IPAddress dns(1,1,1,1);
IPAddress gate(192,168,1,98);
IPAddress mask(255,255,255,0);

WebSocketsClient client;
MQTTPubSubClient mqtt_client;
Adafruit_AHTX0 aht;

void debug(String message, int line = 1);
void temphum();
void signal();
void connect();
uint random(int min, int max);

void setup() { // ########################################################################################################################

  if ( DEBUG_SERIAL != 0 ) {
    Serial.begin(115200);
  }

  analogReadResolution(12);
  analogWriteResolution(12);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  pinMode(kam[0], OUTPUT);
  digitalWrite(kam[0], kamstat[0]);
  pinMode(kam[1], OUTPUT);
  digitalWrite(kam[1], kamstat[1]);
  pinMode(s[0], OUTPUT);
  digitalWrite(s[0], HIGH);
  pinMode(s[1], OUTPUT);
  digitalWrite(s[1], HIGH);
  pinMode(l[0], OUTPUT);
  digitalWrite(l[0], LOW);
  pinMode(l[1], OUTPUT);
  digitalWrite(l[1], LOW);
  pinMode(l[2], OUTPUT_12MA);
  digitalWrite(l[2], LOW);
  pinMode(se[0], INPUT);
  analogReadResolution(12);
  pinMode(se[1], INPUT);
  pinMode(b[0], OUTPUT_12MA);
  analogWriteFreq(0);
  analogWrite(b[0], 0);
  pinMode(r[0], OUTPUT);
  digitalWrite(r[0], LOW);

//  WiFi.mode(WIFI_STA);
//  WiFi.config(ip, dns, gate, mask);
  WiFi.begin(ssid, pass);
  debug("connecting to WiFi");

  srand(time(NULL));   // Initialization, should only be called once.

  if ( aht.begin() ) {
    sensors = 1;
  }

  digitalWrite(LED_BUILTIN, LOW);

  rp2040.wdt_begin(8300);
//  rp2040.wdt_reset();

}

void loop() { // ##########################################################################################################################

  now = millis();

  if ( client.isConnected() ) {
    mqtt_client.update(); // should be called
  }

// podłączenie do sieci (WiFi i mqtt)

  if ( !( WiFi.status() == WL_CONNECTED ) ) { // &&&&&&&&&&&&&&&&&&&&&&& połaczenie WiFi z routerem
    mqtt_status = 0;
    if (now - last[3] > wc1*60000UL )  {
      wc1 *= 2;
      if ( wc1 > 60 ) { // ok. godziny
        // restart routera
        digitalWrite(r[0], HIGH);
        delay(5000);
        digitalWrite(r[0], LOW);
        delay(120000);
        rp2040.restart();
      }
      last[3] = now;
    }
  } else if ( WiFi.status() == WL_IDLE_STATUS ) {
    mqtt_status = 0;
  } else if ( !timeset || ( (int)localtime(&t)->tm_hour == 3 && (int)localtime(&t)->tm_min == 0 && (int)localtime(&t)->tm_sec == 0 ) ) {
    NTP.begin(ntpServer1, ntpServer2);
    // NTP.waitSet([]() { debug("waiting to timeserver"); });
    timeset = 1;
  } else if ( !mqtt_initialised ) {
    debug("connecting to MQTT");
    rp2040.wdt_reset();
    client.beginSSL(mqttServer, mqttPort, "/", NULL, "mqtt"); // &&&&&&&&&& połączenie z serwerem mqtt
    client.setReconnectInterval(1000UL);
    mqtt_client.begin(client);
    mqtt_client.connect(mqttId, mqttUser, mqttPass); // &&&&&&&&&& połączenie z mqtt websocket
    rp2040.wdt_reset();
    connect(); // subskrypcja tematów mqtt
    mqtt_initialised = 1;
  }
  if ( !mqtt_status ) {
    mqtt_client.publish(mqttTopicPing, "ping", false, 0); // final connection check
  }
  if ( client.isConnected() ) {
    mqtt_client.update(); // should be called
  }
  if ( pong ) {
    mqtt_status = 1;
    wifi_counter = 0;
    wc1 = 0;
    pong = 0;
    blink = 5000;
    debug("communication is OK (after disconnecting)");
    rp2040.wdt_reset();
  }
  if ( client.isConnected() ) {  
    mqtt_client.update(); // should be called
  }

// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&& mysi odstraszacz
// Na przykład w eksperymentach naukowcy odkryli, że szczury boją się hałasu w następujących zakresach częstotliwości:
// 25–28 kHz. Więc szczur płacze, gdy odczuwa ból;
// 32-33 kHz jest sygnałem niebezpiecznym. Publikuje go na przykład szczur, którego kot próbuje złapać;
// 35–60 kHz - w tym zakresie występuje „pisk”, z którym zwierzę po prostu wyraża dyskomfort.
// (Oczywiście ważna jest tu nie tylko częstotliwość, ale także modulacja sygnału).
// U myszy sygnały stresu występują również w kilku zakresach częstotliwości, z których najwyższy wychwytuje dźwięki o częstotliwości 96 kHz.

  t = time(NULL);
  if ( !rndset[0] ) {
    if ( (int)localtime(&t)->tm_min == 5 ) {
      for ( int i = 0; i < 5; i++ ) {
        minuty[i] = random(2,59);
      }
      debug("minuty właczenia alarmu");
      debug((String)minuty[0]);
      debug((String)minuty[1]);
      debug((String)minuty[2]);
      debug((String)minuty[3]);
      debug((String)minuty[4]);
      rndset[0] = 1;
    } else if ( (int)localtime(&t)->tm_min == 6 ) {
      rndset[0] = 0;
    }
  }

  tt = (int)localtime(&t)->tm_min;
  if ( ( tt == minuty[0] || tt == minuty[1] || tt == minuty[2] || tt == minuty[3] || tt == minuty[4] ) && mouse ) {
    rp2040.wdt_reset();
    if ( !rndset[1] ) {
      strenght[0] = random(0,255);
      strenght[1] = random(0,255);
      freq = random(25000,50000);
//      freq = random(1000,19000); // słyszalne ludzie częstotliwości do testów 
      duration = now + random(500,25000);
      rndset[1] = 1;
    }
    analogWriteResolution(12);
    analogWriteFreq(freq);
    if ( now <= duration ) {
      analogWrite(b[0], strenght[0]);
      silence = 0;
      debug((String)freq);
      if ( random(0,100) > 50 ) {
        freq += random(0,5);
      } else {
        freq -= random(0,5);
      }
    } else {
      if ( !silence ) {
        analogWriteFreq(0);
        analogWrite(b[0], 0);
        silence = 1;
      }
    }
    rp2040.wdt_reset();
  } else {
    rndset[1] = 0;
  }

// ##################################### sprawdzanie i restart kamer

  if ( client.isConnected() ) {
    mqtt_client.update(); // should be called

    if ( now - last[2] >= wc2*30000UL ) {
      if ( !kamstat[0] ) {
        if ( digitalRead(kam[0]) == HIGH ) {
          digitalWrite(kam[0], LOW);
        } else if ( kamtest[0] == 0 ) {
          mqtt_client.publish(mqttTopicDebug, "restart kam1", false, 0);
          digitalWrite(kam[0], HIGH);
          wc2 *= 2;
          if ( wc2 > 2880 ) {
            wc2 = 1;
          }
        } else if ( kamtest[0] > 0 ) {
          wc2 = 1;
        }
      }
      kamtest[0] = 0;
      last[2] = now;
    }

    if ( now - last[4] >= wc3*30000UL ) {
      if ( !kamstat[1] ) {
        if ( digitalRead(kam[1]) == HIGH ) {
          digitalWrite(kam[1], LOW);
        } else if ( kamtest[1] == 0 ) {
          digitalWrite(kam[0], HIGH);
          wc3 *= 2;
          if ( wc3 > 2880 ) {
            wc3 = 1;
          }
          mqtt_client.publish(mqttTopicDebug, "restart kam2", false, 0);   
        } else if ( kamtest[0] > 0 ) {
          wc3 = 1;
        }
      }
      kamtest[1] = 0;
      last[4] = now;
    }

// przesłanie wyników z sensorów

    if ( sensors && (now - last[0] >= 60000UL ) ) {
      temphum();
      const String light1 = (String)analogRead(se[0]);
      mqtt_client.publish(mqttTopicLight1, light1, false, 0);
      const String light2 = (String)analogRead(se[1]);
      mqtt_client.publish(mqttTopicLight2, light2, false, 0);
      last[0] = now;
    }

  }

  if (now - last[1] >= blink ) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    last[1] = now;
  }

  rp2040.wdt_reset();

}

// debagowanie

void debug(String message, int line) { // ########################################################################################

  if ( DEBUG_SERIAL != 0 ) {
    if (line == 1) {
      Serial.println(message);
    } else {
      Serial.print(message);
    }
  }
  if ( DEBUG_MQTT && mqtt_status == 1 ) {
    mqtt_client.publish(mqttTopicDebug, message, false, 0);
  }

}

void temphum() { // ########################################################################################

  if ( DEBUG_MQTT && mqtt_status == 1 ) {
    aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
    dtostrf(temp.temperature, 2, 1, te); // 4 is mininum width, 3 is precision; float value is copied onto buff
    mqtt_client.publish(mqttTopicTemp, te, false, 0);
    dtostrf(humidity.relative_humidity, 2, 0, hu);
    mqtt_client.publish(mqttTopicHum, hu, false, 0);
  }

}

void signal() { // ########################################################################################

  int32_t rssi = WiFi.RSSI();
  debug("Signal strength (RSSI): ");
  debug((String)rssi);
  debug(" dBm");

}

void connect() { // subscribe mqtt topics ################################################################################

  mqtt_client.subscribe(mqttTopicKam1, [](const char * payload, const size_t size) {
    kamtest[0]++;
  });
  mqtt_client.subscribe(mqttTopicKam2, [](const char * payload, const size_t size) {
    kamtest[1]++;
  });
  mqtt_client.subscribe(mqttTopicIn, [](const char * payload, const size_t size) {
    if ( strcmp(payload, mqtt_echo) == 0 ) {
      debug(mqtt_echo_return);
    } else if ( strcmp(payload, mqtt_time) == 0 ) {
      debug("current time: ",0);
      t = time(NULL);
      debug(asctime(localtime(&t)));
    } else if ( strcmp(payload, mqtt_stime) == 0 ) {
      NTP.begin(ntpServer1, ntpServer2);
    } else if ( strcmp(payload, mqtt_signal) == 0 ) {
      signal();
    } else if ( payload[0] == 'k' && payload[1] == 'l' && payload[2] == 'i' && payload[3] == 'c' && payload[4] == 'k' ) {
      int cipher = payload[5];
      int pin = klick[cipher - 48];
      debug((String)pin);
      if ( digitalRead(pin) == LOW ) {
        digitalWrite(pin,HIGH);
        debug("HIGH");
      } else if ( digitalRead(pin) == HIGH ) {
        digitalWrite(pin, LOW);
        debug("LOW");
      }
      if ( pin == 0 ) {
        kamstat[0] = !kamstat[0];
      }
      if ( pin == 1 ) {
        kamstat[1] = !kamstat[1];
      }
    } else if ( payload[0] == 's' && payload[1] == 't' && payload[2] == 'a' && payload[3] == 't' && payload[4] == 'e' ) {
      int cipher = payload[5];
      int pin = klick[cipher - 48];
      debug((String)pin);
      if ( digitalRead(pin) == LOW ) {
        debug("LOW");
      } else if ( digitalRead(pin) == HIGH ) {
        debug("HIGH");
      }
    } else if ( strcmp(payload, mqtt_pins) == 0 ) {
      char pins[15];
      char zero = 48;
      char one = 49;
      for ( int i = 0; i <= 14; i++ ) {
        if ( digitalRead(i) ) {
          pins[i] = one;
        } else {
          pins[i] = zero;
        }
      }
      debug((String)pins);
    } else if ( strcmp(payload, mqtt_buzz) == 0 ) {
      debug("minuty właczenia alarmu");
      debug((String)minuty[0]);
      debug((String)minuty[1]);
      debug((String)minuty[2]);
      debug((String)minuty[3]);
      debug((String)minuty[4]);
    } else if ( strcmp(payload, mqtt_pong) == 0 ) {
      pong = 1;
    } else if ( strcmp(payload, mqtt_restart) == 0 ) {
      rp2040.restart();
    } else if ( strcmp(payload, mqtt_mouseOff) == 0 ) {
      mouse = 0;
    } else if ( strcmp(payload, mqtt_mouseOn) == 0 ) {
      mouse = 1;
    } else {
      debug("command not recognized");
    }
  });

}

uint random(int min, int max) {

  int tmp;
  if ( max >= min ) {
    max -= min;
  } else {
    tmp = min - max;
    min = max;
    max = tmp;
  }
  return max ? (rand() % max + min) : min;

}

To dalej jest robocza wersja, chociaż bardzo stabilna, na pewno zawiera jeszcze błędy, których nie znalazłem. Jest misz-masz w komentarzach, część jest przygotowana do publikacji, a część to moje notatki. To jeszcze nie jest wersja, która trafi na githuba.

Najpoważniejszą zmianą jest przejście na komunikację websocket (MQTT). Szybkość przesyłania zdjęć wzrosła drastycznie. Drugą, istotną zmianą jest przejście na programowanie w czasie rzeczywistym (rezygnacja z delay itp.). Raczkuję w tym temacie, wszelkie uwagi mile widziane.

Całość jest pisana przy pomocy Platformio, więc zamieszcza również zawartość pliku platformio.ini:

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
; https://arduino-pico.readthedocs.io/en/latest/platformio.html

; [env:rpipicow]
[env:pico]
; platform = raspberrypi
; platform = https://github.com/earlephilhower/arduino-pico.git
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
board = rpipicow
; board = pico
framework = arduino
board_build.core = earlephilhower

; in reference to a board = pico config (2MB flash)
; Flash Size: 2MB (Sketch: 1MB, FS:1MB)
; board_build.filesystem_size = 1m
; Flash Size: 2MB (No FS)
; board_build.filesystem_size = 0m
; Flash Size: 2MB (Sketch: 0.5MB, FS:1.5MB)
; board_build.filesystem_size = 1.5m

board_build.filesystem_size = 0.5m

; PSRAM size: 1MB
; board_upload.psram_length = 1048576
; PSRAM size: 2MB
; board_upload.psram_length = 2097152
; PSRAM size: 4MB
; board_upload.psram_length = 4194304

; expect an ISSI IS25LP080 flash, SPI frequency = CPU frequency divided by 2
; board_build.arduino.earlephilhower.boot2_source = boot2_is25lp080_2_padded_checksum.S

; 133MHz
board_build.f_cpu = 133000000L

; upload_protocol = picotool
; upload_port = /dev/ttyACM0
; upload_speed = 500000
; monitor_port = /dev/ttyACM0
; monitor_speed = 115200
; debug_tool = picoprobe
; debug_init_break = tbreak loop

build_flags =
    -D ARDUINO_RASPBERRY_PI_PICO_W

lib_deps =
    WiFi
    links2004/WebSockets@^2.6.1
    hideakitai/MQTTPubSubClient@^0.3.2
    adafruit/Adafruit AHTX0@^2.0.5

To niemal najnowsza wersja płytki (jeszcze bez filtra na zasilaniu 12V, zdobię zdjęcia "w akcji"):

pytka-centrala.thumb.png.4ac697fa3ca7c75db7ec48095b326913.png

Chciałbym kolejną wersję zrobić na dedykowanej płytce i uczę się, jak to przygotować w KiKad'zie. No, powiedzmy, że jestem na wstępnym etapie nauki. 🙂

Pewne zmiany nastąpiły w czujnikach. Mam temperaturę i wilgotność pobieraną z AHT-10, jasność pobieraną z fotorezystora i napięcie (nazwa na wykresie "prąd" jest myląca) pobierane z mikro panelu solarnego (zbieram dane na temat opłacalności instalacji jakichś paneli). Wszystko ląduje na serwerze w bazie MySQL. A tak wygląda bardzo prymitywny interface do przeglądania tego (jak będę miał trochę więcej czasu, zrobię lepszy.

wykres2.thumb.png.473366d7b7fa6f3e1f11bd9564fd79cd.png

Największym problemem jest to, że do tej pory nie uruchomiłem efektywnie czujnika ruchu. Może mam wadliwy egzemplarz, a może coś robię źle. Przy okazji pokażę o co chodzi, może ktoś mi coś doradzi.

To co robię teraz to prymitywna przeróbka jednej kamery na night-vision i oświetlenie IR. Jak się z tym uporam, napiszę o tym więcej.

W każdym razie Aktywny System Monitorujący działa i spełnia swoje zadanie. Każdą krytykę przyjmę z pokorą, sugestie zmian i poprawek są bardzo mile widziane.

  • Lubię! 2
26 minut temu, Szern napisał:

Największym problemem jest to, że do tej pory nie uruchomiłem efektywnie czujnika ruchu.

Cóż, te najtańsze modele tak mają, nie są zbyt pewne. Przepraszam jeśli to już było poruszane, czy przy każdym pir jest kamera? Można wykorzystać kamerkę jako czujnik ruchu skoro i tak tam jest 

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...