Neeraj Rane
Published © CC BY-NC-SA

UV-C Sterilizer

Build a sterilizer using a UV-C lamp and a 3D printed enclosure!

IntermediateFull instructions provided8,791
UV-C Sterilizer

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
0.96" OLED 64x128 Display Module
ElectroPeak 0.96" OLED 64x128 Display Module
×1
UV-C Germicidal Lamp
Along with suitable electronic ballast
×1
Rotary Encoder with Push-Button
Rotary Encoder with Push-Button
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

lid.stl

clamp.stl

ctrl+box.stl

drawer.stl

handle.stl

knob.stl

main.stl

ctrl+panel.stl

oled_pin.stl

Schematics

UVC Sterilizer Schematic

Code

UV-C Sterilizer Code

Arduino
/*
This Project is inspired by UVClean by Henry Mayne
https://www.hackster.io/henry-mayne/diy-ultraviolet-sterilization-device-uvclean-7d31b1
All the hard work of creating a menu has been done by him. I have just modified his code to fit my needs! 
*/

#define CLK 3
#define DT 4
#define SW 5
#define BULB 6
#define BUZZER 8
#define REED 7

int counter = 0;
int state;
int Laststate;
int menuID = 1;
int menuChange = 0;
int leave = 0;
int minutes = 1;
int timeSelect = 1;
int seconds10 = 0;
int seconds1 = 0;
unsigned long startMillis;

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define OLED_RESET     4 
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup(){
  pinMode(BULB, OUTPUT);
  pinMode(CLK,INPUT);
  pinMode(DT,INPUT);
  pinMode(SW,INPUT_PULLUP);
  pinMode(BUZZER, OUTPUT);
  pinMode(REED, INPUT_PULLUP);
  Serial.begin(9600);
  Laststate = digitalRead(CLK);
  digitalWrite(BULB, LOW);
  
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)){ 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
 
  display.clearDisplay();
  display.setTextSize(2);             
  display.setTextColor(SSD1306_WHITE);       
  display.setCursor(0,0);             
  display.println(F(" MAIN MENU"));
  display.setTextSize(1);
  display.println(F(""));
  display.println(F("-> Manual Mode"));
  display.println(F(""));
  display.println(F("   Timer Mode"));  
  display.println(F(""));
  display.println(F("   Safety"));           
  display.display();  
}

