Skip to Content

Anschluss des SenseCAP Watcher W1-B an ESP32

Anschluss des SenseCAP Watcher W1-B an ESP32

Der SenseCAP Watcher ist ein KI-gestützter Assistent von Seeed Studio. Er nutzt den ESP32-S3 Mikrocontroller für lokale Bild- und Sprachverarbeitung.

Der Watcher verfügt über einen 1,2 Zoll großen, runden Touchscreen, eine integrierte Kamera, ein Mikrofon und einen eingebauten Lautsprecher. Er bietet Wi-Fi- und Bluetooth-Konnektivität und ist erweiterbar über einen Grove-Anschluss, einen Erweiterungsheader mit serieller Schnittstelle und einen microSD-Kartensteckplatz.

SenseCAP Watcher (source)

In diesem Tutorial lernst du, wie du den SenseCAP Watcher mit einem ESP32 verbindest, um Erkennungsergebnisse über die serielle Schnittstelle zu empfangen und darauf zu reagieren. Wir bauen einen Desk Inactivity Monitor, der dich zum Bewegen auffordert, wenn du länger als 60 Minuten am Schreibtisch sitzt.

Benötigte Teile

Du benötigst einen SenseCAP Watcher, den du bei Seeed Studio bekommst. Er wird mit einem USB-C-Kabel, einem Ständer und einem 1/4″ Adapter geliefert. Außerdem brauchst du einen ESP32. Ich habe einen XIAO ESP32-C5 gewählt, aber jeder andere ESP32 funktioniert ebenfalls. Für das Desk Inactivity Monitor Projekt benötigst du außerdem einen aktiven Summer sowie einige Kabel und ein Breadboard zum Verbinden.

SenseCAP Watcher

XIAO ESP32-C5

USB C Kabel

Aktiver Summer 5V

Dupont wire set

Dupont Kabelsatz

Half_breadboard56a

Breadboard

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Was ist der SenseCAP Watcher W1-B?

Der SenseCAP Watcher W1-B ist ein kompakter, eigenständiger KI-Sensorknoten, der Computer Vision, Audio-Interaktion und Aufgabenautomatisierung in einem Gerät vereint.

Auf Hardware-Ebene integriert das Gerät einen ESP32-S3 Mikrocontroller zusammen mit einem dedizierten KI-Beschleuniger, eine Weitwinkelkamera, Mikrofon, Lautsprecher, Touchscreen und drahtlose Konnektivität via Wi-Fi und Bluetooth.

Diese Kombination ermöglicht es dem Watcher, Echtzeit-Inferenz direkt auf dem Gerät durchzuführen, wie Objekterkennung oder Ereigniserkennung, ohne vollständig auf die Cloud angewiesen zu sein, was Latenz und Datenschutz verbessert.

SenseCraft platform
SenseCraft Plattform (source)

Ein zentrales Konzept des Watchers ist seine hybride KI-Architektur. Vision und grundlegende Logik laufen lokal auf dem Gerät, während komplexere Verarbeitung an externe Dienste oder große Sprachmodelle über die SenseCraft Plattform ausgelagert werden kann.

Aufgabenbasierter Betrieb und Benutzerinteraktion

Anstelle traditioneller Firmware-Logik arbeitet der Watcher mit einem Task-Flow-Modell. Intern sind Funktionen in modulare „Blöcke“ organisiert, die Daten erzeugen oder konsumieren können, ähnlich wie bei Node-RED. Diese Blöcke werden verbunden, um Verhalten zu definieren, z.B.: Person erkennen → Zustand analysieren → Benachrichtigung senden → externes System auslösen.

Die Interaktion mit dem Gerät ist multimodal. Die eingebaute Kamera ermöglicht visuelle Auslöser, während Mikrofon und Lautsprecher Sprachbefehle über eine Push-to-Talk-Schnittstelle unterstützen. Touchscreen und Drehregler bieten lokale Steuerung und Rückmeldung.

IoT-Integration

