#include <avr/io.h>
#include <avr/interrupt.h>
// Constants for button debounce
#define DEBOUNCE_TIME 150 // in milliseconds
volatile int dutyCycle = 0; // Duty cycle of PWM (0-255)
volatile bool updateDisplay = false; // Flag to update 7-segment display
const uint8_t segmentMap[10] = {
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111 // 9
};
volatile bool button0Pressed = false;
volatile bool button1Pressed = false;
// Initialize PWM on pin D9
void initPWM() {
pinMode(9, OUTPUT);
TCCR1A = (1 << WGM10) | (1 << COM1A1);
TCCR1B = (1 << CS11) | (1 << CS10); // Prescaler 64
OCR1A = 0; // Initial duty cycle
}
// Initialize interrupts for buttons
void initInterrupts() {
EICRA = (0 << ISC01) | (1 << ISC00) | (0 << ISC11) | (1 << ISC10); // Rising edge for INT0 and INT1
EIMSK = (1 << INT0) | (1 << INT1); // Enable INT0 and INT1
sei(); // Enable global interrupts
}
// Update 7-segment display for common anode
void update7SegmentDisplay(int value) {
uint8_t segments = segmentMap[value % 10];
// Using PORTD for pins 4-7 and PORTB for pins 8, 10, 11
// Segment a (PD4)
if (segments & 0x01) PORTD &= ~(1 << PD4); // LOW
else PORTD |= (1 << PD4); // HIGH
// Segment b (PD5)
if (segments & 0x02) PORTD &= ~(1 << PD5); // LOW
else PORTD |= (1 << PD5); // HIGH
// Segment c (PD6)
if (segments & 0x04) PORTD &= ~(1 << PD6); // LOW
else PORTD |= (1 << PD6); // HIGH
// Segment d (PD7)
if (segments & 0x08) PORTD &= ~(1 << PD7); // LOW
else PORTD |= (1 << PD7); // HIGH
// Segment e (PB0)
if (segments & 0x10) PORTB &= ~(1 << PB0); // LOW
else PORTB |= (1 << PB0); // HIGH
// Segment f (PB2)
if (segments & 0x20) PORTB &= ~(1 << PB2); // LOW
else PORTB |= (1 << PB2); // HIGH
// Segment g (PB3)
if (segments & 0x40) PORTB &= ~(1 << PB3); // LOW
else PORTB |= (1 << PB3); // HIGH
}
// Interrupt Service Routine for INT0
ISR(INT0_vect) {
static unsigned long lastInterruptTime0 = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime0 > DEBOUNCE_TIME) {
if (dutyCycle < 255) dutyCycle += 28;
if (dutyCycle > 255) dutyCycle = 255;
OCR1A = dutyCycle;
updateDisplay = true;
lastInterruptTime0 = interruptTime;
}
}
// Interrupt Service Routine for INT1
ISR(INT1_vect) {
static unsigned long lastInterruptTime1 = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime1 > DEBOUNCE_TIME) {
if (dutyCycle > 0) dutyCycle -= 28;
if (dutyCycle < 0) dutyCycle = 0;
OCR1A = dutyCycle;
updateDisplay = true;
lastInterruptTime1 = interruptTime;
}
}
void setup() {
// Set up 7-segment display pins
for (int i = 4; i <= 8; i++) {
pinMode(i, OUTPUT);
}
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
update7SegmentDisplay(0); // Initialize display to 0
initPWM();
initInterrupts();
}
void loop() {
if (updateDisplay) {
update7SegmentDisplay(dutyCycle / 28); // Display the step 0-9
updateDisplay = false;
}
}
// #include <avr/io.h>
// #include <avr/interrupt.h>
// // Constants for button debounce
// #define DEBOUNCE_TIME 5 // in milliseconds
// volatile int dutyCycle = 0; // Duty cycle of PWM (0-255)
// volatile bool updateDisplay = false; // Flag to update 7-segment display
// const uint8_t segmentMap[10] = {
// 0b00111111, // 0
// 0b00000110, // 1
// 0b01011011, // 2
// 0b01001111, // 3
// 0b01100110, // 4
// 0b01101101, // 5
// 0b01111101, // 6
// 0b00000111, // 7
// 0b01111111, // 8
// 0b01101111 // 9
// };
// // Initialize PWM on pin D9
// void initPWM() {
// pinMode(9, OUTPUT);
// TCCR1A = (1 << WGM10) | (1 << COM1A1);
// TCCR1B = (1 << CS11) | (1 << CS10); // Prescaler 64
// OCR1A = 0; // Initial duty cycle
// }
// // Initialize interrupts for buttons
// void initInterrupts() {
// EICRA = (1 << ISC01) | (1 << ISC00) | (1 << ISC11) | (1 << ISC10); // Rising edge for INT0 and INT1
// EIMSK = (1 << INT0) | (1 << INT1); // Enable INT0 and INT1
// sei(); // Enable global interrupts
// }
// // Update 7-segment display
// void update7SegmentDisplay(int value) {
// uint8_t segments = segmentMap[value % 10];
// digitalWrite(4, segments & 0x01);
// digitalWrite(5, (segments >> 1) & 0x01);
// digitalWrite(6, (segments >> 2) & 0x01);
// digitalWrite(7, (segments >> 3) & 0x01);
// digitalWrite(8, (segments >> 4) & 0x01);
// digitalWrite(10, (segments >> 5) & 0x01);
// digitalWrite(11, (segments >> 6) & 0x01);
// }
// // Interrupt Service Routine for INT0
// ISR(INT0_vect) {
// static unsigned long lastInterruptTime0 = 0;
// unsigned long interruptTime = millis();
// if (interruptTime - lastInterruptTime0 > DEBOUNCE_TIME) {
// if (dutyCycle < 255) dutyCycle += 28;
// if (dutyCycle > 255) dutyCycle = 255;
// OCR1A = dutyCycle;
// updateDisplay = true;
// lastInterruptTime0 = interruptTime;
// }
// }
// // Interrupt Service Routine for INT1
// ISR(INT1_vect) {
// static unsigned long lastInterruptTime1 = 0;
// unsigned long interruptTime = millis();
// if (interruptTime - lastInterruptTime1 > DEBOUNCE_TIME) {
// if (dutyCycle > 0) dutyCycle -= 28;
// if (dutyCycle < 0) dutyCycle = 0;
// OCR1A = dutyCycle;
// updateDisplay = true;
// lastInterruptTime1 = interruptTime;
// }
// }
// void setup() {
// // Set up 7-segment display pins
// for (int i = 4; i <= 8; i++) {
// pinMode(i, OUTPUT);
// }
// pinMode(10, OUTPUT);
// pinMode(11, OUTPUT);
// initPWM();
// initInterrupts();
// }
// void loop() {
// if (updateDisplay) {
// update7SegmentDisplay(dutyCycle / 28); // Display the step 0-9
// updateDisplay = false;
// }
// }
// #include <avr/io.h>
// #include <util/delay>
// #include <avr/interrupt.h>
// #include <avr/io.h>
// // #include <LiquidCrystal_I2C.h>
// // LiquidCrystal_I2C lcd(0x27, 16, 2);
// ISR(PCINT2_vect) {
// //inputs are active low
// uint8_t pd = ~PIND;
// if (pd & 0x80)//we need to determine which pin generated interrupt
// PORTB |= 1 << PB1;
// else if (pd & 0x40)
// PORTB &= ~(1 << PB1);
// }
// float read_adc() {
// ADCSRA |= (1 << ADSC); // Start the Conversion
// while (ADCSRA & (1 << ADSC)); // Wait for Conversion to Complete
// uint16_t adcValue = ADC; // Read the ADC Value
// int brightness = adcValue / (1023 / 9);
// return brightness;
// }
// volatile float brightness = 0.0;
// volatile int state=LOW;
// byte bit5;
// void print_brightness() {
// }
// void setup() {
// // PORTD = 1 << PD2;//interal pull up
// // brightness = read_adc();
// // print_brightness();
// DDRD &= ~((1 << PD7) | (1 << PD6)) ;//port D as input
// PORTD = (1 << PD7) | (1 << PD6);//use pull up resistors PORTD6 and 7
// DDRB= 1 << PB1;//output port bit
// PORTD = 0x04;//configure to use pull up resistor
// /* set PORTB BIT IN PIN 13 as output */
// DDRB |= 0x20;// DDRB5 pin 13 as output
// // Enable pin change interrupts
// PCICR = 1 << PCIE2; //enable pin change interrupt bank 2
// PCMSK2 = (1 << PCINT22) | (1 << PCINT23); //enable pin change interrupt on PCINT22 PCINT23
// sei();// Set global interrupt flag
// }
// int main() {
// init();
// setup();
// // while(true) {
// // float new_brightness = read_adc();
// // if (new_brightness != brightness) {
// // brightness = new_brightness;
// // print_brightness();
// // }
// // }
// // DDRD = 0x40; //PORTD bit 2 as input
// EIMSK |= 0b00000001;//Enable ext interrupt INT0
// EICRA |= 0b00000010;//Trig. INT0 on falling edge
// bit5 = 1 << 5;//set bit 5 to 1 shifting 5 times
// sei();//Enable interrupts
// while (true) {
// PORTB = state;//change state
// }
// }