Slimme UV-C & hitte mondmasker desinfectie-apparaat — Arduino-gestuurd
Onderdelen en benodigdheden
- Seeed Grove Infrarood Temperatuursensor (1x)
- Arduino UNO (1x)
- Seeed Base Shield V2 (1x)
- Seeed Grove Lichtsensor (P) v1.1 (1x)
- Adafruit Quad Alphanumerisch Display - Wit 0,54" met I2C Backpack (1x)
- Seeed 12mm Domed Drukknop (1x)
- Piezo summer (1x)
- Seeed Wandadapter voeding 12VDC 1,2A (1x)
Over dit project
Mondmasker desinfectie-apparaat
UV-C / hitte, Arduino-gestuurd, mondmasker desinfecterend apparaat voor Coronavirus (SARS-CoV-2)

Dit is een open-source project gedeeld onder Creative Commons "Attribution-NonCommercial-ShareAlike" (CC BY-NC-SA).
Disclaimer: Dit document valt onder de "Good Samaritan Law".
Originele publicatie: needlab.org/face-masks-disinfection-device

Inleiding
FFP1 en FFP2 maskers zijn onmisbare beschermingsmiddelen tijdens epidemieën. Ze zijn bedoeld voor eenmalig gebruik, maar tijdens een crisis is hergebruik onvermijdelijk en zijn desinfectiemethoden vereist. Tijdens de SARS-CoV-2 pandemie implementeerden ziekenhuizen en zorginstellingen verschillende desinfectiemethoden, meestal UVGI (ultraviolet germicidal irradiation) en/of hitte. Deze methoden zijn echter niet beschikbaar voor kwetsbare groepen, waar hergebruik door tekort de enigste optie is. De noodzaak voor een haalbare desinfectiemethode wordt versterkt door bewijs dat SARS-CoV-2 extreem stabiel is op chirurgische maskers, zelfs na 7 dagen.
Dit project heeft als doel een budgetvriendelijk, draagbaar apparaat te creëren dat UVGI en droge hitte effectief gebruikt om mondmaskers van SARS-CoV virussen te desinfecteren, en dat eenvoudig gereproduceerd kan worden door wie het nodig heeft.
DIY-instructies voor het bouwen van het desinfectie-apparaat
Apparaat opzet diagram

- Temperatuur moet worden gehandhaafd op 65 ± 5 °C
- De lamp moet UV-C golflengte leveren
- Desinfectiecyclus: minimaal 30 minuten (aanbevolen: niet langer dan 30 min om maskerdegradatie te voorkomen)

Apparaatafmetting

Eerste hitte-tests




Verwarmingssysteem bouwen
- Bakpan van 22 cm diameter (inductie-geschikt) met handvat verwijderd
- Bakpan bekleden met aluminiumfolie voor UV-C reflectie
- Gat van 20 cm in het midden van de bodem van de doos/apparaat
- Vier metalen beugels om de bakpan te positioneren (zie afbeelding)

Belangrijk: De bakpan mag het hout van de doos niet aanraken — dit verlaagt de warmte-efficiëntie. Kies de juiste gatdiameter en vorm de beugels volgens dit diagram:




Bovenkap maken


UV-C Systeem

Als UV-C bron werd een 11W lamp uit een "Aquarium Sterilizer" kit gebruikt. De UV-C bulb werd uitgehaald en aan de bovenkap gemonteerd aan de twee uiteinden. Bevestiging: 4 gaten in de kap, kabelbinder/zipp-tie met zachte padding. Het bovenvlak is met aluminium bekleed voor reflectie.
Voel je vrij een andere UV-C lamp te gebruiken. Gebruik geen glas als vervanging voor de kwartsbuis — glas blokkeert UV-straling.
⚠ WAARSCHUWING
UV-C straling is gevaarlijk voor ogen en huid. De UV-C lamp mag alleen aanstaan wanneer de bovenkap dicht is, en moet uit zijn wanneer het apparaat open is.
Belangrijke aanbevelingen van Horror Coder (zie reacties):
"...De onzichtbare gevaren van UVC: controleer of de doos echt lichtdicht is. De zichtbare straling is maar 3-4% van de totale emissie — vertrouw niet op je ogen. Er is groot risico op lekkage die je niet ziet. Controleer lichtdichtheid door een krachtige lichtbron (10x de lampvermogen) in de doos te plaatsen en in een volledig donkere omgeving te kijken naar lekkages. Vul alle gaten, gebruik schuimranden of randen om UV-C lekkage te voorkomen, en test met de bovenstaande methode."



