REQUIREMENT
Use a timer to count seconds (arduino doesn’t have a built in clock to track time.) When starting the board, you’ll first need to set the time. You’ll do so by using a combination of the buttons and the potentio meter. The buttons let you select hours or minutes, the potentio meter lets you adjust the value 0-24 hours 0-59 minutes.
Once the time has been set, and the clock is running, the time HH.MM will displayed on the 7 segment display. The dot, between HH and MM will toggle on/off every second.
The problem
After uploading the code it shows 0000 in the segment display theres no problem there but when pressing the middle button in the shield to set the timers the second segement of the segment display doesnt show the number clearly and the dot is also between the second and third segment it should be in the middle to separate hours with minutes.
-------------------------------------------this is button.c and button.h
//button.h
#ifndef BUTTON_H
#define BUTTON_H
#include <stdint.h>
#include <stdbool.h>
#define BUTTON1_PIN PC1
#define BUTTON2_PIN PC2
#define BUTTON3_PIN PC3
#define HIGH 1
#define LOW 0
void setupButtons();
bool isButtonPressed(uint8_t buttonPin);
#endif
//button.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include "button.h"
#include "timer.h"
void setupButtons() {
// Set button pins as input with pull-up resistors enabled
DDRC &= ~((1 << BUTTON1_PIN) | (1 << BUTTON2_PIN) | (1 << BUTTON3_PIN));
PORTC |= (1 << BUTTON1_PIN) | (1 << BUTTON2_PIN) | (1 << BUTTON3_PIN);
}
bool isButtonPressed(uint8_t buttonPin) {
static uint8_t buttonState[3] = {LOW, LOW, LOW};
static uint8_t lastButtonState[3] = {LOW, LOW, LOW};
static unsigned long lastDebounceTime[3] = {0, 0, 0};
unsigned long debounceDelay = 50;
uint8_t buttonIndex = buttonPin - BUTTON1_PIN;
uint8_t reading = (PINC & (1 << buttonPin)) ? HIGH : LOW;
if (reading != lastButtonState[buttonIndex]) {
lastDebounceTime[buttonIndex] = millis();
}
if ((millis() - lastDebounceTime[buttonIndex]) > debounceDelay) {
if (reading != buttonState[buttonIndex]) {
buttonState[buttonIndex] = reading;
if (buttonState[buttonIndex] == LOW) {
return true;
}
}
}
lastButtonState[buttonIndex] = reading;
return false;
}
-------------------------------------this is display.c and display.h
//display.h
#ifndef DISPLAY_H
#define DISPLAY_H
#include <avr/io.h>
#include "timer.h"
#define LOW 0
#define HIGH 1
/* Define shift register pins used for seven segment display */
#define LATCH_DIO PD4
#define CLK_DIO PD7
#define DATA_DIO PB0
#define LSBFIRST 0
#define MSBFIRST 1
#define NUMBER_OF_SEGMENTS 8
#define sbi(register, bit) (register |= (1 << bit))
#define cbi(register, bit) (register &=~ (1<< bit))
void displayTime(Time time);
void initDisplay();
void writeNumberToSegment(uint8_t segment, uint8_t value);
void writeNumber(int number);
#endif
//display.c
#include "display.h"
#include <avr/io.h>
#include <util/delay.h>
#include "timer.h"
// Segment byte maps for numbers 0 to 9
const uint8_t SEGMENT_MAP[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99,
0x92, 0x82, 0xF8, 0x80, 0x90};
// Byte maps to select digit 1 to 4
const uint8_t SEGMENT_SELECT[] = {0xF1, 0xF2, 0xF4, 0xF8};
void initDisplay() {
DDRD |= (1 << LATCH_DIO) | (1 << CLK_DIO);
DDRB |= (1 << DATA_DIO);
}
void shift(uint8_t val, uint8_t bitorder) {
for (uint8_t i = 0; i < NUMBER_OF_SEGMENTS; i++) {
uint8_t bit = (bitorder == LSBFIRST) ? !!(val & (1 << i)) : !!(val & (1 << (7 - i)));
if (bit) {
PORTB |= (1 << DATA_DIO);
} else {
PORTB &= ~(1 << DATA_DIO);
}
PORTD |= (1 << CLK_DIO);
PORTD &= ~(1 << CLK_DIO);
}
}
void writeNumberToSegment(uint8_t segment, uint8_t value) {
PORTD &= ~(1 << LATCH_DIO);
shift(SEGMENT_MAP[value], MSBFIRST);
shift(SEGMENT_SELECT[segment], MSBFIRST);
PORTD |= (1 << LATCH_DIO);
}
void displayTime(Time time) {
uint8_t hoursTens = time.hours / 10;
uint8_t hoursOnes = time.hours % 10;
uint8_t minutesTens = time.minutes / 10;
uint8_t minutesOnes = time.minutes % 10;
writeNumberToSegment(0, hoursTens);
_delay_ms(5);
writeNumberToSegment(1, hoursOnes);
_delay_ms(5);
writeNumberToSegment(2, minutesTens);
_delay_ms(5);
writeNumberToSegment(3, minutesOnes);
_delay_ms(5);
}
------------------------------this is timer.h and timer.c
// timer.h
#ifndef TIMER_H
#define TIMER_H
#include <stdint.h>
uint32_t millis();
typedef struct {
uint8_t hours;
uint8_t minutes;
uint8_t seconds;
} Time;
void setupTimer();
Time getCurrentTime();
uint32_t millis();
void initMillis();
#endif
// timer.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include "timer.h"
volatile Time currentTime;
volatile uint32_t timer_millis;
ISR(TIMER0_COMPA_vect) {
timer_millis++;
}
uint32_t millis() {
return timer_millis;
}
void initMillis() {
TCCR0A = (1 << WGM01);
TCCR0B = (1 << CS01) | (1 << CS00);
OCR0A = 249;
TIMSK0 |= (1 << OCIE0A);
sei();
}
void setupTimer() {
currentTime.hours = 0;
currentTime.minutes = 0;
currentTime.seconds = 0;
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);
OCR1A = 15624;
TIMSK1 = (1 << OCIE1A);
sei();
}
ISR(TIMER1_COMPA_vect) {
currentTime.seconds++;
if (currentTime.seconds >= 60) {
currentTime.seconds = 0;
currentTime.minutes++;
if (currentTime.minutes >= 60) {
currentTime.minutes = 0;
currentTime.hours++;
if (currentTime.hours >= 24) {
currentTime.hours = 0;
}
}
}
}
Time getCurrentTime() {
return currentTime;
}
-----------------------------------this is potentiometer.c and potentiometer.h
// potentiometer.h
#ifndef POTENTIOMETER_H
#define POTENTIOMETER_H
#include <stdint.h>
#define POTENTIOMETER_PIN 0
void setupPotentiometer();
int readPotentiometer();
#endif
// potentiometer.c
#include "potentiometer.h"
#include <avr/io.h>
void setupPotentiometer() {
ADMUX = (1 << REFS0);
ADCSRA = (1 << ADEN) | (1 << ADPS2);
}
int readPotentiometer() {
ADMUX &= 0xF0;
ADMUX |= POTENTIOMETER_PIN;
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC));
return ADCW;
}type here
Razer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.