void loop(){
  state = digitalRead(CLK);
  if(state != Laststate){
    if(digitalRead(DT) != state){
      counter++;
    }
    else{  
      counter--;
    }
  }
  if(digitalRead(SW) != 1){
    counter = 0;
    tone(BUZZER, 3000, 50);
    }
    
    Laststate = state;
    if(counter == 2){
      counter = 0;
      menuID++;
      menuChange = 1;
    }

    if(counter == -2) {
      counter = 0;
      menuID--;
      menuChange = 1;
    }
    
    if(digitalRead(SW) != 1) {
      tone(BUZZER, 3000, 50);
      menuChange = 1;
      switch(menuID) {
        case 1:
        menuID = 11;
        break;
        case 2:
        menuID = 21;
        break;
        case 3:
        menuID = 31;
        break;
        case 11:
        menuID = 101;
        break;
        case 12:
        menuID = 1;
        break;
        case 21:
        menuID = 210;
        break;
        case 22:
        menuID = 220;
        break;
        case 23:
        menuID = 1;
        break;
        case 31:
        menuID = 3;
        break;
        case 210:
        menuID = 21;
        timeSelect = 1;
        break;
        case 211:
        menuID = 21;
        timeSelect = 2;
        break;
        case 212:
        menuID = 21;
        timeSelect = 3;
        break;
      }
      delay(250);
    }

    if(menuID == 0 || menuID == 4 || menuID == 10 || menuID == 13 || menuID == 20 || menuID == 24 || menuID == 213 || menuID == 209 ){
      switch(menuID){
        case 0:
        menuID = 3;
        break;
        case 4:
        menuID = 1;
        break;
        case 10:
        menuID = 12;
        break;
        case 13:
        menuID = 11;
        break;
        case 20:
        menuID = 23;
        break;
        case 24:
        menuID = 21;
        break;
        case 30:
        menuID = 31;
        break;
        case 32:
        menuID = 31;
        break;
        case 213:
        menuID = 210;
        break;
        case 209:
        menuID = 212;
        break;
      }
      menuChange = 1;
    }
    
    if(menuChange == 1){
      switch(menuID){
        case 1:
        menu1();
        menuChange = 0;
        break;
        
        case 2:
        menu2();
        menuChange = 0;
        break;
        
        case 3:
        menu3();
        menuChange = 0;
        break;
        
        case 11:
        menu11();
        menuChange = 0;
        break;
        
        case 101:
        if(digitalRead(REED) == 0){
        digitalWrite(BULB, HIGH);
        Serial.println("BULB ON");
        while(leave == 0 && digitalRead(REED) == 0) {
          menu101();
          if(digitalRead(SW) != 1){
            leave = 1;
          }
          else if(digitalRead(REED) != 0){
            leave = 1;
            errorMessage;
          }
         }
        }
        else{
          errorMessage();
        }
        tone(BUZZER, 3000, 1000);
        digitalWrite(BULB, LOW);
        Serial.println("BULB OFF");
        leave = 0;
        menuID = 11;
        menuChange = 1;
        delay(500);
        break;
        
        case 12:
        menu12();
        menuChange = 0;
        break;
        
        case 21:
        menu21();
        menuChange = 0;
        break;
        
        case 220:
        minutes = timeSelect;
        seconds10 = 0;
        seconds1 = 0;
        if(digitalRead(REED) == 0){
        digitalWrite(BULB, HIGH);
        Serial.println("BULB ON");
        
        while(leave == 0 && digitalRead(REED) == 0) {
          display.clearDisplay();
          display.setTextSize(2);
          display.setTextColor(SSD1306_WHITE);
          display.setCursor(0,0);
          display.println(F("CAUTION:"));
          display.setTextSize(1);
          display.println(F("UVC irradiation in   progress"));
          display.setCursor(0,34);
          display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
          display.println(F("    TIME REMAINING:  "));
          display.setTextColor(SSD1306_WHITE);
          display.setCursor(14,43);
          display.setTextSize(3);
          display.print(F(" "));
          display.print(minutes);
          display.print(F(":"));
          display.print(seconds10);
          display.print(seconds1);
          display.display();

          if(minutes == 0 && seconds10 == 0 && seconds1 == 0) {
            leave = 1;
          }
           
          if(seconds1 == 0) {
            seconds1 = 9;
            seconds10--;
          }
          else {
            seconds1--;
          }
          
          if(seconds10 == -1) {
            seconds10 = 5;
            minutes--;
          }
          if(digitalRead(REED) != 0){ 
            leave = 1;
            errorMessage();
          }
          startMillis = millis();
          while(millis() <= startMillis + 1000 && leave == 0) {
            if(digitalRead(SW) != 1) {
              leave = 1;
            }
          }  
        }
        }
        else{
          errorMessage();
        }
        tone(BUZZER, 3000, 1000);
        digitalWrite(BULB, LOW);
        Serial.println("BULB OFF");
        leave = 0;
        menuID = 21;
        menuChange = 1;
        delay(500);
        break;
        
        case 22:
        menu22();
        menuChange = 0;
        break;

        case 23:
        menu23();
        menuChange = 0;
        break;

        case 31:
        menu31();
        menuChange = 0;
        break;

        case 210:
        menu210();
        menuChange = 0;
        break;

        case 211:
        menu211();
        menuChange = 0;
        break;

        case 212:
        menu212();
        menuChange = 0;
        break;
      }
    }  
}

void menu1() {
  display.clearDisplay();
  display.setTextSize(2);            
  display.setTextColor(SSD1306_WHITE);        
  display.setCursor(0,0);             
  display.println(F(" MAIN MENU"));
  display.setTextSize(1);
  display.println(F(""));
  display.println(F("-> Manual Mode"));
  display.println(F(""));
  display.println(F("   Timer Mode"));          
  display.println(F("")); 
  display.println(F("   Safety"));          
  display.display(); 
}

void menu2() {
  display.clearDisplay();
  display.setTextSize(2);             
  display.setTextColor(SSD1306_WHITE);        
  display.setCursor(0,0);             
  display.println(F(" MAIN MENU"));
  display.setTextSize(1);
  display.println(F(""));
  display.println(F("   Manual Mode"));
  display.println(F(""));
  display.println(F("-> Timer Mode"));       
  display.println(F(""));
  display.println(F("   Safety"));          
  display.display();   
}

void menu3(){
  display.clearDisplay();
  display.setTextSize(2);             
  display.setTextColor(SSD1306_WHITE);        
  display.setCursor(0,0);             
  display.println(F(" MAIN MENU"));
  display.setTextSize(1);
  display.println(F(""));
  display.println(F("   Manual Mode"));
  display.println(F(""));
  display.println(F("   Timer Mode"));       
  display.println(F(""));  
  display.println(F("-> Safety"));          
  display.display(); 
}