Oppervlakken bekleden met aluminiumfolie

Voor het installeren van de UV-C buis en het metalen rek, bekled de zijden en bovenkant van de doos met aluminiumfolie (doel: UV-C reflectie op zijvlakken). Dubbelzijdig tape houdt de folie op plaats; randen kunnen met ducttape worden afgewerkt.
Metalen rek maken voor mondmaskers
De maskers liggen op een metalen rek. Gemaakt van gedraaide koperdraad (30 mm tussenruimte). Het rek zit 120 mm boven de bodem. Samengehouden door draad door kleine gaten in voor- en achterzijde.



Arduino & sensoren opzetten
Arduino overzicht

Stuklijst (Bill of Materials)
- Arduino UNO Rev3 — Seeed Studio
- Grove Base Shield V2 — Seeed Studio
- Grove Infrarood Temperatuursensor — Seeed Studio
- Grove Lichtsensor (P) — Seeed Studio
- Drukknop — Seeed Studio
- Piezo speaker — Gotronic
- Quad Alphanumerisch Display 0,54" I2C — Adafruit
- Wandadapter 12VDC 1,2A — Seeed Studio
Temperatuur- en lichtsensor


Zie ook: Benchmarking van temperatuursensoren voor Arduino
Arduino besturing (staatmachine)
- INIT: Display toont temperatuur. Wachten op 70°C → dan naar COUNT.
- COUNT: Aftellen van 30 naar 0 minuten, naast temperatuur. Bij te lage temp of UV-licht uit → ERR.
- END: Normale eindstaat. Summer geluid. Druk knop → INIT.
- ERR: Foutstaat (UV uit of temp te laag). Summer geluid. Druk knop → INIT.
Alarmen:
- Systeem in ERR staat (UV uit/verloren of temp te laag)
- Temperatuur te hoog (> 75 °C)
Bij alarm: specifieke toonsoort op summer + berichten op display.

Broncode voor Arduino
Externe bibliotheken:
- Adafruit_LEDBackpack.h — Adafruit tutorial
- Metro.h — GitHub
Gebruikshandleiding

- Plaats de doos op je inductie- of weerstandskookplaat.
- Zet de Arduino voeding AAN.
- Sluit de doos en verhit op 70-80% vermogen.
- Wacht tot 60°C bereikt is. Verlaag dan vermogen naar 30%.
- Open het apparaat, leg maskers in, sluit het apparaat.
- Druk de knop om te starten → resterende tijd wordt getoond (30 minuten).
- Wacht tot de timer op 00 minuten staat → signaal op de summer.
- Om een nieuwe cyclus te starten: druk opnieuw op de knop.
Opmerking: Tijdens aftellen (COUNT staat) knippert het puntje tussen Timer en Temperatuur op 1-seconde ritme.
Temperatuurcycli


