You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
camera: add status label, hide buttons until found
This commit is contained in:
+22
-16
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user