void menu11() {
  display.clearDisplay();
  display.setTextSize(2);             
  display.setTextColor(SSD1306_WHITE);        
  display.setCursor(0,0);             
  display.println(F("MANUAL"));
  display.setTextSize(1);
  display.println(F("Press button to      turn the UVC lamp    ON/OFF"));
  display.println(F(""));
  display.setTextSize(2);
  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  display.print(F("START"));
  display.setTextColor(SSD1306_WHITE);
  display.println(F(" EXIT"));          
  display.display();  
}

void menu12() {
  display.clearDisplay();
  display.setTextSize(2);             
  display.setTextColor(SSD1306_WHITE);        
  display.setCursor(0,0);             
  display.println(F("MANUAL"));
  display.setTextSize(1);
  display.println(F("Press button to      turn the UVC lamp    ON/OFF"));
  display.println(F(""));
  display.setTextSize(2);
  display.print(F("START "));
  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  display.println(F("EXIT"));        
  display.display();
}

void menu21() {
  display.clearDisplay();
  display.setTextSize(2);            
  display.setTextColor(SSD1306_WHITE);       
  display.setCursor(0,0);             
  display.println(F("   TIMER"));
  display.setTextSize(1);
  display.println(F("Exposure time:"));
  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  display.print(timeSelect);
  display.println(" min");
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.println(F(""));
  display.print(F("START"));
  display.print(F(" EXIT"));
  display.display(); 
}

void menu22() {
  display.clearDisplay();
  display.setTextSize(2);             
  display.setTextColor(SSD1306_WHITE);       
  display.setCursor(0,0);             
  display.println(F("   TIMER"));
  display.setTextSize(1);
  display.println(F("Exposure time:"));
  display.print(timeSelect);
  display.println(" min");
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.println(F(""));
  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  display.print(F("START"));
  display.setTextColor(SSD1306_WHITE);
  display.print(F(" EXIT"));
  display.display(); 
}

void menu23() {
  display.clearDisplay();
  display.setTextSize(2);            
  display.setTextColor(SSD1306_WHITE);       
  display.setCursor(0,0);            
  display.println(F("   TIMER"));
  display.setTextSize(1);
  display.println(F("Exposure time:"));
  display.print(timeSelect);
  display.println(" min");
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.println(F(""));
  display.print(F("START "));
  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  display.print(F("EXIT"));
  display.display(); 
}

void menu31(){
  display.clearDisplay();
  display.setTextSize(2);            
  display.setTextColor(SSD1306_WHITE);        
  display.setCursor(0,0);             
  display.println("CAUTION");
  display.println("");
  display.setTextSize(1);
  display.print("UV-C Radiation can   cause damage to your skin and eyes");
  display.display();
}

void menu101(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.println(F("CAUTION:"));
  display.setTextSize(1);
  display.println(F("UVC irradiation in   progress"));
  display.setTextSize(2);
  display.println(F(""));
  display.print(F("   "));
  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
  display.println(F("STOP"));
  display.display();
}

void menu210(){
    display.clearDisplay();
    display.setTextSize(2);             
    display.setTextColor(SSD1306_WHITE);        
    display.setCursor(0,0);            
    display.println(F(""));
    display.setTextSize(1);
    display.println(F("Exposure time:"));
    display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
    display.println("1 min");
    display.setTextColor(SSD1306_WHITE);
    display.println("2 min");
    display.println("3 min");
    display.display(); 
}

void menu211(){
    display.clearDisplay();
    display.setTextSize(2);             
    display.setTextColor(SSD1306_WHITE);        
    display.setCursor(0,0);             
    display.println(F(""));
    display.setTextSize(1);
    display.println(F("Exposure time:"));
    display.setTextColor(SSD1306_WHITE);
    display.println("1 min");
    display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
    display.println("2 min");
    display.setTextColor(SSD1306_WHITE);
    display.println("3 min");
    display.display(); 
}

void menu212(){
    display.clearDisplay();
    display.setTextSize(2);             
    display.setTextColor(SSD1306_WHITE);        
    display.setCursor(0,0);             
    display.println(F(""));
    display.setTextSize(1);
    display.println(F("Exposure time:"));
    display.setTextColor(SSD1306_WHITE);
    display.println("1 min");
    display.println("2 min");
    display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
    display.println("3 min");
    display.display(); 
}

void errorMessage(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.println("CLOSE THE");
  display.println("DRAWER");
  display.display();
  delay(2000);
}
  

Credits

Neeraj Rane

Neeraj Rane

18 projects • 46 followers
Electrical Engineer and a Maker from India. Engineering is fun once you start applying it!

Comments