Der Watcher ist als Brücke zwischen KI-Wahrnehmung und bestehender IoT-Infrastruktur konzipiert. Er stellt Daten und Ereignisse über mehrere Schnittstellen bereit, darunter HTTP, UART und nachrichtenbasierte Integrationen, was die Anbindung an Frameworks wie Node-RED und Home Assistant ermöglicht.

In einer Node-RED-Umgebung fungiert der Watcher typischerweise als intelligenter Ereignisquelle. Erfasste Ereignisse wie „Person erkannt“ oder „Objekt fehlt“ können per HTTP oder MQTT in einen Node-RED-Flow gesendet und dort weiterverarbeitet werden.

In der Integration mit Home Assistant wird der Watcher zu einem hochentwickelten Sensor, der traditionelle Binärsensoren ergänzt. Statt nur Bewegung zu melden, liefert er semantische Informationen wie die Identifikation bestimmter Objekte oder Situationen. So sind komplexere Automatisierungen möglich, z.B. unterschiedliche Aktionen je nach Person oder erkannter Aktivität.

Für Maker-Projekte kann der Watcher als hochentwickeltes Wahrnehmungsmodul an Mikrocontroller wie ESP32-Boards angeschlossen werden. Er kann z.B. Personen oder Gesten erkennen und strukturierte Daten via UART oder HTTP senden, um LEDs, Summer, Motoren oder andere Hardware auszulösen.

Typische Anwendungsszenarien

Die Kombination aus On-Device-KI und externer Orchestrierung ermöglicht vielfältige Anwendungen. Im Smart Home kann der Watcher Präsenz und Kontext erkennen, z.B. wenn jemand einen Raum betritt, und automatisch Licht anpassen oder relevante Informationen anzeigen. Er kann auch Haustiere überwachen oder ungewöhnliche Situationen wie Stürze erkennen.

In Sicherheitsanwendungen kann das Gerät als intelligenter Überwachungsknoten fungieren, der zwischen normaler Aktivität und Anomalien unterscheidet und so Fehlalarme gegenüber herkömmlichen Bewegungssensoren reduziert. Da die Verarbeitung lokal erfolgt, müssen sensible Bilddaten das Gerät nicht verlassen.

In diesem Tutorial verwenden wir den Watcher, um einen Desk Inactivity Monitor zu bauen. Der Watcher überwacht die Anwesenheit einer Person am Schreibtisch. Die Personenerkennung wird via UART an einen verbundenen ESP32 gesendet, der die Zeit misst. Bleibt die Person länger als 60 Minuten am Schreibtisch, ertönt ein Summer als Erinnerung zum Bewegen.

Hardware des SenseCAP Watcher

Der SenseCAP Watcher wird von einem ESP32-S3 Mikrocontroller mit 240 MHz angetrieben. Dieser Chip bietet Dual-Core-Verarbeitung und native Unterstützung für Wi-Fi und Bluetooth. Er verfügt über 8 MB dedizierten PSRAM für speicherintensive Anwendungen. Das System besitzt außerdem 32 MB Flash-Speicher für Firmware und Daten.

Architektur des SenseCAP Watcher (source)

Ein separater Himax HX6538 KI-Prozessor übernimmt fortgeschrittene Bild- und Vektorberechnungen. Dieser sekundäre Prozessor verfügt über zusätzliche 16 MB Flash-Speicher für KI-Modelle.

Visuelle und Audio-Fähigkeiten

Die Vorderseite des Geräts beherbergt einen 1,45 Zoll großen, runden Touchscreen mit 412×412 Pixel Auflösung. Ein OV5647 Kamerasensor bietet ein 120-Grad-Weitwinkel-Sichtfeld. Die Kamera ist auf eine feste Fokussierung bei drei Metern eingestellt.

Audioeingang erfolgt über ein einzelnes integriertes Mikrofon auf der Platine. Ein eingebauter 1W-Lautsprecher liefert Audio-Feedback und Sprachantworten. Das Bild unten zeigt Vorder- und Rückseite des SenseCAP Watcher:

