camera: add status label, hide buttons until found

This commit is contained in:
Thomas Farstrike
2025-05-15 12:49:27 +02:00
parent 08c0370eed
commit f982f28f54
2 changed files with 61 additions and 44 deletions
+22 -16
View File
@@ -108,10 +108,11 @@ static void save_raw_rgb565(const char *filename, uint16_t *data, int width, int
}
static int init_webcam(webcam_obj_t *self, const char *device) {
//WEBCAM_DEBUG_PRINT("webcam.c: init_webcam\n");
self->fd = open(device, O_RDWR);
if (self->fd < 0) {
WEBCAM_DEBUG_PRINT("Cannot open device: %s\n", strerror(errno));
return -1;
return -errno;
}
struct v4l2_format fmt = {0};
@@ -123,7 +124,7 @@ static int init_webcam(webcam_obj_t *self, const char *device) {
if (ioctl(self->fd, VIDIOC_S_FMT, &fmt) < 0) {
WEBCAM_DEBUG_PRINT("Cannot set format: %s\n", strerror(errno));
close(self->fd);
return -1;
return -errno;
}
struct v4l2_requestbuffers req = {0};
@@ -133,7 +134,7 @@ static int init_webcam(webcam_obj_t *self, const char *device) {
if (ioctl(self->fd, VIDIOC_REQBUFS, &req) < 0) {
WEBCAM_DEBUG_PRINT("Cannot request buffers: %s\n", strerror(errno));
close(self->fd);
return -1;
return -errno;
}
for (int i = 0; i < NUM_BUFFERS; i++) {
@@ -144,14 +145,14 @@ static int init_webcam(webcam_obj_t *self, const char *device) {
if (ioctl(self->fd, VIDIOC_QUERYBUF, &buf) < 0) {
WEBCAM_DEBUG_PRINT("Cannot query buffer: %s\n", strerror(errno));
close(self->fd);
return -1;
return -errno;
}
self->buffer_length = buf.length;
self->buffers[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, self->fd, buf.m.offset);
if (self->buffers[i] == MAP_FAILED) {
WEBCAM_DEBUG_PRINT("Cannot map buffer: %s\n", strerror(errno));
close(self->fd);
return -1;
return -errno;
}
}
@@ -162,14 +163,14 @@ static int init_webcam(webcam_obj_t *self, const char *device) {
buf.index = i;
if (ioctl(self->fd, VIDIOC_QBUF, &buf) < 0) {
WEBCAM_DEBUG_PRINT("Cannot queue buffer: %s\n", strerror(errno));
return -1;
return -errno;
}
}
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(self->fd, VIDIOC_STREAMON, &type) < 0) {
WEBCAM_DEBUG_PRINT("Cannot start streaming: %s\n", strerror(errno));
return -1;
return -errno;
}
self->frame_count = 0;
@@ -180,7 +181,7 @@ static int init_webcam(webcam_obj_t *self, const char *device) {
free(self->gray_buffer);
free(self->rgb565_buffer);
close(self->fd);
return -1;
return -errno;
}
return 0;
}
@@ -215,12 +216,14 @@ static mp_obj_t free_buffer(webcam_obj_t *self) {
}
static mp_obj_t capture_frame(mp_obj_t self_in, mp_obj_t format) {
int res = 0;
webcam_obj_t *self = MP_OBJ_TO_PTR(self_in);
struct v4l2_buffer buf = {0};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if (ioctl(self->fd, VIDIOC_DQBUF, &buf) < 0) {
mp_raise_OSError(MP_EIO);
res = ioctl(self->fd, VIDIOC_DQBUF, &buf);
if (res < 0) {
mp_raise_OSError(-res);
}
if (!self->gray_buffer) {
@@ -243,8 +246,9 @@ static mp_obj_t capture_frame(mp_obj_t self_in, mp_obj_t format) {
// snprintf(filename, sizeof(filename), "frame_%03d.raw", self->frame_count++);
// save_raw(filename, self->gray_buffer, OUTPUT_WIDTH, OUTPUT_HEIGHT);
mp_obj_t result = mp_obj_new_memoryview('B', OUTPUT_WIDTH * OUTPUT_HEIGHT, self->gray_buffer);
if (ioctl(self->fd, VIDIOC_QBUF, &buf) < 0) {
mp_raise_OSError(MP_EIO);
res = ioctl(self->fd, VIDIOC_QBUF, &buf);
if (res < 0) {
mp_raise_OSError(-res);
}
return result;
} else {
@@ -253,8 +257,9 @@ static mp_obj_t capture_frame(mp_obj_t self_in, mp_obj_t format) {
// snprintf(filename, sizeof(filename), "frame_%03d.rgb565", self->frame_count++);
// save_raw_rgb565(filename, self->rgb565_buffer, OUTPUT_WIDTH, OUTPUT_HEIGHT);
mp_obj_t result = mp_obj_new_memoryview('H', OUTPUT_WIDTH * OUTPUT_HEIGHT, self->rgb565_buffer);
if (ioctl(self->fd, VIDIOC_QBUF, &buf) < 0) {
mp_raise_OSError(MP_EIO);
res = ioctl(self->fd, VIDIOC_QBUF, &buf);
if (res < 0) {
mp_raise_OSError(-res);
}
return result;
}
@@ -273,8 +278,9 @@ static mp_obj_t webcam_init(size_t n_args, const mp_obj_t *args) {
self->gray_buffer = NULL;
self->rgb565_buffer = NULL;
if (init_webcam(self, device) < 0) {
mp_raise_OSError(MP_EIO);
int res = init_webcam(self, device);
if (res < 0) {
mp_raise_OSError(-res);
}
return MP_OBJ_FROM_PTR(self);
@@ -7,9 +7,6 @@
import time
appscreen = lv.screen_active()
th.disable()
keepgoing = True
keepliveqrdecoding = False
width = 240
@@ -20,7 +17,11 @@ current_cam_buffer = None
image_dsc = None
image = None
qr_label = None
status_label = None
use_webcam = False
qr_button = None
snap_button = None
memview = None
@@ -121,7 +122,7 @@ def try_capture():
def build_ui():
global image, image_dsc,qr_label, cam
global image, image_dsc,qr_label, status_label, cam, use_webcam, qr_button, snap_button
cont = lv.obj(appscreen)
cont.set_style_pad_all(0, 0)
cont.set_style_border_width(0, 0)
@@ -137,12 +138,14 @@ def build_ui():
snap_button = lv.button(cont)
snap_button.set_size(60, 60)
snap_button.align(lv.ALIGN.RIGHT_MID, 0, 0)
snap_button.add_flag(lv.obj.FLAG.HIDDEN)
snap_label = lv.label(snap_button)
snap_label.set_text(lv.SYMBOL.OK)
snap_label.center()
snap_button.add_event_cb(snap_button_click,lv.EVENT.CLICKED,None)
snap_label.center()
snap_button.add_event_cb(snap_button_click,lv.EVENT.CLICKED,None)
qr_button = lv.button(cont)
qr_button.set_size(60, 60)
qr_button.add_flag(lv.obj.FLAG.HIDDEN)
qr_button.align(lv.ALIGN.BOTTOM_RIGHT, 0, 0)
qr_label = lv.label(qr_button)
qr_label.set_text(lv.SYMBOL.EYE_OPEN)
@@ -151,8 +154,6 @@ def build_ui():
# Initialize LVGL image widget
image = lv.image(cont)
image.align(lv.ALIGN.LEFT_MID, 0, 0)
if not use_webcam:
image.set_rotation(900)
# Create image descriptor once
image_dsc = lv.image_dsc_t({
"header": {
@@ -167,6 +168,9 @@ def build_ui():
'data': None # Will be updated per frame
})
image.set_src(image_dsc)
status_label = lv.label(appscreen)
status_label.set_text("No camera found.")
status_label.center()
def init_cam():
@@ -201,11 +205,13 @@ def init_cam():
appscreen = lv.screen_active()
build_ui()
cam = init_cam()
if not cam:
if cam:
image.set_rotation(900)
else:
print("camtest.py: no internal camera found, trying webcam on /dev/video0")
try:
import webcam
@@ -215,23 +221,28 @@ if not cam:
print(f"camtest.py: webcam exception: {e}")
if cam:
build_ui()
count=0
while appscreen == lv.screen_active() and keepgoing is True:
status_label.set_text("")
qr_button.remove_flag(lv.obj.FLAG.HIDDEN)
snap_button.remove_flag(lv.obj.FLAG.HIDDEN)
# Task handler needs to be updated from this app's thread, otherwise it causes concurrency issues
th.disable()
while appscreen == lv.screen_active() and keepgoing is True:
if cam:
try_capture()
# Task handler needs to be updated from the same thread, otherwise it causes concurrency issues:
lv.task_handler()
time.sleep_ms(1)
lv.tick_inc(1)
print("camtest.py: stopping...")
if use_webcam:
webcam.deinit(cam) # Deinitializes webcam
else:
cam.deinit()
else:
print("No camera found, exiting...")
lv.task_handler()
time.sleep_ms(5)
lv.tick_inc(5)
th.enable()
print("camtest.py: stopping...")
if use_webcam:
webcam.deinit(cam)
elif cam:
cam.deinit()
print("camtest.py: showing launcher...")
show_launcher()
th.enable()