PicoCentrifuge: Een DIY-centrifuge met Raspberry Pi Pico
Een centrifuge voor het verwerken van bloed, gebouwd met een drone-motor, een Raspberry Pi Pico en een 3D-printer.
Achtergrond
Drie dagen geleden was het 13 jaar geleden dat mijn moeder overleed. Het moment dat kanker haar wegnam, realiseerde ik me dat het mijn levensmissie is om de definitieve genezing voor kanker te vinden.
Dat doel is niet veranderd. Wat ik hier bouw, is onderdeel van een experiment om gepersonaliseerde neoantigenen te creëren die specifieke kankercellen bij een klein aantal specifieke mensen kunnen doden.
Ik bouw Bloom. Deze software neemt de sequentiegegevens van een patiënt, vindt de mutaties en voorspelt welke peptiden een immuunrespons zullen triggeren. Het bewijzen dat dit werkt, gebeurt in een 'wet lab'.
De loop in het wet lab is simpel. Toon een peptide aan T-cellen en kijk of ze reageren:
- De T-cellen verkrijgen: Bloed afnemen, centrifugeren over een dichtheidsgradiënt en de PBMC-laag extraheren.
- Ze in leven houden: 37°C, steriel, gevoed.
- Het peptide introduceren: Gesynthetiseerd peptide + cellen in een well.
- De respons aflezen: Scheidde men IFN-γ uit? Een ELISpot-plaat geeft dit aan.
Stap 1 vereist een centrifuge. Een gebruikte laboratoriumcentrifuge die 15 ml conische buisjes kan bevatten, kost tussen de $800 en $3.000 op eBay. Dat is het duurste onderdeel in een DIY wet lab dat verder minder dan $500 kost via Amazon.
Ik bezit al een A2212 borstelloze motor, een 30A ESC, een Raspberry Pi Pico en een 3D-printer.
De natuurkunde is simpel: draai buisjes snel genoeg in een cirkel zodat de middelpuntvliedende versnelling het bloed scheidt op basis van dichtheid. PBMC-isolatie via Ficoll vereist ongeveer 400 × g gedurende 30 minuten, gevolgd door een langzame uitloop (coast down).
Daarom bouw ik er zelf een.
Het eerste ontwerp dat mislukte
Ik gaf een AI-agent de taak om een centrifuge met zwaaibekers (swinging-bucket) te ontwerpen voor vier 15 ml conische buisjes bij 400 × g. De AI kwam terug met een compleet pakket in Fusion 360: parametrisch bestand, STEP-exports, negen STL's, een assemblage-tekening, een BOM (bill of materials) en een build-script. Op papier was het prachtig.
Op papier was er echter ook een opvangbak nodig met een interne diameter van 466 mm. Dat is ter grootte van een restaurantpan voor soep. De straal van de rotor was 150 mm, wat het ingestelde toerental op 1.545 rpm zette. Dat is redelijk voor de motor, maar de hele constructie was enorm; het zou de helft van mijn werkbank in beslag nemen.
Ik heb daar even naar gekeken en ben toen doorgegaan. Dat ontwerp bevindt zich nu in failed-iterations/BLOOM-2-fusion. Ik bewaar mislukte ontwerpen omdat het falen juist het interessante deel is.
Het uiteindelijke ontwerp
Ik heb alles vanaf nul opnieuw opgebouwd in Onshape. Dit ontwerp is veel compacter.
De motor bevindt zich in de basisbehuizing samen met de ESC. Een starre koppeling van 5 naar 8 mm gaat naar een stalen stang van 8 mm. Lagers zitten in een houder en daarbovenop bevindt zich een rotor met vier armen. Het geheel staat in een opvangbak.
Ik heb gekozen voor een ontwerp met een vaste hoek (fixed-angle) in plaats van zwaaibekers. Het nadeel is dat je een schuine interface krijgt op een Ficoll-gradiënt en dat het trekken met de pipet lastiger is. De trade-off is het waard: het is mechanisch eenvoudiger, korter en makkelijker in balans te brengen. Voor een eerste prototype wint eenvoud.
De rotor
De rotor is een kruis met vier armen, 3D-geprint in PETG. Elke arm houdt een conisch buisje van 15 ml (17 × 120 mm). Tegenover elkaar staande buisjes moeten tot op ±0,1 g nauwkeurig gelijk zijn in gewicht. Onbalans bij 1.500+ rpm kan ertoe leiden dat een buisje door een muur wordt geslingerd.
De straal van de rotor (van het rotatiecentrum tot de middellijn van de vloeistof) bepaalt het RPM-setpoint:
$$\text{rpm} = \sqrt{\frac{\text{RCF}}{1,118 \times 10^{-5} \times r_{\text{cm}}}}$$
Bij 400 × g betekent een kleinere straal een hoger RPM. Het exacte getal is bepaald door de werkelijke rotor uit de Onshape-assemblage te meten.
De aandrijflijn
De A2212/1000KV is een drone-motor. Deze is geschikt voor veel hogere toerentallen dan ik nodig heb. De ESC heeft de remfunctie uitgeschakeld en is geprogrammeerd voor een soepele versnelling. Je remt een centrifuge nooit abrupt af. De uitloop moet minimaal 2 minuten duren, anders verstoor je de gradiënt die je net in 30 minuten hebt gevormd.
Ik heb de motor en ESC eerst getest op de Pico voordat ik verder ging met het ontwerp. Met een MicroPython ramp-script, zonder belasting en zonder rotor, heb ik bevestigd dat de aandrijflijn werkt:
from machine import Pin, PWM
import time
esc = PWM(Pin(1))
esc.freq(50)
def us(val):
esc.duty_u16(int(val / 20000 * 65535))
# arm
us(1000)
time.sleep(3)
# ramp up
for throttle in range(1060, 1300, 20):
us(throttle)
time.sleep(2)
# ramp down
for throttle in range(1300, 1040, -20):
us(throttle)
time.sleep(2)
us(1000)
time.sleep(1)
esc.deinit()
De test verliep schoon. De motorspoelen maken een zingend geluid bij een hoger toerental; dit is normaal en geen alarmsignaal. De gebruikte koppelingen zijn van echt aluminium en niet geprint.
Snelheidsregeling en veiligheid
Het RPM-setpoint moet gedurende 30 minuten in een closed-loop systeem worden vastgehouden. Een IR-reflectiesensor die op de onderkant van de rotor is gericht, geeft een tachometersignaal. De Pico telt de pulsen en past het ESC-gas aan om het doel te behouden via een standaard PID-loop.
Voor de veiligheid is er een MPU-6050 accelerometer/gyro op het chassis geplaatst. Deze is plat, rigide en vlakbij de lagerhouder gebout (NIET op de rotor). Dit dient als trillingssensor: als er iets losraakt of een buisje verschuift, verandert het trillingspatroon en schakelt de Pico de stroom naar de motor uit. Dit is de onbalans-uitschakeling.
De gehele constructie draait in een opvangbak met een deksel. Het deksel moet bij elke test waarbij stroom wordt gebruikt gesloten zijn, zonder uitzonderingen.
Printen
Alle structurele onderdelen zijn geprint in PETG op een Bambu A1 mini. Het filament moet gedroogd zijn, anders ontstaan er vochtbubbels die bij hoge snelheden kunnen fungeren als stressconcentraties (stress risers). Dit is niet optioneel.
Tegenover elkaar staande rotorarmen worden in dezelfde printjob geprint, zodat ze identiek krimpen. Er worden gematched sets gebruikt, geen willekeurige combinaties.
Onderdelenlijst
Onderdelen die reeds aanwezig zijn
| Onderdeel | Notities |
|---|---|
| A2212 borstelloze motor (1000 KV, 5 mm as) | Versnellingscurve getest, werkt schoon |
| 30A sensorless ESC | Rem uitgeschakeld, soepele versnelling |
| Raspberry Pi Pico | MicroPython |
| 2S LiPo (~7.4V) | Vereist een zekering en fysieke disconnect |
| Bambu A1 mini | PETG, gedroogd filament |
| 5-naar-8 mm rigide koppeling | Echte aluminium koppeling; niet printen |
| Lagers (maat nader te bepalen) | Echte lagers aanwezig; maat bevestigen voor assemblage |
Onderdelen die nog nodig zijn
| Onderdeel | Notities |
|---|---|
| 8 mm geslepen stalen stang | ~100-125 mm |
| M4 × 6 schroeven | Assemblage-hardware |
| IR reflectiesensor | Tachometer, 4-8 mm gap |
| MPU-6050 | Onbalansdetectie |
| 15 ml conische buisjes (×4) | Tegenover elkaar staande buisjes gematched op ±0,1 g |
| Opvangbak + deksel | Eerst straal van rotortip meten |
| Glycerol + kleurstof | Validatieronde vóór gebruik van bloed |
Geprinte onderdelen (PETG, gedroogd, matched sets)
| Onderdeel | Onshape naam |
|---|---|
| Basis | Base |
| Basisafdekking | Base Cover |
| Lagerhouder | Bearing Holder |
| Bovenkant | Top |
| Rotor | Rotor |
Validatieplan
Er wordt geen bloed gebruikt voordat alle volgende stappen in deze volgorde zijn voltooid:
- Controle van bevestigingsmiddelen na 10 minuten onbelast draaien.
- Controleren of de rotor recht draait, zonder zichtbare wiebel op het setpoint.
- Balanscontrole: eerst leeg, daarna beladen met ±0,1 g op tegenovergestelde buisjes.
- Controleren of de MPU-6050 uitschakeling triggert bij een bewuste onbalans.
- Beveiligde overspeed-test met het deksel gesloten.
- De echte test: gekleurd water over glycerol, setpoint RPM, 30 minuten, uitloop van 2 minuten.
De laatste stap is de doorslaggevende test. Een strakke interface betekent dat het apparaat voldoende g-kracht over een lange periode kan behouden om te scheiden op basis van dichtheid. Een vervaagde of ontbrekende interface betekent dat de test is mislukt. Pas daarna wordt er met echt bloed gewerkt.
Waarom dit publiekelijk bouwen?
Een gebruikte laboratoriumcentrifuge zou makkelijker zijn geweest. Ik heb gekeken naar OpenFuge en andere 3D-geprinte centrifuge-ontwerpen, maar de meeste kunnen geen 15 ml conische buisjes bevatten, wat essentieel is voor de PBMC-wasstappen.
Als dit werkt, daalt de kostprijs van bloedverwerking van $800-$3.000 naar ongeveer $50 aan onderdelen. Elk stuk infrastructuur voor kankeronderzoek dat open-source en goedkoop gemaakt kan worden, zou dat moeten worden.
De Bloom-pipeline is al open source; de computationele voorspelling is gratis. Als de validatie in het wet lab ook kan worden gedaan met geprinte onderdelen en een Pico, dan verschuift de drempel voor het testen van een neoantigeen-kandidaat van "je hebt een laboratorium nodig" naar "je hebt een werkbank en wat geduld nodig."
Wat volgt er nu?
Voordat er bloed aan te pas komt, moet ik de validatiedrempel passeren: mechanische retentie, balans, onbalans-uitschakeling, beveiligde overspeed en de scheidingstest met gekleurd water over glycerol. Als die slagen, is de volgende stap het verkrijgen van een bloedmonster en het uitvoeren van de echte bloedverwerkingstest. Ik zal documenteren wat er gebeurt.
- CAD-bestanden: Publiek beschikbaar op Onshape - ComfyBloom Centrifuge Assembly
- Code: Wordt toegevoegd aan de repository zodra de firmware verder is ontwikkeld dan de ramp-test.
- BOM, build log en voice notes: Allemaal in de repo op
github.com/ThomasVuNguyen/picocentrifuge
Groetjes,