Front and Back of the SenseCAP Watcher
Vorder- und Rückseite des SenseCAP Watcher (source)

Interaktions- und Anzeigeelemente

Benutzer können die interne Software über ein digitales Krönchenrad an der Seite steuern. Dieses Rad unterstützt Scrollen und eine Button-Funktion zum Auswählen. Eine einzelne RGB-LED zeigt Statusinformationen wie Stromversorgung oder Verbindungsstatus an. Ein dedizierter Reset-Knopf ist durch ein kleines Loch an der Unterseite zugänglich. Das Gerät verfügt außerdem über einen microSD-Kartensteckplatz für erweiterbaren Speicher bis 32 GB.

Konnektivität und Stromversorgung

Die drahtlose Kommunikation erfolgt über 2,4 GHz Wi-Fi und Bluetooth 5.0. Das Gerät besitzt zwei USB-C-Anschlüsse für verschiedene Montage- und Stromversorgungsszenarien. Der untere Anschluss unterstützt 5V Stromversorgung und serielle Programmierung für die Entwicklung. Der hintere Anschluss ist ausschließlich für 5V Stromversorgung reserviert. Eine 400mAh Lithium-Ionen-Batterie dient als Backup-Stromquelle für kurze Einsätze.

Für externe Hardware bietet der Watcher einen Grove I2C-Port und einen 2×4 Female Header für GPIO-Erweiterungen. Das Bild unten zeigt die verschiedenen Anschlüsse auf der Rückseite des SenseCAP Watcher:

Schnittstellen des SenseCAP Watcher (source)

Beachte, dass der 5V-Pin ein Eingang ist, während der 3V3-Pin ein Ausgang ist. Verbinde den 5V-Eingang nicht gleichzeitig mit der Stromversorgung über den USB-Port.

Technische Spezifikationen

Die folgende Tabelle fasst die technischen Spezifikationen des SenseCAP Watcher zusammen:

Hardware Beschreibung
MCU ESP32-S3 @240MHz 8MB PSRAM
Integrierter KI-Prozessor Himax HX6538 (Cortex M55 + Ethos-U55)
Kamera OV5647 120° Sichtfeld
Feste Fokussierung 3 Meter
Wi-Fi IEEE 802.11b/g/n-konform
2,4 GHz Band
Reichweite: Bis zu 100 Meter (Freifeldtest)
Bluetooth LE Bluetooth 5
Antenne Integrierte Wi-Fi- und BLE-Antenne
Display Touchscreen 1,45 Zoll, 412×412 Pixel
Mikrofon Einzelnes Mikrofon
Lautsprecher 1W Lautsprecherausgang
Rad Unterstützt Scrollen und Button
LED 1x RGB-Licht zur Anzeige
microSD-Kartensteckplatz Unterstützt bis zu 32GB FAT32 microSD-Karten
Flash 32MB Flash für ESP32-S3
16MB Flash für Himax HX6538
Erweiterungsschnittstelle 1x Grove I2C Schnittstelle
2×4 Female Header (1x I2C, 2x GPIO, 2x GND, 1x 3.3V_OUT, 1x 5V_IN)
USB-C 1x USB-C hinten (nur Stromversorgung)
1x USB-C unten (Stromversorgung und Programmierung)
Reset-Knopf 1x RST-Knopf im unteren Loch
Stromversorgung 5V DC Stromversorgung
Batterie 3,7V 400mAh Li-Ion Batterie als Backup
Betriebstemperatur 0 ~ 45°C

SenseCAP Watcher mit ESP32 verbinden

Der SenseCAP Watcher bietet verschiedene Möglichkeiten, Erkennungsinformationen an andere Systeme wie Node-RED oder Home Assistant zu übertragen. Dafür ist jedoch ein Node-RED- oder Home Assistant-Server erforderlich.

