Works kindof

This commit is contained in:
Thomas Farstrike
2025-04-25 11:43:05 +02:00
parent c0774f1310
commit 42b341ea81
+65 -37
View File
@@ -20,6 +20,32 @@
#define CAM_LEDC_CHANNEL LEDC_CHANNEL_0
# OV5640 I2C address
#sensor_addr = 0x3C
#reg_addr = 0x4300
#reg_value = 0x4F # RGB565 (bit[6]=1) + sequence 0xF (bits[3:0]=0xF)
#from machine import I2C, Pin
#i2c = I2C(scl=Pin(16), sda=Pin(21))
#i2c.readfrom_mem(0x3C, 0x4300, 1)
#i2c.writeto_mem(sensor_addr, reg_addr, bytes([reg_value]))
subwindow.clean()
canary = lv.obj(subwindow)
canary.add_flag(lv.obj.FLAG.HIDDEN)
width = 160
height = 120
#width = 120
#height = 160
image = lv.image(subwindow)
image.align(lv.ALIGN.CENTER, 0, 0)
#image.set_size(width, height)
#image.set_size(height, width)
#image.set_rotation(900)
from camera import Camera, GrabMode, PixelFormat, FrameSize, GainCeiling
cam = Camera(
@@ -33,47 +59,49 @@ cam = Camera(
xclk_freq=20000000,
powerdown_pin=-1,
reset_pin=-1,
#pixel_format=PixelFormat.RGB565,frame_size=FrameSize.QQVGA,grab_mode=GrabMode.LATEST # 160x120, FrameSize.QVGA = 320x240
#pixel_format=PixelFormat.JPEG,frame_size=FrameSize.QVGA,grab_mode=GrabMode.LATEST
pixel_format=PixelFormat.RGB565,frame_size=FrameSize.QQVGA,grab_mode=GrabMode.LATEST # 160x120, FrameSize.QVGA = 320x240
)
cam.init()
#cam.init() done default (see above)
cam.set_vflip(True)
# LVGLs expected RGB565 format is likely little-endian: GGGBBBBB RRRRRGGG, since swapping bytes fixed the issue.
# The sensors default sequence is 0x0 ({b[4:0],g[5:3]},{g[2:0],r[4:0]}), which is big-endian-like (BGR in the first byte, RG in the second).
# After swapping bytes, you get {g[2:0],r[4:0]},{b[4:0],g[5:3]}, which matches LVGLs expectation.
# From the datasheet, the sequence {g[2:0],r[4:0]},{b[4:0],g[5:3]} corresponds to 0xF.
# This suggests setting bits[3:0] to 0xF should produce the correct order without manual swapping.
# default writes:
# 0x1: {r[4:0],g[5:3]},{g[2:0],b[4:0]} so that's RRRRR GGGGGG BBBBB
def try_capture():
if cam.frame_available():
img = bytes(cam.capture())
cam.free_buffer()
# Swap bytes for each 16-bit pixel
#img_swapped = bytearray(len(img))
#for i in range(0, len(img), 2):
# img_swapped[i] = img[i+1] # Swap high and low bytes
# img_swapped[i+1] = img[i]
image_dsc = lv.image_dsc_t({
"header": { "magic": lv.IMAGE_HEADER_MAGIC, "w": width, "h": height, "stride": width * 2, "cf": lv.COLOR_FORMAT.RGB565 },
'data_size': len(img),
'data': img
})
image.set_src(image_dsc)
try_capture()
while canary.is_valid():
try_capture()
#pixel_format=PixelFormat.JPEG,frame_size=FrameSize.QVGA,grab_mode=GrabMode.LATEST
#cam.reconfigure(pixel_format=PixelFormat.RAW,frame_size=FrameSize.QVGA,grab_mode=GrabMode.LATEST, fb_count=2)
#cam.reconfigure(pixel_format=PixelFormat.YUV420,frame_size=FrameSize.QVGA,grab_mode=GrabMode.LATEST, fb_count=2)
#img = cam.capture()
def memoryview_to_hex_spaced(mv: memoryview) -> str:
"""Convert the first 50 bytes of a memoryview to a spaced hex string."""
sliced = mv[:50]
return ' '.join('{:02x}'.format(b & 0xFF) for b in sliced)
#cam.reconfigure(pixel_format=PixelFormat.YUV420,frame_size=FrameSize.QQVGA,grab_mode=GrabMode.LATEST, fb_count=2)
#cam.reconfigure(pixel_format=PixelFormat.RGB565,frame_size=FrameSize.QQVGA,grab_mode=GrabMode.LATEST, fb_count=2)
#memoryview_to_hex_spaced(img)
def capture():
width = 160
height = 120
image = lv.image(subwindow)
image_data = cam.capture()
memoryview_to_hex_spaced(image_data)
image_dsc = lv.image_dsc_t({
"header": {
"magic": lv.IMAGE_HEADER_MAGIC,
"w": width,
"h": height,
"stride": width * 2,
"cf": lv.COLOR_FORMAT.RGB565
},
'data_size': len(image_data),
'data': image_data
})
image.set_src(image_dsc)
image.align(lv.ALIGN.TOP_MID, 0, 0)
image.set_size(width, height)
#for _ in range(10):
# capture()
capture()