Hitte-inactivatie van virussen
Moeste hitte (onder 100°C) is bekend sinds Pasteur. Dit apparaat gebruikt droge hitte, die effectief SARS-CoV inactiveert. Studies tonen aan: aanzienlijke inactivatie bij 56°C (30-90 min), bijna volledige bij 65°C (20-60 min), volledige bij 75°C (30-45 min). Recente studie: SARS-CoV-2 verliest alle detecteerbare infectiositeit na 30 min op 56°C of 5 min op 70°C.
Op basis van bewijzen en overwegingen tot maskerfunctionaliteit gekozen voor 65 °C gedurende 30 min.
Germicidale protocollen op mondmaskers
Desinfectie van maskers is effectief tegen influenza-virus met UVGI (~1 J/cm²), UVGI (~18 J/cm²), of vochtige hitte (65±5°C, 3 uur). Geen studies met coronavirussen op maskers, maar influenza is ook een ssRNA-virus → vergelijkbare effecten verwacht.
Meer informatie over
- UVGI: germicidaal effect van UVC-licht
- Nadelige effecten van fysieke desinfectie op maskers
Aanbevolen methode voor desinfectie van mondmaskers
Belangrijk: goed procedure voor hergebruik. Vragen: personalisatie, aantal cycli tellen, verpakking gedesinfecteerde maskers. Inspiratie: "N95 Filtering Facepiece Respirator Ultraviolet Germicidal Irradiation (UVGI) Process for Decontamination and Reuse" (Nebraska Medicine).
n-95-decon-process.pdf
Conclusies
Op basis van bewijzen en technische details: desinfectieprotocol = 30 min UV-C bestraling + droge hitte 65±5 °C. De tijd moet geteld worden vanaf het bereiken van de vereiste temperatuur en lichtintensiteit. Zowel UV-C als hitte apart zouden bijna alle SARS-CoV-2 infectiositeit elimineren; gecombineerd is het nog veiliger.
Veiligheidsoverwegingen
- UV-C straling is schadelijk voor huid en ogen. Lamp alleen aan wanneer doos dicht is.
- Let op: metalen delen kunnen na verwarmen brandwonden veroorzaken.
Disclaimer
Op basis van beschikbaar wetenschappelijk bewijs zal het protocol waarschijnlijk bijna alle SARS-CoV infectiositeit elimineren en maskers zeker veiliger maken dan zonder desinfectie. Toch: Needlab en team aanvaarden geen aansprakelijkheid voor het gebruik van dit apparaat. Het is ontworpen met goeie wil en beste kennis, maar:
Er is nog geen officiële laboratoriumtest gedaan voor SARS-CoV-2 inactivatie met dit apparaat, noch kunnen de daadwerkelijke effecten op de filtratiekwaliteit van maskers vooraf met zekerheid worden beoordeeld. Gebruik van het apparaat en deze handleiding is een vrije keuze.
Volgende stappen (V2)
We werken aan V2 met verbeteringen:
- Grotere afmetingen voor meer maskers
- Bestanden voor CNC-frezen en laser cutter
- 3 keuzes voor verwarming: inductie, elektrische kookplaat, infrarood stralend (met PID-temperatuurregeling)
- 2x16 LCD display voor HMI
- Meerdere cycli: Hitte+UV-C, Alleen hitte, Alleen UV-C
- Ondersteuning voor verschillende temperatuursensoren
Infrarood stralend en UV-C om het virus te doden

We zoeken samenwerking met gespecialiseerde laboratoria voor validatie.
Update 11 juni: V2 met 12 FFP2/N95 maskers binnenin


We wonnen de OPT 1e prijs en werken met de universiteit in Marokko aan lokale productie.

Update 2 september: V2 project op Hackaday:
Team: Jean Noel Lefebvre, Daniel Moreno, Dr. Alejandra Duque, Dr. Felipe Gutiérrez Arango, Jason Knight, Maria Isabel Velez Isaza, Sameera Chukkapalli.