Für ein kleines, lokales Erkennungssystem ist es besser, den SenseCAP Watcher mit einem Mikrocontroller zu verbinden, der die Erkennungsergebnisse auswertet und dann Aktionen ausführt, z.B. einen Alarm auslöst. Dies kann über die serielle Schnittstelle (UART) des Watchers realisiert werden.

Auf der Rückseite des Watchers befindet sich ein 8-poliger Anschluss mit I2C (SCL, SDA), UART (RX, TX) und Stromversorgung. Das folgende Schaltbild zeigt, wie du den SenseCAP Watcher über UART mit einem XIAO ESP32-C5 verbindest:

Connecting SenseCAP Watcher to an ESP32
SenseCAP Watcher mit XIAO ESP32-C5 verbinden

Verbinde zuerst TX des Watchers mit Pin D7 (RX) des XIAO ESP32-C5. Dann verbinde RX des Watchers mit Pin D6 (TX) des ESP32-C5. Die Stromversorgung des Watchers erfolgt über den ESP32-C5, indem 5V und GND verbunden werden. Die folgende Tabelle zeigt die Verbindungen:

Watcher ESP32-C5
RX D6/TX
TX D7/RX
5V 5V
GND GND

Stelle sicher, dass du den USB-C-Anschluss am ESP32-C5 zur Stromversorgung nutzt. So werden ESP32-C5 und Watcher gemeinsam versorgt. Verbinde nicht den USB-C-Anschluss des Watchers mit Strom.

Task mit UART-Benachrichtigung erstellen

Das Senden von Erkennungsergebnissen vom Watcher via UART an einen verbundenen ESP32 muss für jede Aufgabe in der SenseCraft APP aktiviert werden. In diesem Abschnitt lernst du, wie das geht. Du benötigst die SenseCraft APP auf deinem Handy und eine Verbindung zum SenseCAP Watcher. Falls nicht, lies zuerst Quick Start Guide und folge den dortigen Anweisungen.

Eine Erkennungsaufgabe in der SenseCraft APP zu erstellen ist einfach. Tippe z.B. „Notify via uart if person detected“, um eine Personenerkennungsaufgabe anzulegen:

Create Task with UART notification
Task mit UART-Benachrichtigung erstellen

Nach der Erstellung klicke auf „Detail Configs“, um den manuellen Konfigurationsdialog zu öffnen. Dort findest du mehrere Checkboxen. Stelle sicher, dass „Serial Port / UART Output“ aktiviert ist:

Task mit UART-Benachrichtigung konfigurieren

Die meisten anderen Checkboxen sind standardmäßig aktiviert, für die serielle Kommunikation benötigen wir sie jedoch nicht. Für detailliertere Informationen siehe den UART Output Abschnitt in der Seeed Studio Dokumentation zum SenseCAP Watcher.

Zum Schluss drücke den „Run Task“-Button unten im Dialog, um die Aufgabe zu starten.

Code-Beispiel: Erkennungsergebnisse lesen

Sobald die Aufgabe läuft und der Watcher via UART mit dem ESP32-C5 verbunden ist, können wir die Übertragung der Erkennungsergebnisse testen. Lade den folgenden Code auf deinen ESP32-C5, der per USB-C-Kabel mit deinem PC verbunden sein muss. Verbinde den Watcher nicht per USB!

#include <ArduinoJson.h>

DynamicJsonDocument doc(1024 * 100); // 100K

void setup() {
  Serial.begin(115200);
  Serial1.begin(115200, SERIAL_8N1, D7, D6);  // RX, TX
  while (!Serial)
    ;
  delay(100);
  Serial.println("Ready.");
}

void loop() {
  if (Serial1.available()) {
    deserializeJson(doc, Serial1);
    if (doc.containsKey("inference")) {
      Serial.println(doc["inference"].as<String>());
    }
  }
}

Der obige Code empfängt die JSON-formatierten Erkennungsdaten, die der Watcher über die serielle Verbindung sendet, und gibt die Informationen im Serial Monitor aus.

Imports

