0% found this document useful (0 votes)
36 views14 pages

Lab 6

embedded systems lab 6 with codes

Uploaded by

engr.ahmadali99
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views14 pages

Lab 6

embedded systems lab 6 with codes

Uploaded by

engr.ahmadali99
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

Page 1 of 14

Lab. 6
Communication Protocols-Serial Peripheral Interface and
Matrix Keypad Interfacing
Objectives:

1. To understand Serial peripheral Interface (SPI) protocol communication


2. Interfacing SPI devices with ESP32
3. Interfacing matric keypad with ESP32
➢ SPI protocol
SPI is a widely used serial communication protocol that facilitates bidirectional binary data
communication among a digital controller and peripheral devices such as ADCs, DACs,
EEPROMS, SRAMs and digital displays. SPI is a synchronous communication protocol that
primarily uses four digital lines. These lines are CLK (clock), CS (chip select), MISO (data
input, from peripheral (slave) to the controller (master)), and MOSI (data out, from controller
(master) to the peripheral (slave)). The MISO and MOSI are also called DIN and DOUT,
respectively. CLK is the clock signal that is controlled by the master. SPI can operate safely
from 100 kHz to 4 MHz. CS is the chip select line that enables that slave device with which
master wants to communicate. If more than one slaves are to be interfaced with single master,
then an Nx2N decoder is to be used. MISO is the master input line that transfers data from the
slave to the master. MOSI is the master output line that transfers data from the master to the
slave. SPI is a high-speed link that facilitates hardware designers interfacing several devices of
different nature in an embedded system. Owed to its simplicity, it can be easily programmed in
a general-purpose microcontroller using its GPIOs. It is a one-byte or two-byte oriented
protocol that uses MSB-first scheme for data communication. Data is sampled on the rising
edge of the clock and is shifted to either master or slave on the falling edge. During entire
communication session, CS remains at the active logic level
Figure 1 shows the schematic diagram of interfacing multiple peripherals with a master using
SPI link.

Figure 2 shows the waveforms of SPI communication link.


Page 2 of 14

Figure 2

➢ MAX7219 8-digit multiplexed LED driver


MAX7219 is an 8-digit multiplexed LED driver integrated circuit that has SPI interface. This
circuit can be easily interfaced with any microcontroller. A single MAX7219 circuit can control
up to 8 7-segment displayed in multiplexed scheme. MAX7219 has several 8-bit registers that
are to be programmed for displaying numbers on an LED display. For details, refer to the
datasheet of MAX7219 available on: https://www.analog.com/media/en/technical-
documentation/data-sheets/MAX7219- MAX7221.pdf
Safety Instructions:
➢ Disconnect the ESP32 board from the computer while setting up the circuit.
➢ Constructing circuit around ESP32 while it is connected with computer can damage both
the board and the computer.
➢ Only connect the ESP32 board with the computer when circuit has been fully constructed.
Program 1:
#include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #define CLK 18
//CLK line of MAX7219 #define LOAD 19 //LOAD line of MAX7219
#define D_IN 21 //DIN line of MAX7219
#define SCAN_DIGITS 4 //number of digits to scan
#define INTENS_VAL 0x0F //intensity of display. 0x04 for normal view #define DASH 0x01
//code for '-' sign //addresses of MAX7219 registers
#define DIG0 0x0 #define DIG1 0x02 #define DIG2 0x03 #define DIG3 0x04 #define DIG4 0x05
#define DIG5 0x06 #define DIG6 0x07 #define DIG7 0x08
#define DECODE 0x09
#define INTENS 0x0A
#define SCAN_LIMIT 0x0B
#define SHUT_DOWN 0x0C #define DISPLAY_TEST 0x0F
typedef unsigned char UCHAR; typedef
unsigned int UINT;
typedef unsigned short USHORT;

// Delay for milliseconds


