0% found this document useful (0 votes)
16 views

Lab 7

embedded systems lab 7 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)
16 views

Lab 7

embedded systems lab 7 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/ 11

Page 1 of 7

Lab. 7
External Interrupts and Timers

Objectives:

1. Understanding external interrupt request (IRQ) mechanism


2. Programming ESP32 for handling external IRQs and managing interrupt service
routines (ISRs)
3. Programming on-chip timers of ESP32 for generating delays and pulse width
modulation (PWM) waveforms
4. Interfacing DC motor for speed and direction control
5. Interfacing servo motor
➢ Interrupts
An interrupt is a mechanism in a digital circuit that causes a predefined change in the state of
the circuit. In the context of a microprocessor or a microcontroller, an interrupt is a special
input, either externally or internally, that brings the CPU in a new state. Upon acknowledging
an interrupt, CPU performs following actions, generally in the order described below.
✓ It completes the instruction currently in execution.
✓ Pushes the address of next instruction to be executed on to the stack.
✓ Loads program counter with a specific address called ‘interrupt vector (IV)’.
✓ Starts executing program from the instruction pointed to by the IV until ‘return from
interrupt (RFI)’ mechanism is not encountered.
✓ After encountering RFI, pops the address of instruction that is postponed from the stack in
the program counter.
✓ Starts executing the program from this popped off address.
The program section that starts from the IV and ends at the RFI is called ‘interrupt service
routine (ISR)’. Hence, an ISR is a special section in the program that is executed upon
acknowledging the relevant interrupt. There can be multiple interrupts in a microprocessor or
microcontroller, each having its own IV. Interrupts can be triggered externally by changing
logic level on the designated inputs. Or they can be triggered internally such as upon
completion of reception of a byte by UART, completion of transmission of a byte by UART,
overflow of a timer or other similar events.Interrupts are among the most essential features of a
microprocessor or a microcontroller that gives embedded system design engineer the liberty to
handle untimely or asynchronous events.
➢ Interrupts on ESP32 microcontroller
ESP32 is a dual core 32-bit MCU, and each core has 32 interrupt sources. All GPIOs on ESP32
can be configured to trigger external interrupts. Each GPIO, if configured as external interrupt
source, can trigger interrupt on a specific logic level or edge transition. If interrupt is triggered
on a specific logic level, then it is called ‘level-triggered’. If interrupt is triggered on a specific
edge, then it is called ‘edge-triggered’.
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 the circuit has been fully
constructed.
Page 2 of 7

Program 1:

This program configures GPIOs on ESP32 to trigger external interrupts.


#include "freertos/FreeRTOS.h"#include "freertos/task.h" #include "driver/gpio.h"
#define INTERRUPT_PIN GPIO_NUM_34 // GPIO pin for external interrupt
#define LED_PIN GPIO_NUM_2 // On-board LED GPIO pin
void delay_ms(unsigned int ms){ vTaskDelay(pdMS_TO_TICKS(ms)); } void
delay_us(unsigned int i){ esp_rom_delay_us(i);}
static void IRAM_ATTR GPIO_INT_ISR(void *arg) {
gpio_set_level(LED_PIN, 1); // Turn on LED
delay_us(500000); gpio_set_level(LED_PIN, 0); // Turn
off LED } void app_main() {
esp_rom_gpio_pad_select_gpio(LED_PIN);
gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
gpio_set_level(LED_PIN, 1); // Turn on LED
delay_ms(200);
gpio_set_level(LED_PIN, 0);

esp_rom_gpio_pad_select_gpio(INTERRUPT_PIN); gpio_set_direction(INTERRUPT_PIN,
GPIO_MODE_INPUT); gpio_set_intr_type(INTERRUPT_PIN, GPIO_INTR_NEGEDGE);
gpio_install_isr_service(0); gpio_isr_handler_add(INTERRUPT_PIN,
GPIO_INT_ISR, NULL);for(;;);}
Task 1:
Make changes in Program 1 such that the two GPIOs (18 and 19) trigger two separate
interrupts. GPIO18 should trigger a falling-edge-sensitive interrupt whereas GPIO19 should
trigger a rising-edge-interrupt. Falling-edge interrupt should turn on the on-board LED for 200
ms whereas rising-edge interrupt should turn on the on-board LED for 500 ms.
Use a breadboard to implement the circuit. Show your work to the instructor and record your
observations in the box below.

Behavior:
• Pressing or toggling the signal at GPIO18 will trigger the ISR, turning the LED on for
200 ms.
• Pressing or toggling the signal at GPIO19 will trigger its ISR, turning the LED on for
500 ms.
Shared LED Resource:
• Both ISRs control the same LED. If interrupts occur simultaneously or in quick
succession, behavior may be unpredictable (e.g., timing overlap or LED flicker).

➢ Timers on ESP32 microcontroller


