A guy need a incubator motor controller and asked me to built one for him. The function will be as following.
- Wait one hour
- Run the dc gear motor forward for 10 seconds
- Wait one hour
- Run the dc gear motor reverse for 10 seconds
- Repeat from step 1
It seemed like a little arduino project and can be done in 2 minutes. But when he said that the time periods can be set to any duration by the user on run time, and display current step and remaining time, it became harder.
Now i have to decide how will i take user inputs to set the time. There are several options:
- Use four variable resistor on four ADC pin.
- Use a keypad to set the four time slots
- Use four SMT Slide Push Button Tactile Miniture Electronic Piano DIP Switch (or whatever the name is)
- Use 4 directional buttons, a lcd and make a menu to set and display time.
- Use a rotary encoder and a lcd
Let’s clarify one thing, I’m too much afraid of debounce and implementing hardware/software to remove debounce. Using four variable resistor seems too old, i will not go for it. Using a keypad requires a lot of IO port usage and it is prone to debounce, so i will left it. Using Slide Push Button Tactile Miniture Electronic Piano DIP Switch makes it non user friendly and requires too much IO port usage. Using 4 buttons is also prone to debounce, so i left these option.
So, now i’m left with only one option: Use a rotary encoder. I have tried many code examples from the internet and almost all of those seemed buggy for me. I have used the following code(though i have to hide the bug using clever logic in software).
#define encoderPin1 2 //clk
#define encoderPin2 3 //dt
#define encoderSwitchPin 4 //push button switch
int lastEncoded = 0, encoderValue = 0;
void setup() {
pinMode(encoderSwitchPin, INPUT);
digitalWrite(encoderPin1, LOW); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on
digitalWrite(encoderSwitchPin, HIGH); //turn pullup resistor on
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
}
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
lastEncoded = encoded; //store this value for next time
}
After struggling a week with the rotary encoder, I succeeded. The following is a video of the Incubator timer in action. It will be available to purchase from my electronics shop: tecshop.org
A video of working device:
https://youtube.com/watch?v=7F6U73fTx1k%3Ffeature%3Doembed