Der mmWave C4002 Human Presence Sensor ist ein radarbasierendes Modul, das für eine präzise Menschenerkennung entwickelt wurde. Er nutzt 24 GHz FMCW Millimeterwellen-Technologie, um sowohl Bewegungen als auch Mikrobewegungen wie Atmung zu erfassen, wodurch Personen auch dann erkannt werden können, wenn sie völlig stillstehen.
Im Gegensatz zu herkömmlichen PIR Sensoren bietet dieses Modul eine Präsenzdetektion. Es kann zwischen keinem Ziel, sich bewegenden Zielen und stationärer menschlicher Präsenz in einer Reichweite von bis zu 10 Metern unterscheiden. In diesem Tutorial lernst du, wie du den mmWave C4002 Sensor an ein Arduino oder ESP32 anschließt, um Präsenz- und Bewegungserkennung durchzuführen.
Benötigte Teile
Den mmWave C4002 Sensor kannst du bei DFRobot erwerben. Außerdem benötigst du ein Arduino oder ein 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 für die Verkabelung hilfreich.

mmWave C4002 Radar 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 C4002 Sensors
Der mmWave C4002 basiert auf 24 GHz FMCW (Frequency Modulated Continuous Wave) Radar-Technologie. Er sendet kontinuierlich elektromagnetische Wellen im Bereich von 24,0 GHz bis 24,25 GHz aus und misst die von Objekten in der Umgebung reflektierten Signale. Das Bild unten zeigt die Vorder- und Rückseite des Moduls. An der Vorderseite sind die zwei goldfarbenen Radarantennen zu sehen.

Auf der Vorderseite befinden sich außerdem eine LED mit der Bezeichnung „RUN“ und eine LED mit der Bezeichnung „OUT“. Die grüne RUN-LED blinkt, wenn der Sensor aktiv detektiert, und die blaue OUT-LED leuchtet, wenn eine Person erkannt wird.
Die FMCW-Modulationstechnik ermöglicht es dem Sensor, Entfernung, Geschwindigkeit und Bewegungsmerkmale aus dem reflektierten Signal zu extrahieren. Der Sensor kann sehr kleine Positionsänderungen erkennen, wie z. B. die Brustbewegung beim Atmen. Dadurch ist die Erkennung von stationären Personen möglich, was mit passiven Infrarotsensoren nicht machbar ist.
Das Radar arbeitet unabhängig von Umgebungslicht und Temperatur. Es wird nicht durch Umweltbedingungen wie Dunkelheit, Staub oder Temperaturschwankungen beeinflusst. Dies verbessert die Stabilität in Smart-Home-Anwendungen im Innenbereich.
Erkennungsfähigkeiten und Signalverarbeitung
Der C4002 unterstützt eine Multi-Mode-Menschenerkennung, einschließlich Bewegung, Mikrobewegung und vollständiger Stillstand. Er kann den Zielzustand in Kategorien wie kein Ziel, sich bewegendes Ziel und stationäre Präsenz einordnen.
Die maximale Erkennungsreichweite beträgt bis zu 11 Meter für Bewegung und 10 Meter für stationäre Präsenz. Der Erkennungsbereich umfasst je nach Installationsbedingungen etwa eine Fläche von 10 × 10 Metern.
Der Sensor verwendet interne Signalverarbeitung, um zusätzliche Parameter zu extrahieren. Er kann Entfernung zum Ziel, Signalenergie, Bewegungsgeschwindigkeit und -richtung melden. Diese Werte werden aus Doppler-Verschiebungen und Frequenzänderungen im reflektierten Radarsignal abgeleitet.
Ein adaptiver Hintergrundfilterungsalgorithmus ist implementiert, um Fehlalarme zu reduzieren. Der Sensor lernt die statische Umgebung und unterdrückt Störungen von nicht-menschlichen Quellen wie bewegten Vorhängen oder Luftströmungen.
Sichtfeld und räumliche Abdeckung
Das Modul bietet einen weiten Erkennungswinkel von 120° horizontal und vertikal. Dadurch kann ein einzelner Sensor große Innenbereiche mit minimalen toten Winkeln abdecken.
Die Erkennungsreichweite kann softwareseitig konfiguriert werden. Dies ermöglicht es Entwicklern, die Erfassungsdistanz auf eine bestimmte Zone innerhalb eines Raums zu begrenzen. So werden unerwünschte Erkennungen durch Wände oder in angrenzenden Bereichen vermieden.
Die Montageposition beeinflusst die effektive Abdeckung. Die Deckenmontage bietet ein Erkennungsmuster von oben nach unten, während die Wandmontage einen nach vorne gerichteten Erkennungskegel erzeugt.
Elektrische Eigenschaften und Schnittstellen
Der Sensor arbeitet mit einer Versorgungsspannung von 3,6 V bis 5,5 V und ist somit kompatibel mit gängigen Mikrocontroller-Plattformen wie Arduino und ESP32.
Er bietet zwei Hauptausgangsschnittstellen. Eine UART-Schnittstelle mit 9600 Baud wird für detaillierte Datenkommunikation verwendet, einschließlich vollständiger Radarmessungen und Konfigurationsbefehle. Ein digitaler OUT-Pin kann als einfacher Präsenzsignal-Ausgang für Anwendungen mit geringer Komplexität konfiguriert werden.
Das Bild unten zeigt das Pinout des Moduls mit Pins für Stromversorgung (VIN), Masse (GND), serielles Senden (TX), serielles Empfangen (RX) und das digitale Ausgangssignal (OUT):