ESP32 MCU has four 64-bit on-chip general-purpose timers embedded in the chip. Each timer
has 16-bit prescaler and 64-bit auto-reload-capable up/down count capability. ESP32 chip
contains two hardware timer groups, and each group has two general-purpose hardware timers.
Default clock for the timers is system’s clock running at 280 MHz.
Program 2:
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/ledc.h"
#include "ADC_ESP32.c" #define LEDC_TIMER LEDC_TIMER_0 #define LEDC_MODE
LEDC_HIGH_SPEED_MODE #define LEDC_OUTPUT_IO 18 #define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_FREQUENCY 1000
void delay_ms(unsigned int ms){ vTaskDelay(pdMS_TO_TICKS(ms)); }
void delay_us(unsigned int i){ esp_rom_delay_us(i);}
Page 3 of 7

void
LEDC_Timer_Config(){ledc_timer_config_
t ledc_timer = { .speed_mode
LEDC_MODE, .timer_num = LEDC_TIMER,
.duty_resolution = LEDC_TIMER_10_BIT,
.freq_hz = LEDC_FREQUENCY,.clk_cfg = LEDC_AUTO_CLK };ledc_timer_config(&ledc_timer);
ledc_channel_config_t ledc_channel = {
.speed_mode = LEDC_MODE,
.channel = LEDC_CHANNEL,.timer_sel = LEDC_TIMER, .intr_type = LEDC_INTR_DISABLE,
.gpio_num = LEDC_OUTPUT_IO,.duty = 512, // 50% duty cycle (1024 max for 10-bit
resolution) .hpoint = 0 }; ledc_channel_config(&ledc_channel); }
void Set_DutyCycle(unsigned char dc_percent)}
ledc_set_duty(LEDC_MODE,LEDC_CHANNEL, dc_percent*10.24);
ledc_update_duty(LEDC_MODE, LEDC_CHANNEL); }void
app_main(){
LEDC_Timer_Config();
unsigned char DC;
while(1){
for (DC = 0; DC <= 100; DC += 5) {Set_DutyCycle(DC);delay_ms(50);}}}

Task 1:
Make changes in Program 2 such that the GPIO23 is used as the PWM output. Set frequency
of PWM equal to 5 kHz. Use an external LED connected with GPIO18 to show the response
of PWM waveform. Use a breadboard to implement the circuit. Show your work to the
instructor and record your observations in the box below.

PWM Behavior:
• The PWM waveform on GPIO23 has a frequency of 5 kHz.
• The duty cycle changes gradually from 0% to 100% in 5% increments, repeating in a
loop.
External LED Response:
• When the PWM duty cycle exceeds 50%, the external LED on GPIO18 turns on.
Below 50%, it remains off. This demonstrates a binary threshold response to the duty
cycle.
PWM Visualization:
• The PWM signal can be verified on GPIO23 using an oscilloscope or logic analyzer,
where the pulse width will vary as the duty cycle changes.
LED Smoothness:
• A connected LED (on GPIO23 or GPIO18) visually dims and brightens smoothly as
the duty cycle changes, creating a "breathing" effect.

Lab Task 1:
Construct an embedded system using ESP32 that drives a DC motor. DC motor should run in
both directions and its speed is to be controlled through PWM. Use a GPIO18 as input to select
the direction of rotation of the motor. If GPIO18 is at logic 1, the motor should run clockwise,
and if GPIO18 is at logic 0, the motor should run counterclockwise. The ES must contain a
potentiometer that controls the dutycycle of PWM. Save your code and attach it to this Lab.
Use breadboard to construct the circuit.
Page 4 of 7

