|
@@ -71,7 +71,7 @@ static void camera_suite_view_camera_draw(Canvas* canvas, void* model) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void save_image(void* model) {
|
|
|
|
|
|
|
+static void save_image_to_flipper_sd_card(void* model) {
|
|
|
furi_assert(model);
|
|
furi_assert(model);
|
|
|
|
|
|
|
|
UartDumpModel* uartDumpModel = model;
|
|
UartDumpModel* uartDumpModel = model;
|
|
@@ -187,131 +187,150 @@ static bool camera_suite_view_camera_input(InputEvent* event, void* context) {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
} else if(event->type == InputTypePress) {
|
|
} else if(event->type == InputTypePress) {
|
|
|
- uint8_t data[1] = {'X'};
|
|
|
|
|
switch(event->key) {
|
|
switch(event->key) {
|
|
|
- // Camera: Stop stream.
|
|
|
|
|
case InputKeyBack: {
|
|
case InputKeyBack: {
|
|
|
- // Stop camera stream.
|
|
|
|
|
- data[0] = 's';
|
|
|
|
|
- furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1);
|
|
|
|
|
- // Go back to the main menu.
|
|
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
instance->view,
|
|
instance->view,
|
|
|
UartDumpModel * model,
|
|
UartDumpModel * model,
|
|
|
{
|
|
{
|
|
|
UNUSED(model);
|
|
UNUSED(model);
|
|
|
|
|
+
|
|
|
|
|
+ // Stop camera stream.
|
|
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t[]){'s'}, 1);
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
+
|
|
|
|
|
+ // Go back to the main menu.
|
|
|
instance->callback(CameraSuiteCustomEventSceneCameraBack, instance->context);
|
|
instance->callback(CameraSuiteCustomEventSceneCameraBack, instance->context);
|
|
|
},
|
|
},
|
|
|
true);
|
|
true);
|
|
|
- return true;
|
|
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
- // Camera: Toggle invert on the ESP32-CAM.
|
|
|
|
|
case InputKeyLeft: {
|
|
case InputKeyLeft: {
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
instance->view,
|
|
instance->view,
|
|
|
UartDumpModel * model,
|
|
UartDumpModel * model,
|
|
|
{
|
|
{
|
|
|
|
|
+ // Play sound.
|
|
|
camera_suite_play_happy_bump(instance->context);
|
|
camera_suite_play_happy_bump(instance->context);
|
|
|
camera_suite_play_input_sound(instance->context);
|
|
camera_suite_play_input_sound(instance->context);
|
|
|
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
|
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
|
|
|
|
+
|
|
|
if(model->is_inverted) {
|
|
if(model->is_inverted) {
|
|
|
- data[0] = 'i';
|
|
|
|
|
|
|
+ // Camera: Set invert to false on the ESP32-CAM.
|
|
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t[]){'i'}, 1);
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
+
|
|
|
model->is_inverted = false;
|
|
model->is_inverted = false;
|
|
|
} else {
|
|
} else {
|
|
|
- data[0] = 'I';
|
|
|
|
|
|
|
+ // Camera: Set invert to true on the ESP32-CAM.
|
|
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t[]){'I'}, 1);
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
+
|
|
|
model->is_inverted = true;
|
|
model->is_inverted = true;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
instance->callback(CameraSuiteCustomEventSceneCameraLeft, instance->context);
|
|
instance->callback(CameraSuiteCustomEventSceneCameraLeft, instance->context);
|
|
|
},
|
|
},
|
|
|
true);
|
|
true);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- // Camera: Enable/disable dithering.
|
|
|
|
|
case InputKeyRight: {
|
|
case InputKeyRight: {
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
instance->view,
|
|
instance->view,
|
|
|
UartDumpModel * model,
|
|
UartDumpModel * model,
|
|
|
{
|
|
{
|
|
|
|
|
+ // Play sound.
|
|
|
camera_suite_play_happy_bump(instance->context);
|
|
camera_suite_play_happy_bump(instance->context);
|
|
|
camera_suite_play_input_sound(instance->context);
|
|
camera_suite_play_input_sound(instance->context);
|
|
|
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
|
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
|
|
|
|
+
|
|
|
if(model->is_dithering_enabled) {
|
|
if(model->is_dithering_enabled) {
|
|
|
- data[0] = 'd';
|
|
|
|
|
|
|
+ // Camera: Disable dithering.
|
|
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t[]){'d'}, 1);
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
+
|
|
|
model->is_dithering_enabled = false;
|
|
model->is_dithering_enabled = false;
|
|
|
} else {
|
|
} else {
|
|
|
- data[0] = 'D';
|
|
|
|
|
|
|
+ // Camera: Enable dithering.
|
|
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t[]){'D'}, 1);
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
+
|
|
|
model->is_dithering_enabled = true;
|
|
model->is_dithering_enabled = true;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
instance->callback(CameraSuiteCustomEventSceneCameraRight, instance->context);
|
|
instance->callback(CameraSuiteCustomEventSceneCameraRight, instance->context);
|
|
|
},
|
|
},
|
|
|
true);
|
|
true);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- // Camera: Increase contrast.
|
|
|
|
|
case InputKeyUp: {
|
|
case InputKeyUp: {
|
|
|
- data[0] = 'C';
|
|
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
instance->view,
|
|
instance->view,
|
|
|
UartDumpModel * model,
|
|
UartDumpModel * model,
|
|
|
{
|
|
{
|
|
|
UNUSED(model);
|
|
UNUSED(model);
|
|
|
|
|
+
|
|
|
|
|
+ // Play sound.
|
|
|
camera_suite_play_happy_bump(instance->context);
|
|
camera_suite_play_happy_bump(instance->context);
|
|
|
camera_suite_play_input_sound(instance->context);
|
|
camera_suite_play_input_sound(instance->context);
|
|
|
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
|
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
|
|
|
|
+
|
|
|
|
|
+ // Camera: Increase contrast.
|
|
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t[]){'C'}, 1);
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
+
|
|
|
instance->callback(CameraSuiteCustomEventSceneCameraUp, instance->context);
|
|
instance->callback(CameraSuiteCustomEventSceneCameraUp, instance->context);
|
|
|
},
|
|
},
|
|
|
true);
|
|
true);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- // Camera: Reduce contrast.
|
|
|
|
|
case InputKeyDown: {
|
|
case InputKeyDown: {
|
|
|
- data[0] = 'c';
|
|
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
instance->view,
|
|
instance->view,
|
|
|
UartDumpModel * model,
|
|
UartDumpModel * model,
|
|
|
{
|
|
{
|
|
|
UNUSED(model);
|
|
UNUSED(model);
|
|
|
|
|
+
|
|
|
|
|
+ // Play sound.
|
|
|
camera_suite_play_happy_bump(instance->context);
|
|
camera_suite_play_happy_bump(instance->context);
|
|
|
camera_suite_play_input_sound(instance->context);
|
|
camera_suite_play_input_sound(instance->context);
|
|
|
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
|
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
|
|
|
|
+
|
|
|
|
|
+ // Camera: Reduce contrast.
|
|
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t[]){'c'}, 1);
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
+
|
|
|
instance->callback(CameraSuiteCustomEventSceneCameraDown, instance->context);
|
|
instance->callback(CameraSuiteCustomEventSceneCameraDown, instance->context);
|
|
|
},
|
|
},
|
|
|
true);
|
|
true);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- // Camera: Take picture.
|
|
|
|
|
case InputKeyOk: {
|
|
case InputKeyOk: {
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
instance->view,
|
|
instance->view,
|
|
|
UartDumpModel * model,
|
|
UartDumpModel * model,
|
|
|
{
|
|
{
|
|
|
|
|
+ // Play sound.
|
|
|
camera_suite_play_long_bump(instance->context);
|
|
camera_suite_play_long_bump(instance->context);
|
|
|
camera_suite_play_input_sound(instance->context);
|
|
camera_suite_play_input_sound(instance->context);
|
|
|
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
|
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
|
|
|
|
|
|
|
- // Save picture directly to ESP32-CAM.
|
|
|
|
|
- // @todo - Future functionality.
|
|
|
|
|
- // data[0] = 'P';
|
|
|
|
|
- // furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1);
|
|
|
|
|
|
|
+ // @todo - Save picture directly to ESP32-CAM.
|
|
|
|
|
+ // furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t[]){'P'}, 1);
|
|
|
|
|
+
|
|
|
|
|
+ // Save currently displayed image to the Flipper Zero SD card.
|
|
|
|
|
+ save_image_to_flipper_sd_card(model);
|
|
|
|
|
|
|
|
- // Take a picture.
|
|
|
|
|
- save_image(model);
|
|
|
|
|
instance->callback(CameraSuiteCustomEventSceneCameraOk, instance->context);
|
|
instance->callback(CameraSuiteCustomEventSceneCameraOk, instance->context);
|
|
|
},
|
|
},
|
|
|
true);
|
|
true);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- // Camera: Do nothing.
|
|
|
|
|
case InputKeyMAX:
|
|
case InputKeyMAX:
|
|
|
default: {
|
|
default: {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- if(data[0] != 'X') { // 'X' is the default/null value.
|
|
|
|
|
- // Send `data` to the ESP32-CAM.
|
|
|
|
|
- furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1);
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
@@ -330,25 +349,23 @@ static void camera_suite_view_camera_enter(void* context) {
|
|
|
CameraSuite* instance_context = instance->context;
|
|
CameraSuite* instance_context = instance->context;
|
|
|
|
|
|
|
|
// Start camera stream.
|
|
// Start camera stream.
|
|
|
- uint8_t start_camera = 'S';
|
|
|
|
|
- furi_hal_uart_tx(FuriHalUartIdUSART1, &start_camera, 1);
|
|
|
|
|
- furi_delay_ms(10);
|
|
|
|
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t[]){'S'}, 1);
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
|
|
|
// Get/set dither type.
|
|
// Get/set dither type.
|
|
|
uint8_t dither_type = instance_context->dither;
|
|
uint8_t dither_type = instance_context->dither;
|
|
|
furi_hal_uart_tx(FuriHalUartIdUSART1, &dither_type, 1);
|
|
furi_hal_uart_tx(FuriHalUartIdUSART1, &dither_type, 1);
|
|
|
- furi_delay_ms(10);
|
|
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
|
|
|
// Make sure the camera is not inverted.
|
|
// Make sure the camera is not inverted.
|
|
|
- uint8_t invert_camera = 'i';
|
|
|
|
|
- furi_hal_uart_tx(FuriHalUartIdUSART1, &invert_camera, 1);
|
|
|
|
|
- furi_delay_ms(10);
|
|
|
|
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t[]){'i'}, 1);
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
|
|
|
// Toggle flash on or off based on the current state. If the user has this
|
|
// Toggle flash on or off based on the current state. If the user has this
|
|
|
// on the flash will stay on the entire time the user is in the camera view.
|
|
// on the flash will stay on the entire time the user is in the camera view.
|
|
|
uint8_t flash_state = instance_context->flash ? 'F' : 'f';
|
|
uint8_t flash_state = instance_context->flash ? 'F' : 'f';
|
|
|
furi_hal_uart_tx(FuriHalUartIdUSART1, &flash_state, 1);
|
|
furi_hal_uart_tx(FuriHalUartIdUSART1, &flash_state, 1);
|
|
|
- furi_delay_ms(10);
|
|
|
|
|
|
|
+ furi_delay_ms(50);
|
|
|
|
|
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
instance->view,
|
|
instance->view,
|