void delay_ms(UINT ms){
vTaskDelay(pdMS_TO_TICKS(ms));
}
/*********************************************************
7-segment data buffer with all HEX characters from 0 to F.

bit no. 7 6 5 4 3 2 1 0

seg. no. dp a b c d e f g

*********************************************************/
char codes[16] = {0x7E,0x30,0x6D,0x79,0x33,0x5B,0x5F,0x70
,0x7F,0x7B,0x77,0x1F,0x4E,0x3D,0x4F,0x47};
//function to transfer 16-bit packet to MAX7219 with MSB-first void
MAX7219_packet_write(char reg, char val){
Page 3 of 14

UINT packet;
char i;
gpio_set_level(LOAD, 0); //LOAD line is low
packet = ((((unsigned int)reg)<<8) | (unsigned int)val);
for(i=0; i<16; i++){
if(packet&(0x8000>>i)){
gpio_set_level(D_IN, 1);
gpio_set_level(CLK, 1);
gpio_set_level(CLK, 0);
} //end if else{
gpio_set_level(D_IN, 0);
gpio_set_level(CLK, 1);
gpio_set_level(CLK, 0);
} //end else} //end for //LOAD line is high to latch data
gpio_set_level(LOAD, 1);
gpio_set_level(LOAD, 0);} //end MAX7219_packet_write
//function configures MAX7219 for normal operation void
MAX7219_Config(){
gpio_set_direction(D_IN, GPIO_MODE_OUTPUT);
gpio_set_direction(LOAD, GPIO_MODE_OUTPUT);
gpio_set_direction(CLK, GPIO_MODE_OUTPUT);
gpio_set_level(CLK, 0); gpio_set_level(LOAD, 0);
//set normal operation AX7219_packet_write(SHUT_DOWN,1);
//set normal operation MAX7219_packet_write(DISPLAY_TEST,0);
//set no decode MAX7219_packet_write(DECODE,0x00);
//set intensity value MAX7219_packet_write(INTENS,INTENS_VAL);
/set number of digits scanned MAX7219_packet_write(SCAN_LIMIT,SCAN_DIGITS-1);
} //end MAX7219_Config //function to send number to display void NumOut(USHORT
num){ USHORT temp, d0, d1, d2, d3;
temp = num;
d0 = temp%10; //extract unit digit temp
= temp/10; d1 = temp%10; //extract 10th digit temp
= temp/10; d2 = temp%10; //extract 100th digit
d3 = temp/10; //extract 1000th digit
MAX7219_packet_write(DIG0,codes[d0]);
MAX7219_packet_write(DIG1,codes[d1]);
MAX7219_packet_write(DIG2,codes[d2]);
MAX7219_packet_write(DIG3,codes[d3]);
} //end NumOut
/***************************************************************************/
void app_main() {UINT NUM = 0;n MAX7219_Config();
MAX7219_packet_write(DISPLAY_TEST,1); delay_ms(1000);
MAX7219_Config(); for(;;){ NumOut(NUM++); delay_ms(50); }}

Task 1:
Make changes in Program 1 such that it displays a 4-digit random number (ranging from 0000
to 9999) after interval of one second.
Construct the circuit on breadboard and show the output to the lab instructor. Follow the safety
instructions while demonstrating the task.
code:
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_system.h" // Required for random number generation
#define CLK 18 // CLK line of MAX7219
#define LOAD 19 // LOAD line of MAX7219
Page 4 of 14

#define D_IN 21 // DIN line of MAX7219