#include "freertos/FreeRTOS.h" };
#include "freertos/task.h" ledc_channel_config(&ledc_channel);
#include "driver/ledc.h" }void Set_DutyCycle(unsigned char
#include "driver/gpio.h" duty_cycle) {
#include "driver/adc.h" uint32_t duty = (duty_cycle * 1023) /
#include "esp_adc_cal.h"
100;
#define DIR_PIN GPIO_NUM_18
#define IN1_PIN GPIO_NUM_19 ledc_set_duty(LEDC_MODE,
#define IN2_PIN GPIO_NUM_21 LEDC_CHANNEL, duty);
#define PWM_PIN GPIO_NUM_23 ledc_update_duty(LEDC_MODE,
#define POT_PIN ADC1_CHANNEL_6 LEDC_CHANNEL);
#define LEDC_TIMER LEDC_TIMER_0 }
#define LEDC_MODE
LEDC_HIGH_SPEED_MODE void Motor_Config() {
#define LEDC_CHANNEL gpio_pad_select_gpio(DIR_PIN);
LEDC_CHANNEL_0 gpio_set_direction(DIR_PIN,
#define PWM_FREQUENCY 1000 GPIO_MODE_INPUT);
#define ADC_MAX_VALUE 4095
void ADC_Config() {
gpio_pad_select_gpio(IN1_PIN);
adc1_config_width(ADC_WIDTH_BIT_12);
gpio_set_direction(IN1_PIN,
adc1_config_channel_atten(POT_PIN,
GPIO_MODE_OUTPUT);
ADC_ATTEN_DB_11);
}unsigned char Get_DutyCycle() {
gpio_pad_select_gpio(IN2_PIN);
int adc_reading =
gpio_set_direction(IN2_PIN,
adc1_get_raw(POT_PIN);
GPIO_MODE_OUTPUT);
return (adc_reading * 100) /
}
ADC_MAX_VALUE;
}void PWM_Config() {
void Set_Direction(bool clockwise) {
ledc_timer_config_t ledc_timer = {
if (clockwise) {
.speed_mode = LEDC_MODE,
gpio_set_level(IN1_PIN, 1);
.timer_num = LEDC_TIMER,
gpio_set_level(IN2_PIN, 0);
.duty_resolution =
} else {
LEDC_TIMER_10_BIT,
gpio_set_level(IN1_PIN, 0);
.freq_hz = PWM_FREQUENCY,
gpio_set_level(IN2_PIN, 1);
.clk_cfg = LEDC_AUTO_CLK
}
};ledc_timer_config(&ledc_timer);
}
ledc_channel_config_t ledc_channel = {
void app_main() {
.speed_mode = LEDC_MODE,
ADC_Config();
.channel = LEDC_CHANNEL,
PWM_Config();
.timer_sel = LEDC_TIMER,
Motor_Config();
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = PWM_PIN,
while (1) {
.duty = 0,
bool clockwise =
.hpoint = 0
gpio_get_level(DIR_PIN);
Set_Direction(clockwise);
unsigned char duty_cycle =
Get_DutyCycle();
Set_DutyCycle(duty_cycle);
vTaskDelay(pdMS_TO_TICKS(100));
}
}
Page 5 of 7

Lab Task 2:
Construct an embedded system using ESP32 that drives a servo motor. Generate servo motor
control waveform using on-chip timer. Save your code and attach it to this Lab. Use
breadboard to construct the circuit.

#include "freertos/FreeRTOS.h" };
#include "freertos/task.h" ledc_channel_config(&ledc_channel);
#include "driver/ledc.h" } uint32_t Calculate_PulseWidth(uint8_t angle)
#define SERVO_PIN GPIO_NUM_23 { return SERVO_MIN_PULSEWIDTH +
#define LEDC_TIMER LEDC_TIMER_0 ((SERVO_MAX_PULSEWIDTH -
#define LEDC_MODE SERVO_MIN_PULSEWIDTH) * angle) /
LEDC_HIGH_SPEED_MODE SERVO_MAX_ANGLE;
#define LEDC_CHANNEL }
LEDC_CHANNEL_0 void Set_Servo_Angle(uint8_t angle) {
#define LEDC_FREQUENCY 50 uint32_t pulse_width =
#define SERVO_MIN_PULSEWIDTH 500 Calculate_PulseWidth(angle);
#define SERVO_MAX_PULSEWIDTH 2500 uint32_t duty = (pulse_width * 65536) /
#define SERVO_MAX_ANGLE 180 (1000000 / LEDC_FREQUENCY);
void LEDC_Timer_Config() { ledc_set_duty(LEDC_MODE,
ledc_timer_config_t ledc_timer = { LEDC_CHANNEL, duty);
.speed_mode = LEDC_MODE, ledc_update_duty(LEDC_MODE,
.timer_num = LEDC_TIMER, LEDC_CHANNEL);
.duty_resolution = LEDC_TIMER_16_BIT, }void app_main() {
.freq_hz = LEDC_FREQUENCY, LEDC_Timer_Config();
.clk_cfg = LEDC_AUTO_CLK LEDC_Channel_Config();
}; while (1) {
ledc_timer_config(&ledc_timer); for (uint8_t angle = 0; angle <= 180; angle
} += 10) {
void LEDC_Channel_Config() { Set_Servo_Angle(angle);
ledc_channel_config_t ledc_channel = { vTaskDelay(pdMS_TO_TICKS(500));
.speed_mode = LEDC_MODE, }
.channel = LEDC_CHANNEL, for (uint8_t angle = 180; angle >= 10; angle
.timer_sel = LEDC_TIMER, -= 10) {
.intr_type = LEDC_INTR_DISABLE, Set_Servo_Angle(angle);
.gpio_num = SERVO_PIN, vTaskDelay(pdMS_TO_TICKS(500));}
.duty = 0, }}
.hpoint = 0
Page 6 of 7
Page 7 of 7
Page 8 of 7
Page 9 of 7
Page 10 of
7
Page 11 of
7

You might also like