Lab 1 - Alarm Multi-Blink
MCU Timer Based Interrupts
Summary
Create a classic 'hello world' LED blinker, then change it to run using interrupts & control multiple LEDs.
1. build a basic 'hello world' project using cpu sleep to control blinking.
2. alter the project to use an alarm function that calls itself instead of cpu sleep timing.
3. add 2-3 more external LEDs that all blink at different rates using alarm functions.
Required Equipment and Supplies
- Rasperry Pi Pico with Headers - pinout diagram
- LED - indicator [x3]
- 820Ω Resistor [x3]
- USB Micro Cable
- Breadboard
- Cables and 22ga wire as needed
Wiring
- Only begin adding external LEDs after your basic blink and alarm blink are working.
- LEDs consume very little power, you may power everything from the USB cable.
- Use VBus or Vsys to supply your breadboard power rail from the Pi Pico.
- Connect each LED to separate GPIO pin and in series with a current limiting resistor connected to ground like the example below.

Sample Code - CPU Timed Blink
#include "pico/stdlib.h"
int main() {
// setup and initialize
gpio_init(25);
gpio_set_dir(25, GPIO_OUT);
// primary loop
while (true) {
gpio_put(25, 1);
sleep_ms(500);
gpio_put(25, 0);
sleep_ms(500);
}
}
Sample Code - Single Alarm Timed Blink
#include "pico/stdlib.h"
uint led_pin = 25;
bool led_state = false;
int64_t led_delay_ms = 500ll;
alarm_callback_t alarmStuff(alarm_id_t id, void* user_data){
//what our alarm will do when it triggers.
led_state = !led_state;
gpio_put(led_pin, led_state);
int64_t reschedule_micros = led_delay_ms*-1000ll;
return reschedule_micros;
}
int main() {
// setup and initialize
gpio_init(led_pin);
gpio_set_dir(led_pin, GPIO_OUT);
gpio_put(led_pin, 0);
//set an alarm
add_alarm_in_ms(3000, alarmStuff, NULL, true);
// primary loop
while (true) {
sleep_ms(250);
}
}
Sample Code - Alarms Multi Blink
#include "pico/stdlib.h"
const uint LED_1 = 18;
const uint LED_2 = 19;
const uint LED_3 = 20;
const uint LED_4 = 21;
bool led_1_state = true;
bool led_2_state = true;
bool led_3_state = true;
bool led_4_state = true;
int64_t led1_delay = 61ll;
int64_t led2_delay = 294ll;
int64_t led3_delay = 167ll;
int64_t led4_delay = 83ll;
int64_t alarm_call_led1(alarm_id_t id, void* userdata) {
led_1_state = !led_1_state;
gpio_put(LED_1, led_1_state);
int64_t reschedule_micros = led1_delay * -1000ll;
// multiply by 1000 to convert to microseconds
// make sure to usea 64bit integer types - long long
// literal values need two lower-case 'l' characters at the end
return reschedule_micros;
}
int64_t alarm_call_led2(alarm_id_t id, void* userdata) {
led_2_state = !led_2_state;
gpio_put(LED_2, led_2_state);
int64_t reschedule_micros = led_delay * -1000ll;
// multiply by 1000 to convert to microseconds
// make sure to usea 64bit integer types - long long
// literal values need two lower-case 'l' characters at the end
return reschedule_micros;}
int64_t alarm_call_led3(alarm_id_t id, void* userdata) {
led_3_state = !led_3_state;
gpio_put(LED_3, led_3_state);
int64_t reschedule_micros = led3_delay * -1000ll;
// multiply by 1000 to convert to microseconds
// make sure to usea 64bit integer types - long long
// literal values need two lower-case 'l' characters at the end
return reschedule_micros;}
int64_t alarm_call_led4(alarm_id_t id, void* userdata) {
led_4_state = !led_4_state;
gpio_put(LED_4, led_4_state);
int64_t reschedule_micros = led4_delay * -1000ll;
// multiply by 1000 to convert to microseconds
// make sure to usea 64bit integer types - long long
// literal values need two lower-case 'l' characters at the end
return reschedule_micros;}
int main() {
// setup and initialize
gpio_init(LED_1);
gpio_set_dir(LED_1,led_1_state);
gpio_put(LED_1, 1);
gpio_init(LED_2);
gpio_set_dir(LED_2,led_2_state);
gpio_put(LED_2, 1);
gpio_init(LED_3);
gpio_set_dir(LED_3,led_3_state);
gpio_put(LED_3, 1);
gpio_init(LED_4);
gpio_set_dir(LED_4,led_4_state);
gpio_put(LED_4, 1);
//delay for verification
sleep_ms(1000);
add_alarm_in_ms(led1_delay,alarm_call_led1, NULL, true);
add_alarm_in_ms(led2_delay,alarm_call_led2, NULL, true);
add_alarm_in_ms(led3_delay,alarm_call_led3, NULL, true);
add_alarm_in_ms(led4_delay,alarm_call_led4, NULL, true);
// primary loop
while (true) {
sleep_ms(500);
}
}
Sample Code - Alarm Based Servo Intro
#include "pico/stdlib.h"
#define SERVO_SIGNAL_PERIOD_MICROS 20000LL
uint servo_pin = 16; //temporary
bool servo_signal_level = false;
uint64_t servo_pulse_w_micros = 1500LL;
void servo_pin_setup();
uint64_t servo_alarm_callback(alarm_id_t id, void* user_data);
int main() {
// setup and initialize
servo_pin_setup();
add_alarm_in_ms(100, servo_alarm_callback, NULL, true);
// primary loop
while (true) {
sleep_ms(100);
}
}
void servo_pin_setup(){
gpio_init(servo_pin);
gpio_set_dir(servo_pin, GPIO_OUT);
}
uint64_t servo_alarm_callback(alarm_id_t id, void* user_data){
servo_signal_level = !servo_signal_level; //toggle signal pin high/low
gpio_put(servo_pin, servo_signal_level);;
uint64_t delay_micros = 0;
if(servo_signal_level == true){
delay_micros = -servo_pulse_w_micros;
} else {
delay_micros = -(SERVO_SIGNAL_PERIOD_MICROS - servo_pulse_w_micros);
}
return delay_micros;
}