Migrate MCP and utilities to CircuitPython, including color GIF and volume fixes

This commit is contained in:
Adolfo Reyna
2026-06-22 10:13:10 -04:00
parent 2863f21459
commit 8f871e499e
53 changed files with 4239 additions and 108 deletions
+47 -8
View File
@@ -19,21 +19,53 @@ def rgb565be(image: Image.Image) -> bytes:
return bytes(output)
def send_frame(sock: socket.socket, image: Image.Image) -> None:
def send_frame_tcp(sock: socket.socket, image: Image.Image) -> None:
payload = rgb565be(image)
header = struct.pack(">4sBBHHIH", b"IMCR", 1, 1, image.width, image.height, len(payload), 0)
sock.sendall(header + payload)
def sleep_us(duration_us: int) -> None:
target = time.perf_counter_ns() + duration_us * 1000
while time.perf_counter_ns() < target:
pass
def send_frame_udp(sock: socket.socket, ip: str, port: int, frame_idx: int, image: Image.Image, pacing_us: int) -> None:
payload = rgb565be(image)
frame_id = frame_idx % 256
for chunk_idx in range(154):
packet = bytearray(1002)
packet[0] = frame_id
packet[1] = chunk_idx
start = chunk_idx * 1000
packet[2:1002] = payload[start : start + 1000]
sock.sendto(packet, (ip, port))
if pacing_us > 0:
sleep_us(pacing_us)
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--ip", required=True, help="iPhone Wi-Fi IP")
parser.add_argument("--port", type=int, default=8083)
parser.add_argument("--width", type=int, default=400)
parser.add_argument("--height", type=int, default=300)
parser.add_argument("--protocol", choices=["tcp", "udp"], default="tcp")
parser.add_argument("--port", type=int)
parser.add_argument("--width", type=int, default=320)
parser.add_argument("--height", type=int, default=240)
parser.add_argument("--pacing-us", type=int, default=1000, help="Microseconds pacing between UDP chunks")
args = parser.parse_args()
with socket.create_connection((args.ip, args.port), timeout=8) as sock:
port = args.port
if port is None:
port = 8083 if args.protocol == "tcp" else 8084
if args.protocol == "tcp":
sock = socket.create_connection((args.ip, port), timeout=8)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
else:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
frame = 0
while True:
hue = (frame * 4) % 256
@@ -45,11 +77,18 @@ def main() -> None:
draw.line((x, 0, x, args.height - 1), fill=(red, 70, blue))
draw.rounded_rectangle((20, 20, args.width - 20, args.height - 20), radius=22,
outline=(255, 255, 255), width=4)
draw.text((40, 45), "iPhone MCP RGB565", fill=(255, 255, 255))
draw.text((40, 45), f"iPhone MCP RGB565 ({args.protocol.upper()})", fill=(255, 255, 255))
draw.text((40, 72), f"Frame {frame}", fill=(255, 240, 80))
send_frame(sock, image)
if args.protocol == "tcp":
send_frame_tcp(sock, image)
else:
send_frame_udp(sock, args.ip, port, frame, image, args.pacing_us)
frame += 1
time.sleep(1 / 20)
time.sleep(1 / 15)
finally:
sock.close()
if __name__ == "__main__":