Zusätzliche Sensor- und Umweltfunktionen
Der C4002 enthält einen Lichtsensor mit einem Messbereich von 0 bis 50 Lux. Dies ermöglicht eine kombinierte Präsenz- und Umgebungslicht-Erkennung in einem einzigen Modul.
Das Modul unterstützt eine automatische Umweltkalibrierung. Während des Betriebs kann es sich an die Umgebung anpassen, um die Erkennungsgenauigkeit zu verbessern. Dies reduziert den manuellen Abstimmungsaufwand bei der Inbetriebnahme.
Technische Spezifikation
Die folgende Tabelle fasst die technischen Spezifikationen des mmWave C4004 Sensors zusammen.
| Parameter | Spezifikation |
|---|---|
| Betriebsspannung | 3,6 V bis 5,5 V |
| Betriebsfrequenz | 24,0 GHz bis 24,25 GHz |
| Erkennungsfähigkeit | Bewegung, Mikrobewegung und stationäre Menschenerkennung |
| Maximale Erkennungsdistanz | 11 m (Bewegung), 10 m (stationäre Präsenz) |
| Erkennungswinkel | 120° × 120° |
| Erkennungsbereich | Bis zu 10 m × 10 m Abdeckung |
| Ausgangsschnittstellen | UART und konfigurierbarer digitaler OUT-Pin |
| Lichtmessbereich | 0 bis 50 Lux |
| Betriebstemperatur | −20 °C bis 85 °C |
| Modulabmessungen | 22 mm × 26 mm |
Verwendung des mmWave C4002 Sensors ohne Mikrocontroller
Du benötigst einen Mikrocontroller (oder Computer), um spezifische Einstellungen des mmWave C4002 Sensors zu programmieren. Zum Beispiel kannst du die Erkennungsdistanz oder die Empfindlichkeit einstellen. Nach der Konfiguration kannst du den C4002 jedoch auch ohne Mikrocontroller verwenden.
Das folgende Schaltbild zeigt, wie du eine LED anschließt, die aufleuchtet, wenn der Sensor eine Person erkennt. Du musst lediglich Strom (5V) an die VIN- und GND-Pins anschließen und dann eine LED mit einem Widerstand an den OUT-Pin verbinden:

Für die meisten praktischen Anwendungen möchtest du wahrscheinlich ein Relais statt einer LED anschließen, um ein Gerät mit höherer Spannung oder Strom zu schalten. Das ist möglich, aber du benötigst ein Relay Module mit integriertem Verstärkerschaltkreis, da der OUT-Pin die Relaisspule nicht direkt treiben kann. Unten ist ein Beispielschaltplan:

Weitere Informationen zu Relaismodulen findest du im How To Use A Relay With Arduino, Interfacing a Relay Module With ESP32 und im Control AC devices with Solid State Relay Tutorial.
In den nächsten Abschnitten zeige ich dir, wie du den mmWave C4002 Sensor an ein Arduino oder ESP32 anschließt.
Anschluss des mmWave C4002 Sensors an Arduino
Den mmWave C4002 Sensor an ein Arduino UNO anzuschließen ist einfach. Verbinde zuerst VIN mit 5V des Arduino. Dann verbinde GND mit GND. Schließlich verbinden wir die UART-Schnittstelle, indem RX mit GPIO 5 und TX mit GPIO 4 verbunden wird. Das Bild unten zeigt die vollständige Verkabelung:

Zur Übersicht hier eine Tabelle mit den Verbindungen, die du herstellen musst:
| C4002 | Arduino Uno |
|---|---|
| VIN | 5V |
| GND | GND |
| RX | GPIO 5 |
| TX | GPIO 4 |
Du benötigst nicht einmal ein Breadboard, um den Sensor an ein Arduino UNO anzuschließen. Vier Dupont-Kabel reichen aus. Das Foto unten zeigt meine Verkabelung:

Anschluss des mmWave C4002 Sensors an ESP32
Der ESP32 verfügt über drei serielle Schnittstellen, und du kannst die Pins und Schnittstellen frei konfigurieren. 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 Verkabelung:

Beachte, dass du einen ESP32 mit einem 5V-Ausgangspin benötigst und dass du VIN des C4002 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.

Denke daran, dass der C4002 3,6V … 5V an VIN benötigt und 3,3V daher nicht ausreichen. Zur Übersicht hier eine Tabelle mit den Verbindungen, die du herstellen musst.
| C4002 | ESP32-C3 Supermini |
|---|---|
| VIN | 5V |
| GND | G |
| RX | 4 |
| TX | 3 |
Installation der DFRobot_C4002 Bibliothek
Bevor wir Code schreiben können, müssen wir die DFRobot_C4002 Bibliothek installieren. Um diese Bibliothek zu installieren, gehe zum DFRobot_C4002 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_C4002-master.zip):

Code: Kalibrierung des C4002
Der C4002 benötigt einen Kalibrierungsprozess, der eine Basislinie der Umgebung erstellt, damit statische Objekte wie Wände oder Möbel nicht fälschlicherweise als Ziele erkannt werden. Da der Sensor auf Radarreflexionen basiert, muss er zunächst lernen, wie „normal“ in einem bestimmten Raum aussieht, bevor er zuverlässig menschliche Präsenz oder Bewegung erkennen kann.
Die Kalibrierung wird mit der c4002.startEnvCalibration(delay, duration) Funktion gestartet, wobei die Verzögerung Zeit gibt, den Bereich zu räumen, und die Dauer definiert, wie lange der Sensor die Umgebung misst. Während dieser Zeit zeichnet der Sensor Hintergrundreflexionen auf und erstellt ein internes Modell. Es ist wichtig, dass keine Personen anwesend sind, da Bewegung oder sogar stationäre Präsenz die Genauigkeit negativ beeinflussen können.
Nach Abschluss der Kalibrierung vergleicht der Sensor Echtzeitdaten mit dieser Basislinie und meldet nur bedeutende Änderungen. Dies ermöglicht eine präzise Erkennung von Bewegung und statischer Präsenz. Für beste Ergebnisse sollte die Kalibrierung wiederholt werden, wenn sich die Umgebung wesentlich ändert. Der folgende Code führt diesen Kalibrierungsprozess aus:
// Libraries:
// - DFRobot_C4002 V 1.0.0
// https://github.com/DFRobot/DFRobot_C4002
// - ESP32 Core V 3.3.8
#include "DFRobot_C4002.h"
#if defined(ESP8266) || defined(ARDUINO_AVR_UNO)
SoftwareSerial mySerial(4, 5);
DFRobot_C4002 c4002(&mySerial, 115200);
#elif defined(ESP32)
DFRobot_C4002 c4002(&Serial1, 115200, 3, 4);
#else
DFRobot_C4002 c4002(&Serial1, 115200);
#endif
void setup() {
Serial.begin(115200);
while (!c4002.begin()) {
Serial.println("Can't find C4002!");
delay(1000);
}
c4002.setRunLedState(eLedOn);
delay(50);
c4002.setOutLedState(eLedOn);
delay(50);
delay(3000);
c4002.setReportPeriod(10);
c4002.startEnvCalibration(10, 30); // Delay time:10s,Calibration time:30s
Serial.println("Start calibration:");
}
void loop() {
sRetResult_t retResult = c4002.getNoteInfo();
if (retResult.noteType == eCalibration) {
Serial.print(retResult.calibCountdown);
Serial.println(" s");
if (retResult.calibCountdown == 0) {
Serial.println("Calibration Complete!");
}
}
delay(10);
}
Imports
Der Sketch beginnt mit dem Einbinden der benötigten Bibliothek für den Sensor. Diese Bibliothek stellt die DFRobot_C4002 Klasse bereit, die die Kommunikation und Steuerung des Sensors abstrahiert.
#include "DFRobot_C4002.h"
Serielle Kommunikation
Der nächste Codeabschnitt konfiguriert, wie der Sensor mit dem Mikrocontroller kommuniziert, abhängig von der verwendeten Plattform. Der Code prüft, für welches Board kompiliert wird, und wählt die passende serielle Schnittstelle.
#if defined(ESP8266) || defined(ARDUINO_AVR_UNO) SoftwareSerial mySerial(4, 5); DFRobot_C4002 c4002(&mySerial, 115200); #elif defined(ESP32) DFRobot_C4002 c4002(&Serial1, 115200, 3, 4); #else DFRobot_C4002 c4002(&Serial1, 115200); #endif
Bei Boards wie Arduino Uno oder ESP8266 sind Hardware-Seriellports begrenzt, daher wird eine SoftwareSerial Instanz auf den Pins 4 (RX) und 5 (TX) erstellt. Diese serielle Schnittstelle wird dann zusammen mit einer Baudrate von 115200 an das DFRobot_C4002 Objekt übergeben.
Beim ESP32 verwendet der Code Serial1, eine Hardware-UART. Zusätzlich werden die Pins 3 und 4 für RX und TX definiert.
Für andere Boards wird die Standard- Serial1 Schnittstelle ohne Pinangabe verwendet, da die Hardwarekonfiguration diese bereits definiert.
Setup-Funktion
Die setup() Funktion ist verantwortlich für die Initialisierung der seriellen Kommunikation und die Vorbereitung des Sensors für den Betrieb.
void setup() {
Serial.begin(115200);
Der serielle Monitor wird mit 115200 Baud gestartet, damit Statusmeldungen zur Fehlerbehebung und Überwachung ausgegeben werden können.
Der nächste Abschnitt stellt sicher, dass der Sensor korrekt verbunden ist und reagiert.
while (!c4002.begin()) {
Serial.println("Can't find C4002!");
delay(1000);
}
Die begin() Funktion versucht, die Kommunikation mit dem Sensor zu initialisieren. Wenn der Sensor nicht erkannt wird, wird jede Sekunde eine Fehlermeldung ausgegeben. Dies blockiert effektiv die Ausführung, bis der Sensor gefunden wird.
Nach erfolgreicher Initialisierung konfiguriert der Code die LEDs auf dem Sensor.
c4002.setRunLedState(eLedOn); delay(50); c4002.setOutLedState(eLedOn); delay(50);
Die setRunLedState() Funktion steuert die interne Lauf-LED, während setOutLedState() die Ausgangs-LED steuert. Beide werden hier eingeschaltet, um visuelles Feedback zu geben, dass der Sensor aktiv ist.
Kurze Verzögerungen sorgen für eine stabile Kommunikation zwischen den Befehlen.
Der Code pausiert dann für einige Sekunden, bevor er fortfährt.
delay(3000);
Als nächstes wird das Meldeintervall konfiguriert.
c4002.setReportPeriod(10);
Die setReportPeriod() Funktion legt fest, wie häufig der Sensor Daten meldet. Hier ist die Periode auf 10 Einheiten gesetzt, was einem Meldezyklus von 10 * 0,1 = 1 Sekunde entspricht. Schließlich wird die Umweltkalibrierung gestartet.
c4002.startEnvCalibration(10, 30); // Delay time:10s,Calibration time:30s
Serial.println("Start calibration:");
}
Die startEnvCalibration() Funktion startet die Kalibrierung mit zwei Parametern. Der erste Parameter gibt eine Verzögerung vor Beginn der Kalibrierung an, der zweite definiert die Dauer des Kalibrierungsprozesses. Hier beginnt die Kalibrierung nach 10 Sekunden und läuft 30 Sekunden.
Loop-Funktion
Die loop() Funktion überwacht kontinuierlich den Status des Sensors, insbesondere den Kalibrierungsprozess.
void loop() {
sRetResult_t retResult = c4002.getNoteInfo();
Die getNoteInfo() Funktion ruft die neuesten Statusinformationen vom Sensor ab. Die zurückgegebene Struktur sRetResult_t enthält verschiedene Felder, die den aktuellen Zustand beschreiben.
Der Code prüft, ob sich der Sensor gerade im Kalibrierungsmodus befindet.
if (retResult.noteType == eCalibration) {
Das noteType Feld zeigt die Art der empfangenen Benachrichtigung an. Wenn es den Wert eCalibration hat, befindet sich der Sensor in der Kalibrierungsphase. Wenn die Kalibrierung läuft, wird die verbleibende Zeit ausgegeben.
Serial.print(retResult.calibCountdown);
Serial.println(" s");
Das calibCountdown Feld enthält die Anzahl der Sekunden bis zum Abschluss der Kalibrierung. Schließlich erkennt der Code, wenn die Kalibrierung beendet ist.
if (retResult.calibCountdown == 0) {
Serial.println("Calibration Complete!");
}
}
delay(10);
}
Wenn der Countdown null erreicht, wird eine Meldung ausgegeben, die das Ende der Kalibrierung anzeigt.
Ausgabe-Beispiel
Das Bild unten zeigt, was im Serial Monitor während des Kalibrierungsprozesses ausgegeben wird. Wie erwähnt, solltest du dich während der Kalibrierung nicht in der Nähe des Sensors aufhalten.

Code: Bewegungserkennung und Präsenz mit C4002
Sobald der Sensor kalibriert ist, kann er für die Erkennung verwendet werden. Das folgende Codebeispiel zeigt, welche Arten von Erkennungen und Messungen der Sensor durchführen kann:
// Libraries:
// - DFRobot_C4002 V 1.0.0
// https://github.com/DFRobot/DFRobot_C4002
// - ESP32 Core V 3.3.8
#include "DFRobot_C4002.h"
#if defined(ESP8266) || defined(ARDUINO_AVR_UNO)
SoftwareSerial mySerial(4, 5);
DFRobot_C4002 c4002(&mySerial, 115200);
#elif defined(ESP32)
DFRobot_C4002 c4002(&Serial1, 115200, 3, 4);
#else
DFRobot_C4002 c4002(&Serial1, 115200);
#endif
void setup() {
Serial.begin(115200);
while (!c4002.begin()) {
Serial.println("Can't find C4002!");
delay(1000);
}
c4002.setRunLedState(eLedOn);
delay(50);
c4002.setOutLedState(eLedOn);
delay(50);
c4002.setOutPinMode(eOutpinMode1); // Motion detected
delay(50);
c4002.setDetectRange(0, 1100); // 0-1100 cm
delay(50);
c4002.setLightThresh(0); //0-50 lux
delay(50);
c4002.setTargetDisappearDelay(1); // 0-65535s
delay(50);
c4002.setReportPeriod(10); // 10 * 0.1s = 1s
delay(50);
}
void loop() {
sRetResult_t retResult = c4002.getNoteInfo();
if (retResult.noteType == eResult) {
Serial.println("---------- RESULTS ------------");
float light = c4002.getLightIntensity();
Serial.print("Light: ");
Serial.print(light);
Serial.println(" lux");
eTargetState_t targetState = c4002.getTargetState();
Serial.print("Target state: ");
if (targetState == eNoTarget) {
Serial.println("No Target");
} else if (targetState == ePresence) {
Serial.println("Static Presence");
} else if (targetState == eMotion) {
Serial.println("Motion");
}
sPresenceTarget_t presenceTarget = c4002.getPresenceTargetInfo();
Serial.print("Presence distance: ");
Serial.print(presenceTarget.distance);
Serial.println(" m");
Serial.print("Presence energy: ");
Serial.println(presenceTarget.energy);
sMotionTarget_t motionTarget = c4002.getMotionTargetInfo();
Serial.print("Motion distance: ");
Serial.print(motionTarget.distance);
Serial.println(" m");
Serial.print("Motion energy: ");
Serial.println(motionTarget.energy);
Serial.print("Motion speed: ");
Serial.print(motionTarget.speed);
Serial.println(" m/s");
Serial.print("Motion direction: ");
if (motionTarget.direction == eAway) {
Serial.println("Away!");
} else if (motionTarget.direction == eNoDirection) {
Serial.println("No Direction!");
} else if (motionTarget.direction == eApproaching) {
Serial.println("Approaching!");
}
}
delay(50);
}
Imports
Der Sketch beginnt mit dem Einbinden der benötigten Sensorbibliothek. Diese Bibliothek definiert die DFRobot_C4002 Klasse sowie mehrere zugehörige Datentypen wie sRetResult_t, sPresenceTarget_t und sMotionTarget_t.
#include "DFRobot_C4002.h"
Konditionale Kompilierung und Objektinitialisierung
Als nächstes konfigurieren wir die serielle Schnittstelle für die UART-Kommunikation wie zuvor. Die Konfiguration hängt vom Mikrocontroller ab.
#if defined(ESP8266) || defined(ARDUINO_AVR_UNO) SoftwareSerial mySerial(4, 5); DFRobot_C4002 c4002(&mySerial, 115200); #elif defined(ESP32) DFRobot_C4002 c4002(&Serial1, 115200, 3, 4); #else DFRobot_C4002 c4002(&Serial1, 115200); #endif
Bei Boards wie Arduino Uno oder ESP8266 wird eine SoftwareSerial Instanz mit den Pins 4 und 5 erstellt. Beim ESP32 verwenden wir die Pins 3 und 4, du kannst aber auch andere wählen. Achte nur darauf, dass deine Hardwareverkabelung mit der Pinbelegung im Code übereinstimmt.
Setup-Funktion
Die setup() Funktion initialisiert die Kommunikation und konfiguriert die Sensorparameter im Detail.
void setup() {
Serial.begin(115200);
Die serielle Kommunikation wird gestartet, um Debugging und Datenausgabe über den Serial Monitor zu ermöglichen. Der nächste Abschnitt stellt sicher, dass der Sensor verbunden und ansprechbar ist.
while (!c4002.begin()) {
Serial.println("Can't find C4002!");
delay(1000);
}
Die begin() Funktion initialisiert den Sensor. Wenn die Initialisierung fehlschlägt, wird eine Fehlermeldung ausgegeben und jede Sekunde ein neuer Versuch gestartet.
Nach erfolgreicher Initialisierung werden die Sensor-LEDs aktiviert.
c4002.setRunLedState(eLedOn); delay(50); c4002.setOutLedState(eLedOn); delay(50);
Diese LEDs geben visuelles Feedback über den Betrieb des Sensors. Die „Run“-LED blinkt grün während der Erkennung, die „Out“-LED leuchtet, wenn eine Person erkannt wurde.
Als nächstes konfigurieren wir den Ausgangspin (OUT).
c4002.setOutPinMode(eOutpinMode1); // Motion detected delay(50);
Die setOutPinMode() Funktion legt fest, unter welcher Bedingung der OUT-Pin des Sensors aktiviert wird. In diesem Fall wird eOutpinMode1 so eingestellt, dass er eine Bewegungserkennung anzeigt. Für andere Modi siehe den eOutpinMode_t Typ:
typedef enum {
eOutpinMode1 = 0x01, /* Only when motion is detected will a high level be output */
eOutpinMode2 = 0x02, /* A high level is output only when its presence is detected */
eOutpinMode3 = 0x03, /* A high level only appears when motion or presence is detected */
eOutpinModex = 0xFF /* reserved */
} eOutpinMode_t;
Danach wird die Erkennungsreichweite definiert.
c4002.setDetectRange(0, 1100); // 0-1100 cm delay(50);
Die setDetectRange() Funktion setzt die minimale und maximale Erkennungsdistanz in Zentimetern. Hier ist der Sensor so konfiguriert, dass er Ziele zwischen 0 cm und 1100 cm (11 Meter) erkennt.
Der Schwellenwert für Umgebungslicht wird als nächstes eingestellt.
c4002.setLightThresh(0); //0-50 lux delay(50);
Die setLightThresh() Funktion legt die minimale Lichtstärke fest, die für eine Erkennung erforderlich ist. Ein Wert von 0 deaktiviert effektiv die lichtbasierte Filterung, sodass die Erkennung unter allen Lichtbedingungen möglich ist.
Die Verzögerung, bevor ein Ziel als verschwunden gilt, wird dann eingestellt.
c4002.setTargetDisappearDelay(1); // 0-65535s delay(50);
Die setTargetDisappearDelay() Funktion definiert, wie lange der Sensor wartet, bevor er meldet, dass ein erkanntes Ziel nicht mehr vorhanden ist. Hier ist die Verzögerung auf 1 Sekunde gesetzt.
Das Meldeintervall wird zuletzt konfiguriert.
c4002.setReportPeriod(10); // 10 * 0.1s = 1s delay(50); }
Die setReportPeriod() Funktion bestimmt, wie oft der Sensor Daten sendet. Ein Wert von 10 entspricht einem Intervall von 1 Sekunde.
Kurze Verzögerungen zwischen den Konfigurationsbefehlen sorgen für eine stabile Kommunikation mit dem Sensor.
Loop-Funktion
Die loop() Funktion liest und verarbeitet kontinuierlich Sensordaten.
void loop() {
sRetResult_t retResult = c4002.getNoteInfo();
Die getNoteInfo() Funktion ruft die neueste Benachrichtigung vom Sensor ab. Die zurückgegebene Struktur enthält Informationen über die Art der verfügbaren Daten.
Der Code prüft, ob die empfangenen Daten Erkennungsergebnisse enthalten.
if (retResult.noteType == eResult) {
Das noteType Feld zeigt die Art der Nachricht an. Wenn es den Wert eResult hat, hat der Sensor Messdaten geliefert.
Eine Überschrift wird ausgegeben, um Ausgabeblöcke zu trennen.
Serial.println("---------- RESULTS ------------");
Die Umgebungslichtintensität wird dann ausgelesen.
float light = c4002.getLightIntensity();
Serial.print("Light: ");
Serial.print(light);
Serial.println(" lux");
Die getLightIntensity() Funktion gibt den gemessenen Lichtwert in Lux zurück.
Als nächstes wird der Zielzustand bestimmt.
eTargetState_t targetState = c4002.getTargetState();
Serial.print("Target state: ");
Die getTargetState() Funktion zeigt an, ob ein Ziel vorhanden ist und ob es sich bewegt oder stationär ist.
if (targetState == eNoTarget) {
Serial.println("No Target");
} else if (targetState == ePresence) {
Serial.println("Static Presence");
} else if (targetState == eMotion) {
Serial.println("Motion");
}
Der Code unterscheidet zwischen keinem Ziel, einer stationären Person und einer sich bewegenden Person.
Die Präsenz-Zielinformationen werden dann abgerufen.
sPresenceTarget_t presenceTarget = c4002.getPresenceTargetInfo();
Serial.print("Presence distance: ");
Serial.print(presenceTarget.distance);
Serial.println(" m");
Serial.print("Presence energy: ");
Serial.println(presenceTarget.energy);
Die getPresenceTargetInfo() Funktion gibt eine Struktur zurück, die Entfernung und Signalenergie eines stationären Ziels enthält. Der Energie-Wert spiegelt die Stärke des erfassten Signals wider.
Als nächstes werden Bewegungsziel-Daten erfasst.
sMotionTarget_t motionTarget = c4002.getMotionTargetInfo();
Serial.print("Motion distance: ");
Serial.print(motionTarget.distance);
Serial.println(" m");
Serial.print("Motion energy: ");
Serial.println(motionTarget.energy);
Die getMotionTargetInfo() Funktion liefert ähnliche Daten für sich bewegende Ziele.
Zusätzliche Bewegungsparameter werden ebenfalls ausgegeben.
Serial.print("Motion speed: ");
Serial.print(motionTarget.speed);
Serial.println(" m/s");
Die Geschwindigkeit des sich bewegenden Ziels wird in Metern pro Sekunde angegeben.
Abschließend wird die Bewegungsrichtung ausgewertet.
Serial.print("Motion direction: ");
if (motionTarget.direction == eAway) {
Serial.println("Away!");
} else if (motionTarget.direction == eNoDirection) {
Serial.println("No Direction!");
} else if (motionTarget.direction == eApproaching) {
Serial.println("Approaching!");
}
Der Sensor kann erkennen, ob sich das Ziel entfernt, nähert oder keine klare Richtung vorliegt.
Am Ende der Schleife wird eine kurze Verzögerung eingefügt.
} delay(50); }
Diese Verzögerung verhindert übermäßiges Abfragen und sorgt für eine stabile Kommunikation.
Ausgabe-Beispiel
Das folgende Bild zeigt, welche Erkennungsinformationen im Serial Monitor ausgegeben werden:

Fazit
In diesem Tutorial hast du gelernt, wie du den mmWave C4002 Sensor an ein Arduino oder ESP32 für Bewegungs- und Präsenzdetektion anschließt. Im Vergleich zu passiven Infrarot- (PIR) Bewegungssensoren ist der radarbasierte C4002 zuverlässiger und kann stationäre Personen in bestimmten Entfernungsbereichen erkennen.
Wenn du nur ein binäres Erkennungssignal (erkannt, nicht erkannt) benötigst, kannst du den Sensor einmalig (z. B. Erkennungsdistanz einstellen) über einen Mikrocontroller programmieren und dann den OUT-Pin verwenden. Für komplexere Steuerungsaktionen kannst du den Mikrocontroller programmieren, um auf die Sensormessungen zu reagieren.
Beachte, dass es auch den sehr ähnlichen mmWave C4001 gibt, der eine größere Reichweite von 16–25 Metern hat, aber weniger integrierte Intelligenz besitzt. Das bedeutet, dass du typischerweise mehr Logik auf der Mikrocontroller-Seite handhaben musst, wie Filterung, Zustandsinterpretation oder Aufbau höherer Verhaltensweisen, wenn du den C4001 verwendest.
Für weitere Informationen zum mmWave C4002 Sensor siehe die Wiki Seite und das repo mit weiteren Codebeispielen.
Wenn du Fragen hast, kannst du sie gerne im Kommentarbereich stellen.
Viel Spaß beim Tüfteln ; )

