when I connect the board to my pc, my pc recognizes memory card connected which has 34MB of memory, in it, there is a main.py file contains
# main.py -- put your code here!
import pyb, time
led = pyb.LED(3)
usb = pyb.USB_VCP()
while (usb.isconnected()==False):
led.on()
time.sleep_ms(150)
led.off()
time.sleep_ms(100)
led.on()
time.sleep_ms(150)
led.off()
time.sleep_ms(600)
I have modified this code to
import sensor, time, sys
sensor.reset()
sensor.set_framesize(sensor.FHD)
sensor.set_pixformat(sensor.JPEG)
sensor.skip_frames(time=2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
while True:
img = sensor.snapshot()
compressed = img.compress(quality=30)
print("FRAME_START")
print(len(compressed))
sys.stdout.buffer.write(compressed)
print("\nFRAME_END")
and then in my pc
#!/usr/bin/env python3
import serial
import time
import cv2
import numpy as np
import threading
from collections import deque
class OpenMVStreamer:
def _init_(self, port=‘/dev/ttyACM0’, baudrate=115200):
self.ser = serial.Serial(port, baudrate, timeout=0.1, dsrdtr=False)
self.frame_buffer = deque(maxlen=5)
self.running = False
self.frame_count = 0
self.last_frame = None # Store last frame for saving original resolution
def start_streaming(self):
self.running = True
self.stream_thread = threading.Thread(target=self._stream_worker)
self.stream_thread.daemon = True
self.stream_thread.start()
def _stream_worker(self):
buffer = b""
while self.running:
try:
if self.ser.in_waiting > 0:
data = self.ser.read(self.ser.in_waiting)
buffer += data
while b"FRAME_START\r\n" in buffer and b"\r\nFRAME_END\r\n" in buffer:
start_idx = buffer.find(b"FRAME_START\r\n")
end_idx = buffer.find(b"\r\nFRAME_END\r\n")
if start_idx < end_idx:
frame_data = buffer[start_idx:end_idx + len(b"\r\nFRAME_END\r\n")]
buffer = buffer[end_idx + len(b"\r\nFRAME_END\r\n"):]
frame = self._parse_frame(frame_data)
if frame is not None:
self.last_frame = frame.copy() # Store original frame
self.frame_buffer.append(frame)
else:
break
time.sleep(0.001)
except Exception as e:
print(f"Stream error: {e}")
continue
def _parse_frame(self, frame_data):
try:
lines = frame_data.split(b’\r\n’)
if len(lines) >= 4 and lines[0] == b"FRAME_START":
size_str = lines[1].decode(‘utf-8’)
if size_str.isdigit():
frame_size = int(size_str)
img_start = frame_data.find(lines[1] + b’\r\n’) + len(lines[1]) + 2
img_end = frame_data.find(b’\r\nFRAME_END’)
if img_end > img_start:
img_data = frame_data[img_start:img_end]
if len(img_data) == frame_size:
nparr = np.frombuffer(img_data, np.uint8)
frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
return frame
except Exception as e:
print(f"Parse error: {e}")
return None
def get_frame(self):
if self.frame_buffer:
self.frame_count += 1
return self.frame_buffer.popleft()
return None
def stop(self):
self.running = False
if hasattr(self, ‘stream_thread’):
self.stream_thread.join(timeout=1)
self.ser.close()
def main():
print(“Starting OpenMV video stream…”)
print(“Controls:”)
print(" ‘q’ - Quit")
print(" ‘s’ - Save original resolution frame")
print(" ‘d’ - Save display resolution frame")
streamer = OpenMVStreamer()
streamer.start_streaming()
fps_counter = 0
fps_start = time.time()
try:
while True:
frame = streamer.get_frame()
if frame is not None:
fps_counter += 1
# Get original dimensions
original_height, original_width = frame.shape[:2]
# Calculate FPS
current_time = time.time()
elapsed = current_time - fps_start
if elapsed >= 1.0:
fps = fps_counter / elapsed
print(f"FPS: {fps:.1f} | Resolution: {original_width}x{original_height}")
fps_counter = 0
fps_start = current_time
# Resize for display
display_frame = cv2.resize(frame, (640, 480))
# Add information overlay
cv2.putText(display_frame, f"Frame: {streamer.frame_count}", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
cv2.putText(display_frame, f"Original: {original_width}x{original_height}", (10, 60),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
cv2.putText(display_frame, f"Display: 640x480", (10, 80),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
cv2.putText(display_frame, “Press ‘s’ for original, ‘d’ for display, ‘q’ to quit”, (10, 460),
cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1)
cv2.imshow(‘OpenMV Video Stream’, display_frame)
key = cv2.waitKey(1) & 0xFF
if key == ord(‘q’):
break
elif key == ord(‘s’):
# Save original resolution
if streamer.last_frame is not None:
filename = f"openmv_original_{streamer.frame_count:04d}.jpg"
cv2.imwrite(filename, streamer.last_frame)
h, w = streamer.last_frame.shape[:2]
print(f"Saved original ({w}x{h}): {filename}")
elif key == ord(‘d’):
# Save display resolution
filename = f"openmv_display_{streamer.frame_count:04d}.jpg"
cv2.imwrite(filename, display_frame)
print(f"Saved display (640x480): {filename}")
else:
time.sleep(0.01)
except KeyboardInterrupt:
print(“\nStopping…”)
finally:
streamer.stop()
cv2.destroyAllWindows()
print(“Stream stopped”)
if _name_ == ‘_main_’:
main()
when I run this code, it gives me 1920x1080 with almost 5FPS
with 1280x720, almost 15FPS.
with 320x240, almost 45FPS
does it mean, 1920x1080 with 30FPS not supported right?