#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
// Pin definitions
#define BUTTON_PIN 4 // Button connected to GPIO 4
uint8_t led_pins[] = {38, 37, 36, 35, 0, 45, 48, 47}; //8-bit unsigned int array for LEDs w/ their GPIO pins. Uint8 array saves memory. (JI)
// Function declarations
int readPinStateWithDebounce(int pin);
void writeToPins(uint8_t pins[], uint8_t val);
void printbin8(uint8_t val);
void app_main() {
uint8_t counter = 0; //Declaring counter and initializing it to zero. (JI)
int lastButtonState = 1; //Declaring variable to track the last button state to prevent counter from increasing quickly. (JI)
gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT); //Setting the button as an input. (JI)
for (int i = 0; i < 8; i++) { //For-loop to initialize all LEDs as outputs. (JI)
gpio_set_direction(led_pins[i], GPIO_MODE_OUTPUT); //"i" iterates through each LED. (JI)
}
while (1) {
int btnState = readPinStateWithDebounce(BUTTON_PIN); //Reading the button state through the function and storing the value in a variable. (JI)
if (lastButtonState == 1 && btnState == 0) { //If the last state of the button was low and the current state of the button is high. (JI)
counter++; //Increase the count if the above conditions are met. (JI)
writeToPins(led_pins, counter); //Calling function to write the binary representation of the value to the correct LEDs. (JI)
printbin8(counter); //Printing the binary representation of the current count by calling function. (JI)
}
lastButtonState = btnState; //Resetting the button state. When you release the button, the lastButtonState is saved as '1'. (JI)
vTaskDelay(pdMS_TO_TICKS(200)); // Small delay to prevent excessive looping
}
}
//Function definition for the binary counter. (JI)
void printbin8(uint8_t valu) { //This is a function which will print the value of an 8-bit unsigned integer when called. (JI)
printf("0b");
for (int i = 7; i >= 0; i--) { //For-loop structure ensures we are printing from MSB to LSB and not exceeding 8 bits. (JI)
printf("%u", (valu >> i) & 1); //The value of 'valu' is right-shifted by 'i' from the for-loop. (JI)
}
printf("\n"); //Ensures each whole binary number is printed on a new line. (JI)
}
//Button debounce function definition. (JI)
int readPinStateWithDebounce(int pin) {
int initialState = gpio_get_level(pin); //Read the level of the button and store the value in a variable. (JI)
if (initialState == 0) {
vTaskDelay(pdMS_TO_TICKS(50));
printf("\nButton pressed. Pin state 1 = %d\n", initialState);
int currentState = gpio_get_level(pin);
if (currentState == 0) {
printf("Button pressed. Pin state 2 = %d\n\n", currentState);
return 0;
} else {
return 1;
}
} else {
return 1;
}
}
//Function definition for writing to the pins, which turns the corresponding LEDs to high or low. (JI)
void writeToPins(uint8_t pins[], uint8_t val) {
for (int i = 0; i < 8; i++) { //Iterates through each bit for each binary number. (JI)
uint8_t bitState = (val >> (7-i)) & 1; //Reading the bits in reverse order to have the LEDs appear from top to botton. (JI)
gpio_set_level(pins[i], bitState); //Set the pins to high or low based on the result of ANDing the val (counter) and 1. (JI)
}
}