| Menu | JAQForum Ver 19.10.27 |
Forum Index : Microcontroller and PC projects : Claude Code and PicoCom3 MicroPython
I've gotten my Claude Code subscription to work interactively with the PicoCom3 in PowerShell over Com4. Regarding the hardware, I have no RM2, audio, keyboard, mouse, or monitor, but do have PSRAM, microSD card, and RTC battery. Access is via the USB-C connector. I asked Claude Code to exercise the available hardware. This is its conclusion: Pico Computer 3 — MicroPython hardware test suite: results and findings Board: Pico Computer 3 v0.9 (RP2350B), MicroPython v1.29.0-preview, console on UART1 GP8/GP9 @115200 via CH340. Fitted: DS3231 RTC (battery), micro-SD, PSRAM. No RM2 WiFi, no audio, no HDMI, no USB peripherals. I put together a Python test suite (pctest.py) covering flash, SD, RTC, PSRAM, CPU and MicroPython internals, with PASS/FAIL and measured values. Final run: 23 PASS / 0 FAIL / 0 SKIP. A few findings seem worth sharing. 1. STORAGE SPEED — SD and flash are opposites write read SD 489 KB/s 494 KB/s Flash 66 KB/s 1120 KB/s SD writes about 7x faster than internal flash, but reads about 2x slower. So it's worth choosing per workload: SD for write-heavy or bulk logging, flash for read-heavy. SD's near-symmetric figures suggest the SPI link is the limit rather than the card. The slow flash write path (~66 KB/s) has a practical side effect — see point 4. 2. SD SOCKET — a card can sit in a "feels seated" position I lost a debugging cycle to this, so flagging it. The socket had a catch that lets a card rest partly inserted while making no contact. It does not feel obviously wrong. Symptoms: - /sd missing from os.listdir('/') - pcsd.mounted() and pcsd.start() both False - machine.SDCard() constructs OK, but ioctl(4,0) returns -5 (block-count query unanswered) - vfs.mount() gives OSError(16) EBUSY - survives a soft reset and a casual reseat This reads like a driver or format problem but is purely mechanical. Push the card in further before suspecting software. Once seated properly it auto-mounted at boot with no other change. Two related traps: - ioctl(5,0) returns 512 even with no working card. That's the driver's default block size, NOT proof a card is present. - os.statvfs('/sd') does NOT raise when the SD is absent — it returns the FLASH stats, so it looks like a healthy 12MB card. Detect the card with os.listdir('/sd') in a try/except instead. 3. PSRAM — effective bandwidth is dominated by cache residency This was the most interesting result. Writing a large buffer measured absurdly slow (~0.3 MiB/s), so I swept buffer size. Every row below does an IDENTICAL amount of work: 256 slice-assignments of 16 KiB = 4 MiB moved in total. buffer time effective 16 KiB 21 ms 190.48 MiB/s 64 KiB 683 ms 5.86 128 KiB 1273 ms 3.14 256 KiB 2420 ms 1.65 512 KiB 4692 ms 0.85 1024 KiB 9227 ms 0.43 2048 KiB 18293 ms 0.22 Constant work, but time scales with buffer size. My reading is that this is cache hit rate rather than memory bandwidth: a small buffer is rewritten in place and stays resident, a large one misses on essentially every write. Reads measured ~2.4 MiB/s on a 4 MiB buffer. Caveat: these are MicroPython-level numbers (bytearray/memoryview slice assignment), not raw hardware bandwidth, and I have not confirmed the cache mechanism directly — that's an inference from the shape of the data. Happy to be corrected if someone knows the RP2350 PSRAM path better. Practical takeaway either way: keep hot working sets small (tens of KiB). Streaming multi-MiB buffers through PSRAM is roughly 500x slower than working cache-resident, and will dominate runtime. Also: a 4 MiB bytearray allocates fine on a clean heap but raised MemoryError after earlier alloc/free cycles, so the heap fragments — allocate large buffers early. 4. UPLOADING FILES — per-line paste delay is not enough Pasted uploads were silently corrupting: files valid on the PC arrived as SyntaxError on the board, with no error from the upload itself. The dropped characters were WITHIN single long lines (a 180-char line failed to parse), not at line boundaries. I had been using a 20 ms per-line delay — twice the 10 ms per-line that works fine in TeraTerm under MMBasic — and it still corrupted. The difference seems to be that MMBasic tokenises each line on receipt, whereas the MicroPython REPL echoes and parses per character and floods its RX buffer mid-line. Flash block-erase stalls (see the 66 KB/s write figure) make it worse. What fixed it: pacing bytes WITHIN the line (16-byte blocks, 4 ms apart), base64-encoding the file, prompt-syncing each chunk, and verifying length + checksum afterwards with a retry. Byte-exact since. If you're scripting uploads over serial to MicroPython, verify the file after transfer — autosave() paste gives no integrity guarantee. 5. RTC DS3231 works well: reads, ticks, and agrees with the MicroPython system clock to within a second. It arrived reading exactly one month behind (2026-06-18 for an actual 2026-07-18), plus about 6 minutes slow. The reading was internally self-consistent — yearday 169 and weekday both matched June 18 — so the month field is 1-based and the chip had simply been set wrong at some point. An exactly-one-month offset looks like a setter writing the month without a +1 adjustment somewhere, but I can't say where it came from, and it may just be this board's history. (lizby: I set the RTC when I got the board and may simply have entered the wrong month.) API note: ds3231.settime(Y, M, D, h, m, s) takes POSITIONAL ints; a tuple raises "TypeError: can't convert tuple to int". It updates the MicroPython system clock too, so no separate sync call is needed. Battery backup confirmed with a real power cycle: stamp written at 12:06:10, board fully powered down, RTC read 12:30:22 on next boot with an uptime of only 127 s — so it tracked ~22 minutes unpowered. 6. OTHER - CPU 252 MHz: ~284 kflop/s, ~864 kiop/s. These are interpreted MicroPython figures, not FPU peak. - ulab 6.12.1-2D-c is included. Roughly 3x faster per element than a list comprehension on the same work (~1.8 us vs ~6.1 us). - gc reclaims reliably; ~8 MiB free heap in PSRAM. - Multi-line blocks (try/for/def) pasted into the REPL get mangled by auto-indent — use a file. I can share pctest.py or the uploader if anyone wants them. Note on setup. I got Claude Code in the browser to walk me through getting Claude Code in Powershell working (Pro, Opus 4.8--$20/month subscription). After it was talking to the PicoCom3 I hit shift+tab until it got into autoApprove mode, so it was no longer asking me about every interaction. Then I gave it the prompt, and it went through dozens if not hundreds of interactions, with me inserting a few "/btw" notes as it went along. I know next to nothing about Python, but what a sweet setup. Thank you Peter. ~ Edited 2026-07-19 02:02 by lizby PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on FOTS |
||||||
Well, I didn't expect to get back today. After a little bit of setup to prepare and provide the files, at 1:20 I asked Claude to replicate my PicoDB project. By 3:39 it had done it to the extent of running my 56 test queries and comparing successfully to the results from running those tests on the MMBasic version. Against the MMBasic original ┌──────────────────────┬───────┬───────┐ │ │ lines │ code │ ├──────────────────────┼───────┼───────┤ │ d8a2.bas │ 2,826 │ 2,068 │ ├──────────────────────┼───────┼───────┤ │ library.bas + db.bas │ 2,837 │ 2,099 │ ├──────────────────────┼───────┼───────┤ │ Python runtime │ 2,450 │ 1,649 │ └──────────────────────┴───────┴───────┘ Exclusive of comments, 1,649 lines in 2 hours and 19 minutes. I thought I was doing very will to build MMBasic PicoDB interactively with Gemini in about 5 very full weeks. Gemini provided the code, I uploaded to to the PicoMite, passed back the results, and repeated day after day. Claude started with much more complete documentation and a results file to build to, but 1,649 lines of working code in that amount of time is spectacular by my standards. Claude made hundreds, perhaps thousands of iterations. I dropped in a few more "/btw" notes. All of this within (as far a I could tell) a single token-block of time with never a pause. Here's a comparison of the test run times MMBasic vs micropython: Per-test comparison, PC3 flash, both RP2350 38 faster · 4 about equal · 11 slower MMBasic total : 237.6 s Python total : 33.2 s overall : 7.2x faster Excluding test 56 (MMBasic's pathological 123 s, corrupted by leaked state): 114.3 s vs 31.8 s — still 3.6×. Index build (4.5 s) excluded from both, since MMBasic's startup index build wasn't timed either. Where Python wins big — the indexed compound queries ┌─────────────────────────────────────┬────────────┬──────────┬──────┐ │ test │ MMBasic │ Python │ │ ├─────────────────────────────────────┼────────────┼──────────┼──────┤ │ 5 (Abilene|Fresno)&CA │ 10,694 ms │ 66 ms │ 162× │ ├─────────────────────────────────────┼────────────┼──────────┼──────┤ │ 25 verify delete │ 4,856 ms │ 46 ms │ 106× │ ├─────────────────────────────────────┼────────────┼──────────┼──────┤ │ 56 city~%City │ 123,263 ms │ 1,336 ms │ 92× │ ├─────────────────────────────────────┼────────────┼──────────┼──────┤ │ 2 Abilene & state=TX │ 4,994 ms │ 69 ms │ 72× │ ├─────────────────────────────────────┼────────────┼──────────┼──────┤ │ 27 verify undelete │ 4,853 ms │ 73 ms │ 67× │ ├─────────────────────────────────────┼────────────┼──────────┼──────┤ │ 30 city~%Los% & occupation=Engineer │ 6,997 ms │ 289 ms │ 24× │ └─────────────────────────────────────┴────────────┴──────────┴──────┘ These are exactly the cases where MMBasic fell back to scanning and my planner uses an index. Next test: 65,000 records on SD card. |
||||||
Nifty !! That would be useful for many others, it would be good to post it. BTW who owns code generated by Claude - are there issues with that ? |
||||||
Any code generated by an AI under instruction from a user is owned by the user. For paid AI coding tools (Copilot, ChatGPT Plus, Claude Pro, etc.), the industry‑standard rule is: The user owns the output. This is because: You provided the instructions. The AI generated original code in response. Paid AI services explicitly grant you rights to use the output commercially. Microsoft, OpenAI, Google, Anthropic — all follow this model. |
||||||
Zip file contains pctest.py, which tests selected hardware on the PicoCom3, mp_bridge.py, which handles interaction between the (Win11 laptop) PC and the PicoCom3 on (in my case) COM4, and CLAUDE.md, which contains instructions for claude code including general (regarding the hardware and python) and some specific to the task of building PicoDB in micropython to run on this board. pctest.zip |
||||||
Couple of observations based on previous MicroPython use: SD Card: the official sd card library - sdcard (MIM install link: sdcard | mim) - is a little slow, but works. There have been numerous attempts to refactor this for speed, but so far none have been portable or reliable enough. Automount polling hasn't been a thing as detection of card presence isn't always possible on all hardware. Serial transfer: mpremote, MicroPython's own REPL/management tool, needs no EOL or character delays. For pasting code, the REPL expects you to be in Paste mode (Ctrl-E, then Ctrl-D to finish or Ctrl-C to cancel paste) or you may lose characters or lock up the board. |
||||||
Thanks for the comments regarding SD card and serial transfer. In this case, Claude determined what would work empirically--with multiple block size tests for the SD card, and inter-line and eventually inter-character delays in serial transmission. Some of it I watched, but I never intervened (and didn't know enough to be helpful in any case). If investigations by others determine better ways, they can be folded back into the CLAUDE.md file. For me, the important thing was that after laying the foundation and giving the prompt, I did almost nothing, including pay attention to what was happening. |
||||||
So Claude Code (Opus 4.8) built the 64,000 record database, iterated the batch test run with 56 queries, fixed some problems including garbage collection that only showed up after query # 53, and ultimately provided code which ran all the queries. I connected a 7" hdmi screen so I could see Claude working--not quite as useful as telnet with MMBasic, but good for viewing Claude at work. I only had a few interactions as I mostly did other things for the past two days. The 2 linked files are 13.7 and 2.8 megabytes on the SD card. Indices are on the flash drive. Queries on indexed fields which just hit the main file are quick--1-2 seconds. Results which include fields from the two linked files and which require maybe hundreds of random access reads on the two files may take 10 minutes. The whole 56-query test run took 87 minutes. My 2-month interactive journey with Gemini to initially build PicoDB and PicoRR in MMBasic proved that the prediction that I read in January was true -- 2026 would be the year when coders who knew what they wanted could use AI "all day, every day". But "agentic" AI, where you tell AI to do a long task and leave it to run on its own interactively with connected hardware (or with multiple facilities on your PC and on the internet) is a different matter. I don't have enough tasks to keep subscription Claude Code busy. And for a long task, it's Claude that is busy "all day", not me. I suspect I could tell Claude Code to implement Windows 3.1 on this hardware in C and it could do it, since I think the PicoCom3 is pretty close in capacity to an early Pentium. Of course, with the SD card, the storage available is far beyond what a 90's desktop would have. |
||||||
Isn't this super-impressive or am I misinterpreting? |
||||||
Thanks for the write-up. John |
||||||
| The Back Shed's forum code is written, and hosted, in Australia. |