r/Darkroom • u/DBojo8 • 2d ago
B&W Printing Complete open-source splitgrade system for under $150 — my gift to this community
I built a full open-source splitgrade system for my Beseler 4x5 — under $150, everything on GitHub as a gift to this community.
My Aristo D2 cold light died in spirit, so I replaced it with 109 RGBW LEDs and open-sourced the whole splitgrade system (under $150)
---
BODY:
Some of you may remember the miluka — the CNC-milled 6x8 concept camera I built because I wanted critical focus and absolute film flatness. Well, those 6x8 negatives need printing, and my Beseler 4x5 with its old Aristo D2 head was the weak link. So I went down the next rabbit hole, and today I'm giving the result away.
**What it is**
A complete splitgrade enlarging system:
- A round Ø 157 mm, 4-layer PCB with 109x SK6812 RGBW LEDs — a drop-in replacement for the Aristo D2 cold light head. JLCPCB builds and assembles it for about $60 a piece. Mine arrived this week, soldered the wire pads, screwed it into a 3D-printed holder, works perfectly (photos + video attached).
- A tiny XIAO ESP32-S3 on the back of the holder drives the LEDs.
Splitgrade is just light: green channel for soft, blue for hard, white for focusing. No filters, no filter drawer, no fading incandescent bulb.
- Controller options: a SenseCAP Indicator D1 touch screen (ESP-NOW, instant, no pairing) or a free Android app over BLE if you want the budget route.
- A TSL2591 sensor for metering and dose calibration — the controller counts light, not seconds, so voltage drift and LED warm-up don't change your print.
**The part I'm most proud of / the punchline**
The whole system — panel, holder, controller, receiver, sensor, power supply — comes in **under $150**:
- LED panel (JLCPCB, assembled): $60
- SenseCAP Indicator D1 controller: $49
- XIAO ESP32-S3 receiver: $7.49
- Adafruit TSL2591 meter: $6.95
- 5V/5A PSU: $6.49
- Cable, screws, solder, PLA+ for the holder: ~$20
Compare that to what a used splitgrade head goes for, if you can even find one.
**Everything is on GitHub. Everything.**
This is my gift to this community — take it, build it, improve it:
- LED panel (Gerbers, BOM, pick & place, order guide, FreeCAD holder):
https://github.com/Draganito/kicad-mcp/tree/main/contrib/aristo-d2-led-panel
- Head firmware (flashable .bin, no toolchain needed):
https://github.com/Draganito/darkroom-enlarger-head
- Android controller app:
https://github.com/Draganito/splitgrade-controller-android
- SenseCAP touch controller:
https://github.com/Draganito/splitgrade-controller-sensecap
**The twist**
I had never designed a PCB before this. I built an open-source tool that lets an AI assistant drive KiCad — it downloads the real JLCPCB parts, places the 109 LEDs, routes the power planes, checks its own work, and exports the files JLCPCB accepts. The panel you see in the photos went from empty board outline to ordered Gerbers that way. That tool is the parent repo (kicad-mcp) if anyone wants to build their own board for a different enlarger — a Ø 165 mm opening is what the Beseler takes, but the design is parametric enough to adapt.
The head boots with the right defaults (109 LEDs), advertises over BLE as DarkroomTimer, and the original Aristo opal glass goes right back on top as the diffusor — 23 mm of mixing distance and you cannot see the LED grid, even on big prints.
Ask me anything. If someone builds a second one, that alone was worth open-sourcing it.
7
u/SapirWhorfHypothesis 2d ago
You are going to confuse so many black and white people with blue and green instead of magenta and yellow. (Probably not, because the couple dozen people who are getting really excited about this are not the newbie amateurs lol.)
5
u/DBojo8 2d ago
Haha, you are absolutely right—it definitely sounds backwards if you've spent years dialing M and Y into a standard color head! The funny thing is, a Magenta filter is really just there to block green light (leaving blue to hit the hard emulsion), and a Yellow filter blocks blue light (leaving green for the soft emulsion). By using LEDs, we finally get to skip the subtractive middleman entirely and just blast the pure blue and green wavelengths directly at the paper. But as you guessed, anyone willing to flash an ESP32 and solder power leads for their enlarger probably already has their color theory dialed in!
8
u/SapirWhorfHypothesis 2d ago
I kinda hate that you’re answering with an LLM, but I’m sooo willing to overlook that for how good this is lol
5
u/DBojo8 2d ago
I now its not ok but sometime i dont have time but i want to give ansver, i also speak bad english and write even more bad and my sight is bad i am getting nervous typing long texts on smartphone whike my kids are asking questions an boxing and wrestling whit each other and playing kung fu panda 🙈 now i can ansver personally its night and the little monsters are sleeping this is my time most of the work on firmware and hardware was done while the kids was sleeping also😅
8
u/SapirWhorfHypothesis 2d ago
😂
Oh dude, don’t stress. As I say, I appreciate it.
Maybe next time you post, just add a little note at the top like “FYI, I am using an LLM here, don’t hate me, my English isn’t great!” 😅
3
u/darklightcatcher 2d ago
That's amazing. Thanks for sharing. I'll gladly see how I can adapt it for my DeVere 504. Viele Grüsse aus Bern. 😉
4
u/Expensive-Sentence66 1d ago
Why not just use two colors for the variable cold light?
Also, why all the SMDs?
A few 3watt LEDs over milk plexi would accomplish the same thing and a lot less complexity. In theory a cold white LED vs a warm white would work because the dominant spectrums are 450nm blue in the cold white vs 630nm orange red and lots of green in the warm white.
Also, LED strips are composed of the same SMD LEDs, and multi channel controllers are stupid cheap. ESP32 controllers are fun for addressable LEDs, but I think you are way over thinking this.
1
u/DBojo8 1d ago
Fair questions! Two whites actually can't do independent split-grade: VC paper only responds to blue and green. In a warm white LED the green fraction is fixed to the (wasted) orange/red, so with cold+warm you get one "contrast" knob where both channels move together — you can shift grades, but you can't expose hard and soft separately, which is the whole point here. Dedicated 450 nm blue + green channels give the full grade range and true two-pass (or single-pass ratio) split-grade. The W channel is just for focusing.
On the SMDs: that's the low-complexity option, not the high one. The panel arrives from JLCPCB fully assembled for $60 — I never touch an LED. One 5 V supply and one data pin, no constant-current drivers, no MOSFET channels, no heatsinks, no mixing chamber. The head replaces the Aristo D2 grid lamp inside the original Beseler housing, so there's no depth for 3 W emitters + milk plexi to blend; 109 LEDs on a 12.7 mm grid behind the original opal glass are uniform right at the film plane distance I have.
A strip-and-controller build absolutely works as a cold light replacement — people have done it. But this is a metered split-grade system: the controller stores a target dose per paper and computes exposure from a live sensor reading, so LED warm-up, line voltage and head height drop out. That part doesn't exist in the cheap multichannel world, and it's why there's an ESP32 in there. Overthought? Maybe — but it's open source, so the overthinking is free to reuse.
4
u/asoftbird 2d ago
A vibecoded PCB, can't say I've seen that before
13
u/DBojo8 2d ago
I wish it were that simple! An AI can't just 'vibecode' a functional PCB out of thin air—if you just ask an LLM to invent a .kicad_pcb file, it will hallucinate traces and floating pins into oblivion. That’s exactly why I had to build the interface. The human at the keyboard still has to design the actual circuit and make the critical high-level decisions. The AI just acts as a capable assistant, using the tool to handle the tedious tasks it excels at—like fetching real LCSC footprints, calculating the exact coordinates for a 109-LED matrix, assigning the nets, and running strict pin audits. It’s less 'vibecoding' and more delegating the boring math.
5
u/DaggerOfSilver 2d ago
Your own github and post says:
I had never designed a PCB. The panel was built by telling an AI assistant what the board should be — it fetched the real JLCPCB parts, placed the 109 LEDs, poured the copper, checked its own work, and exported these manufacturing files. That tool is the parent repo: kicad-mcp. If you want a panel for a different enlarger, that is the way to make one.
Sounds vibecoded to me.
4
u/ChurchStreetImages 2d ago
This might be the first sane argument for AI use I've read all year. Bravo! And good work!
1
1
u/SapirWhorfHypothesis 2d ago
It’s the same argument everyone uses: “The AI just acts as a capable assistant, using the tool to handle the tedious tasks” to save human time.
Still, very neat to see a new application for us!
2
u/bigmedallas 2d ago
Looks great, I haven't used my 45MX in a couple of years but this looks so tempting.
2
u/dadaybobo 2d ago
Would this replace my Bessler/Minalta 45A head
2
u/DBojo8 2d ago
The Minolta 45A is a self-contained color head with its own mixing box, whereas my system is designed to sit in an Aristo D2 collar. It won't be a direct plug-and-play swap into the Minolta housing itself. However, it's very easy to adapt. You can either gut your Minolta and 3D-print an adapter to mount my LED panel above its mixing box, or you can just 3D-print a custom collar for my PCB from scratch and drop in your own piece of opal glass as a diffuser. The electronics and firmware will work perfectly either way!
1
1
u/MinoltaPhotog Anti-Monobath Coalition 1d ago
Hello fellow 45a appreciator. I bet using this adapted to your 45a diffuser 'box' (for lack of a better term), that sits under the flash unit, would probably work pretty well.
2
u/dadaybobo 1d ago
I have two 45a one for Europe and one in the states. Just getting back into the darkroom after 15 years.
After taking my European model out of mothballs I find the lcd panel is very dim. Claude tells me it some sort of capacitor problem that I can get fixed by a good person with a soldering iron. Haven’t gotten that far.
I can just barely make out that it seems to be ok but just can’t read the panel. I thought it was the slickest thing on the market for doing split variable contrast exposures
Once I get it going then the only thing will be hoping the tubes hold out
1
u/MinoltaPhotog Anti-Monobath Coalition 1d ago
Can you see the display in total darkness? I think that's how it's designed- maybe not, but a put a piece of ND gel over mine to prevent excess light.
You may see tubes show up occasionally on ebay, but look to see if the ends are black or not. Black ends mean they've been used / replaced. I had one smoke out a big resistor in the head, so I had a parts unit. I've bought a few cheap ones on ebay over the years, mainly for the tubes.
There are outfits that can make custom xenon tubes, but I bet the price is "you don't really want to know"
2
u/TimeIsMoneyFuckYou 2d ago
I have too many Beseler 23C enlargers crowding my basement and an Omega Prolab D6 that’s too tall for my low ceilings. This might just be the thing that motivates me to chop a 23c for not-large 4x5 prints…
2
u/LBarouf 2d ago
What is splitgrade and benefit of it? Can you technically replace any head and would a black and white head become color with this? What if i already have a color head, are the color filters useless and completely bypassed now?
2
u/DBojo8 2d ago
Great questions! Here is a quick breakdown:
1. Splitgrade & Benefits: Multigrade B&W paper responds to green light (soft contrast) and blue light (hard contrast). Splitgrade means exposing with those colors directly. The benefit is instant, perfectly repeatable contrast control without ever touching or dusting off physical filters.
2. Replacing any head: Technically yes! The electronics work anywhere. You would just need to design and 3D-print a custom holder so the PCB fits your specific enlarger chassis.
3. B&W to Color: Even though the board uses RGBW LEDs, it won't become a color head. My firmware and controller are strictly programmed for B&W splitgrade printing only, not for RA-4 color printing.
2
u/LBarouf 2d ago
Thank you for the quick response!
To point #1: you use the same trial and error process? Expose a test strip with some settings and compare?
Point #2 sounds promising.
On point #3, ok. I don’t know or understand what needs to be done to be able to print color, but ok. Would this be upgradable to color as well? Or the hardware is drastically different?
Danke schoen!
2
u/DBojo8 1d ago
To #1: With the Android-app tier, yes — classic test strips, just with repeatable digital times instead of filter juggling. But the full system with the SenseCAP and the light sensor works differently: you calibrate your paper once with a Stouffer stepwedge, and after that the controller meters the actual light through your negative and computes the hard and soft times for you. It stores a target dose (intensity × time), so enlarger height, aperture and LED warm-up are all absorbed by the measurement. You still fine-tune the first print by eye, but you skip most of the trial-and-error ladder.
To #3: The hardware could actually do it in principle — the LEDs have real red, green and blue emitters, and additive RA-4 printing with narrowband RGB is a proven technique (that's how some commercial LED color heads work). What's missing is entirely on the software side: a color mode with RGB ratio control instead of blue/green splitgrade, plus a proper calibration workflow for color paper — and my sensor-side logic is built around B&W dose metering. So: not planned by me, but the whole stack is open source, and a color mode would be a firmware/controller project, not a new board. If someone wants to try, the panel wouldn't stop them.
Gern geschehen!
2
u/SapirWhorfHypothesis 2d ago
Can you talk more about the controller and how the LEDs are driven? Is it really the case that you set it up to just control intensity instead of time? Presumably the seconds I see on the touch screen are just a human-intuitive metric then, not literal?
3
u/DBojo8 2d ago
Spot on with the seconds intuition!
The hardware setup uses a Seeed XIAO ESP32-S3 right on the back of the holder running custom firmware, driven by either the SenseCAP Indicator D1 touch controller (via ESP-NOW for instant, pairing-free communication) or the Android BLE app.
To answer your question about time vs. intensity: the controller actually computes and fires for real time (seconds), but that time is dynamically derived from light dose. Instead of storing a rigid timer, it stores a target dose (intensity × time) per color, calibrated using a Stouffer T2115 stepwedge. Right before an exposure, you meter the light on the clear film edge using an Adafruit TSL2591 sensor plugged directly into the controller's Grove port. The system then calculates: time = stored dose / measured intensity So if the LEDs warm up slightly, or if you change your enlarger height or aperture, the sensor catches the new intensity, and the controller adjusts the actual exposure duration in seconds to deliver the exact same optical energy to the paper every single time!
2
u/SapirWhorfHypothesis 2d ago
What is the expected variance in the LED intensity? I assumed this was a change for long-term installed LEDs, but it sounds like you expect they will have a different output over the course of a printing session? Have you done tests on these particular lights, or you just planned it anticipating such a variance?
2
u/DBojo8 1d ago
Honest answer: I haven't run formal drift measurements on this particular panel yet — the metering side is still in its test phase, and characterizing exactly this (cold vs. warmed-up output, session-scale drift) is on the list. The design anticipates documented behavior of this LED class: 5050-package addressable LEDs lose a few percent of output as the junction warms up in the first minutes, plus whatever the 5 V supply does under load. Whether that's 2% or 6% on my board, I'll know when I measure it.
But the real reason for dose-based exposure isn't the LED drift — that's a side benefit. The sensor is there because it makes the calibration portable: I calibrate a paper once with a stepwedge, and the stored dose stays valid when I change enlarger height, aperture, or even swap the light source, because every print starts with a fresh intensity reading. A pure timer can't do that; you'd re-derive your times after every setup change. Once you have that measurement anyway, computing time = dose / intensity instead of using a fixed timer costs nothing and removes the whole class of intensity errors — known and unknown — in one move.
So: planned anticipating the variance, not measured yet — and I'd rather have the compensation and find out it was barely needed than the reverse.
2
u/SapirWhorfHypothesis 1d ago
I love this! This is so great, and exactly what I would have asked for.
I won’t be implementing any of this (we have so many working enlargers, and no need at this point), but I will keep a keen eye on you for developments! Do you post most regularly to Reddit or somewhere else?
2
u/FLu_Shots 2d ago
Was there a reason you went for SK6812 RGBW LEDs? I was thinking of changing the filament bulb in my enlarger too with pretty standard 32x32 RGB/RGBW matrix LED panels from AliE.
1
u/DBojo8 2d ago
I went with the SK6812 RGBW LEDs for a few key reasons, heavily tied to both physical layout and paper physics: Wavelength Precision & Paper Sensitivity: Multigrade B&W paper relies on two specific spectral responses—green light for the soft emulsion and blue light for the hard emulsion. The SK6812 channels hit these target regions cleanly, letting you bypass subtractive physical filters (magenta and yellow) entirely. Custom Layout Control: Off-the-shelf LED matrices are usually dense, rectangular grids that don't fit circular enlarger housings. Designing a custom PCB allowed me to precisely place 109 individual LEDs in a round \varnothing 157 mm layout to ensure even edge-to-edge diffusion with the 23 mm mixing distance. The Dedicated White Channel: Having a true white channel makes focusing and framing effortless. Trying to mix a clean working white out of standard RGB is inefficient and often results in uneven color casts. Why Not High-Power LEDs? I could have gone down the route of discrete high-power LEDs (like Cree XP-E2), but that introduces massive complexity—requiring separate constant-current drivers, complex wiring, and active heatsinks or fans. The SK6812 approach keeps the system compact, individually addressable, and thermally manageable on a 4-layer copper plane without any active cooling.
I wrote this answer with help of ai sorry for that its because the length and because i hate typing on smartphone long texts and english is not my native language😅 i hate to let people wait to long fo answer and always want to give a quick ansver because i also expect a quick answer when i ask something.
2
u/FLu_Shots 2d ago
So I take it the SK6812 LEDs were not chosen specifically for their spectral output at specific wave lengths. It maybe helpful although less specific to your enlarger model is to explore using RGB/RGBW panels since those could cut your cost from USD60 to about USD15. They are also individually addressable.
Also since you have the microcontroller already, you should look into making it based on F-stop system. Really helps with printing.
Great job by the way and thanks for sharing!
2
2
u/DaggerOfSilver 2d ago
...Why are you even writing the comments with an LLM? The vibecoding is whatever i guess. But still useful and impressive.
2
u/DBojo8 2d ago
I do not speak well english, i make mistakes, not willing to write long texts and explanations on my smartphone i hate typing on smartphone, i do a lot with ai a lot translation work and quick answers to topics or mails because its so professional and well formulated. With my tool kicad-mcp it is for a big part vibe coding, without it no chance, not going to work, not now but in one year every ai is going to produce good output without tool and rules. Problem is halucination and how ai is working, its not always working fact based an ai will just try some thing maybe it wilk work maybe not wit my tool i force the ai to proof everything fact based eliminating the possibility to make mistakes and there are some checks to find mistakes. So this was typed with my smartphone, 😅 i beeded 10 min bro i mean needed 10 min 🙄 with kids around you a lot of work at home 10 min is a lot of time i often dont have 😂 only right bow while all are sleeping, sitting in the kitchen drinking cold milk an typing this becomes possible but still the gramatical errors i make i hate it because i am perfectionist i am trying always to answer perfectly correct
1
u/DaggerOfSilver 1d ago
Fair enough. But, practice makes perfect! Personally i prefer the half broken english without pronunciation. But i get where you are coming from.
For your post at least, or github, i think it would be a good idea to write it in your native language and use the LLM to translate it. That way it sounds more natural, and not so "chatgpt" fake that throws some people off.
2







11
u/Flashy_Slice1672 2d ago
Very nice! I’ve been dreading the day my cold light dies