#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
#include <TimeLib.h>
//TODO: set up seven segment decoder pins as outputs
//and bit combinations for them, and since no register is enought to host
//all of them u need to use 2 registers' pins
const int ledPin=5;
const int debounceTime=20;
unsigned long int currentTime0=0;
unsigned long int currentTime1=0;
volatile unsigned long int triggerTime0=0;
volatile unsigned long int triggerTime1=0;
volatile int luminosity=0;
void setup(){
//TODO: setting up an analog pin for the PWM for the LED
DDRB|=(1<<PB5|1<<PB4|1<<PB3|1<<PB2|1<<PB1|1<<PB0);//outputs for segments A B C D E F
DDRD|=(1<<PD7|1<<PD5);//output for G segment and PWM output on pin5 for LED
DDRD&=~(1<<PD2|1<<PD3);//configuring pin 2 and 3 as inputs
PORTB=(1<<PB5|1<<PB4|1<<PB3|1<<PB2|1<<PB1|1<<PB0);//7 segment default will be 0
PORTD&=~(1<<PD7|1<<PD5);//setting G segment and LED to 0
PORTD|=(1<<PD2|1<<PD3);//pullup resistor for both pins
EIMSK|=0b00000011;//configuring both INT0 and INT1 interrupts
EICRA|=0b00000000;//interrupt if low level is detected
Serial.begin(9600);
sei();
}
ISR(INT0_vect){
//debouncing on low level but since it steps in every time it sees a low
//level on the pin the millis() function cant progress beyond a few (2-3)
// iterations so the current time wont be able to change until we release
//the button, cuz it steps in the interrupt so fast the other proccesses cant
//progress
currentTime0=millis();
if(currentTime0-triggerTime0>debounceTime){
if(luminosity>0)luminosity--;
triggerTime0=millis();
}
}
ISR(INT1_vect){
currentTime1=millis();
if(currentTime1-triggerTime1>debounceTime){
if(luminosity<9)luminosity++;
triggerTime1=millis();
}
//for some reason it doesnt step into this part ever even if i hold the button
//i suspect its cuz once low level was detected and it triggerd an interrupt
//it wont trigger one again until it goes back to high and than again low
//on the other hand it does step into the ISR constantly, but since
//the interrupt is immediately triggered after it steps out the millis()
//doesn't go forward so it will never reach the
//currentTime-triggerTime>debounceTime condition
//and if we remove the condition it will quickly count up since there are
//no blocking conditions
/*
if(currentTime1-triggerTime1>=debounceTime-10&&!(PIND&1<<PD3)){
Serial.print("curr time- trig time1: ");
Serial.println(currentTime1-triggerTime1);
Serial.print("curr time1- 10: ");
Serial.println(currentTime1-10);
triggerTime1=millis();
}*/
}
void updateLuminosity();
int main(){
init();
setup();
while(true){
updateLuminosity();
}
}
void updateLuminosity(){
switch (luminosity){
case 0:
PORTB=1<<PB5|1<<PB4|1<<PB3|1<<PB2|1<<PB1|1<<PB0;
PORTD&=~(1<<PD7);
break;
case 1:
PORTB=1<<PB4|1<<PB3;
PORTD&=~(1<<PD7);
break;
case 2:
PORTB=1<<PB5|1<<PB4|1<<PB2|1<<PB1;
PORTD|=1<<PD7;
break;
case 3:
PORTB=1<<PB5|1<<PB4|1<<PB3|1<<PB2;
PORTD|=1<<PD7;
break;
case 4:
PORTB=1<<PB4|1<<PB3|1<<PB0;
PORTD|=1<<PD7;
break;
case 5:
PORTB=1<<PB5|1<<PB3|1<<PB2|1<<PB0;
PORTD|=1<<PD7;
break;
case 6:
PORTB=1<<PB5|1<<PB3|1<<PB2|1<<PB1|1<<PB0;
PORTD|=1<<PD7;
break;
case 7:
PORTB=1<<PB5|1<<PB4|1<<PB3;
PORTD&=~(1<<PD7);
break;
case 8:
PORTB=1<<PB5|1<<PB4|1<<PB3|1<<PB2|1<<PB1|1<<PB0;
PORTD|=1<<PD7;
break;
case 9:
PORTB=1<<PB5|1<<PB4|1<<PB3|1<<PB2|1<<PB0;
PORTD|=1<<PD7;
break;
}
analogWrite(ledPin,pow(1.851,luminosity)-0.5);//the task was to do 9 steps of 28 but this way brightness increases somewhat linearly
}