Der Code beginnt mit dem Einbinden der ArduinoJson Bibliothek, die für das Parsen der JSON-Daten vom Watcher notwendig ist. Diese Bibliothek erleichtert die Verarbeitung strukturierter JSON-Daten.

#include <ArduinoJson.h>

JSON-Dokument-Objekt

Anschließend wird ein DynamicJsonDocument mit dem Namen doc deklariert, das eine Kapazität von 100 Kilobyte (1024 * 100 Bytes) hat. Dieses Objekt hält die geparsten JSON-Daten von der Kamera. Die Größe ist so gewählt, dass sie die maximale Größe der vom Watcher gesendeten JSON-Nachrichten abdeckt.

DynamicJsonDocument doc(1024 * 100); // 100K

Setup-Funktion

In der setup() Funktion werden zwei serielle Schnittstellen initialisiert. Die erste, Serial, wird mit 115200 Baud für die Kommunikation mit dem Serial Monitor der Arduino IDE gestartet. Die zweite, Serial1, wird ebenfalls mit 115200 Baud gestartet, aber mit den Pins D7 (RX) und D6 (TX) konfiguriert, um mit der SenseCAP Watcher Kamera zu kommunizieren.

Der Code wartet, bis die USB-Seriell-Verbindung hergestellt ist, bevor er fortfährt, damit Debug-Meldungen sofort sichtbar sind. Nach einer kurzen Verzögerung von 100 Millisekunden wird „Ready.“ ausgegeben, um anzuzeigen, dass der ESP32 bereit ist, Daten zu empfangen.

void setup() {
  Serial.begin(115200);
  Serial1.begin(115200, SERIAL_8N1, D7, D6);  // RX, TX
  while (!Serial)
    ;
  delay(100);
  Serial.println("Ready.");
}

Loop-Funktion

Die loop() Funktion prüft kontinuierlich, ob Daten auf Serial1, das mit dem Watcher verbunden ist, verfügbar sind. Wenn Daten erkannt werden, versucht sie, den eingehenden JSON-Stream in das doc Objekt zu deserialisieren.

Wenn das geparste JSON den Schlüssel "inference" enthält, wird der zugehörige Wert als String extrahiert und im Serial Monitor ausgegeben.

void loop() {
  if (Serial1.available()) {
    deserializeJson(doc, Serial1);
    if (doc.containsKey("inference")) {
      Serial.println(doc["inference"].as<String>());
    }
  }
}

Ausgabe-Beispiel

Beim Ausführen dieses Codes auf dem ESP32-C5 sollten Erkennungsergebnisse ähnlich den folgenden im Serial Monitor erscheinen:

Falls nicht, überprüfe die Verkabelung und stelle sicher, dass „Serial port / UART output“ für die Erkennungsaufgabe aktiviert ist.

Die gesendeten Daten hängen vom Erkennungsmodell ab. Bei der Personenerkennung erhältst du immer die Begrenzungsrahmen der erkannten Personen, den Vertrauenswert, die Klassen-ID und die Liste der Klassennamen, hier nur [„person“].

Wenn du das Gestenerkennungsmodell verwendest, das Rock, Paper oder Scissors erkennt, sehen die vom Watcher gesendeten Daten z.B. so aus:

{"boxes":[[176,208,144,218,83,0]],"classes_name":["Paper","Rock","Scissors"]}

Code-Beispiel: Erkennungsdaten extrahieren

Im vorherigen Beispiel haben wir die vom Watcher übertragenen Erkennungsdaten als String interpretiert und ausgegeben. Oft möchtest du jedoch spezifische Informationen als numerische Werte extrahieren, z.B. Breite und Höhe des Begrenzungsrahmens.

Das folgende Codebeispiel zeigt, wie das geht. Es extrahiert die Daten aus dem JSON-Dokument und gibt sie als Zahlen aus:

#include <ArduinoJson.h>

DynamicJsonDocument doc(1024 * 100); // 100K