#define SCAN_DIGITS 4 // Number of digits to scan
#define INTENS_VAL 0x0F // Intensity of display. 0x04 for normal view
#define DASH 0x01 // Code for '-' sign #define DIG0 0x01
#define DIG1 0x02 #define DIG2 0x03 #define DIG3 0x04 #define DIG4 0x05 #define DIG5
0x06 #define DIG6 0x07 #define DIG7 0x08 #define DECODE 0x09 #define INTENS 0x0A
#define SCAN_LIMIT 0x0B #define SHUT_DOWN 0x0C #define DISPLAY_TEST 0x0F
typedef unsigned char UCHAR; typedef unsigned int UINT; typedef unsigned short USHORT;
void delay_ms(UINT ms) { vTaskDelay(pdMS_TO_TICKS(ms));}7-segment data buffer with
all HEX characters from 0 to F.
bit no. 7 6 5 4 3 2 1 0
seg. no. dp a b c d e f g
*********************************************************/
char codes[16] = {
0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70,
0x7F, 0x7B, 0x77, 0x1F, 0x4E, 0x3D, 0x4F, 0x47};
void MAX7219_packet_write(char reg, char val) {
UINT packet; char i; gpio_set_level(LOAD, 0); // LOAD line is low
packet = ((((unsigned int)reg) << 8) | (unsigned int)val); for (i = 0; i < 16; i++) {
if (packet & (0x8000 >> i)) {gpio_set_level(D_IN, 1); gpio_set_level(CLK, 1);
gpio_set_level(CLK, 0); } else { gpio_set_level(D_IN, 0); gpio_set_level(CLK, 1);
gpio_set_level(CLK, 0); )} gpio_set_level(LOAD, 1); gpio_set_level(LOAD, 0))
void MAX7219_Config() {
gpio_set_direction(D_IN, GPIO_MODE_OUTPUT);
gpio_set_direction(LOAD, GPIO_MODE_OUTPUT);
gpio_set_direction(CLK, GPIO_MODE_OUTPUT);=
gpio_set_level(CLK, 0);
gpio_set_level(LOAD, 0);
MAX7219_packet_write(SHUT_DOWN, 1);
MAX7219_packet_write(DISPLAY_TEST, 0);
MAX7219_packet_write(DECODE, 0x00);
MAX7219_packet_write(INTENS, INTENS_VAL);
MAX7219_packet_write(SCAN_LIMIT, SCAN_DIGITS - 1);))
void NumOut(USHORT num) {
USHORT temp, d0, d1, d2, d3; temp = num;
d0 = temp % 10; // Extract unit digit temp = temp / 10;
d1 = temp % 10; // Extract 10th digit
temp = temp / 10;
d2 = temp % 10; // Extract 100th digit
d3 = temp / 10; // Extract 1000th digit
MAX7219_packet_write(DIG0, codes[d0]);
MAX7219_packet_write(DIG1, codes[d1]);
MAX7219_packet_write(DIG2, codes[d2]);
MAX7219_packet_write(DIG3, codes[d3]);
}void app_main() {
MAX7219_Config();
MAX7219_packet_write(DISPLAY_TEST, 1);
delay_ms(1000);
MAX7219_Config(); while (1) {
// Generate a random number between 0000 and 9999
USHORT random_number = esp_random() % 10000;
NumOut(random_number); // Display the random number
delay_ms(1000); // Wait for 1 seconds )}
Page 5 of 14

Task 2:
Make changes in Program 1 such that it displays counting from 0 to 999 on digits 0 to 2 (first
3 digits on right side) and from 999 to 0 on digits 5 to 7 (last 3 digits on left side). The two
digits in the middle (digit 3 and digit 4) should remain off. Count should be updated after
interval of 100 ms. Construct the circuit on breadboard and show the output to the lab
instructor. Follow the safety instructions while demonstrating the task

code:
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#define CLK 18 // CLK line of MAX7219
#define LOAD 19 // LOAD line of MAX7219
#define D_IN 21 // DIN line of MAX7219
#define SCAN_DIGITS 8 // Number of digits to scan
#define INTENS_VAL 0x0F // Intensity of display
#define OFF 0x00 // Code to turn off digits #define DIG0 0x01
#define DIG1 0x02
#define DIG2 0x03
#define DIG3 0x04
#define DIG4 0x05
#define DIG5 0x06
#define DIG6 0x07
#define DIG7 0x08
#define DECODE 0x09
#define INTENS 0x0A
#define SCAN_LIMIT 0x0B
#define SHUT_DOWN 0x0C
#define DISPLAY_TEST 0x0F
typedef unsigned char UCHAR;
typedef unsigned int UINT;
typedef unsigned short USHORT;
void delay_ms(UINT ms) {
vTaskDelay(pdMS_TO_TICKS(ms));
}.
bit no. 7 6 5 4 3 2 1 0
seg. no. dp a b c d e f g
*********************************************************/
char codes[16] = {
0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70,
0x7F, 0x7B, 0x77, 0x1F, 0x4E, 0x3D, 0x4F, 0x47
};
void MAX7219_packet_write(char reg, char val) {
UINT packet;
char i; gpio_set_level(LOAD, 0); // LOAD line is low
packet = ((((unsigned int)reg) << 8) | (unsigned int)val); for (i = 0; i < 16; i++) {
if (packet & (0x8000 >> i)) { gpio_set_level(D_IN, 1);
gpio_set_level(CLK, 1);
gpio_set_level(CLK, 0);
} else { gpio_set_level(D_IN, 0);
gpio_set_level(CLK, 1);
gpio_set_level(CLK, 0);
}} gpio_set_level(LOAD, 1);
Page 6 of 14

gpio_set_level(LOAD, 0);
}
void MAX7219_Config() {
gpio_set_direction(D_IN, GPIO_MODE_OUTPUT);
gpio_set_direction(LOAD, GPIO_MODE_OUTPUT);
gpio_set_direction(CLK, GPIO_MODE_OUTPUT);
gpio_set_level(CLK, 0);
gpio_set_level(LOAD, 0);
MAX7219_packet_write(SHUT_DOWN, 1); MAX7219_packet_write(DISPLAY_TEST,
0); MAX7219_packet_write(DECODE, 0x00);
MAX7219_packet_write(INTENS, INTENS_VAL);
MAX7219_packet_write(SCAN_LIMIT, SCAN_DIGITS - 1);))
void DisplayNumberOnDigits(USHORT num, UCHAR digit_start) {
USHORT temp, d0, d1, d2;
temp = num;
d0 = temp % 10; // Extract unit digit
temp = temp / 10;
d1 = temp % 10; // Extract 10th digit
temp = temp / 10;
d2 = temp % 10; // Extract 100th digit
MAX7219_packet_write(digit_start, codes[d0]);
MAX7219_packet_write(digit_start + 1, codes[d1]);
MAX7219_packet_write(digit_start + 2, codes[d2]);
}
void app_main() {USHORT count_up = 0; USHORT count_down = 999; MAX7219_Config();
while (1) { DisplayNumberOnDigits(count_up, DIG0);
MAX7219_packet_write(DIG3, OFF);
MAX7219_packet_write(DIG4, OFF);
DisplayNumberOnDigits(count_down, DIG5);
count_up = (count_up + 1) % 1000; // Increment and reset at 1000
count_down = (count_down == 0) ? 999 : count_down - 1; // Decrement and reset at 0
delay_ms(100); }}

➢ Matrix Keypad

A matrix keypad is an input device that can be used to input data to a processing device such
as an MCU. A matrix keypad is arranged in the form of a pushbutton grid that are organized in
rows and columns. Each pushbutton behaves as a simple pushbutton that can be configured as
either pulled-up or pulled-down. In order to scan a keypad to identify any key pressed, all the
columns are pulled-up and rows are scanned one by one by providing logic 0 on one row at a
time. The other condition is also possible when all the rows are pulled-up and columns are
scanned one by one by providing logic 0 on one column at a time.
A 4x3 (4 rows and 3 columns) matrix keypad is shown in figure 3.
Page 7 of 14

Program 2: This program interfaces a 4x3 matrix keypad with ESP32 MCU board. The key
input by the keypad is displayed on an I2C LCD.
➢ Make ‘include.c’ file that contains the following text.
This file contains the dependencies needed for interfacing keypad and PCF8574 I2C LCD.
Copy this file in the designated folder (refer to Lab 5).
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h" #include "PCF8574_LCD.c" #include "KP4x3_ESP32.c" ➢ Place the
PCF8574_LCD.c file designated folder (refer to Lab 5).
➢ Make ‘KP4x3_ESP32.c’ file that contains the following code.
This file defines the functions and variables required for keypad scanning and key reading.
/***********************************************************************
This file defines the functions that scan a 4x3 matrix keypad and return the ASCII of that key.
CPU: ESP32 Written By: Engr. Usman Rafique Dated: Nov. 05, 2024
***********************************************************************/ //
Define GPIO pins for rows and columns
#define R0 GPIO_NUM_13
#define R1 GPIO_NUM_12
#define R2 GPIO_NUM_14
#define R3 GPIO_NUM_27 #define C0 GPIO_NUM_26 #define C1 GPIO_NUM_25
#define C2 GPIO_NUM_33 #define KP_Delay 10 //keypad key press delay in milliseconds //
4x3 Keypad layout
char keys[4][3] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'*', '0', '#'} }; // Initialize GPIOs void
Keypad_Config() { // Set rows as output and columns as input
esp_rom_gpio_pad_select_gpio(R0); esp_rom_gpio_pad_select_gpio(R1);
esp_rom_gpio_pad_select_gpio(R2); esp_rom_gpio_pad_select_gpio(R3);
esp_rom_gpio_pad_select_gpio(C0); esp_rom_gpio_pad_select_gpio(C1);
esp_rom_gpio_pad_select_gpio(C2); gpio_set_direction(R0, GPIO_MODE_OUTPUT);
gpio_set_direction(R1, GPIO_MODE_OUTPUT); gpio_set_direction(R2,
GPIO_MODE_OUTPUT); gpio_set_direction(R3, GPIO_MODE_OUTPUT); // Default high
gpio_set_level(R0, 1); gpio_set_level(R1, 1); gpio_set_level(R2, 1); gpio_set_level(R3, 1);
gpio_set_direction(C0, GPIO_MODE_INPUT); gpio_set_direction(C1,
GPIO_MODE_INPUT); gpio_set_direction(C2, GPIO_MODE_INPUT); // Enable pull-up
resistors gpio_pullup_en(C0); gpio_pullup_en(C1); gpio_pullup_en(C2); } // Function to scan
the keypad and return the key char keypad_get_key() { char c0, c1, c2; //scan row0 only
gpio_set_level(R0, 0); gpio_set_level(R1, 1); gpio_set_level(R2, 1); gpio_set_level(R3, 1); c0
= gpio_get_level(C0); c1 = gpio_get_level(C1); c2 = gpio_get_level(C2); if(c0==0 && c1==1
&& c2==1) return(keys[0][0]); else if(c0==1 && c1==0 && c2==1) return(keys[0][1]); else
if(c0==1 && c1==1 && c2==0) return(keys[0][2]); //scan row1 only gpio_set_level(R0, 1);
gpio_set_level(R1, 0); gpio_set_level(R2, 1); gpio_set_level(R3, 1); c0 = gpio_get_level(C0);
c1 = gpio_get_level(C1); c2 = gpio_get_level(C2); if(c0==0 && c1==1 && c2==1)
return(keys[1][0]); else if(c0==1 && c1==0 && c2==1) return(keys[1][1]); else if(c0==1 &&
c1==1 && c2==0) return(keys[1][2]); //scan row2 only gpio_set_level(R0, 1);
gpio_set_level(R1, 1); gpio_set_level(R2, 0); gpio_set_level(R3, 1); c0 = gpio_get_level(C0);
c1 = gpio_get_level(C1); c2 = gpio_get_level(C2); if(c0==0 && c1==1 && c2==1)
return(keys[2][0]); else if(c0==1 && c1==0 && c2==1) return(keys[2][1]); else if(c0==1 &&
c1==1 && c2==0) return(keys[2][2]); //scan row3 only gpio_set_level(R0, 1);
gpio_set_level(R1, 1); gpio_set_level(R2, 1); gpio_set_level(R3, 0); c0 = gpio_get_level(C0);
c1 = gpio_get_level(C1); c2 = gpio_get_level(C2); if(c0==0 && c1==1 && c2==1)
return(keys[3][0]); else if(c0==1 && c1==0 && c2==1) return(keys[3][1]); else if(c0==1 &&
c1==1 && c2==0) return(keys[3][2]); //this must be the very last statement else return '\0'; //
Return null if no key is pressed } // Task to display key presses char Keypad_Read() { char key
= '\0'; while (key == '\0') { key = keypad_get_key(); }
vTaskDelay(pdMS_TO_TICKS(KP_Delay)); return key; } ➢ Copy the following code in
Page 8 of 14

main.c. Run the code and show the output to the lab instructor. #include "include.c" #define
LED GPIO_NUM_2 // Delay for milliseconds void delay_ms(unsigned int ms){
vTaskDelay(pdMS_TO_TICKS(ms)); }
/***************************************************************************
***/ void app_main() { char buff[20]; char num; gpio_set_direction(LED,
GPIO_MODE_OUTPUT); for(int j=0; j<6; j++){ gpio_set_level(LED, 1); delay_ms(50);
gpio_set_level(LED, 0); delay_ms(50); } PCF8574_LCD_init(); Keypad_Config();
cursor_position(0,5); lcd_print("Start"); cursor_position(1,5); lcd_print("ESP32");
delay_ms(1000); lcd_command(0x01); // clear display cursor_position(0,1); lcd_print("Key
pressed:"); for(;;){ num = Keypad_Read(); sprintf(buff,"%c ", num); cursor_position(1,7);
lcd_print(buff);
}
}

Lab Task 1:

Construct an embedded system (ES) using ESP32 that reads a temperature threshold value from
keypad and controls an LED. A matrix keypad is used to read numbers. The required ES also
has an RTC (DS1307) and an LM35 centigrade temperature sensor for measuring ambient
temperature. Time and ambient temperature are to be displayed on a MAX7219 LED display
stick. LED display should show the time in hours, minutes and seconds, separated with ‘-’ sign.
There should be a pushbutton that, when pressed, shows the current temperature on display.
When temperature exceeds the threshold, on-board LED turn on until it falls below the
threshold. Temperature threshold is to be read from the keypad when ES is powered up.

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "PCF8574_LCD.c"
#include "KP4x3_ESP32.c"
#include "DS1307.c" // RTC Driver
#include "LM35.c" // LM35 Driver
#define LED GPIO_NUM_2
#define BUTTON GPIO_NUM_15
void system_init() {
gpio_set_direction(LED, GPIO_MODE_OUTPUT);
gpio_set_direction(BUTTON, GPIO_MODE_INPUT);
gpio_pullup_en(BUTTON); // Enable pull-up for button
PCF8574_LCD_init(); // Initialize LCD
Keypad_Config(); // Initialize keypad
DS1307_Init(); // Initialize RTC
LM35_Init(); // Initialize LM35
}int threshold = 0; int mode = 0; // 0: Display time, 1: Display temperature
Page 9 of 14

