#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include <stdbool.h>
#include <string.h>
#include <math.h>
// setting the password to be four characters long
#define SEQUENCE_LENGTH 4
void setup_gpio();
char scan_keypad();
float readTemperature(adc1_channel_t channel, float nominalRes, float B);
// defining the two main variables
#define ROWS 4
#define COLS 4
// defining two arrays, one horizontal and oone vertiacal
int scanRowPins[ROWS] = {38, 37, 36, 35};
int colPins[COLS] = {0, 45, 48, 47};
// combing rows and colums to make a two dimensional array
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
// array to define the leds
int leds[3] = {2, 19, 18};
void app_main()
{
setup_gpio();
// sets the width of adcto 12 bit
adc1_config_width(ADC_WIDTH_BIT_12);
// sets attenuation to GPIO 4
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_11);
printf("Enter your code:\n");
gpio_set_level(leds[1], 0);
gpio_set_level(leds[2], 0);
while (1)
{
//creating the hardcoded password
const char correctCode[] = "1234";
static char input[5];
input[0] = '1';
input[1] = '2';
input[2] = '3';
input[3] = '4';
input[4] = '\0';
static int index = 0;
// Blink blue LED
gpio_set_level(leds[0], 1);
vTaskDelay(pdMS_TO_TICKS(500));
gpio_set_level(leds[0], 0);
vTaskDelay(pdMS_TO_TICKS(500));
// Check keypad using non-blocking
char key = scan_keypad();
if (key != '\0')
{
input[index++] = key;
printf("*");
fflush(stdout);
if (index == SEQUENCE_LENGTH)
{
input[index] = '\0'; // null-terminate string before comparing
if (strcmp(input, correctCode) == 0)
{
printf("\nAccess granted! Correct sequence entered.\n");
gpio_set_level(leds[0], 0);
//calling the function with specific values for it to calculate
float tempC = readTemperature(ADC1_CHANNEL_3, 10000, 3950);
printf("\nCurrent temperature: %.2f°C\n", tempC);
gpio_set_level(leds[2], 1);
vTaskDelay(pdMS_TO_TICKS(5000));
gpio_set_level(leds[2], 0);
}
else
{
printf("\nAccess denied! Incorrect sequence.\n");
gpio_set_level(leds[0], 0);
for (int i = 0; i <= 1; i++)
{
gpio_set_level(leds[1], 1);
vTaskDelay(pdMS_TO_TICKS(1000));
gpio_set_level(leds[1], 0);
vTaskDelay(pdMS_TO_TICKS(1000));
index = 0;
}
}
//set to remove possible overflow
key = 0;
}
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}
/**
setup_gpio
sets all the pins to input and makes them use pullup resistor logic
void
*/
void setup_gpio()
{
for (int i = 0; i < ROWS; i++)
{
gpio_set_direction(scanRowPins[i], GPIO_MODE_OUTPUT);
gpio_set_level(scanRowPins[i], 1);
}
for (int i = 0; i < COLS; i++)
{
gpio_set_direction(colPins[i], GPIO_MODE_INPUT);
gpio_set_pull_mode(colPins[i], GPIO_PULLUP_ONLY); // all buttons are set as pullup configuration using the internal pullup resistor in the microcontroller
}
gpio_set_direction(leds[0], GPIO_MODE_OUTPUT);
gpio_set_direction(leds[1], GPIO_MODE_OUTPUT);
gpio_set_direction(leds[2], GPIO_MODE_OUTPUT);
}
/**
scan_keypad
scans all of the rows and colums contineously checking for an input
char
*/
char scan_keypad()
{
uint8_t scanVal;
for (int i = 0; i < ROWS; i++)
{
scanVal = ~(1 << i);
for (int j = 0; j < ROWS; j++)
{
gpio_set_level(scanRowPins[j], (scanVal >> j) & 1); // here, 'pins' can be either row pins or column pins. Select the correct one
}
for (int k = 0; k < COLS; k++)
{
if (gpio_get_level(colPins[k]) == 0)
{ // pullup configuration
if (gpio_get_level(colPins[k]) == 0)
{
return keys[i][k]; //
}
return keys[i][k];
}
}
}
return '\0';
}
/*
readTemperature
It reads analog value from the thermistor and converts to °C.
adc1_channel_t channel, float nominalRes,float B
Returns: float, the temp in Celsius
*/
float readTemperature(adc1_channel_t channel, float nominalRes, float B)
{
// setting it into celcius format
float T1 = 25 + 273.15;
// total resistance
float RT;
// Voltage
float VRT;
// current temerature
float T2;
float R2 = 10000;
// getting the raw data and setting it to adc_value
int adc_value = adc1_get_raw(channel);
int adc_10bit = adc_value >> 2;
// setting the voltage to be equal to the raw times 3.3 divided by max adc value for 10bit resolution
VRT = (adc_10bit * 3.3f) / 4095;
// total resistance
RT = (R2 * VRT) / (3.3 - VRT);
// temperature
T2 = 1 / ((1 / T1) + (logf(RT / nominalRes) / B));
// setting it to celcius
float celcius = T2 - 273.15;
return celcius;
}