void setup() {
  Serial.begin(115200);
  Serial1.begin(115200, SERIAL_8N1, D7, D6);  // RX, TX
  while (!Serial)
    ;
  delay(100);
  Serial.println("Ready.");
}

void loop() {
  if (Serial1.available()) {
    deserializeJson(doc, Serial1);

    if (doc.containsKey("inference")) {
      JsonArray b = doc["inference"]["boxes"][0].as<JsonArray>();
      Serial.printf("x:%d y:%d w:%d h:%d | score:%d cls_id:%d\n",
                    b[0].as<int>(), b[1].as<int>(), b[2].as<int>(), b[3].as<int>(), 
                    b[4].as<int>(), b[5].as<int>());
    }
  }
}

Der Code ist identisch zum vorherigen Beispiel, außer bei der Ausgabe der Erkennungsdaten. Statt als String (doc["inference"].as()) werden die ersten Begrenzungsrahmen aus dem "boxes" Array innerhalb der Inferenzdaten extrahiert.

Dieser Begrenzungsrahmen ist ein JSON-Array mit sechs Ganzzahlen, die die Koordinaten und Metadaten des erkannten Objekts repräsentieren: x, y, width, height, score (Vertrauenswert) und cls_id (Klassen-ID). Diese Werte werden in einem formatierten String ausgegeben. Hier ein Beispiel für die Ausgabe.

x:131 y:290 w:240 h:208 | score:71 cls_id:0

Hast du die Erkennungsergebnisse als numerische Werte, kannst du Berechnungen durchführen. Zum Beispiel könntest du die Entfernung einer Person zum Watcher approximieren, indem du

distance = c * b[2].as<int>() * b[3].as<int>();

berechnest, wobei b[2] und b[3] die Breite und Höhe des Begrenzungsrahmens enthalten und c eine Konstante ist, um die Messung in eine Entfernungseinheit umzuwandeln.

Code-Beispiel: Desk Inactivity Monitor

Im letzten Codebeispiel bauen wir einen Desk Inactivity Monitor. Der SenseCAP Watcher wird auf einem Schreibtisch platziert und führt kontinuierlich die Personenerkennungsaufgabe aus. Die Erkennungsdaten werden periodisch an den verbundenen ESP32-C5 gesendet, der einen Timer laufen hat. Bleibt die Person länger als 60 Minuten ohne Unterbrechung am Schreibtisch, ertönt ein Summer als Erinnerung.

Da der ESP32-C5 keinen eingebauten Summer hat, müssen wir einen externen anschließen. Das ist einfach: Verbinde den Minuspol des Summers mit GND und den Pluspol mit dem D0-Pin, wie unten gezeigt.

Connecting SenseCAP Watcher to an XIAO ESP32-C5 with a buzzer
SenseCAP Watcher mit XIAO ESP32-C5 und Summer verbinden

Die anderen Verbindungen bleiben wie zuvor. Die folgende Tabelle listet alle notwendigen Verbindungen auf.

Watcher ESP32-C5 Summer
RX D6/TX
TX D7/RX
5V 5V
GND GND GND
D0 +

Falls du mehr Hilfe zum Summer brauchst, schau dir unser Active and Passive Piezo Buzzers with Arduino Tutorial an.

Achte darauf, den Summer richtig gepolt anzuschließen und dass es sich um einen aktiven Summer handelt – sonst funktioniert der folgende Code für den Desk Inactivity Monitor nicht.

#include <ArduinoJson.h>

DynamicJsonDocument doc(1024 * 100);  // 100K

const int BUZZER_PIN = D0; // GPIO 1
const unsigned long MAX_SIT_TIME_MS = 1000 * 60 * 60;

unsigned long tPerson = 0;
unsigned long tSitting = 0;
bool personDetected = false;

void setup() {
  Serial.begin(115200);
  Serial1.begin(115200, SERIAL_8N1, D7, D6);  // RX, TX
  pinMode(BUZZER_PIN, OUTPUT);
  digitalWrite(BUZZER_PIN, LOW);

  while (!Serial)
    ;
  delay(100);
  tPerson = millis();
  tSitting = millis();
  Serial.println("running...");
}

