My 6yo daughter asked for a microscope after reading one of the Magic School Bus books. Being handy with a 3d printer and having most of the parts lying around in drawers, and having acquired conversational SCAD through adjacent hobbies, OFM “just clicked”.
tl;dr
totally pleased, works entirely as advertised, very extensible, a joy to build and to play with. I made some opinionated changes to the electronics, especially driving the motors in software off the Raspberry Pi 4 GPIOs instead of using a dedicated MCU or Sangaboard. The kids are already begging to put various household items and debris under it. Even the spousal unit approved, which is rare among my hobbies.
Detailed notes
Plan
My notes start on August 5, the build was mechanically complete on Aug 30 or so and I eventually took to the software. Operational readiness yesterday. Most of the time was waiting for oddball parts to be delivered, probably 3 weeks of shipping delay overall, and a few iterations figuring out what I’d need between the BoM, what I have on hand, translating into AliExpress-ese and Amazon-ese, and comparing what eventually arrived to the instructions and the parts I had printed out ![]()
Assembly was a breeze, the instructions were great overall, I would estimate more than one standard deviations above the average DIY project and especially for something of this novelty and complexity. Moderate difficulty overall and some of that self-induced.
I initially had missed the detours in the build instructions around HQ optics and had mentally merged the condenser lens and the tube lens, but figured that out eventually and with only minimal impact to the schedule.
Design
As a hobbyist I flinched at the Sangaboard, mostly due to familiarity with why one would make a board like that. I know the joys of finding and ordering a niche PCB, but personally and for my daughter’s use case I preferred the pleasure of commodity components, i.e., abundance. Especially temporal abundance, as in, when something inevitably breaks I have a pile of them in reserve. This is a personal preference. My preferences also take me away from Arduino products. I have raspberry pi picos in drawers and would have used them, especially as the alternate electronics scads seem pico friendly, except I didn’t see the power path worked out in the alternate workflow.
I saw the thread about direct wiring everything from the Raspberry Pi, understand the reasoning behind a separate MCU, but used direct wiring anyway since I think it’s fine for my 6yo and me.
The 3.0.0 server made it straightforward to extend the server process with custom stage and illumination logic.
I built the upright microscope with HQ optics.
Build
For power, I took the workaround motor scad and refactored that to substitute a commodity USB PD “decoy” [1] running at 20V and a buck converter [2] that I have lying around (the links are representative, these seemingly generic parts do not seem to have common names), in the place where the Arduino was. Opened up the GPIO pin header cutout so I could route cables comfortably to any of the Raspberry Pi’s 40 GPIO pins from the ULN2003’s above.
For the illumination I made a little 15mm round “pcb” in OpenSCAD in the style of a constant current circuit I found online [3] using again commodity through-hole bits I had in drawers, reamed with a 1mm drill, and poked the components through that and soldered the leads together to make the circuit. I adjusted the resistor values to fit my bulk white LED, which self-identifies as 20mA, 2.8V-3.6V, giving 4.7 kΩ for R2 and 20 Ω for R1. I opened up the upright condenser platform a little as the completed circuit was around 2mm or 3mm too tall, also I had tacked on another transistor, between R1 and GND, for PWM on the LED, which necessitated a wider opening at the front for the extra pin. The constant current circuit overall was a little challenging due to the scale and density of the features, both for the printer and for hand soldering but it worked out.
Hardware PWM on the Pi for the LED, and a custom OFM server 3.0.0 software extension drives the 28byj-48 motors with their bundled ULN2003 drivers using pins from the Raspberry Pi header.
I printed all the parts on a Prusa XL out of Overture PETG. Didn’t spend a lot of time calibrating but did drop the extrusion temperature a bit to get the ladders in the test prints clean. The XL enclosure and the extruders can apparently suffer some heat creep, so I kept the chamber open for the first half-hour or so after clogging 2 nozzles and haven’t had any problems since (I was able to unclog the nozzles by removing them, zapping them with a heat gun, and plunging them out with 2mm steel rod). In spite of the OFM build instructions deterring supports, I put supports in a couple places with the Prusaslicer “paint on supports” function, which I think helped, for my setup at least.
For optics I found a 12mm / 50mm focal length doublet on Ali, a random 12mm condenser lens off Amazon, and an Amscope plan 40X objective off Amazon. I picked up a calibration slide off Amazon too, which helped a lot during setup and optics calibration.
I used these commodity o-rings off Amazon.
For cabling I crimped “dupont” headers on 26ga (power) and 28ga (signals) silicone coated tinned copper wire, stranded, except the LED circuit connector, where I used a JST-XH female header due to space. JST-XH has the same 2.54 mm pitch as dupont headers but they are shorter – these are the same family as the white plastic ones as the ULN2003 boards use with the motors. Spliced the power lead and ground into five lines for the motors, the raspberry pi, and the LED, and covered the splice with heatshrink.
The software install was straightforward once I sorted out issues I had with the raspberry pi imager as noted in the other thread. Started on the 2.x server series but upgraded to 3.0.0 beta as that was timely for my build.
I had Qwen 3.8 27B build out the extension for direct GPIO control from the pi and the LED circuit, it took all of 15 minutes or so once I got the thing pointed in the right direction and gave it access to all the source. Filtered the OFM openapi spec into just the pertinent bits to reduce context demands on my DIY setup. The extension model in 3.0.0 was a snap.
Results
Overall great, this thing is very intuitive and fun to use. I love the no-nonsense visual style, very functional, no distractions. Let’s start observing!
I have used only the web interface.
In terms of performance, jitter is indeed a problem with software driving the motors. It doesn’t pass stage calibration, complaining about jitter. My desk is vibrating all the time apparently. At all times the calibration slide appears wobbly to the tune of a few pixels on the webcam stream and with visible tears in a few places, even when the motors are off.
A commodity 20mA white LED is enough to light up the pi camera 2, but I am contemplating an upgrade to something brighter.
My Raspberry pi crashes and reboots sometimes. First guess is a power concern. With hindsight, probably shouldn’t have omitted the power line capacitor I had drawn in
, will probably crimp one in if it gets annoying.
Remarks
Overall tickled with the quality of the OpenFlexure project, it’s been a purified strain of joy throughout. Clearly a lot of thought and love has been put into every aspect. And the overall concept is genius.
In terms of critique, I have very little beyond my personal interests, perhaps not much that hasn’t been shared by others previously. In case it’s of value:
- the route of the ribbon cable to the Pi camera doesn’t feel finished, it’s currently rubbing the edge of the slide as it routes down to the electronics. first I would probably turn the camera pcb 90 degrees as this seems to improve the routing of the ribbon cable to where it is located on the pi, then I may create some kind of shelf or conduit for it
- I would consider using heat-press inserts instead of captive nuts for fixtures. Or use square nuts instead of hex to reduce spinning. For hobby projects I usually just plumb an M3 hole and tap it out by hand, and then use regular M3 machine screws directly in the tapped hole. Takes just a moment, plenty strong, and is good for a small number of uses.
- Stylistically if it were my design I’d substitute flathead for caphead in a few places and smooth some of the lines. It’s gratuitous and fattens the BoM but that’s my preference.
- The M3 25mm hex bolts were annoying to source, those seem pretty niche. Not expensive just hard to come by here in the US on Amazon, Ali, etc. Didn’t want to go through McMaster. Might aim for a similar experience by altering the shape to have an embedded nut on the other side of the gears and driving an M3 screw through it. Flathead if you were bothered but a caphead looks like it’d be fine, dimensionally.
- a few places where 2mm screws could be substituted with tabs, such as the cable tidies, it’s a small optimization really.
- in terms of software, the calibration wizard started at first boot but I didn’t have the LED turned on yet in my customized build, ended up putting in a config option in my illumination module to start with the LED on so I didn’t have to call the API by hand to turn on the LED. chicken and egg problem. not sure I can find an LED on / off button tbh in the web interface, will probably put one in.
- overall heat management seems to be potentially an opportunity for improvement. The electronics and the motors get warm to the touch and airflow seems to convect right up to the slide. Some grills at least on the side of the stand would help. Perhaps the electronics can be moved to the perimeter of the stand and airflow directed passively outward, so that it doesn’t fume (exaggerating for jest, it’s just warm not smoking) the slide constantly. Especially the sangaboard and official illumination seems to be a 1W part? Heatsinks and passive air circulation elements feel due.
- inserting the Pi and the extension board assembly into the upright stand was an ergonomic novelty, not in a good way. I found it much more intuitive to drop in the board assembly from the top, especially with wires going everywhere and the wires being stiffened by heatshrink and the dupont connectors. It nearly works with the current geometry, except the captive nut block on the stand that receives the Pi assembly interferes slightly with vertical insertion – it seems otherwise perfect geometry if you rotate the Pi assembly 90 degrees about the sdcard - usb axis as you insert the Pi assembly squarely into the upright stand. With the current geometry though if you get it just right and apply gentle pressure vertically and laterally it’ll eventually click in with a satisfying (and initially scary) loud pop.
- I have thoughts on iterations to Pi-native motor control. E.g., upgrading to DRV8825 type controllers and driving the step/dir interface (i.e., the step pins) with GPIO general purpose clocks on the BCM2711, or perhaps trying to run the motors from the GPU and / or interrupt logic.
[1] [2] [3] will try to attach images in a reply, the image attachment function gave me some grief last time I tried it.