#COVID19DetectProtect
Originele publicatie: needlab.org/face-masks-disinfection-device
Bibliografie
- CDC - Recommended Guidance for Extended Use and Limited Reuse of N95 Filtering Facepiece Respirators in Healthcare Settings (2019)
- Chin A et al. - Stability of SARS-CoV-2 in different environmental conditions. medRxiv (2020)
- Tseng C-C, Li C-S - Inactivation of Viruses on Surfaces by UVGI. J Occup Environ Hyg (2007)
- Hackerfarm - HOWTO: NUKEMETER – Measuring UV-C Light Intensity (2020)
- van Doremalen N et al. - Aerosol and Surface Stability of SARS-CoV-2. NEJM (2020)
- Kariwa H et al. - Inactivation of SARS coronavirus. Jpn J Vet Res (2004)
- Duan SM et al. - Stability of SARS Coronavirus. Biomed Environ Sci (2003)
- Darnell MER et al. - Inactivation of the coronavirus SARS-CoV. J Virol Methods (2004)
- Ansaldi F et al. - SARS-CoV, influenza A and syncitial respiratory virus resistance. (2004)
- Mills D et al. - UVGI of influenza-contaminated N95 respirators. Am J Infect Control (2018)
- Lore MB et al. - Effectiveness of Three Decontamination Treatments. Ann Occup Hyg (2012)
- Lindsley WG et al. - Effects of UVGI on N95 Respirator Filtration. J Occup Environ Hyg (2015)
- Viscusi DJ et al. - Evaluation of Five Decontamination Methods. Ann Occup Hyg (2009)
- Bergman MS et al. - Evaluation of Multiple (3-Cycle) Decontamination Processing. J Eng Fiber Fabr (2010)
- Kampf G et al. - Persistence of coronaviruses on inanimate surfaces. J Hosp Infect (2020)
Code
TheBox V1 (C/C++)
/* * Author: Jean Noel Lefebvre - www.ootsidebox.fr - march 31th 2020 * */
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include <math.h>
#include <Metro.h>
#define LIGHT_SENSOR A2
#define SUR_TEMP_PIN A0
#define OBJ_TEMP_PIN A1
#define BUZZER 3
#define BP 2
#define SEUIL_TEMP 59
#define HIGH_TEMP 75
#define SEUIL_LIGHT 60
#define TIMER 30
float temp_calibration=0;
float objt_calibration=0.000;
float temperature_range=10;
float offset_vol=0.014;
float tempValue = 0;
float objtValue= 0;
float current_temp=0;
float temp=0;
float temp1=0;
float temp2=0;
unsigned int temp3=0;
const float reference_vol=0.500;
unsigned char clear_num=0;
float R=0;
float voltage=0;
long res[100]={ 318300,302903,288329,274533,261471,249100,237381,226276,215750,205768, 196300,187316,178788,170691,163002,155700,148766,142183,135936,130012, 124400,119038,113928,109059,104420,100000,95788,91775,87950,84305, 80830,77517,74357,71342,68466,65720,63098,60595,58202,55916, 53730,51645,49652,47746,45924,44180,42511,40912,39380,37910, 36500,35155,33866,32631,31446,30311,29222,28177,27175,26213, 25290,24403,23554,22738,21955,21202,20479,19783,19115,18472, 17260,16688,16138,15608,15098,14608,14135,13680,13242,12819, 12412,12020,11642,11278,10926,10587,10260,9945,9641,9347, 9063,8789,8525,8270,8023,7785,7555,7333,7118,6911};
float obj[13][12]={ /*0*/{0,-0.274,-0.58,-0.922,-1.301,-1.721,-2.183,-2.691,-3.247,-3.854,-4.516,-5.236}, /*1*/{0.271,0,-0.303,-0.642,-1.018,-1.434,-1.894,-2.398,-2.951,-3.556,-4.215,-4.931}, /*2*/{0.567,0.3,0,-0.335,-0.708,-1.121,-1.577,-2.078,-2.628,-3.229,-3.884,-4.597}, /*3*/{0.891,0.628,0.331,0,-0.369,-0.778,-1.23,-1.728,-2.274,-2.871,-3.523,-4.232}, /*4*/{1.244,0.985,0.692,0.365,0,-0.405,-0.853,-1.347,-1.889,-2.482,-3.13,-3.835}, /*5*/{1.628,1.372,1.084,0.761,0.401,0,-0.444,-0.933,-1.47,-2.059,-2.702,-3.403}, /*6*/{2.043,1.792,1.509,1.191,0.835,0.439,0,-0.484,-1.017,-1.601,-2.24,-2.936}, /*7*/{2.491,2.246,1.968,1.655,1.304,0.913,0.479,0,-0.528,-1.107,-1.74,-2.431}, /*8*/{2.975,2.735,2.462,2.155,1.809,1.424,0.996,0.522,0,-0.573,-1.201,-1.887}, /*9*/{3.495,3.261,2.994,2.692,2.353,1.974,1.552,1.084,0.568,0,-0.622,-1.301}, /*10*/{4.053,3.825,3.565,3.27,2.937,2.564,2.148,1.687,1.177,0.616,0,-0.673}, /*11*/{4.651,4.43,4.177,3.888,3.562,3.196,2.787,2.332,1.829,1.275,0.666,0}, /*12*/{5.29,5.076,4.83,4.549,4.231,3.872,3.47,3.023,2.527,1.98,1.379,0.72} };
int Light;
float Heat;
int Timer=0;
int Minute=59;
Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();
Metro ledMetro = Metro(1000);
enum States{INIT, COUNT, END, ERR};
int Automate=INIT;
bool TemperatureOK=false;
bool LightOK=false;
void setup() {
pinMode(BP, INPUT_PULLUP);
Serial.begin(9600);
analogReference(INTERNAL);
alpha4.begin(0x70);
alpha4.clear();
alpha4.writeDisplay();
PrintLed(alpha4,"TboX");
tone(3, 3000, 500);
delay(1000);
Automate=INIT;
}
void loop() {
static int Point=1;
float T1=measureSurTemp();
float T2=measureObjectTemp();
Heat=T1+0;
if ((ledMetro.check() == 1)) {
#ifndef TEST
if (Automate==COUNT)
#endif
{
if(Point) Point=0; else Point=1;
Minute--;
if(Minute==0) { Minute=59; if(Timer) Timer--; PrintSensors(); }
}
if(Automate==END) tone(3, 3000, 100);
if(Automate==ERR) tone(3, 300, 200);
}
#ifdef TEST
TemperatureOK=true;
#else
if (Heat >= SEUIL_TEMP) TemperatureOK=true; else TemperatureOK=false;
#endif
Light=analogRead(LIGHT_SENSOR)/10;
if(Light >= SEUIL_LIGHT) LightOK=true; else LightOK=false;
if(Heat>=HIGH_TEMP) { tone(3, 300, 200); delay(500); }
switch(Automate) {
case INIT:
Timer=0;
if((!digitalRead(BP)) && TemperatureOK) { Automate=COUNT; Timer=TIMER; tone(3, 3000, 500); }
if((!digitalRead(BP)) && !TemperatureOK) { PrintLed(alpha4,"lowT"); tone(3, 300, 200); }
else PrintLedVal(alpha4,Timer,(int)Heat,Point);
break;
case COUNT:
if(Timer==0) Automate=END;
if(!LightOK || !TemperatureOK) Automate=ERR;
PrintLedVal(alpha4,Timer,(int)Heat,Point);
break;
case END:
if(!digitalRead(BP)) Automate=INIT;
PrintLed(alpha4,"END.");
break;
case ERR:
if(!digitalRead(BP)) Automate=INIT;
PrintLed(alpha4,"Err.");
break;
}
}
void PrintSensors() {
Serial.print(Timer); Serial.print(", "); Serial.print((int)Heat); Serial.print(", "); Serial.print(100); Serial.println();
}
float binSearch(long x) {
int low=0, mid=0, high=100;
while (low<=high) {
mid=(low+high)/2;
if(x<res[mid]) low=mid+1; else high=mid-1;
}
return mid;
}
float arraysearch(float x,float y) {
int i=0;
float tem_coefficient=100;
i=(x/10)+1;
voltage=(float)y/tem_coefficient;
for(temp3=0;temp3<13;temp3++) {
if((voltage>obj[temp3][i])&&(voltage<obj[temp3+1][i])) return temp3;
}
}
float measureSurTemp() {
unsigned char i=0;
float current_temp1=0;
int signal=0;
tempValue=0;
for(i=0;i<10;i++) { tempValue+= analogRead(SUR_TEMP_PIN); delay(10); }
tempValue=tempValue/10;
temp = tempValue*1.1/1023;
R=2000000*temp/(2.50-temp);
signal=binSearch(R);
current_temp=signal-1+temp_calibration+(res[signal-1]-R)/(res[signal-1]-res[signal]);
return current_temp;
}
float measureObjectTemp() {
unsigned char i=0;
unsigned char j=0;
float sur_temp=0;
unsigned int array_temp=0;
float temp1,temp2;
float final_temp=0;
objtValue=0;
for(i=0;i<10;i++) { objtValue+= analogRead(OBJ_TEMP_PIN); delay(10); }
objtValue=objtValue/10;
temp1=objtValue*1.1/1023;
sur_temp=temp1-(reference_vol+offset_vol);
array_temp=arraysearch(current_temp,sur_temp*1000);
temp2=current_temp;
temp1=(temperature_range*voltage)/(obj[array_temp+1][(int)(temp2/10)+1]-obj[array_temp][(int)(temp2/10)+1]);
final_temp=temp2+temp1;
return(final_temp);
}
void PrintLed(Adafruit_AlphaNum4 &alpha4, char _buffer[]) {
alpha4.writeDigitAscii(0, _buffer[0]);
alpha4.writeDigitAscii(1, _buffer[1]);
alpha4.writeDigitAscii(2, _buffer[2]);
alpha4.writeDigitAscii(3, _buffer[3]);
alpha4.writeDisplay();
Wire.endTransmission();
}
void PrintLedVal(Adafruit_AlphaNum4 &alpha4, int ValueG, int ValueD, boolean Point) {
char _buffer[]="AB";
int P = Point ? 1 : 0;
itoa(ValueG,_buffer,10);
if(ValueG<=9) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, _buffer[0],P); }
else { alpha4.writeDigitAscii(1, _buffer[1],P); alpha4.writeDigitAscii(0, _buffer[0]); }
itoa(ValueD,_buffer,10);
if(ValueD<=9) { alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, _buffer[1],0); }
else { alpha4.writeDigitAscii(3, _buffer[1],0); alpha4.writeDigitAscii(2, _buffer[0]); }
alpha4.writeDisplay();
Wire.endTransmission();
}
GitHub bibliotheken
Schema

Productieproces
- Uitgebreide Gids tot Moderne Epilatieapparaten: Ontwerp, Geschiedenis en Toekomst
- Een buitenweerstation bouwen met Raspberry Pi 2 en ADS-WS1
- LM35-gebaseerd temperatuurregelsysteem met AT89S52 microcontroller
- Compacte DHT temperatuur- en vochtigheidsbreakout voor Raspberry Pi – ATtiny85 & DHT22/DHT11
- Pico-aangedreven Boot-switch: Kies je OS voordat je aanzet
- Medische hulpmiddel accessoires begrijpen: Definities, classificaties en regelgevende impact
- Thyristortechnologie: Van SCR tot TRIAC, GTO, en UJT
- Vooruitgang in medische apparaattechnologie volgen
- IoT‑provisioning schalen: veilige, efficiënte strategieën voor device‑onboarding
- Databeveiliging in mobiele scanning: waarom on-device processing essentieel is
- Apparaatattestatie: Hoe GlobalPlatform vertrouwen in IoT bouwt