void loop() {
  unsigned long tCurrent = millis();

  if (Serial1.available()) {
    deserializeJson(doc, Serial1);
    if (doc.containsKey("inference")) {
      Serial.printf("person sitting %d sec\n", (tCurrent - tSitting)/1000);
      tPerson = tCurrent;
      if (!personDetected)
        tSitting = tCurrent;
      personDetected = true;
    }
  }

  if ((tCurrent - tPerson) > 1000 * 10) {
    personDetected = false;
    tSitting = tCurrent;
  }

  if (personDetected && ((tCurrent - tSitting) >= MAX_SIT_TIME_MS)) {
    tSitting = tCurrent;
    digitalWrite(BUZZER_PIN, HIGH);
    Serial.println("Take a break now!");
    delay(1000);
    digitalWrite(BUZZER_PIN, LOW);
  }
}

Imports

Wie zuvor binden wir die ArduinoJson Bibliothek ein, die zum Parsen der JSON-Daten vom Watcher verwendet wird.

#include <ArduinoJson.h>

JSON-Dokument

Dann wird ein DynamicJsonDocument mit dem Namen doc erstellt, das eine Kapazität von 100 Kilobyte hat. Dieses Dokument hält die geparsten JSON-Daten vom Watcher.

DynamicJsonDocument doc(1024 * 100);  // 100K

Konstanten

Die Konstante BUZZER_PIN definiert den GPIO-Pin, der mit dem Summer verbunden ist, hier auf D0 gesetzt (entspricht GPIO 1 am ESP32-C5). Eine weitere Konstante, MAX_SIT_TIME_MS, definiert die maximal erlaubte Sitzzeit in Millisekunden, hier 60 Minuten (1000 ms × 60 s × 60 min).

const int BUZZER_PIN = D0; // GPIO 1
const unsigned long MAX_SIT_TIME_MS = 1000 * 60 * 60;

Variablen

Wir verwenden mehrere Variablen, um Zeit und Erkennungsstatus zu verfolgen. tPerson speichert die letzte Zeit, zu der eine Person erkannt wurde, tSitting zeichnet den Beginn der Sitzperiode auf, und personDetected ist ein boolesches Flag, das anzeigt, ob gerade eine Person erkannt wird.

unsigned long tPerson = 0;
unsigned long tSitting = 0;
bool personDetected = false;

Setup-Funktion

Die setup() Funktion initialisiert die serielle Kommunikation für Debugging (Serial) und die Kommunikation mit der AI Vision Kamera (Serial1) mit 115200 Baud. Der Summer-Pin wird als Ausgang konfiguriert und zunächst ausgeschaltet. Der Code wartet, bis der serielle Port bereit ist, und initialisiert dann die Zeitvariablen tPerson und tSitting mit der aktuellen Zeit in Millisekunden. Abschließend wird „running…“ im Serial Monitor ausgegeben, um den Programmstart anzuzeigen.

void setup() {
  Serial.begin(115200);
  Serial1.begin(115200, SERIAL_8N1, D7, D6);  // RX, TX
  pinMode(BUZZER_PIN, OUTPUT);
  digitalWrite(BUZZER_PIN, LOW);

  while (!Serial)
    ;
  delay(100);
  tPerson = millis();
  tSitting = millis();
  Serial.println("running...");
}

Loop-Funktion

Die loop() Funktion läuft wiederholt und führt die Kernüberwachungslogik aus. Zuerst wird die aktuelle Zeit in Millisekunden in tCurrent gelesen.

Wenn Daten auf Serial1 (von der AI Vision Kamera) verfügbar sind, versucht der Code, das eingehende JSON in doc zu parsen. Enthält das JSON den Schlüssel "inference", wurde eine Person erkannt. Der Code gibt aus, wie viele Sekunden die Person bereits da ist, aktualisiert tPerson auf die aktuelle Zeit und, falls dies die erste Erkennung nach einer Pause ist, setzt tSitting zurück, um die Sitzdauer zu messen. Das Flag personDetected wird auf true gesetzt.

