Der C1001 60GHz mmWave Indoor Sturzerkennungssensor ist ein kompakter Radarmodul, der für die Überwachung von Anwesenheit und Sicherheit von Menschen entwickelt wurde. Er arbeitet im 60-GHz-Millimeterwellenbereich und kann Bewegung, Haltung und sogar sehr kleine Körperbewegungen wie Atmung erkennen.
Im Gegensatz zu herkömmlichen PIR- oder kamerabasierten Systemen verwendet dieser Sensor Radarsignale, um reflektierte Wellen vom menschlichen Körper zu analysieren. Dadurch kann er sowohl Bewegung als auch Stillstand erkennen, einschließlich Situationen, in denen eine Person gestürzt ist und regungslos bleibt. Er funktioniert auch bei völliger Dunkelheit und erfasst keine Bilder, was ihn für datenschutzsensiblen Innenbereich geeignet macht.
Das Modul enthält integrierte Algorithmen für Sturzerkennung, Schlafüberwachung, Anwesenheitserkennung und grundlegende Vitalzeichenmessungen. Es kann Atmung und Herzschlag im Nahbereich messen und menschliche Aktivität bis zu etwa 11 Metern erkennen. Verarbeitete Ergebnisse werden direkt über eine serielle Schnittstelle ausgegeben, sodass keine komplexe Signalverarbeitung auf dem Mikrocontroller erforderlich ist.
In diesem Tutorial lernst du, wie du den mmWave C4002 Sensor an ein Arduino oder ESP32 anschließt, um Vitalzeichen zu messen, Stürze zu erkennen und die Schlafqualität zu überwachen.
Benötigte Teile
Den mmWave C1001 Sensor kannst du bei DFRobot oder Amazon erwerben. Du benötigst außerdem ein Arduino, ESP8266 oder ESP32. In diesem Tutorial verwende ich ein Arduino UNO und ein ESP32-C3 SuperMini, aber jedes andere Arduino, ESP32 oder ESP8266 funktioniert, solange es einen 5V-Ausgangspin hat. Schließlich sind ein Breadboard und einige Dupont-Kabel zum Verdrahten nützlich.

mmWave C1001 Sensor

ESP32-C3 SuperMini

USB-C-Kabel

Arduino Uno

USB-Kabel für Arduino UNO

Dupont-Kabelsatz

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.
Hardware des mmWave C1001 Sensors
Der C1001 Sensor basiert auf einem 60-GHz-Millimeterwellen-Radar-Frontend. Er arbeitet im Frequenzbereich von etwa 61 bis 61,5 GHz und sendet elektromagnetische Wellen mit geringer Leistung in die Umgebung. Das ausgesendete Signal wird von Objekten und menschlichen Körpern reflektiert, und der Sensor analysiert das zurückkehrende Signal, um Bewegungs- und Anwesenheitsinformationen zu extrahieren. Das Bild unten zeigt die Rück- und Vorderseite des C1001 Sensormoduls:

Der Radar verwendet einen Point-Cloud-Imaging-Ansatz, um die Position und Bewegung eines menschlichen Ziels zu modellieren. Diese Methode ermöglicht es dem Sensor, Haltungsänderungen und räumliche Bewegungen zu erkennen, anstatt sich nur auf einfache Bewegungsauslöser zu verlassen. Dadurch kann er zwischen Stehen, Bewegen und Liegen mit höherer Zuverlässigkeit unterscheiden.
Der Sensor kann auch Mikrobewegungen wie Brustverlagerungen durch Atmung und Herzschlag erkennen. Dies ist möglich, weil Millimeterwellensignale sehr kleine Oberflächenänderungen, sogar im Submillimeterbereich, erfassen können.
Erfassungsbereich und Sichtfeld
Der C1001 Sensor unterstützt eine maximale Erkennungsdistanz von bis zu 11 Metern unter optimalen Bedingungen. Er bietet ein weites Sichtfeld mit einem ungefähren Abdeckungswinkel von 100 Grad sowohl horizontal als auch vertikal.
Bei der Sturzerkennung wird der Sensor typischerweise an der Decke montiert. Bei einer Installationshöhe von etwa 2,7 Metern bildet der effektive Erkennungsbereich eine kreisförmige Zone mit einem Durchmesser von etwa 4 Metern.

Für die Vitalzeichenüberwachung ist der Erfassungsbereich kürzer. Atmungs- und Herzschlagmessungen sind am genauesten in einem Abstand von etwa 0,4 bis 1,5 Metern. Die Schlafüberwachung kann etwas weiter reichen, bis zu etwa 2,5 Metern vom Sensor entfernt.

Signalverarbeitung und eingebettete Algorithmen
Der C1001 integriert eine Onboard-Signalverarbeitung und Erkennungsalgorithmen. Rohdaten des Radars werden intern verarbeitet, und der Nutzer erhält hochstufige Informationen statt roher Signalströme. Dies reduziert die Rechenlast auf dem angeschlossenen Mikrocontroller.
Die interne Firmware implementiert mehrere Erkennungsmodi. Dazu gehören Anwesenheitserkennung, Bewegungsverfolgung, Sturzerkennung und Schlafüberwachung. Der Sturzerkennungsalgorithmus analysiert Haltungswechsel und identifiziert plötzliche Veränderungen gefolgt von Bewegungsstillstand. Er kann auch die Dauer der Inaktivität nach einem Sturz verfolgen.
Der Vitalzeichenerkennungsalgorithmus extrahiert periodische Muster aus reflektierten Signalen. Er berechnet Atemfrequenzen typischerweise im Bereich von 10 bis 25 Atemzügen pro Minute und Herzfrequenzen zwischen 60 und 100 Schlägen pro Minute.
Elektrische Eigenschaften
Der Sensor arbeitet mit einer Versorgungsspannung von 5 V und verbraucht typischerweise weniger als 100 mA. Das macht ihn geeignet für eingebettete Systeme, die von Standard-Entwicklungsboards versorgt werden.
Der Radarsender gibt ein Signal mit einer Leistung von etwa 6 dBm aus. Dies gewährleistet ausreichende Signalstärke für die Innenraumerkennung bei gleichzeitig niedrigem Stromverbrauch und sicherem Betrieb.
Das Gerät ist für einen Betriebstemperaturbereich von −20 °C bis 60 °C ausgelegt. Dies ermöglicht einen stabilen Betrieb in typischen Innenräumen und vielen halbindustriellen Anwendungen.
Schnittstelle und Datenausgabe
Der C1001 kommuniziert über eine UART-Seriellschnittstelle. Er liefert verarbeitete Datenrahmen, die Erkennungszustände wie Anwesenheit, Sturzstatus und Vitalzeicheninformationen enthalten.
Die Stromversorgung (5V) erfolgt über die VIN- und GND-Pins, während TX und RX für die serielle Kommunikation mit einem Mikrocontroller verwendet werden. Zwei zusätzliche digitale Ausgangspins mit der Bezeichnung IO1 und IO2 sind dafür vorgesehen, Sturzereignisse und Anwesenheit zu melden. Das Foto unten zeigt das Pinout des C1001 Moduls:

