mansfilmt
Published © GPL3+

Easy adjustable minutes AC timer

Ever let your soldering iron or gluegun burning all night by accident? This is the solution!

BeginnerFull instructions provided748
Easy adjustable minutes AC timer

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
Rotary Encoder with Push-Button
Rotary Encoder with Push-Button
×1
TM1637 4 digit 7 segment display
×1
relais 220/5v ac/dc
×1
5 mm LED: Red
5 mm LED: Red
×1
5 mm LED: Green
5 mm LED: Green
×1
AC/DC PCB Mount Power Supply (PSU), 1 Output
AC/DC PCB Mount Power Supply (PSU), 1 Output
×1
Resistor 220 ohm
Resistor 220 ohm
×2
Toggle Switch, Toggle
Toggle Switch, Toggle
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Hot glue gun (generic)
Hot glue gun (generic)
3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

3D printer parts

all the parts you need to get it 3D printed. More on thingiverse (soon)

Schematics

rotary timer switch

schematics

fritzing design

rotary timer

Code

timer

Arduino
AC outlet timer
/* AC-outlet timer 1-255 minutes *
 *  by Mans Rademaker 2021
 *  uses Interrupt-based Rotary Encoder Sketch by Simon Merrett (see below)
 */

#include <TM1637.h>
int CLK = 4;
int DIO = 5;
TM1637 tm(CLK,DIO);

long  previousMillis = 0;        // will store last time
long  previousMillis2= 0;        // will store last time
int   time2go   = 0;
int   change    = 0;

int ledState    = LOW;            // ledState used to set the LED
long interval   = 1000;           // interval at which to blink 

#define relay     12
#define redled    11

/*******Interrupt-based Rotary Encoder Sketch*******
by Simon Merrett, based on insight from Oleg Mazurov, Nick Gammon, rt, Steve Spence
*/
static int pinA = 2; // Our first hardware interrupt pin is digital pin 2
static int pinB = 3; // Our second hardware interrupt pin is digital pin 3
volatile byte aFlag = 0; // let's us know when we're expecting a rising edge on pinA to signal that the encoder has arrived at a detent
volatile byte bFlag = 0; // let's us know when we're expecting a rising edge on pinB to signal that the encoder has arrived at a detent (opposite direction to when aFlag is set)
volatile byte encoderPos = 0; //this variable stores our current value of encoder position. Change to int or uin16_t instead of byte if you want to record a larger range than 0-255
volatile byte oldEncPos = 0; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the serial monitor)
volatile byte reading = 0; //somewhere to store the direct values we read from our interrupt pins before checking to see if we have moved a whole detent
//*******

void setup() {
  tm.init();
  tm.set(2);                  //set brightness; 0-7
  displayNumber(encoderPos);
  pinMode(relay,    OUTPUT);
  pinMode(redled,   OUTPUT);
  power(LOW);
  
  pinMode(pinA, INPUT_PULLUP); // set pinA as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
  pinMode(pinB, INPUT_PULLUP); // set pinB as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
  attachInterrupt(0,PinA,RISING); // set an interrupt on PinA, looking for a rising edge signal and executing the "PinA" Interrupt Service Routine (below)
  attachInterrupt(1,PinB,RISING); // set an interrupt on PinB, looking for a rising edge signal and executing the "PinB" Interrupt Service Routine (below)
  Serial.begin(9600); // start the serial monitor link
}

void PinA(){
  cli(); //stop interrupts happening before we read pin values
  reading = PIND & 0xC; // read all eight pin values then strip away all but pinA and pinB's values
  if(reading == B00001100 && aFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
    encoderPos --; //decrement the encoder's position count
    bFlag = 0; //reset flags for the next turn
    aFlag = 0; //reset flags for the next turn
  }
  else if (reading == B00000100) bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation
  sei(); //restart interrupts
}

void PinB(){
  cli(); //stop interrupts happening before we read pin values
  reading = PIND & 0xC; //read all eight pin values then strip away all but pinA and pinB's values
  if (reading == B00001100 && bFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
    encoderPos ++; //increment the encoder's position count
    bFlag = 0; //reset flags for the next turn
    aFlag = 0; //reset flags for the next turn
  }
  else if (reading == B00001000) aFlag = 1; //signal that we're expecting pinA to signal the transition to detent from free rotation
  sei(); //restart interrupts
}

void loop(){
unsigned long currentMillis = millis();

if(currentMillis - previousMillis > 60000) { // one minute later
  previousMillis = currentMillis;   
  if (time2go>0) {time2go--;}      
  if (time2go==0){power(LOW);}
  displayNumber(time2go);
}

if (time2go==1){ // last minute blink redled
  if(currentMillis - previousMillis2 > interval) {
    // save the last time you blinked the LED 
    previousMillis2 = currentMillis;   
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    // set the LED with the ledState of the variable:
    digitalWrite(redled, ledState);
  }
}  
  if(oldEncPos    != encoderPos) {
    change         = encoderPos - oldEncPos;
    time2go        = time2go + change;
    oldEncPos      = encoderPos;
    displayNumber  (time2go);
    previousMillis = currentMillis;
    if (time2go>0){power(HIGH);} else {power(LOW);}
  }
}

void power(int state){
   digitalWrite(relay,    state); 
   digitalWrite(redled,   state);    
}

void displayNumber(int num){   
    tm.display(3, num % 10);   
    tm.display(2, num / 10 % 10);   
    tm.display(1, num / 100 % 10);   
    tm.display(0, num / 1000 % 10);
}

Credits

mansfilmt

mansfilmt

0 projects • 0 followers

Comments