Sind seit der letzten Personenerkennung mehr als 10 Sekunden vergangen (tCurrent - tPerson > 10000), geht der Code davon aus, dass die Person gegangen ist, setzt personDetected auf false und setzt tSitting auf die aktuelle Zeit zurück.

Schließlich, wenn eine Person erkannt wird und die Sitzzeit die maximale erlaubte Zeit erreicht oder überschreitet (MAX_SIT_TIME_MS), wird der Summer für 1 Sekunde (1000 ms) aktiviert, um an eine Pause zu erinnern. Der Sitz-Timer tSitting wird nach dem Summer zurückgesetzt, um eine neue Überwachungsperiode zu starten.

void loop() {
  unsigned long tCurrent = millis();

  if (Serial1.available()) {
    deserializeJson(doc, Serial1);
    if (doc.containsKey("inference")) {
      Serial.printf("person sitting %d sec\n", (tCurrent - tSitting)/1000);
      tPerson = tCurrent;
      if (!personDetected)
        tSitting = tCurrent;
      personDetected = true;
    }
  }

  if ((tCurrent - tPerson) > 1000 * 10) {
    personDetected = false;
    tSitting = tCurrent;
  }

  if (personDetected && ((tCurrent - tSitting) >= MAX_SIT_TIME_MS)) {
    tSitting = tCurrent;
    digitalWrite(BUZZER_PIN, HIGH);
    Serial.println("Take a break now!");
    delay(1000);
    digitalWrite(BUZZER_PIN, LOW);
  }
}

Du kannst den Code testen, indem du MAX_SIT_TIME_MS auf eine Minute (1000 * 60) reduzierst. Wenn du länger als 60 Sekunden am Schreibtisch sitzt, sollte der Summer ertönen. Verläßt du den Schreibtisch vorher, wird der Timer zurückgesetzt.

Beachte, dass das Personenerkennungsmodell nur die Anwesenheit einer Person erkennt, nicht ob sie sitzt. Du könntest jedoch ein Skelettmodell verwenden, um bestimmte Posen zu erkennen und nur die tatsächliche Sitzzeit zu zählen.

Fazit

Der SenseCAP Watcher W1-B kombiniert eine ESP32-S3 Plattform mit integrierter Bild-, Audio- und KI-Funktionalität. Er ermöglicht den Bau intelligenter Sensoren am Rand des Netzwerks. Die aufgabenbasierte Architektur und flexible Konnektivität erleichtern die Integration in etablierte Tools wie Node-RED und Home Assistant.

Für Maker, die mit Arduino- oder ESP32-Ökosystemen arbeiten, kann der Watcher als hochentwickelter KI-Co-Prozessor dienen, der rechenintensive KI-Aufgaben auslagert. Die anwendungsspezifische und potenziell komplexe Auswertungslogik kann auf einem separaten Mikrocontroller implementiert werden, der über die serielle Schnittstelle mit dem Watcher kommuniziert. Beachte jedoch, dass der SenseCAP Watcher mit 3,3 Volt Logik arbeitet und ein Pegelwandler erforderlich ist, um ihn z.B. an ein 5V Arduino UNO anzuschließen.

Als KI-Bildsensor ähnelt der SenseCAP Watcher Geräten wie dem HUSKYLENS oder dem HUSKYLENS 2. Der Watcher ist jedoch eher ein eigenständiger KI-Agent, der Szenen interpretieren und autonom handeln kann. HUSKLENS und HUSKLENS 2 sind dagegen Bildsensoren, die Interpretation und Reaktion auf erkannte Objekte an einen Mikrocontroller via UART/I2C auslagern.

Bei Fragen kannst du sie gerne im Kommentarbereich stellen.

Viel Spaß beim Tüfteln 😉

Links

Hier eine Liste nützlicher Links, die ich beim Schreiben dieses Tutorials verwendet habe: