-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d7f62e5
commit d783ff8
Showing
7 changed files
with
952 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Flipper Zero Radar Scanner | ||
|
||
## Overview | ||
|
||
The Flipper Zero Radar Scanner is an application designed for the Flipper Zeros GPIO capabilities, utilizing the RCWL-0516 Microwave Radar module to detect the presence and movement of living beings or people. This powerful radar module is capable of detecting movement at a range of approximately 8 meters, depending on the environment, and can even detect humans through walls, ceilings, and floors up to 5-6 meters away. | ||
|
||
## Features | ||
|
||
- **Easy Hardware Setup**: Connect the RCWL-0516 module to your Flipper Zero by supplying 5 volts to the VIN pin with ground connected. The OUT pin of the module should be connected to Pin 7 on the Flipper Zero. Make sure to enable the "5V on GPIO" option when powering the radar module from the Flipper Zero. Be mindful of 5v and GND as reversing these will damage the radar module. | ||
|
||
- **Bi-Directional Detection**: The RCWL-0516 module is bi-directional, meaning it can detect movement from both the front and back sides. The front side with components is the primary detection side and should be oriented away from you. You can modify the detection range by adding metal shielding to focus detection where the Flipper is pointing. | ||
|
||
- **Adjustable Sensitivity**: If the sensitivity is too high, you can solder a resistor to the module's pad to reduce it, allowing you to fine-tune the detection sensitivity to your needs. | ||
|
||
- **User-Friendly Interface**: The app starts in an "inactive" or "standby" state. Press the OK button to activate it. The Flipper display will show "Active," and the app will begin monitoring for movement. | ||
|
||
- **Real-Time Feedback**: | ||
- When movement is detected, the text "No presence" will change to "Presence detected." | ||
- An alarm will sound to alert you. | ||
- The LED will change from green ("clear") to red ("detected"). | ||
- The Flipper will vibrate twice to notify you. | ||
|
||
- **Muted Mode**: Press the Down button to enter "muted" mode. In this mode, detection still triggers text changes, LED status, and vibrations, but there is no sound. You can toggle this mode on and off. | ||
|
||
- **Pause and Resume**: Press the OK button to pause detection and return the Flipper to "standby" mode. Press it again to resume monitoring for movement. | ||
|
||
- **Exit the App**: Use the Back key to exit the app and return to the Flipper Zero's main menu. | ||
|
||
## Getting Started | ||
1. Install the app by moving ```radar_scanner.fap``` into Applications/external | ||
|
||
**Download the version for your firmware:** | ||
|
||
```OFW_radar_scanner.fap -> Official``` | ||
```radar_scanner.fap -> Xtreme``` | ||
```UL_radar_scanner.fap -> Unleashed``` | ||
```RM_radar_scanner.fap -> Rogue Master``` | ||
|
||
2. Power on the Flipper Zero and navigate to GPIO to enable 5V. | ||
|
||
3. Navigate to the GPIO applications folder and launch ```[GPIO] Radar Scanner``` | ||
|
||
4. Press Ok to start and monitor for real-time feedback and respond accordingly. | ||
|
||
5. Use the Down button to toggle "muted" mode on and off. | ||
|
||
6. Press the OK button to pause or resume detection. | ||
|
||
7. Press the Back key to exit the app. | ||
|
||
## Note | ||
|
||
- The range and detection capabilities may vary depending on environmental factors. | ||
|
||
- Experiment with sensitivity adjustments and metal shielding to optimize detection for your specific use case. | ||
|
||
- Be aware of privacy and legal considerations when using radar-based detection systems. | ||
|
||
- Enjoy your Flipper Zero Radar Scanner and explore its various applications! | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
App( | ||
appid="radar_scanner", | ||
name="[RCWL0516] Radar Scan", | ||
apptype=FlipperAppType.EXTERNAL, | ||
entry_point="app_radar_scanner", | ||
requires=["gui"], | ||
stack_size=1 * 1024, | ||
fap_icon="icon.png", | ||
fap_category="GPIO", | ||
fap_author="@MatthewKuKanich", | ||
fap_weburl="https://github.com/MatthewKuKanich/flipper-radar", | ||
fap_version="2.0", | ||
fap_description="Detects the movement of living things using radar", | ||
) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
// Created by @MatthewKuKanich for use with the RCWL-0516 | ||
// Design inspired from @unixispower Wire Tester | ||
|
||
#include <furi_hal.h> | ||
#include <gui/gui.h> | ||
#include <notification/notification_messages.h> | ||
#include <gui/elements.h> | ||
|
||
static const uint32_t EVENT_PERIOD_MS = 10; | ||
static const float BEEP_FREQ = 1000.0f; | ||
static const float BEEP_VOL = 0.9f; | ||
static const GpioPin* const radarPin = &gpio_ext_pc3; // Pin 7 | ||
static const GpioPin* const altRadarPin = &gpio_ext_pa7; // Pin 2 | ||
static const GpioPin* const altGroundPin = &gpio_ext_pa6; // Pin 3 | ||
|
||
bool presenceDetected = false; | ||
bool muted = false; | ||
bool active = false; | ||
bool continuous = false; // Start with no signal from OUT | ||
bool altPinout; // Sets which GPIO pinout config to use | ||
|
||
static void start_feedback(NotificationApp* notifications) { | ||
// Set LED to red for detection | ||
notification_message_block(notifications, &sequence_set_only_red_255); | ||
|
||
// Set vibration | ||
notification_message_block(notifications, &sequence_double_vibro); | ||
|
||
if(!muted) { | ||
// Start beep if not muted | ||
if(furi_hal_speaker_acquire(1000)) { | ||
furi_hal_speaker_start(BEEP_FREQ, BEEP_VOL); | ||
} | ||
} | ||
} | ||
|
||
static void stop_feedback(NotificationApp* notifications) { | ||
// Clear LED | ||
notification_message_block(notifications, &sequence_reset_rgb); | ||
|
||
// Reset vibration | ||
notification_message_block(notifications, &sequence_reset_vibro); | ||
|
||
// Stop beeping | ||
if(furi_hal_speaker_is_mine()) { | ||
furi_hal_speaker_stop(); | ||
furi_hal_speaker_release(); | ||
} | ||
} | ||
|
||
static void draw_callback(Canvas* canvas, void* ctx) { | ||
furi_assert(ctx); | ||
|
||
canvas_clear(canvas); | ||
canvas_set_font(canvas, FontPrimary); | ||
elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Microwave Radar"); | ||
canvas_set_font(canvas, FontSecondary); | ||
if(active) { | ||
elements_multiline_text_aligned(canvas, 64, 12, AlignCenter, AlignTop, "Active"); | ||
} else { | ||
elements_multiline_text_aligned(canvas, 64, 12, AlignCenter, AlignTop, "On Standby"); | ||
} | ||
|
||
// Display presence status | ||
canvas_set_font(canvas, FontPrimary); | ||
if(presenceDetected) { | ||
elements_multiline_text_aligned( | ||
canvas, 64, 20, AlignCenter, AlignTop, "Presence Detected"); | ||
} else { | ||
elements_multiline_text_aligned(canvas, 64, 20, AlignCenter, AlignTop, "No Presence"); | ||
} | ||
|
||
canvas_set_font(canvas, FontSecondary); | ||
if(muted) { | ||
elements_multiline_text_aligned(canvas, 64, 32, AlignCenter, AlignTop, "Muted"); | ||
} | ||
|
||
canvas_set_font(canvas, FontBatteryPercent); | ||
|
||
if(altPinout) { | ||
elements_multiline_text_aligned( | ||
canvas, 64, 42, AlignCenter, AlignTop, "Alt-Pinout Enabled"); | ||
elements_multiline_text_aligned( | ||
canvas, 64, 49, AlignCenter, AlignTop, "VIN -> 5v :: GND -> Pin 3"); | ||
elements_multiline_text_aligned( | ||
canvas, 64, 56, AlignCenter, AlignTop, "OUT -> Pin 2 (A7)"); | ||
} else if(!altPinout) { | ||
elements_multiline_text_aligned( | ||
canvas, 64, 42, AlignCenter, AlignTop, "Alt-Pinout Disabled"); | ||
elements_multiline_text_aligned( | ||
canvas, 64, 49, AlignCenter, AlignTop, "VIN -> 5v :: GND -> GND"); | ||
elements_multiline_text_aligned( | ||
canvas, 64, 56, AlignCenter, AlignTop, "OUT -> Pin 7 (C3)"); | ||
} | ||
} | ||
|
||
static void input_callback(InputEvent* input_event, void* ctx) { | ||
furi_assert(ctx); | ||
FuriMessageQueue* event_queue = ctx; | ||
furi_message_queue_put(event_queue, input_event, FuriWaitForever); | ||
} | ||
|
||
static void get_reading() { | ||
if(altPinout) { | ||
continuous = furi_hal_gpio_read(altRadarPin); | ||
} else { | ||
continuous = furi_hal_gpio_read(radarPin); | ||
} | ||
} | ||
|
||
int32_t app_radar_scanner(void* p) { | ||
UNUSED(p); | ||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); | ||
|
||
// I'm keeping the forced backlight as you will likely be away from Flipper | ||
NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); | ||
notification_message_block(notifications, &sequence_display_backlight_enforce_on); | ||
|
||
ViewPort* view_port = view_port_alloc(); | ||
view_port_draw_callback_set(view_port, draw_callback, view_port); | ||
view_port_input_callback_set(view_port, input_callback, event_queue); | ||
|
||
Gui* gui = furi_record_open(RECORD_GUI); | ||
gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||
view_port_update(view_port); | ||
|
||
stop_feedback(notifications); | ||
|
||
// set input to be low; RCWL-0516 outputs High (3v) on detection | ||
furi_hal_gpio_init(radarPin, GpioModeInput, GpioPullDown, GpioSpeedVeryHigh); | ||
furi_hal_gpio_init(altRadarPin, GpioModeInput, GpioPullDown, GpioSpeedVeryHigh); | ||
furi_hal_gpio_init(altGroundPin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); | ||
furi_hal_gpio_write(altGroundPin, false); | ||
|
||
// Auto 5v- Thanks Willy!! | ||
uint8_t attempts = 0; | ||
bool otg_was_enabled = furi_hal_power_is_otg_enabled(); | ||
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { | ||
furi_hal_power_enable_otg(); | ||
furi_delay_ms(10); | ||
} | ||
|
||
bool alarming = false; // Sensor begins in-active until user starts | ||
bool running = true; // to prevent unwanted false positives | ||
|
||
while(running) { | ||
if(active) { | ||
// start and stop feedback if sensor state is active | ||
get_reading(); | ||
|
||
if(continuous && !alarming) { | ||
presenceDetected = true; | ||
start_feedback(notifications); | ||
|
||
} else if(!continuous && alarming) { | ||
presenceDetected = false; | ||
stop_feedback(notifications); // Green LED if clear/no presence | ||
notification_message_block(notifications, &sequence_set_only_green_255); | ||
} | ||
alarming = continuous; | ||
} | ||
|
||
// Exit on back key | ||
InputEvent event; | ||
if(furi_message_queue_get(event_queue, &event, EVENT_PERIOD_MS) == FuriStatusOk) { | ||
if(event.type == InputTypePress) { | ||
if(event.key == InputKeyBack) { | ||
break; | ||
} | ||
if(event.key == InputKeyOk) { | ||
active = !active; // Toggle the value of 'active' | ||
stop_feedback(notifications); | ||
} | ||
if(event.key == InputKeyDown) { | ||
muted = !muted; // Toggle the value of 'muted' | ||
stop_feedback(notifications); | ||
} | ||
if(event.key == InputKeyRight) { | ||
altPinout = !altPinout; // Toggle alternate pinout | ||
} | ||
} | ||
} | ||
} | ||
|
||
// return control of the LED, beeper, backlight, and stop vibration | ||
stop_feedback(notifications); | ||
notification_message_block(notifications, &sequence_display_backlight_enforce_auto); | ||
|
||
// Disable 5v power | ||
if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) { | ||
furi_hal_power_disable_otg(); | ||
} | ||
|
||
view_port_enabled_set(view_port, false); | ||
gui_remove_view_port(gui, view_port); | ||
view_port_free(view_port); | ||
|
||
furi_message_queue_free(event_queue); | ||
furi_record_close(RECORD_GUI); | ||
furi_record_close(RECORD_NOTIFICATION); | ||
|
||
return 0; | ||
} |