int read_threshold_from_keypad() char key;


int temp_threshold = 0;
PCF8574_LCD_clear();
lcd_print(“Enter Threshold:");
while (1) { key = Keypad_Read();
if (key == '#') break; // End input with #
if (key >= '0' && key <= '9') {
temp_threshold = temp_threshold * 10 + (key - '0');
char buff[2] = {key, '\0'};
lcd_print(buff);}}
return temp_threshold;}
void display_time_on_MAX7219() {
Time time = DS1307_ReadTime(); // Read time from RTC
MAX7219_packet_write(DIG0, codes[time.hours / 10]); // Display hours (tens)
MAX7219_packet_write(DIG1, codes[time.hours % 10]); // Display hours (units)
MAX7219_packet_write(DIG2, codes[10]); // Display '-'
MAX7219_packet_write(DIG3, codes[time.minutes / 10]); // Display minutes (tens)
MAX7219_packet_write(DIG4, codes[time.minutes % 10]); // Display minutes (units)
MAX7219_packet_write(DIG5, codes[10]); // Display '-'
MAX7219_packet_write(DIG6, codes[time.seconds / 10]); // Display seconds (tens)
MAX7219_packet_write(DIG7, codes[time.seconds % 10]); // Display seconds (units)
}void display_temperature_on_MAX7219() {
float temperature = LM35_ReadTemperature(); // Read temperature from LM35
int temp = (int)temperature; MAX7219_packet_write(DIG0, codes[temp / 100]); //
Display hundreds (if any)
MAX7219_packet_write(DIG1, codes[(temp / 10) % 10]); // Display tens
MAX7219_packet_write(DIG2, codes[temp % 10]); // Display units
MAX7219_packet_write(DIG3, codes[12]); // Display 'C'
}void IRAM_ATTR button_isr_handler(void* arg) {
mode = !mode; // Toggle between 0 (time) and 1 (temperature) void button_init() {
gpio_install_isr_service(0);
gpio_set_intr_type(BUTTON, GPIO_INTR_POSEDGE);
gpio_isr_handler_add(BUTTON, button_isr_handler, NULL);
}
void app_main() {
Page 10 of 14

system_init();
button_init();
threshold = read_threshold_from_keypad();

// Main loop
while (1) {
float current_temp = LM35_ReadTemperature();

// Check threshold
if (current_temp > threshold) {
gpio_set_level(LED, 1); // Turn LED ON
} else {
gpio_set_level(LED, 0); // Turn LED OFF
}

// Display on MAX7219 based on mode


if (mode == 0) {
display_time_on_MAX7219(); // Display time
} else {
display_temperature_on_MAX7219(); // Display temperature
}

vTaskDelay(pdMS_TO_TICKS(1000)); // Update every second


}
}
Page 11 of 14
Page 12 of 14
Page 13 of 14
Page 14 of 14

You might also like