Beachte, dass ich IO1 oder IO2 nicht zum Laufen bringen konnte. Ich konnte keine Funktion in der Bibliothek finden, um diese Ausgangspins zu aktivieren, und standardmäßig scheinen sie nicht aktiv zu sein.
Installation und Betriebsbedingungen
Der Sensor benötigt eine gute Positionierung, um optimale Leistung zu erzielen. Für die Sturzerkennung wird eine Deckenmontage empfohlen. Der Radarstrahl bildet einen dreidimensionalen Abdeckungsbereich, und Hindernisse oder bewegte Objekte können die Signalqualität beeinträchtigen.
Die Genauigkeit der Vitalzeichenerkennung hängt von Entfernung, Ausrichtung und Umgebungsstabilität ab. Externe Bewegungsquellen wie Ventilatoren oder Vorhänge können Rauschen im reflektierten Signal verursachen.
Aufgrund der Art der Radarsensorik arbeitet das Modul zuverlässig bei schlechten Lichtverhältnissen oder völliger Dunkelheit. Es ist nicht von Umgebungslicht abhängig und benötigt keine optische Sensorik.
Technische Spezifikation
Die folgende Tabelle fasst die technischen Spezifikationen des mmWave C1001 Sensors zusammen:
| Parameter | Wert / Beschreibung |
|---|---|
| Betriebsfrequenz | 60 GHz mmWave (ca. 61–61,5 GHz) |
| Erkennungstechnologie | FMCW-Radar mit Point-Cloud-Verarbeitung |
| Erfassungsbereich | Bis zu 11 m (Anwesenheit und Bewegung) |
| Sturzerkennungsbereich | Optimiert für Deckenmontage, ~4 m Durchmesser |
| Vitalzeichenerfassungsbereich | ~0,4 m bis 1,5 m (bis zu ~2,5 m für Schlafüberwachung) |
| Sichtfeld | ~100° horizontal und vertikal |
| Erkennungsfähigkeiten | Anwesenheit, Bewegung, Sturzerkennung, Schlafüberwachung |
| Vitalzeichenmessung | Atmung und Herzfrequenz |
| Atemfrequenzbereich | ~10–25 Atemzüge pro Minute |
| Herzfrequenzbereich | ~60–100 bpm |
| Versorgungsspannung | 5 V |
| Betriebsstrom | < 100 mA |
| Sendeleistung | ~6 dBm |
| Kommunikationsschnittstelle | UART (TTL-Pegel) |
| Digitale Ausgangspins | IO1 (Sturzerkennung), IO2 (Anwesenheitserkennung) |
| Logikpegel | 3,3 V |
| Betriebstemperatur | −20 °C bis 60 °C |
| Montagemethode | Decken- oder Wandmontage (Decke bevorzugt für Sturzerkennung) |
| Datenausgabe | Verarbeitete Daten (keine Roh-Radardaten erforderlich) |
| Unterstützte Plattformen | Arduino, ESP32, ESP8266 |
Anschluss des mmWave C1001 Sensors an Arduino
Der Anschluss des mmWave C1001 Sensors an ein Arduino UNO ist einfach. Verbinde zuerst VIN mit 5V des Arduino. Dann verbinde GND mit GND. Schließlich verbinde die UART-Schnittstelle, indem du RX an GPIO 5 und TX an GPIO 4 anschließt. Das Bild unten zeigt die vollständige Verdrahtung:

Zur Übersicht hier eine Tabelle mit den Verbindungen, die du herstellen musst:
| C1001 | Arduino Uno |
|---|---|
| VIN | 5V |
| GND | GND |
| RX | GPIO 5 |
| TX | GPIO 4 |
Anschluss des mmWave C1001 Sensors an ESP32
Der ESP32 hat drei serielle Schnittstellen, und du kannst die Pins und Schnittstelle konfigurieren, die du verwenden möchtest. Hier verbinde ich TX mit GPIO 3 und RX mit GPIO 4. Das müssen wir beim Schreiben des Codes beachten. Schließlich verbinden wir VIN mit 5V und GND mit G. Das Bild unten zeigt die vollständige Verdrahtung:

Beachte, dass du einen ESP32 mit einem 5V-Ausgangspin benötigst und dass du VIN des C1001 mit dem 5V-Pin und nicht mit dem üblichen 3,3V-Pin verbinden musst! Das Bild unten zeigt das Pinout des ESP32-C3 Supermini, den ich hier verwende.

Zur Übersicht hier eine Tabelle mit den Verbindungen, die du herstellen musst.
| C1001 | ESP32-C3 Supermini |
|---|---|
| VIN | 5V |
| GND | G |
| RX | 4 |
| TX | 3 |
Installation der DFRobot_HumanDetection Bibliothek
Bevor wir Code schreiben können, müssen wir die DFRobot_HumanDetection Bibliothek installieren. Um diese Bibliothek zu installieren, gehe zum DFRobot_HumanDetection Repository, klicke auf den grünen „<> Code“ Button und dann auf „Download ZIP“, um die Bibliothek als ZIP-Datei herunterzuladen, wie unten gezeigt:

Erstelle dann einen neuen Arduino Sketch, gehe zu Sketch -> Include Library -> Add .ZIP Library … und installiere die heruntergeladene ZIP-Bibliothek (DFRobot_HumanDetection-master.zip):

Code: Vitalzeichenmessungen
Der folgende Code zeigt, wie man mit dem C1001 Sensor Vitalzeichen wie Herz- und Atemfrequenz misst. Ich habe den Originalcode der basic.ino im GitHub-Repo leicht geändert, indem ich einige Ausgaben entfernt und Unterstützung für Arduino und ESP866 Mikrocontroller zusätzlich zum ESP32 hinzugefügt habe.
// Libraries:
// - DFRobot_HumanDetection V 1.0.0
// https://github.com/DFRobot/DFRobot_HumanDetection
// - ESP32 Core V 3.3.8
#include "DFRobot_HumanDetection.h"
#if defined(ESP8266) || defined(ARDUINO_AVR_UNO)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(4, 5);
DFRobot_HumanDetection hu(&mySerial);
#elif defined(ESP32)
DFRobot_HumanDetection hu(&Serial1);
#else
#error "Unsupported board."
#endif
void setup() {
Serial.begin(115200);
#if defined(ESP32)
Serial1.begin(115200, SERIAL_8N1, 3, 4);
#elif defined(ESP8266) || defined(ARDUINO_AVR_UNO)
mySerial.begin(115200);
#endif
Serial.println("Starting...");
while (hu.begin() != 0) {
Serial.println("init error!!!");
delay(1000);
}
hu.configWorkMode(hu.eSleepMode);
hu.configLEDLight(hu.eHPLed, 1);
// Sensor needs reset after parameters change
hu.sensorRet();
}
void loop() {
Serial.print("Presence : ");
switch (hu.smHumanData(hu.eHumanPresence)) {
case 0:
Serial.println("No"); break;
case 1:
Serial.println("Yes"); break;
default:
Serial.println("Read error");
}
Serial.print("Motion : ");
switch (hu.smHumanData(hu.eHumanMovement)) {
case 0:
Serial.println("None"); break;
case 1:
Serial.println("Still"); break;
case 2:
Serial.println("Active"); break;
default:
Serial.println("Read error");
}
Serial.print("Movement : ");
Serial.println(hu.smHumanData(hu.eHumanMovingRange));
Serial.print("Respiration rate: ");
Serial.println(hu.getBreatheValue());
Serial.print("Heart rate : ");
Serial.println(hu.getHeartRate());
Serial.println("-----------------------");
delay(1000);
}
Imports
Der Code beginnt mit dem Einbinden der benötigten Bibliothek für den Sensor. Die DFRobot_HumanDetection Bibliothek stellt alle Funktionen bereit, die für die Kommunikation mit dem C1001 mmWave Sensor und den Zugriff auf verarbeitete Daten nötig sind.
#include "DFRobot_HumanDetection.h"
Diese Bibliothek abstrahiert das Low-Level UART-Protokoll. Sie ermöglicht die Arbeit mit hochstufigen Funktionen wie Anwesenheitserkennung, Bewegungsstatus und Vitalzeichen.
Boardspezifische serielle Konfiguration
Der Code konfiguriert dann die serielle Schnittstelle abhängig vom Zielboard. Der C1001 Sensor kommuniziert über UART, daher muss ein serieller Port zugewiesen werden.
#if defined(ESP8266) || defined(ARDUINO_AVR_UNO) #include <SoftwareSerial.h> SoftwareSerial mySerial(4, 5); DFRobot_HumanDetection hu(&mySerial); #elif defined(ESP32) DFRobot_HumanDetection hu(&Serial1); #else #error "Unsupported board." #endif
Für Boards wie Arduino Uno oder ESP8266 wird ein softwarebasierter serieller Port auf den Pins 4 und 5 erstellt. Das ist nötig, weil diese Boards oft nur einen Hardware-UART haben.
Für den ESP32 verwendet der Code Serial1, einen Hardware-UART. Das ist zuverlässiger und unterstützt höhere Datenraten.
Das Objekt hu wird als Instanz der Sensor-Klasse erstellt. Es erhält einen Zeiger auf die serielle Schnittstelle, die intern für die Kommunikation mit dem Sensor verwendet wird.
Setup-Funktion
Die setup() Funktion initialisiert die serielle Kommunikation und bereitet den Sensor auf den Betrieb vor.
void setup() {
Serial.begin(115200);
Der Haupt-Seriellport wird mit 115200 Baud gestartet. Dieser wird für Debugging und das Ausgeben von Sensordaten im Serial Monitor verwendet.
#if defined(ESP32)
Serial1.begin(115200, SERIAL_8N1, 3, 4);
Auf dem ESP32 wird der Hardware-UART mit 115200 Baud initialisiert. Die Konfiguration SERIAL_8N1 bedeutet 8 Datenbits, keine Parität und 1 Stoppbit. Die Pins 3 und 4 werden als RX und TX zugewiesen. Für andere Boards wird die Software-Seriellschnittstelle mit der gleichen Baudrate gestartet.
#elif defined(ESP8266) || defined(ARDUINO_AVR_UNO)
mySerial.begin(115200);
#endif
Eine einfache Meldung wird ausgegeben, um anzuzeigen, dass die Initialisierung gestartet wurde:
Serial.println("Starting...");
Die Funktion hu.begin() initialisiert die Kommunikation mit dem Sensor. Sie gibt 0 bei Erfolg zurück. Wenn die Initialisierung fehlschlägt, gibt der Code eine Fehlermeldung aus und versucht es jede Sekunde erneut. Diese Schleife stellt sicher, dass der Sensor bereit ist, bevor es weitergeht:
while (hu.begin() != 0) {
Serial.println("init error!!!");
delay(1000);
}
Sensor-Konfiguration
Nach der Initialisierung wird der Sensor mit Bibliotheksfunktionen konfiguriert. Diese Zeile setzt den Arbeitsmodus des Sensors. Der Modus eSleepMode ist für die Erkennung von stationären Menschen und die Überwachung von Vitalzeichen wie Atmung und Herzfrequenz optimiert.
hu.configWorkMode(hu.eSleepMode);
Diese Funktion steuert die Onboard-LED. Der Parameter eHPLed wählt den LED-Typ, und 1 schaltet sie ein. Das kann beim Debuggen oder als visuelles Feedback nützlich sein.
hu.configLEDLight(hu.eHPLed, 1);
Und diese Funktion setzt den Sensor zurück. Ein Reset ist nach Änderung der Konfigurationsparameter erforderlich, damit diese wirksam werden.
hu.sensorRet();
Loop-Funktion
Die loop() Funktion liest kontinuierlich Daten vom Sensor und gibt sie im Serial Monitor aus.
Zuerst geben wir eine Beschriftung für die Anwesenheitserkennung aus.
void loop() {
Serial.print("Presence : ");
Dann verwenden wir die Funktion smHumanData(), um einen bestimmten Sensordatentyp zu lesen. Der Parameter eHumanPresence wählt die Anwesenheitserkennung.
switch (hu.smHumanData(hu.eHumanPresence)) {
Ein Rückgabewert von 0 bedeutet, dass keine Person erkannt wurde. Ein Wert von 1 bedeutet, dass eine Person anwesend ist. Jeder andere Wert zeigt einen Kommunikations- oder Lese-Fehler an:
case 0:
Serial.println("No"); break;
case 1:
Serial.println("Yes"); break;
default:
Serial.println("Read error");
Bewegungsstatus
Der nächste Abschnitt liest den Bewegungsstatus der erkannten Person. Der Parameter eHumanMovement wählt die Bewegungs-Klassifikation.
Serial.print("Motion : ");
switch (hu.smHumanData(hu.eHumanMovement)) {
Ein Wert von 0 bedeutet, dass keine Bewegung erkannt wird, ein Wert von 1 bedeutet, dass die Person anwesend, aber unbewegt ist, und ein Wert von 2 zeigt aktive Bewegung an.
case 0:
Serial.println("None"); break;
case 1:
Serial.println("Still"); break;
case 2:
Serial.println("Active"); break;
Bewegungsintensität
Der Code gibt dann einen numerischen Wert aus, der die Bewegungsintensität oder -reichweite repräsentiert.
Serial.print("Movement : ");
Serial.println(hu.smHumanData(hu.eHumanMovingRange));
Dieser Wert ist nützlich, um abzuschätzen, wie stark sich die Person im Erfassungsbereich bewegt. Höhere Werte zeigen stärkere oder größere Bewegungen an.
Vitalzeichen
Der Sensor kann auch Atmung und Herzfrequenz messen. Die Funktion getBreatheValue() gibt die Atemfrequenz in Atemzügen pro Minute zurück.
Serial.print("Respiration rate: ");
Serial.println(hu.getBreatheValue());
Und die Funktion getHeartRate() gibt die Herzfrequenz in Schlägen pro Minute zurück. Diese Messungen basieren auf Mikrobewegungen, die vom Radar erkannt werden.
Serial.print("Heart rate : ");
Serial.println(hu.getHeartRate());
Loop-Timing
Am Ende der Schleife wird eine Verzögerung eingefügt, um die Aktualisierungsrate zu steuern.
Serial.println("-----------------------");
delay(1000);
}
Ausgabe-Beispiel
Das folgende Bild zeigt ein Beispiel für die Ausgabe des Codes. Beachte, dass es einige Minuten dauert, bis Messwerte für Atmung und Herzfrequenz erscheinen. Der Sensor benötigt etwas Zeit, um stabile Messwerte zu liefern.

Die kontaktlose Messung von Atmung und Herzfrequenz über eine Distanz von bis zu 1,5 Metern ist beeindruckend. Beachte jedoch, dass die Genauigkeit begrenzt ist. Siehe den Functional Test Report of DFRobot C1001 mmWave Sensor Beitrag für weitere Informationen zu Messbedingungen, Zuverlässigkeit und Genauigkeit.
Code: Sturzerkennung
Der folgende Code zeigt, wie man mit dem C1001 Sensor eine Sturzerkennung durchführt. Wie zuvor ist es eine leicht modifizierte Version des fall.ino Codes im GitHub-Repo der DFRobot_HumanDetection Bibliothek. Er unterstützt Arduino, ESP866 und ESP32 Mikrocontroller.
// Libraries:
// - DFRobot_HumanDetection V 1.0.0
// https://github.com/DFRobot/DFRobot_HumanDetection
// - ESP32 Core V 3.3.8
#include "DFRobot_HumanDetection.h"
#if defined(ESP8266) || defined(ARDUINO_AVR_UNO)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(4, 5);
DFRobot_HumanDetection hu(&mySerial);
#elif defined(ESP32)
DFRobot_HumanDetection hu(&Serial1);
#else
#error "Unsupported board."
#endif
void setup() {
Serial.begin(115200);
#if defined(ESP32)
Serial1.begin(115200, SERIAL_8N1, 3, 4);
#elif defined(ESP8266) || defined(ARDUINO_AVR_UNO)
mySerial.begin(115200);
#endif
Serial.println("Starting...");
while (hu.begin() != 0) {
Serial.println("init error!!!");
delay(1000);
}
hu.configWorkMode(hu.eFallingMode); // Set working mode to fall detection
hu.configLEDLight(hu.eFALLLed, 1); // Set HP LED switch, it will not light up even if the sensor detects a person present when set to 0.
hu.configLEDLight(hu.eHPLed, 1); // Set FALL LED switch, it will not light up even if the sensor detects a person falling when set to 0.
hu.dmInstallHeight(270); // Set installation height, it needs to be set according to the actual height of the surface from the sensor, unit: CM.
hu.dmFallTime(5); // Set fall time, the sensor needs to delay the current set time after detecting a person falling before outputting the detected fall, this can avoid false triggering, unit: seconds.
hu.dmUnmannedTime(1); // Set unattended time, when a person leaves the sensor detection range, the sensor delays a period of time before outputting a no person status, unit: seconds.
hu.dmFallConfig(hu.eResidenceTime, 200); // Set dwell time, when a person remains still within the sensor detection range for more than the set time, the sensor outputs a stationary dwell status. Unit: seconds.
hu.dmFallConfig(hu.eFallSensitivityC, 3); // Set fall sensitivity, range 0~3, the larger the value, the more sensitive.
hu.sensorRet(); // Module reset, must perform sensorRet after setting data.
}
void loop() {
Serial.print("Fallen : ");
switch (hu.getFallData(hu.eFallState)) {
case 0:
Serial.println("No"); break;
case 1:
Serial.println("Yes"); break;
default:
Serial.println("Read error");
}
Serial.print("Stationary: ");
switch (hu.getFallData(hu.estaticResidencyState)) {
case 0:
Serial.println("No"); break;
case 1:
Serial.println("Yes"); break;
default:
Serial.println("Read error");
}
Serial.println("-----------------");
delay(1000);
}
Imports und Objekterstellung
Das Einbinden der Bibliothek und die Objekterstellung sind identisch zum vorherigen Beispiel. Die gleiche DFRobot_HumanDetection Bibliothek wird verwendet, und das Sensorobjekt hu wird je nach Board mit einer Hardware- oder Software-Seriellschnittstelle initialisiert.
Die UART-Konfiguration und Kommunikationsvorbereitung folgen der gleichen Struktur wie zuvor. Details zur seriellen Initialisierung und Objekterstellung findest du in der vorherigen Erklärung.
Setup-Funktion
Die Initialisierungssequenz in setup() ist ebenfalls gleich. Die seriellen Schnittstellen werden gestartet, und der Sensor wird mit hu.begin() initialisiert. Die Schleife, die die Initialisierung wiederholt, sorgt für stabile Kommunikation vor dem Fortfahren.
Der Unterschied in diesem Beispiel beginnt mit der Sensor-Konfiguration. Der Sensor wird jetzt explizit für die Sturzerkennung konfiguriert.
Konfiguration des Sturzerkennungsmodus
Der Arbeitsmodus wird auf einen speziellen Sturzerkennungsmodus umgestellt.
hu.configWorkMode(hu.eFallingMode);
Dies schaltet die interne Firmware auf Sturzerkennungsalgorithmen um, anstatt allgemeine Anwesenheits- oder Schlafüberwachung zu verwenden. Der Sensor konzentriert sich nun auf Haltungsänderungen und plötzliche Bewegungen gefolgt von Bewegungsstillstand.
LED-Konfiguration
Zwei LED-Anzeigen werden für visuelles Feedback konfiguriert.
hu.configLEDLight(hu.eFALLLed, 1); hu.configLEDLight(hu.eHPLed, 1);
Die eFALLLed steuert die LED, die ein erfasstes Sturzergebnis anzeigt. Die eHPLed steuert die Anwesenheits-LED. Das Setzen beider auf 1 aktiviert sie.
Diese LEDs werden von der internen Erkennungslogik gesteuert und können beim Testen und Kalibrieren helfen.
Installationshöhe
Die Installationshöhe ist ein kritischer Parameter für eine genaue Sturzerkennung. Der folgende Funktionsaufruf setzt die Montagehöhe des Sensors auf 270 cm. Der Wert muss der tatsächlichen Installationshöhe entsprechen, da die Radarverarbeitung von der Geometrie abhängt.
hu.dmInstallHeight(270);
Falsche Höhenwerte können zu ungenauer Positionsbestimmung und Fehlalarmen führen.
Sturzerkennungs-Timing
Der Sensor enthält eine konfigurierbare Verzögerung, bevor ein Sturzergebnis bestätigt wird. Der folgende Funktionsaufruf setzt eine Verzögerung von 5 Sekunden. Nach der Erkennung eines möglichen Sturzes wartet der Sensor diese Zeit, bevor er ihn als gültigen Sturz meldet.
hu.dmFallTime(5);
Dies hilft, kurze oder unkritische Bewegungen herauszufiltern, die sonst Fehlalarme auslösen könnten.
Verzögerung bei Abwesenheitserkennung
Der Sensor verzögert auch die Meldung, wenn keine Person anwesend ist. Die folgende Funktion setzt eine Verzögerung von 1 Sekunde, bevor in den Zustand „keine Person“ gewechselt wird.
hu.dmUnmannedTime(1);
Dies verhindert schnelles Umschalten, wenn eine Person kurz den Erfassungsbereich verlässt oder sich am Rand bewegt.
Erkennung von längerem Stillstand
Der Sensor kann erkennen, wenn eine Person längere Zeit unbewegt bleibt. Der folgende Funktionsaufruf setzt die Verweilzeit auf 200 Sekunden.
hu.dmFallConfig(hu.eResidenceTime, 200);
Wenn eine Person länger als diese Zeit im Erfassungsbereich regungslos bleibt, meldet der Sensor einen stationären Zustand.
Diese Funktion ist in Sturzerkennungsszenarien nützlich, da eine nach einem Sturz regungslose Person erkannt werden kann.
Sturzerkennungsempfindlichkeit
Die Empfindlichkeit des Sturzerkennungsalgorithmus kann angepasst werden. Hier wird die Empfindlichkeit auf Stufe 3 gesetzt, was der höchste Wert ist.
hu.dmFallConfig(hu.eFallSensitivityC, 3);
Eine höhere Empfindlichkeit erhöht die Wahrscheinlichkeit, Stürze zu erkennen, kann aber auch Fehlalarme erhöhen. Niedrigere Werte reduzieren die Empfindlichkeit und erfordern ausgeprägtere Bewegungsänderungen.
Anwenden der Konfiguration
Nachdem alle Parameter gesetzt sind, wird der Sensor zurückgesetzt.
hu.sensorRet();
Wie zuvor erklärt, ist dieser Schritt erforderlich, damit die neue Konfiguration wirksam wird. Der Sensor startet mit den aktualisierten Parametern neu.
Loop-Funktion
Die Schleife liest kontinuierlich sturzbezogene Daten vom Sensor. Im Gegensatz zum vorherigen Beispiel verwendet dieser Code getFallData() statt smHumanData().
Sturzstatus-Erkennung
Die Funktion getFallData() ruft verarbeitete Sturzerkennungsergebnisse ab. Der Parameter eFallState wählt den Sturzstatus:
Serial.print("Fallen : ");
switch (hu.getFallData(hu.eFallState)) {
Ein Wert von 0 bedeutet, dass kein Sturz erkannt wurde, und ein Wert von 1 zeigt an, dass ein Sturzergebnis vom Sensor bestätigt wurde:
case 0:
Serial.println("No"); break;
case 1:
Serial.println("Yes"); break;
Stationärer Zustand
Die estaticResidencyState Konstante wird verwendet, um den stationären Verweilstatus abzurufen:
Serial.print("Stationary: ");
switch (hu.getFallData(hu.estaticResidencyState)) {
Ein Wert von 1 bedeutet, dass eine Person länger als die konfigurierte Verweilzeit unbewegt geblieben ist. Dies kann auf eine kritische Situation hinweisen, besonders in Kombination mit einem erkannten Sturz.
case 0:
Serial.println("No"); break;
case 1:
Serial.println("Yes"); break;
Loop-Timing
Die Schleife endet mit einer Verzögerung und einem Trenner zur besseren Lesbarkeit.
Serial.println("-----------------");
delay(1000);
Code: Schlafüberwachung
Im letzten Codebeispiel führen wir eine Schlafüberwachung mit dem C1001 Sensor durch. Der Code basiert auf dem sleep.ino Beispiel in der DFRobot_HumanDetection Bibliothek. Ich habe nur Unterstützung für Arduino und ESP866 Mikrocontroller hinzugefügt.
// Libraries:
// - DFRobot_HumanDetection V 1.0.0
// https://github.com/DFRobot/DFRobot_HumanDetection
// - ESP32 Core V 3.3.8
#include "DFRobot_HumanDetection.h"
#if defined(ESP8266) || defined(ARDUINO_AVR_UNO)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(4, 5);
DFRobot_HumanDetection hu(&mySerial);
#elif defined(ESP32)
DFRobot_HumanDetection hu(&Serial1);
#else
#error "Unsupported board."
#endif
void setup() {
Serial.begin(115200);
#if defined(ESP32)
Serial1.begin(115200, SERIAL_8N1, 3, 4);
#elif defined(ESP8266) || defined(ARDUINO_AVR_UNO)
mySerial.begin(115200);
#endif
Serial.println("Starting...");
while (hu.begin() != 0) {
Serial.println("init error!!!");
delay(1000);
}
hu.configWorkMode(hu.eSleepMode);
hu.configLEDLight(hu.eHPLed, 1);
// Sensor needs reset after parameters change
hu.sensorRet();
}
void loop() {
Serial.print("Bed entry status:");
switch (hu.smSleepData(hu.eInOrNotInBed)) {
case 0:
Serial.println("Out of bed"); break;
case 1:
Serial.println("In bed"); break;
default:
Serial.println("Read error");
}
Serial.print("Sleep status:");
switch (hu.smSleepData(hu.eSleepState)) {
case 0:
Serial.println("Deep sleep"); break;
case 1:
Serial.println("Light sleep"); break;
case 2:
Serial.println("Awake"); break;
case 3:
Serial.println("None"); break;
default:
Serial.println("Read error");
}
Serial.print("Awake duration: ");
Serial.println(hu.smSleepData(hu.eWakeDuration));
Serial.print("Deep sleep duration: ");
Serial.println(hu.smSleepData(hu.eDeepSleepDuration));
Serial.print("Sleep quality score: ");
Serial.println(hu.smSleepData(hu.eSleepQuality));
sSleepComposite comprehensiveState = hu.getSleepComposite();
Serial.println("Comprehensive sleep status:{");
Serial.print("\tExistence status: ");
switch (comprehensiveState.presence) {
case 0:
Serial.println("No one"); break;
case 1:
Serial.println("Someone is present"); break;
default:
Serial.println("Read error");
}
Serial.print("\tSleep status:");
switch (comprehensiveState.sleepState) {
case 0:
Serial.println("Deep sleep"); break;
case 1:
Serial.println("Light sleep"); break;
case 2:
Serial.println("Awake"); break;
case 3:
Serial.println("None"); break;
default:
Serial.println("Read error");
}
Serial.print("\tAverage respiration rate: ");
Serial.println(comprehensiveState.averageRespiration);
Serial.print("\tAverage heart rate: ");
Serial.println(comprehensiveState.averageHeartbeat);
Serial.print("\tNumber of turns: ");
Serial.println(comprehensiveState.turnoverNumber);
Serial.print("\tProportion of significant body movement: ");
Serial.println(comprehensiveState.largeBodyMove);
Serial.print("\tProportion of minor body movement: ");
Serial.println(comprehensiveState.minorBodyMove);
Serial.print("\tNumber of apneas: ");
Serial.println(comprehensiveState.apneaEvents);
Serial.println("}");
Serial.print("Sleep abnormalities:");
switch (hu.smSleepData(hu.eSleepDisturbances)) {
case 0:
Serial.println("Sleep duration less than 4 hours"); break;
case 1:
Serial.println("Sleep duration more than 12 hours"); break;
case 2:
Serial.println("Long time abnormal absence of person"); break;
case 3:
Serial.println("None"); break;
default:
Serial.println("Read error");
}
sSleepStatistics statistics = hu.getSleepStatistics(); // Get sleep statistics, for whole night
Serial.print("\tSleep quality score: ");
Serial.println(statistics.sleepQualityScore);
Serial.print("\tProportion of awake time: ");
Serial.println(statistics.sleepTime);
Serial.print("\tProportion of light sleep time: ");
Serial.println(statistics.wakeDuration);
Serial.print("\tProportion of light sleep time: ");
Serial.println(statistics.shallowSleepPercentage);
Serial.print("\tProportion of deep sleep time: ");
Serial.println(statistics.deepSleepPercentage);
Serial.print("\tOut of bed duration: ");
Serial.println(statistics.timeOutOfBed);
Serial.print("\tNumber of times out of bed: ");
Serial.println(statistics.exitCount);
Serial.print("\tNumber of turns: ");
Serial.println(statistics.turnOverCount);
Serial.print("\tAverage respiration: ");
Serial.println(statistics.averageRespiration);
Serial.print("\tAverage heartbeat: ");
Serial.println(statistics.averageHeartbeat);
Serial.println("}");
Serial.print("Sleep quality rating: ");
switch (hu.smSleepData(hu.eSleepQualityRating)) {
case 0:
Serial.println("None"); break;
case 1:
Serial.println("Good sleep quality"); break;
case 2:
Serial.println("Average sleep quality"); break;
case 3:
Serial.println("Poor sleep quality"); break;
default:
Serial.println("Read error");
}
Serial.print("Abnormal struggle status: ");
switch (hu.smSleepData(hu.eAbnormalStruggle)) {
case 0:
Serial.println("None"); break;
case 1:
Serial.println("Normal status"); break;
case 2:
Serial.println("Abnormal struggle status"); break;
default:
Serial.println("Read error");
}
Serial.println("-----------------------------------");
delay(1000);
}
Imports und Objekterstellung
Das Einbinden der Bibliothek und die Objekterstellung sind identisch zu den vorherigen Beispielen. Die gleiche DFRobot_HumanDetection Klasse wird verwendet, und der Sensor ist über eine UART-Schnittstelle verbunden. Das Objekt hu übernimmt die gesamte Kommunikation und Datenverarbeitung.
Die serielle Konfiguration für ESP32, ESP8266 und Arduino Uno bleibt unverändert. Siehe die vorherigen Erklärungen für Details zur Initialisierung der UART-Schnittstelle und warum Hardware-Serial auf dem ESP32 bevorzugt wird.
Setup-Funktion
Die Initialisierungssequenz in setup() folgt dem gleichen Muster wie zuvor. Die seriellen Ports werden gestartet, und der Sensor wird mit hu.begin() initialisiert, mit einer Wiederholungsschleife, um stabile Kommunikation sicherzustellen.
Der wesentliche Unterschied ist der gewählte Arbeitsmodus. In diesem Beispiel wird der Sensor für die Schlafüberwachung statt für die Sturzerkennung konfiguriert.
hu.configWorkMode(hu.eSleepMode);
Dieser Modus aktiviert Algorithmen zur Erkennung von Anwesenheit im Bett, Schlafphasen und Vitalzeichen wie Atmung und Herzfrequenz über die Zeit.
hu.configLEDLight(hu.eHPLed, 1);
Die Anwesenheits-LED ist aktiviert, die visuelles Feedback gibt, wenn eine Person erkannt wird.
hu.sensorRet();
Wie zuvor muss der Sensor nach Konfigurationsänderungen zurückgesetzt werden, damit die neuen Parameter wirksam werden.
Überblick Loop-Funktion
Die loop() Funktion liest kontinuierlich schlafbezogene Daten vom Sensor. Im Gegensatz zu den vorherigen Beispielen verwendet dieser Code smSleepData() und zusätzliche zusammengesetzte Datenstrukturen, um erweiterte Metriken abzurufen.
Die Ausgabe ist komplexer, da der Sensor Daten über die Zeit aggregiert und analysiert.
Bett-Eintrittserkennung
Der erste Abschnitt prüft, ob eine Person im Bett ist.
Serial.print("Bed entry status:");
switch (hu.smSleepData(hu.eInOrNotInBed)) {
Die Funktion smSleepData() funktioniert ähnlich wie smHumanData(), greift aber auf schlafbezogene Parameter zu.
case 0:
Serial.println("Out of bed"); break;
case 1:
Serial.println("In bed"); break;
Ein Wert von 1 zeigt an, dass eine Person im Bettbereich erkannt wurde. Dies wird durch Anwesenheitserkennung kombiniert mit Positionsanalyse bestimmt.
Schlafzustandserkennung
Der nächste Abschnitt liest die aktuelle Schlafphase aus.
Serial.print("Sleep status:");
switch (hu.smSleepData(hu.eSleepState)) {
Der Sensor klassifiziert den Schlaf in mehrere Phasen.
case 0:
Serial.println("Deep sleep"); break;
case 1:
Serial.println("Light sleep"); break;
case 2:
Serial.println("Awake"); break;
case 3:
Serial.println("None"); break;
Diese Zustände werden aus Bewegungsmustern und Variationen der Vitalzeichen abgeleitet. Tiefschlaf ist durch minimale Bewegung und stabile Atmung gekennzeichnet, während Wachzustände mehr Aktivität zeigen.
Schlafzeit- und Qualitätsmetriken
Der Sensor liefert Dauer- und Qualitätsmetriken als numerische Werte.
Mit der eWakeDuration Konstante gibt die Funktion an, wie lange die Person während des Überwachungszeitraums wach war.
Serial.print("Awake duration: ");
Serial.println(hu.smSleepData(hu.eWakeDuration));
Und mit der eDeepSleepDuration Konstante wird die Dauer des Tiefschlafs verfolgt.
Serial.print("Deep sleep duration: ");
Serial.println(hu.smSleepData(hu.eDeepSleepDuration));
Der Schlafqualitätswert ist eine berechnete Metrik basierend auf Bewegung, Atmungsstabilität und Schlafphasen.
Serial.print("Sleep quality score: ");
Serial.println(hu.smSleepData(hu.eSleepQuality));
Zusammengesetzte Schlafdaten
Anschließend ruft der Code einen strukturierten Datensatz mit mehreren Parametern ab.
sSleepComposite comprehensiveState = hu.getSleepComposite();
Diese Struktur kombiniert mehrere Messwerte in einem Objekt. Sie bietet einen Schnappschuss des aktuellen Schlafzustands. Der presence Wert zeigt an, ob eine Person anwesend ist:
switch (comprehensiveState.presence) {
Als nächstes haben wir den sleepState Wert, der die Schlafphasenklassifikation wiederholt:
switch (comprehensiveState.sleepState) {
Der averageRespiration Wert enthält die durchschnittliche Atemfrequenz, berechnet über ein Zeitfenster:
Serial.print("\tAverage respiration rate: ");
Serial.println(comprehensiveState.averageRespiration);
Während der averageHeartbeat Wert die durchschnittliche Herzfrequenz enthält:
Serial.print("\tAverage heart rate: ");
Serial.println(comprehensiveState.averageHeartbeat);
Der turnoverNumber Wert zählt, wie oft die Person ihre Position im Schlaf gewechselt hat:
Serial.print("\tNumber of turns: ");
Serial.println(comprehensiveState.turnoverNumber);
Und der largeBodyMove Wert repräsentiert den Anteil großer Bewegungen:
Serial.print("\tProportion of significant body movement: ");
Serial.println(comprehensiveState.largeBodyMove);
während der minorBodyMove Wert kleinere Bewegungen wie leichte Anpassungen anzeigt:
Serial.print("\tProportion of minor body movement: ");
Serial.println(comprehensiveState.minorBodyMove);
Schließlich haben wir apneaEvents, der erkannte Apnoe-Ereignisse (Atempausen) zählt:
Serial.print("\tNumber of apneas: ");
Serial.println(comprehensiveState.apneaEvents);
Schlafanomalien
Der Code prüft auf abnormale Schlafzustände.
Serial.print("Sleep abnormalities:");
switch (hu.smSleepData(hu.eSleepDisturbances)) {
Der Sensor meldet vordefinierte abnormale Zustände.
case 0:
Serial.println("Sleep duration less than 4 hours"); break;
case 1:
Serial.println("Sleep duration more than 12 hours"); break;
case 2:
Serial.println("Long time abnormal absence of person"); break;
case 3:
Serial.println("None"); break;
Diese Zustände basieren auf im Firmware definierten Schwellenwerten.
Schlafstatistiken
Der Code ruft Langzeitstatistiken für den gesamten Überwachungszeitraum ab. Die folgende Struktur liefert aggregierte Daten, typischerweise über eine ganze Nacht.
sSleepStatistics statistics = hu.getSleepStatistics();
Zum Beispiel ist dies der Gesamtwert für die Schlafqualität.
Serial.print("\tSleep quality score: ");
Serial.println(statistics.sleepQualityScore);
Und dieser Wert zeigt den Anteil der Wachzeit.
Serial.print("\tProportion of awake time: ");
Serial.println(statistics.sleepTime);
Als nächstes haben wir einen Indikator für den Prozentsatz der Tiefschlafzeit.
Serial.print("\tProportion of light sleep time: ");
Serial.println(statistics.shallowSleepPercentage);
Und dieser Wert zeigt den Prozentsatz des Tiefschlafs an.
Serial.print("\tProportion of deep sleep time: ");
Serial.println(statistics.deepSleepPercentage);
„timeOutOfBed“ verfolgt, wie lange die Person außer Bett war.
Serial.print("\tOut of bed duration: ");
Serial.println(statistics.timeOutOfBed);
und „exitCount“ zählt, wie oft die Person das Bett verlassen hat.
Serial.print("\tNumber of times out of bed: ");
Serial.println(statistics.exitCount);
Wir erhalten auch Messwerte für die Gesamtzahl der Körperdrehungen
Serial.print("\tNumber of turns: ");
Serial.println(statistics.turnOverCount);
die durchschnittliche Atemfrequenz über den Überwachungszeitraum
Serial.print("\tAverage respiration: ");
Serial.println(statistics.averageRespiration);
und die durchschnittliche Herzfrequenz:
Serial.print("\tAverage heartbeat: ");
Serial.println(statistics.averageHeartbeat);
Schlafqualitätsbewertung
Der Sensor liefert eine vereinfachte Klassifikation der Schlafqualität.
Serial.print("Sleep quality rating: ");
switch (hu.smSleepData(hu.eSleepQualityRating)) {
case 1:
Serial.println("Good sleep quality"); break;
case 2:
Serial.println("Average sleep quality"); break;
case 3:
Serial.println("Poor sleep quality"); break;
Diese Bewertung basiert auf den detaillierten Metriken und bietet ein leicht verständliches Ergebnis.
Erkennung abnormaler Bewegungen
Der letzte Abschnitt erkennt ungewöhnliche Bewegungsmuster.
Serial.print("Abnormal struggle status: ");
switch (hu.smSleepData(hu.eAbnormalStruggle)) {
case 0:
Serial.println("None"); break;
case 1:
Serial.println("Normal status"); break;
case 2:
Serial.println("Abnormal struggle status"); break;
Diese Funktion identifiziert unregelmäßige oder intensive Bewegungen, die auf Unwohlsein oder Stress während des Schlafs hinweisen können.
Loop-Timing
Die Schleife endet mit einer Verzögerung und einem Trenner, ähnlich wie bei den vorherigen Beispielen. Das Ein-Sekunden-Intervall sorgt für eine gleichmäßige Aktualisierungsrate und ermöglicht dem Sensor, zwischen den Messungen aussagekräftige Daten zu sammeln.
Fazit
In diesem Tutorial hast du gelernt, wie du den mmWave C1001 Sensor an ein Arduino oder ESP32 anschließt, um Vitalzeichen zu messen, Stürze zu erkennen und die Schlafqualität zu überwachen. Beachte, dass der C1001 Sensor kein zertifiziertes Medizinprodukt ist und nicht für medizinische Diagnosen oder Behandlungen verwendet werden sollte!
Für weitere Informationen zur Installation des Sensors, seiner Reichweite und Genauigkeit siehe den Functional Test Report of DFRobot C1001 mmWave Sensor Artikel. Schau dir auch die Wiki Seite und den Code repo an.
Wenn du nur Anwesenheitserkennung benötigst, sieh dir unsere Tutorials für die mmWave C4001 und mmWave C4002 Sensoren an. Diese sind ebenfalls Radarsensoren, haben aber keine integrierten Funktionen für Sturzerkennung oder Schlafüberwachung.
Wenn du Fragen hast, hinterlasse sie gerne im Kommentarbereich.
Viel Spaß beim Tüfteln ; )

