We have decided not to make the programs available as a download because this is not the point of the book - the programs are not finished production code but something you should type in and study.
The best solution is to provide the source code of the programs in a form that can be copied and pasted into a NetBeans of VS Code project.
The only downside is that you have to create a project to paste the code into.
To do this follow the instructions in the book.
All of the programs below were copy and pasted from working programs in the IDE. They have been formatted using the built in formatter and hence are not identical in layout to the programs in the book. This is to make copy and pasting them easier. The programs in the book are formatted to be easy to read on the page.
If anything you consider important is missing or if you have any requests or comments contact:
Page 93
#include <stdio.h>
#include "pico/stdlib.h"
int main()
{
stdio_init_all();
gpio_set_function(22, GPIO_FUNC_SIO);
gpio_set_dir(22, false);
gpio_set_function(21, GPIO_FUNC_SIO);
gpio_set_dir(21, true);
gpio_set_function(20, GPIO_FUNC_SIO);
gpio_set_dir(20, true);
gpio_set_function(19, GPIO_FUNC_SIO);
gpio_set_dir(19, true);
gpio_put(19, 1);
gpio_put(20, 0);
gpio_put(21, 0);
uint64_t t, tpush, twait;
int s = 0;
int buttonState = gpio_get(22);
int edge;
int buttonNow;
while (true)
{
t = time_us_64();
buttonNow = gpio_get(22);
edge = buttonState - buttonNow;
buttonState = buttonNow;
switch (s)
{
case 0:
if (edge == 1)
{
s = 1;
gpio_put(19, 0);
gpio_put(20, 1);
gpio_put(21, 0);
}
break;
case 1:
if (edge == 1)
{
s = 2;
gpio_put(19, 0);
gpio_put(20, 0);
gpio_put(21, 1);
}
break;
case 2:
if (edge == 1)
{
s = 0;
gpio_put(19, 1);
gpio_put(20, 0);
gpio_put(21, 0);
}
break;
default:
s = 0;
}
sleep_until((absolute_time_t){t + 1000});
}
}
Page 100
uint32_t gpio_get_events(uint gpio)
{
int32_t mask = 0xF << 4 * (gpio % 8);
return (iobank0_hw->intr[gpio / 8] & mask) >> 4 * (gpio % 8);
}
void gpio_clear_events(uint gpio, uint32_t events)
{
gpio_acknowledge_irq(gpio, events);
}
Page 101
#include <stdio.h>
#include "pico/stdlib.h"
int main()
{
stdio_init_all();
gpio_set_function(22, GPIO_FUNC_SIO);
gpio_set_dir(22, false);
gpio_pull_down(22);
printf("Press Button\n");
sleep_ms(20000);
if (gpio_get(22))
{
printf("Button Pressed\n");
}
else
{
printf("Button Not Pressed\n");
}
}
Page 101
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/structs/iobank0.h"
uint32_t gpio_get_events(uint gpio)
{
int32_t mask = 0xF << 4 * (gpio % 8);
return (iobank0_hw->intr[gpio / 8] & mask) >> 4 * (gpio % 8);
}
void gpio_clear_events(uint gpio, uint32_t events)
{
gpio_acknowledge_irq(gpio, events);
}
int main()
{
stdio_init_all();
gpio_set_function(22, GPIO_FUNC_SIO);
gpio_set_dir(22, false);
gpio_pull_down(22);
printf("Press Button\n");
gpio_clear_events(22, GPIO_IRQ_EDGE_RISE);
sleep_ms(20000);
int32_t event = gpio_get_events(22);
gpio_clear_events(22, GPIO_IRQ_EDGE_RISE);
if (event & GPIO_IRQ_EDGE_RISE)
{
printf("Button Pressed\n");
}
else
{
printf("Button Not Pressed\n");
}
}
Page 103
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/structs/iobank0.h"
uint32_t gpio_get_events(uint gpio)
{
int32_t mask = 0xF << 4 * (gpio % 8);
return (iobank0_hw->intr[gpio / 8] & mask) >> 4 * (gpio % 8);
}
void gpio_clear_events(uint gpio, uint32_t events)
{
gpio_acknowledge_irq(gpio, events);
}
int main()
{
uint64_t t;
stdio_init_all();
gpio_set_function(22, GPIO_FUNC_SIO);
gpio_set_dir(22, false);
gpio_pull_down(22);
while (true)
{
gpio_clear_events(22, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL);
while (!(gpio_get_events(22) & GPIO_IRQ_EDGE_RISE))
{
};
t = time_us_64();
gpio_clear_events(22, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL);
while (!(gpio_get_events(22) & GPIO_IRQ_EDGE_FALL))
{
};
t = (uint64_t)(time_us_64() - t);
printf("%llu\n", t);
sleep_ms(1000);
}
}
Page 105
#include <stdio.h>
#include "pico/stdlib.h"
static uint64_t t;
void MyIRQHandler(uint gpio, uint32_t events)
{
t = time_us_64() - t;
printf("GPIO %d %X %d \n", gpio, events, t);
}
int main()
{
stdio_init_all();
gpio_set_function(22, GPIO_FUNC_SIO);
gpio_set_dir(22, false);
gpio_pull_down(22);
gpio_set_irq_enabled_with_callback(22, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &MyIRQHandler);
while (1)
{
};
return 0;
}
Page 122 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
int main()
{
gpio_set_function(22, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(22);
uint chan = pwm_gpio_to_channel(22);
pwm_set_freq_duty(slice_num, chan, 50, 75);
pwm_set_enabled(slice_num, true);
return 0;
}
Page 124 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
uint32_t pwm_set_freq_duty(uint slice_num,uint chan,
uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16/16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num){
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
int main()
{
gpio_set_function(20, GPIO_FUNC_PWM);
gpio_set_function(21, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(20);
uint chan20 = pwm_gpio_to_channel(20);
uint chan21 = pwm_gpio_to_channel(21);
uint wrap = pwm_set_freq_duty(slice_num, chan20, 50, 75);
pwm_set_duty(slice_num, chan21, 25);
pwm_set_enabled(slice_num, true);
return 0;
}
Page 126 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
uint32_t pwm_set_freq_duty(uint slice_num, uint chan,
uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
int main()
{
gpio_set_function(20, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(20);
uint chan20 = pwm_gpio_to_channel(20);
uint wrap = pwm_set_freq_duty(slice_num, chan20, 50, 50);
pwm_set_enabled(slice_num, true);
while (true)
{
pwm_set_duty(slice_num, chan20, 25);
pwm_set_duty(slice_num, chan20, 50);
}
return 0;
}
Page 122 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
uint32_t pwm_set_freq_duty(uint slice_num, uint chan,
uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
int main()
{
gpio_set_function(20, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(20);
uint chan20 = pwm_gpio_to_channel(20);
uint wrap = pwm_set_freq_duty(slice_num, chan20, 50, 50);
pwm_set_enabled(slice_num, true);
while (true)
{
pwm_set_duty(slice_num, chan20, 25);
while (pwm_get_counter(slice_num))
{
};
pwm_set_duty(slice_num, chan20, 50);
while (pwm_get_counter(slice_num))
{
};
}
return 0;
}
Page 129 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/irq.h"
uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
uint slice_num;
uint chan20;
uint state = 0;
void MyIRQHandler()
{
pwm_clear_irq(slice_num);
if (state)
{
pwm_set_duty(slice_num, chan20, 25);
}
else
{
pwm_set_duty(slice_num, chan20, 50);
}
state = ~state;
}
int main()
{
gpio_set_function(20, GPIO_FUNC_PWM);
slice_num = pwm_gpio_to_slice_num(20);
chan20 = pwm_gpio_to_channel(20);
pwm_clear_irq(slice_num);
pwm_set_irq_enabled(slice_num, true);
irq_set_exclusive_handler(PWM_IRQ_WRAP, MyIRQHandler);
irq_set_enabled(PWM_IRQ_WRAP, true);
uint wrap = pwm_set_freq_duty(slice_num, chan20, 100000, 25);
pwm_set_enabled(slice_num, true);
while (true)
{
}
return 0;
}
Page 131 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/irq.h"
#include "math.h"
uint32_t pwm_get_wrap(uint slice_num)
{
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
uint slice_num;
uint chan20;
uint state = 0;
uint8_t wave[256];
void MyIRQHandler()
{
pwm_clear_irq(slice_num);
pwm_set_duty(slice_num, chan20, wave[state]);
state = (state + 1) % 256;
}
int main()
{
for (int i = 0; i < 256; i++)
{
wave[i] = (uint8_t)((128.0 + sinf((float)i * 2.0 * 3.14159 / 256.0) * 128.0) * 100.0 / 256.0);
}
gpio_set_function(22, GPIO_FUNC_PWM);
slice_num = pwm_gpio_to_slice_num(22);
uint chan22 = pwm_gpio_to_channel(22);
pwm_clear_irq(slice_num);
pwm_set_irq_enabled(slice_num, true);
irq_set_exclusive_handler(PWM_IRQ_WRAP, MyIRQHandler);
irq_set_enabled(PWM_IRQ_WRAP, true);
pwm_set_clkdiv_int_frac(slice_num, 1, 0);
pwm_set_wrap(slice_num, 255);
pwm_set_enabled(slice_num, true);
while (true)
{
}
return 0;
}
Page 134 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
int main()
{
gpio_set_function(22, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(22);
uint chan22 = pwm_gpio_to_channel(22);
pwm_set_freq_duty(slice_num, chan22, 281, 50);
pwm_set_enabled(slice_num, true);
}
Page 134 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
int main()
{
gpio_set_function(25, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(25);
uint chan = pwm_gpio_to_channel(25);
pwm_set_freq_duty(slice_num, chan, 2000, 0);
pwm_set_enabled(slice_num, true);
while (true)
{
for (int d = 0; d <= 100; d++)
{
pwm_set_duty(slice_num, chan, d);
sleep_ms(50);
}
}
}
Page 136 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
int main()
{
gpio_set_function(25, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(25);
uint chan = pwm_gpio_to_channel(25);
pwm_set_freq_duty(slice_num, chan, 2000, 0);
pwm_set_enabled(slice_num, true);
int d = 0;
while (true)
{
for (int b = 0; b <= 100; b++)
{
d = (b * b * b) / 10000;
pwm_set_duty(slice_num, chan, d);
sleep_ms(50);
}
}
}
Page 138 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
int main()
{
gpio_set_function(20, GPIO_FUNC_PWM);
gpio_set_function(21, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(20);
uint chanA = pwm_gpio_to_channel(20);
uint chanB = pwm_gpio_to_channel(21);
pwm_set_clkdiv_int_frac(slice_num, 2, 0);
pwm_set_wrap(slice_num, 127);
pwm_set_chan_level(slice_num, chanA, 63);
pwm_set_clkdiv_mode(slice_num, PWM_DIV_B_RISING);
pwm_set_enabled(slice_num, true);
}
Page 140 remember to add hardware_pwm to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
int main()
{
stdio_init_all();
gpio_set_function(20, GPIO_FUNC_PWM);
gpio_set_function(21, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(20);
uint chanA = pwm_gpio_to_channel(20);
uint chanB = pwm_gpio_to_channel(21);
pwm_set_clkdiv_int_frac(slice_num, 20, 0);
int maxcount = 125000000 * 10 / 20 / 1000;
pwm_set_wrap(slice_num, 65535);
pwm_set_chan_level(slice_num, chanA, 100);
pwm_set_clkdiv_mode(slice_num, PWM_DIV_B_HIGH);
while (true)
{
pwm_set_enabled(slice_num, true);
sleep_ms(10);
pwm_set_enabled(slice_num, false);
uint16_t count = pwm_get_counter(slice_num);
pwm_set_counter(slice_num, 0);
printf("count= %u duty cycle=%d %%\n",
count, (int)count * 100 / maxcount);
sleep_ms(1000);
}
}
Page 29 remember to add hardware_pwm to the CMakeLists.txt file
#include "pico/stdlib.h"
#include "hardware/pwm.h"
uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
typedef struct
{
uint gpio;
uint slice;
uint chan;
uint speed;
uint freq;
uint resolution;
bool on;
} Motor;
void motorInit(Motor *m, uint gpio, uint freq)
{
gpio_set_function(gpio, GPIO_FUNC_PWM);
m->gpio = gpio;
m->slice = pwm_gpio_to_slice_num(gpio);
m->chan = pwm_gpio_to_channel(gpio);
m->freq = freq;
m->speed = 0;
m->resolution = pwm_set_freq_duty(m->slice, m->chan, m->freq, m->speed);
m->on = false;
}
void motorspeed(Motor *m, int s)
{
pwm_set_duty(m->slice, m->chan, s);
m->speed = s;
}
void motorOn(Motor *m)
{
pwm_set_enabled(m->slice, true);
m->on = true;
}
void motorOff(Motor *m)
{
pwm_set_enabled(m->slice, false);
m->on = false;
}
int main()
{
Motor mot1;
motorInit(&mot1, 21, 2000);
motorspeed(&mot1, 50);
motorOn(&mot1);
return 0;
}
Page 157 remember to add hardware_pwm to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
typedef struct
{
uint gpioForward;
uint gpioBackward;
uint slice;
uint Fchan;
uint Bchan;
bool forward;
uint speed;
uint freq;
uint resolution;
bool on;
} BiMotor;
void BiMotorInit(BiMotor *m, uint gpioForward, uint gpioBackward, uint freq)
{
gpio_set_function(gpioForward, GPIO_FUNC_PWM);
m->gpioForward = gpioForward;
m->slice = pwm_gpio_to_slice_num(gpioForward);
m->Fchan = pwm_gpio_to_channel(gpioForward);
gpio_set_function(gpioBackward, GPIO_FUNC_PWM);
m->gpioBackward = gpioBackward;
m->Bchan = pwm_gpio_to_channel(gpioBackward);
m->freq = freq;
m->speed = 0;
m->forward = true;
m->resolution = pwm_set_freq_duty(m->slice, m->Fchan, m->freq, 0);
pwm_set_duty(m->slice, m->Bchan, 0);
m->on = false;
}
void BiMotorspeed(BiMotor *m, int s, bool forward)
{
if (forward)
{
pwm_set_duty(m->slice, m->Bchan, 0);
pwm_set_duty(m->slice, m->Fchan, s);
m->forward = true;
}
else
{
pwm_set_duty(m->slice, m->Fchan, 0);
pwm_set_duty(m->slice, m->Bchan, s);
m->forward = true;
}
m->speed = s;
}
void BiMotorOn(BiMotor *m)
{
pwm_set_enabled(m->slice, true);
m->on = true;
}
void BiMotorOff(BiMotor *m)
{
pwm_set_enabled(m->slice, false);
m->on = false;
}
int main()
{
BiMotor mot1;
BiMotorInit(&mot1, 20, 21, 2000);
BiMotorOn(&mot1);
while (true)
{
BiMotorspeed(&mot1, 50, true);
sleep_ms(2000);
BiMotorspeed(&mot1, 25, false);
sleep_ms(2000);
}
return 0;
}
Page 162 remember to add hardware_pwm to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
uint32_t clock = 125000000;
uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0)
divider16 = 16;
uint32_t wrap = clock * 16 / divider16 / f - 1;
pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
pwm_set_wrap(slice_num, wrap);
pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
return pwm_hw->slice[slice_num].top;
}
void pwm_set_duty(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
void pwm_set_dutyH(uint slice_num, uint chan, int d)
{
pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 10000);
}
typedef struct
{
uint gpio;
uint slice;
uint chan;
uint speed;
uint resolution;
bool on;
bool invert;
} Servo;
void ServoInit(Servo *s, uint gpio, bool invert)
{
gpio_set_function(gpio, GPIO_FUNC_PWM);
s->gpio = gpio;
s->slice = pwm_gpio_to_slice_num(gpio);
s->chan = pwm_gpio_to_channel(gpio);
pwm_set_enabled(s->slice, false);
s->on = false;
s->speed = 0;
s->resolution = pwm_set_freq_duty(s->slice, s->chan, 50, 0);
pwm_set_dutyH(s->slice, s->chan, 250);
if (s->chan)
{
pwm_set_output_polarity(s->slice, false, invert);
}
else
{
pwm_set_output_polarity(s->slice, invert, false);
}
s->invert = invert;
}
void ServoOn(Servo *s)
{
pwm_set_enabled(s->slice, true);
s->on = true;
}
void ServoOff(Servo *s)
{
pwm_set_enabled(s->slice, false);
s->on = false;
}
void ServoPosition(Servo *s, uint p)
{
pwm_set_dutyH(s->slice, s->chan, p * 10 + 250);
}
int main()
{
Servo s1;
ServoInit(&s1, 20, false);
ServoOn(&s1);
while (true)
{
ServoPosition(&s1, 0);
sleep_ms(500);
ServoPosition(&s1, 100);
sleep_ms(500);
}
return 0;
}
Page 173 remember to add hardware_pwm to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
typedef struct
{
uint gpio;
uint speed;
bool forward;
uint32_t gpiomask;
uint phase;
} StepperBi;
uint32_t stepTable[8] = (uint32_t[8]){0x8, 0xC, 0x4, 0x6, 0x2, 0x3, 0x1, 0x9};
/*
{1, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
{1, 0, 0, 1}
*/
void StepperBiInit(StepperBi *s, uint gpio)
{
s->gpio = gpio;
for (int i = 0; i < 4; i++)
{
gpio_set_function((s->gpio) + i, GPIO_FUNC_SIO);
gpio_set_dir((s->gpio) + i, true);
}
s->gpiomask = 0x0F << gpio;
volatile uint32_t mask = stepTable[0] << gpio;
gpio_put_masked(s->gpiomask, mask);
s->phase = 0;
s->speed = 0;
s->forward = true;
}
void setPhase(StepperBi *s, uint p)
{
uint32_t mask = stepTable[p] << (s->gpio);
gpio_put_masked(s->gpiomask, mask);
}
void stepForward(StepperBi *s)
{
s->phase = (s->phase + 1) % 8;
setPhase(s, s->phase);
}
void stepReverse(StepperBi *s)
{
s->phase = (s->phase - 1) % 8;
setPhase(s, s->phase);
}
void rotate(StepperBi *s, bool dir, int speed)
{
s->forward = dir;
s->speed = speed;
}
int main()
{
stdio_init_all();
StepperBi s1;
StepperBiInit(&s1, 18);
while (true)
{
stepForward(&s1);
sleep_ms(1);
}
return 0;
}
Page 178 remember to add hardware_pwm to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
typedef struct
{
uint gpio;
uint speed;
bool forward;
uint32_t gpiomask;
uint phase;
} StepperBi;
uint32_t stepTable[8] = (uint32_t[8]){0x8, 0xC, 0x4, 0x6, 0x2, 0x3, 0x1, 0x9};
/*
{1, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
{1, 0, 0, 1}
*/
void StepperBiInit(StepperBi *s, uint gpio)
{
s->gpio = gpio;
for (int i = 0; i < 4; i++)
{
gpio_set_function((s->gpio) + i, GPIO_FUNC_SIO);
gpio_set_dir((s->gpio) + i, true);
}
s->gpiomask = 0x0F << gpio;
volatile uint32_t mask = stepTable[0] << gpio;
gpio_put_masked(s->gpiomask, mask);
s->phase = 0;
s->speed = 0;
s->forward = true;
}
void setPhase(StepperBi *s, uint p)
{
uint32_t mask = stepTable[p] << (s->gpio);
gpio_put_masked(s->gpiomask, mask);
}
void stepForward(StepperBi *s)
{
s->phase = (s->phase + 1) % 8;
setPhase(s, s->phase);
}
void stepReverse(StepperBi *s)
{
s->phase = (s->phase - 1) % 8;
setPhase(s, s->phase);
}
bool step(struct repeating_timer *t)
{
StepperBi *s = (StepperBi *)(t->user_data);
if (s->forward)
{
stepForward(s);
}
else
{
stepReverse(s);
}
return true;
}
struct repeating_timer timer;
void rotate(StepperBi *s, bool dir, int speed)
{
cancel_repeating_timer(&timer);
s->forward = dir;
if (speed == 0)
{
s->speed = 0;
return;
}
s->speed = 1000 * 1000 / (4 * speed);
add_repeating_timer_us(s->speed, step, s, &timer);
}
int main()
{
static StepperBi s1;
StepperBiInit(&s1, 18);
rotate(&s1, true, 250);
while (true)
{
rotate(&s1, true, 250);
sleep_ms(100);
rotate(&s1, true, 00);
sleep_ms(100);
}
return 0;
}
Page 189 remember to add hardware_spi to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"
int main()
{
stdio_init_all();
spi_init(spi0, 500 * 1000);
gpio_set_function(4, GPIO_FUNC_SPI);
gpio_set_function(6, GPIO_FUNC_SPI);
gpio_set_function(7, GPIO_FUNC_SPI);
spi_set_format(spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
uint16_t wBuff[1] = {0xAA};
uint16_t rBuff[1];
int n = spi_write16_read16_blocking(spi0, wBuff, rBuff, 1);
spi_deinit(spi0);
printf(" %X %X %d ", wBuff[0], rBuff[0], n);
}
Page 197 remember to add hardware_spi to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"
int main()
{
stdio_init_all();
spi_init(spi0, 500 * 1000);
spi_set_format(spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
gpio_set_function(16, GPIO_FUNC_SPI);
gpio_set_function(18, GPIO_FUNC_SPI);
gpio_set_function(19, GPIO_FUNC_SPI);
gpio_init(17);
gpio_set_dir(17, GPIO_OUT);
gpio_put(17, 1);
sleep_ms(1);
uint8_t wBuff[1] = {0xD0};
uint8_t rBuff[8];
gpio_put(17, 0);
sleep_us(1);
spi_write_blocking(spi0, wBuff, 1);
spi_read_blocking(spi0, 0, rBuff, 1);
sleep_us(1);
gpio_put(17, 1);
printf("Chip ID is 0x%x\n", rBuff[0]);
gpio_put(17, 0);
sleep_us(1);
wBuff[0] = 0xF2;
wBuff[1] = 0x1;
spi_write_blocking(spi0, wBuff, 2);
wBuff[0] = 0xF4;
wBuff[1] = 0x27;
spi_write_blocking(spi0, wBuff, 2);
gpio_put(17, 1);
sleep_us(1);
wBuff[0] = 0xF7;
gpio_put(17, 0);
sleep_us(1);
spi_write_blocking(spi0, wBuff, 1);
spi_read_blocking(spi0, 0, rBuff, 8);
sleep_us(1);
gpio_put(17, 1);
uint32_t pressure = ((uint32_t)rBuff[0] << 12) | ((uint32_t)rBuff[1] << 4) | (rBuff[2] >> 4);
uint32_t temperature = ((uint32_t)rBuff[3] << 12) | ((uint32_t)rBuff[4] << 4) | (rBuff[5] >> 4);
uint32_t humidity = (uint32_t)rBuff[6] << 8 | rBuff[7];
printf("Humidity = %d\n", humidity);
printf("Pressure = %d\n", pressure);
printf("Temp. = %d\n", temperature);
}
Page 203 remember to add hardware_adc to the CMakeLists.txt file
#include
#include "pico/stdlib.h"
#include "hardware/adc.h"
int main()
{
stdio_init_all();
adc_init();
adc_gpio_init(26);
adc_gpio_init(27);
while (1)
{
const float conversion_factor = 3.3f / (1 << 12);
adc_select_input(0);
uint16_t result = adc_read();
printf("Raw value 0: 0x%03x, voltage: %f V\n",
result, result * conversion_factor);
adc_select_input(1);
result = adc_read();
printf("Raw value 1: 0x%03x, voltage: %f V\n",
result, result * conversion_factor);
sleep_ms(500);
}
}
Page 205 remember to add hardware_adc to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/adc.h"
int main()
{
stdio_init_all();
adc_init();
adc_gpio_init(26);
adc_gpio_init(27);
adc_set_round_robin(0x03);
adc_fifo_setup(true, false, 0, false, false);
adc_run(true);
const float conversion_factor = 3.3f / (1 << 12);
while (1)
{
uint16_t result = adc_fifo_get();
printf("Raw value 0: 0x%03x, voltage: %f V\n", result, result * conversion_factor);
int level = adc_fifo_get_level();
printf("level: %d \n", level);
}
}
Page 211 remember to add hardware_spi to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"
int main()
{
stdio_init_all();
spi_init(spi0, 500 * 1000);
spi_set_format(spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
gpio_set_function(16, GPIO_FUNC_SPI);
gpio_set_function(18, GPIO_FUNC_SPI);
gpio_set_function(19, GPIO_FUNC_SPI);
gpio_init(17);
gpio_set_dir(17, GPIO_OUT);
gpio_put(17, 1);
sleep_ms(1);
uint16_t wBuff[3] = {0x01, 0x80, 0x00};
uint16_t rBuff[3];
gpio_put(17, 0);
int n = spi_write16_read16_blocking(spi0, wBuff, rBuff, 3);
sleep_us(1);
gpio_put(17, 1);
int data = ((int)rBuff[1] & 0x03) << 8 | (int)rBuff[2];
float volts = (float)data * 3.3f / 1023.0f;
printf("%f V\n", volts);
}
Page 228 remember to add hardware_i2c to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
int main()
{
stdio_init_all();
i2c_init(i2c0, 100 * 1000);
gpio_set_function(4, GPIO_FUNC_I2C);
gpio_set_function(5, GPIO_FUNC_I2C);
uint8_t buf[] = {0xE7};
i2c_write_blocking(i2c0, 0x40, buf, 1, false);
i2c_read_blocking(i2c0, 0x40, buf, 1, false);
printf("User Register = %X \r\n", buf[0]);
}
Page 230 remember to add hardware_i2c to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
int main()
{
stdio_init_all();
i2c_init(i2c0, 100 * 1000);
gpio_set_function(4, GPIO_FUNC_I2C);
gpio_set_function(5, GPIO_FUNC_I2C);
uint8_t buf[4] = {0xE3};
i2c_write_blocking(i2c0, 0x40, buf, 1, true);
i2c_read_blocking(i2c0, 0x40, buf, 3, false);
uint8_t msb = buf[0];
uint8_t lsb = buf[1];
uint8_t check = buf[2];
printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
};
Page 234 remember to add hardware_i2c to the CMakeLists.txt file
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check)
{
uint32_t data32 = ((uint32_t)msb << 16) | ((uint32_t)lsb << 8) |
(uint32_t)check;
uint32_t divisor = 0x988000;
for (int i = 0; i < 16; i++)
{
if (data32 & (uint32_t)1 << (23 - i))
data32 ^= divisor;
divisor >>= 1;
};
return (uint8_t)data32;
}
int main()
{
stdio_init_all();
i2c_init(i2c0, 100 * 1000);
gpio_set_function(4, GPIO_FUNC_I2C);
gpio_set_function(5, GPIO_FUNC_I2C);
uint8_t buf[4] = {0xE3};
i2c_write_blocking(i2c0, 0x40, buf, 1, true);
i2c_read_blocking(i2c0, 0x40, buf, 3, false);
uint8_t msb = buf[0];
uint8_t lsb = buf[1];
uint8_t check = buf[2];
printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
unsigned int data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
printf("crc = %d\n\r", crcCheck(msb, lsb, check));
float temp = (float)(-46.85 + (175.72 * data16 / (float)65536));
printf("Temperature %f C \n\r", temp);
buf[0] = 0xF5;
i2c_write_blocking(i2c0, 0x40, buf, 1, true);
while (i2c_read_blocking(i2c0, 0x40, buf, 3, false) < 0)
{
sleep_ms(1);
};
msb = buf[0];
lsb = buf[1];
check = buf[2];
printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
printf("crc = %d\n\r", crcCheck(msb, lsb, check));
data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
float hum = -6 + (125.0 * (float)data16) / 65536;
printf("Humidity %f %% \n\r", hum);
}
Page 240
.program squarewave
set pindirs, 1 ; Set pin to output
again:
set pins, 1 ; Drive pin high
set pins, 0 ; Drive pin low
jmp again ; Set PC to label `again`
Page 241
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
include(pico_sdk_import.cmake)
pico_sdk_init()
project(pioBlinky C CXX ASM)
add_executable(pio
pio.c
)
pico_generate_pio_header(pio ${CMAKE_CURRENT_LIST_DIR}/sqwave.pio)
target_link_libraries(pio pico_stdlib hardware_pio)
pico_add_extra_outputs(pio)
Page 189 remember to use the CMakeLists.txt file and the PIO program given earlier
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"
int main()
{
uint offset = pio_add_program(pio0, &squarewave_program);
uint sm = pio_claim_unused_sm(pio0, true);
pio_sm_config c = squarewave_program_get_default_config(offset);
sm_config_set_set_pins(&c, 2, 1);
pio_gpio_init(pio0, 2);
pio_sm_init(pio0, sm, offset, &c);
pio_sm_set_enabled(pio0, sm, true);
return 0;
}
Page 247-248
PIO Program
.program squarewave
set pindirs, 1
pull block
again:
set pins, 1
mov x, osr
loop1:
jmp x--,loop1
set pins, 0
mov x, osr
loop2:
jmp x--,loop2
jmp again
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"
int main()
{
uint offset = pio_add_program(pio0, &squarewave_program);
uint sm = pio_claim_unused_sm(pio0, true);
pio_sm_config c = squarewave_program_get_default_config(offset);
sm_config_set_set_pins(&c, 2, 1);
pio_gpio_init(pio0, 2);
sm_config_set_clkdiv_int_frac(&c, 255, 0);
pio_sm_init(pio0, sm, offset, &c);
pio_sm_set_enabled(pio0, sm, true);
pio_sm_put_blocking(pio0, sm, 0xFFFF);
return 0;
}
Page 249-250
PIO Program
.program squarewave
set pindirs, 3
pull block
again:
out pins,2
jmp again
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"
int main()
{
uint offset = pio_add_program(pio0, &squarewave_program);
uint sm = pio_claim_unused_sm(pio0, true);
pio_sm_config c = squarewave_program_get_default_config(offset);
sm_config_set_set_pins(&c, 2, 2);
sm_config_set_out_pins(&c, 2, 2);
pio_gpio_init(pio0, 2);
pio_gpio_init(pio0, 3);
sm_config_set_clkdiv_int_frac(&c, 255, 0);
pio_sm_init(pio0, sm, offset, &c);
pio_sm_set_enabled(pio0, sm, true);
pio_sm_put_blocking(pio0, sm, 0xFEDCBA98);
return 0;
}
Page 252
PIO Program
.program squarewave
again:
out pins,2
jmp again
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"
int main()
{
uint offset = pio_add_program(pio0, &squarewave_program);
uint sm = pio_claim_unused_sm(pio0, true);
pio_sm_config c = squarewave_program_get_default_config(offset);
sm_config_set_set_pins(&c, 2, 2);
sm_config_set_out_pins(&c, 2, 2);
pio_gpio_init(pio0, 2);
pio_gpio_init(pio0, 3);
pio_sm_set_consecutive_pindirs(pio0, sm, 2, 2, true);
sm_config_set_clkdiv_int_frac(&c, 255, 0);
sm_config_set_out_shift(&c, true, true, 6);
pio_sm_init(pio0, sm, offset, &c);
pio_sm_set_enabled(pio0, sm, true);
while (true)
{
pio_sm_put_blocking(pio0, sm, 0xFEDCBA98);
}
return 0;
}
Page 254
PIO Program
.program squarewave
.side_set 1 opt
again:
nop side 1
jmp again side 0
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"
int main()
{
uint offset = pio_add_program(pio0, &squarewave_program);
uint sm = pio_claim_unused_sm(pio0, true);
pio_sm_config c = squarewave_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, 2);
pio_gpio_init(pio0, 2);
pio_sm_set_consecutive_pindirs(pio0, sm, 2, 1, true);
sm_config_set_clkdiv_int_frac(&c, 255, 0);
pio_sm_init(pio0, sm, offset, &c);
pio_sm_set_enabled(pio0, sm, true);
return 0;
}
Page 257
PIO Program
.program light
again:
in pins,1
push block
jmp again
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "light.pio.h"
int main()
{
uint offset = pio_add_program(pio0, &light_program);
uint sm = pio_claim_unused_sm(pio0, true);
pio_sm_config c = light_program_get_default_config(offset);
sm_config_set_in_pins(&c, 2);
pio_gpio_init(pio0, 2);
pio_sm_set_consecutive_pindirs(pio0, sm, 2, 1, false);
sm_config_set_clkdiv_int_frac(&c, 255, 0);
pio_sm_init(pio0, sm, offset, &c);
pio_sm_set_enabled(pio0, sm, true);
gpio_init(25);
gpio_set_dir(25, GPIO_OUT);
while (true)
{
uint32_t flag = pio_sm_get_blocking(pio0, sm);
if (flag == 0)
{
gpio_put(25, 0);
}
else
{
gpio_put(25, 1);
}
}
return 0;
}
Page 259
PIO Program
.program squarewave
again:
wait 0 pin 0
wait 1 pin 0
set pins, 1
set pins, 0
CProgram
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"
int main()
{
uint offset = pio_add_program(pio0, &squarewave_program);
uint sm = pio_claim_unused_sm(pio0, true);
pio_sm_config c = squarewave_program_get_default_config(offset);
sm_config_set_set_pins(&c, 3, 1);
sm_config_set_in_pins(&c, 2);
pio_gpio_init(pio0, 2);
pio_gpio_init(pio0, 3);
pio_sm_set_consecutive_pindirs(pio0, sm, 2, 1, false);
pio_sm_set_consecutive_pindirs(pio0, sm, 3, 1, true);
sm_config_set_clkdiv_int_frac(&c, 255, 0);
pio_sm_init(pio0, sm, offset, &c);
pio_sm_set_enabled(pio0, sm, true);
return 0;
}
Page 189
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
int main()
{
stdio_init_all();
gpio_init(2);
gpio_set_dir(2, GPIO_OUT);
gpio_put(2, 1);
sleep_ms(1);
gpio_put(2, 0);
sleep_ms(1);
gpio_set_dir(2, GPIO_IN);
return 0;
}
Page 267
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
int main()
{
stdio_init_all();
gpio_init(2);
gpio_set_dir(2, GPIO_OUT);
gpio_put(2, 1);
sleep_ms(1);
gpio_put(2, 0);
sleep_ms(1);
gpio_set_dir(2, GPIO_IN);
return 0;
}
Page 270
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
inline static void WaitFallingEdge(uint gpio)
{
while (gpio_get(gpio) == 1)
{
};
while (gpio_get(gpio) == 0)
{
};
}
uint32_t getData(uint gpio)
{
uint32_t t2;
uint32_t data = 0;
uint32_t t1 = time_us_32();
for (int i = 0; i < 32; i++)
{
WaitFallingEdge(2);
t2 = time_us_32();
data = data << 1;
data = data | ((t2 - t1) > 100);
t1 = t2;
}
return data;
}
uint8_t getCheck(uint gpio)
{
uint8_t checksum = 0;
uint32_t t2;
uint32_t t1 = time_us_32();
for (int i = 0; i < 8; i++)
{
WaitFallingEdge(2);
t2 = time_us_32();
checksum = checksum << 1;
checksum = checksum | (t2 - t1) > 100;
t1 = t2;
}
return checksum;
}
void dhtInitalize(uint gpio)
{
gpio_init(gpio);
gpio_set_dir(gpio, GPIO_OUT);
gpio_put(gpio, 1);
sleep_ms(1);
gpio_put(gpio, 0);
sleep_ms(1);
gpio_set_dir(gpio, GPIO_IN);
for (int i = 0; i < 2; i++)
{
WaitFallingEdge(gpio);
}
}
typedef struct
{
float temperature;
float humidity;
bool error;
} dhtData;
void dhtread(uint gpio, dhtData *reading)
{
dhtInitalize(gpio);
uint32_t data = getData(gpio);
uint8_t checksum = getCheck(gpio);
uint8_t byte1 = (data >> 24 & 0xFF);
uint8_t byte2 = (data >> 16 & 0xFF);
uint8_t byte3 = (data >> 8 & 0xFF);
uint8_t byte4 = (data & 0xFF);
reading->error = (checksum != ((byte1 + byte2 + byte3 + byte4) & 0xFF));
reading->humidity = (float)((byte1 << 8) | byte2) / 10.0;
int neg = byte3 & 0x80;
byte3 = byte3 & 0x7F;
reading->temperature = (float)(byte3 << 8 | byte4) / 10.0;
if (neg > 0)
reading->temperature = -reading->temperature;
}
int main()
{
stdio_init_all();
printf("data^^^^^\n");
dhtData reading;
dhtread(2, &reading);
printf("Humidity= %f %\n", reading.humidity);
printf("Temperature= %f C\n", reading.temperature);
return 0;
}
Page 275
PIO Program
.program dht
set pins, 1
set pindirs, 1
again:
pull block
set pins, 0
mov x, osr
loop1:
jmp x--,loop1
set pindirs, 0
wait 1 pin 0
wait 0 pin 0
wait 1 pin 0
wait 0 pin 0
set y,31
bits:
wait 1 pin 0
set x, 0
loop2:
jmp x--,continue
continue: jmp pin,loop2
in x,4
jmp y--,bits
set y,7
check:
wait 1 pin 0
set x, 0
loop3:
jmp x--,continue2
continue2: jmp pin,loop3
in x,4
jmp y--,check
jmp again
C Program
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/pio.h"
#include "DHT.pio.h"
uint dhtInitalize(PIO pio, int gpio)
{
uint offset = pio_add_program(pio, &dht_program);
uint sm = pio_claim_unused_sm(pio, true);
pio_gpio_init(pio, gpio);
pio_sm_config c = dht_program_get_default_config(offset);
sm_config_set_clkdiv_int_frac(&c, 128, 0);
sm_config_set_set_pins(&c, gpio, 1);
sm_config_set_in_pins(&c, gpio);
sm_config_set_jmp_pin(&c, gpio);
sm_config_set_in_shift(&c, true, true, 32);
pio_sm_init(pio0, sm, offset, &c);
pio_sm_set_enabled(pio0, sm, true);
return sm;
}
uint8_t getByte(PIO pio, uint sm)
{
uint32_t count = pio_sm_get_blocking(pio0, sm);
uint8_t byte = 0;
for (int i = 0; i < 8; i++)
{
byte = byte << 1;
if (((count >> i * 4) & 0x0F) > 8)
{
byte = byte | 1;
}
}
return byte;
}
typedef struct
{
float temperature;
float humidity;
bool error;
} dhtData;
void dhtread(PIO pio, uint sm, dhtData *reading)
{
pio_sm_put_blocking(pio, sm, 1000);
uint8_t byte1 = getByte(pio, sm);
uint8_t byte2 = getByte(pio, sm);
uint8_t byte3 = getByte(pio, sm);
uint8_t byte4 = getByte(pio, sm);
uint8_t checksum = getByte(pio, sm);
reading->error = (checksum == (byte1 + byte2 + byte3 + byte4) & 0xFF);
reading->humidity = (float)((byte1 << 8) | byte2) / 10.0;
int neg = byte3 & 0x80;
byte3 = byte3 & 0x7F;
reading->temperature = (float)(byte3 << 8 | byte4) / 10.0;
if (neg > 0)
reading->temperature = -reading->temperature;
}
int main()
{
stdio_init_all();
uint sm = dhtInitalize(pio0, 2);
dhtData reading;
dhtread(pio0, sm, &reading);
printf("Humidity= %f %\n", reading.humidity);
printf("Temperature= %f C\n", reading.temperature);
return 0;
}
Page 280
PIO Program
.program dht
set pins, 1
set pindirs, 1
again:
pull block
set pins, 0
mov x, osr
loop1:
jmp x--,loop1
set pindirs, 0
wait 1 pin 0
wait 0 pin 0
wait 1 pin 0
wait 0 pin 0
set y,31
bits:
wait 1 pin 0 [25]
in pins,1
wait 0 pin 0
jmp y--,bits
set y,7
check:
wait 1 pin 0 [25]
in pins,1
wait 0 pin 0
jmp y--,check
push block
jmp again
C Program
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/pio.h"
#include "DHT.pio.h"
uint dhtInitalize(PIO pio, int gpio)
{
uint offset = pio_add_program(pio, &dht_program);
uint sm = pio_claim_unused_sm(pio, true);
pio_gpio_init(pio, gpio);
pio_sm_config c = dht_program_get_default_config(offset);
sm_config_set_clkdiv_int_frac(&c, 255, 0);
sm_config_set_set_pins(&c, gpio, 1);
sm_config_set_in_pins(&c, gpio);
sm_config_set_in_shift(&c, false, true, 32);
pio_sm_init(pio0, sm, offset, &c);
pio_sm_set_enabled(pio0, sm, true);
return sm;
}
typedef struct
{
float temperature;
float humidity;
bool error;
} dhtData;
void dhtread(PIO pio, uint sm, dhtData *reading)
{
pio_sm_put_blocking(pio, sm, 500);
uint32_t data = pio_sm_get_blocking(pio0, sm);
uint8_t byte1 = (data >> 24 & 0xFF);
uint8_t byte2 = (data >> 16 & 0xFF);
uint8_t byte3 = (data >> 8 & 0xFF);
uint8_t byte4 = (data & 0xFF);
uint8_t checksum = pio_sm_get_blocking(pio0, sm) & 0xFF;
reading->error = (checksum != ((byte1 + byte2 + byte3 + byte4) & 0xFF));
reading->humidity = (float)((byte1 << 8) | byte2) / 10.0;
int neg = byte3 & 0x80;
byte3 = byte3 & 0x7F;
reading->temperature = (float)(byte3 << 8 | byte4) / 10.0;
if (neg > 0)
reading->temperature = -reading->temperature;
}
int main()
{
stdio_init_all();
uint sm = dhtInitalize(pio0, 2);
dhtData reading;
dhtread(pio0, sm, &reading);
printf("Humidity= %f %\n", reading.humidity);
printf("Temperature= %f C\n", reading.temperature);
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
include(pico_sdk_import.cmake)
project(dht C CXX ASM)
pico_sdk_init()
add_executable(dht
DHT.c
)
pico_generate_pio_header(dht ${CMAKE_CURRENT_LIST_DIR}/DHT.pio)
target_link_libraries(dht pico_stdlib hardware_pio)
pico_add_extra_outputs(dht)
Page 300
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
int presence(uint8_t pin)
{
gpio_set_dir(2, GPIO_OUT);
gpio_put(pin, 1);
sleep_ms(1);
gpio_put(pin, 0);
sleep_us(480);
gpio_set_dir(pin, GPIO_IN);
sleep_us(70);
int b = gpio_get(pin);
sleep_us(410);
return b;
}
void writeBit(uint8_t pin, int b)
{
int delay1, delay2;
if (b == 1)
{
delay1 = 6;
delay2 = 64;
}
else
{
delay1 = 60;
delay2 = 10;
}
gpio_set_dir(pin, GPIO_OUT);
gpio_put(pin, 0);
sleep_us(delay1);
gpio_set_dir(pin, GPIO_IN);
sleep_us(delay2);
}
void writeByte(uint8_t pin, int byte)
{
for (int i = 0; i < 8; i++)
{
if (byte & 1)
{
writeBit(pin, 1);
}
else
{
writeBit(pin, 0);
}
byte = byte >> 1;
}
}
uint8_t readBit(uint8_t pin)
{
gpio_set_dir(pin, GPIO_OUT);
gpio_put(pin, 0);
sleep_us(8);
gpio_set_dir(pin, GPIO_IN);
sleep_us(2);
uint8_t b = gpio_get(pin);
sleep_us(60);
return b;
}
int readByte(uint8_t pin)
{
int byte = 0;
int i;
for (i = 0; i < 8; i++)
{
byte = byte | readBit(pin) << i;
};
return byte;
}
int convert(uint8_t pin)
{
writeByte(pin, 0x44);
int i;
for (i = 0; i < 500; i++)
{
sleep_ms(10);
if (readBit(pin) == 1)
break;
}
return i;
}
uint8_t crc8(uint8_t *data, uint8_t len)
{
uint8_t i;
uint8_t j;
uint8_t temp;
uint8_t databyte;
uint8_t crc = 0;
for (i = 0; i < len; i++)
{
databyte = data[i];
for (j = 0; j < 8; j++)
{
temp = (crc ^ databyte) & 0x01;
crc >>= 1;
if (temp)
crc ^= 0x8C;
databyte >>= 1;
}
}
return crc;
}
float getTemperature(uint8_t pin)
{
if (presence(pin) == 1)
return -1000;
writeByte(pin, 0xCC);
if (convert(pin) == 500)
return -3000;
presence(pin);
writeByte(pin, 0xCC);
writeByte(pin, 0xBE);
int i;
uint8_t data[9];
for (i = 0; i < 9; i++)
{
data[i] = readByte(pin);
}
uint8_t crc = crc8(data, 9);
if (crc != 0)
return -2000;
int t1 = data[0];
int t2 = data[1];
int16_t temp1 = (t2 << 8 | t1);
float temp = (float)temp1 / 16;
return temp;
}
int main()
{
stdio_init_all();
gpio_init(2);
if (presence(2) == 1)
{
printf("No device \n");
}
float t;
for (;;)
{
do
{
t = getTemperature(2);
} while (t < -999);
printf("%f\r\n", t);
sleep_ms(500);
};
return 0;
}
Page 309
PIO Program
.program DS1820
.wrap_target
again:
pull block
mov x, osr
jmp !x, read
write: set pindirs, 1
set pins, 0
loop1:
jmp x--,loop1
set pindirs, 0 [31]
wait 1 pin 0 [31]
pull block
mov x, osr
bytes1:
pull block
set y, 7
set pindirs, 1
bit1:
set pins, 0 [1]
out pins,1 [31]
set pins, 1 [20]
jmp y--,bit1
jmp x--,bytes1
set pindirs, 0 [31]
jmp again
read:
pull block
mov x, osr
bytes2:
set y, 7
bit2:
set pindirs, 1
set pins, 0 [1]
set pindirs, 0 [5]
in pins,1 [10]
jmp y--,bit2
jmp x--,bytes2
.wrap
C Program
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "DS1820.pio.h"
uint8_t crc8(uint8_t *data, uint8_t len)
{
uint8_t i;
uint8_t j;
uint8_t temp;
uint8_t databyte;
uint8_t crc = 0;
for (i = 0; i < len; i++)
{
databyte = data[i];
for (j = 0; j < 8; j++)
{
temp = (crc ^ databyte) & 0x01;
crc >>= 1;
if (temp)
crc ^= 0x8C;
databyte >>= 1;
}
}
return crc;
}
void writeBytes(PIO pio, uint sm, uint8_t bytes[], int len)
{
pio_sm_put_blocking(pio, sm, 250);
pio_sm_put_blocking(pio, sm, len - 1);
for (int i = 0; i < len; i++)
{
pio_sm_put_blocking(pio, sm, bytes[i]);
}
}
void readBytes(PIO pio, uint sm, uint8_t bytes[], int len)
{
pio_sm_put_blocking(pio, sm, 0);
pio_sm_put_blocking(pio, sm, len - 1);
for (int i = 0; i < len; i++)
{
bytes[i] = pio_sm_get_blocking(pio, sm) >> 24;
}
}
float getTemperature(PIO pio, uint sm)
{
writeBytes(pio, sm, (uint8_t[]){0xCC, 0x44}, 2);
sleep_ms(1000);
writeBytes(pio, sm, (uint8_t[]){0xCC, 0xBE}, 2);
uint8_t data[9];
readBytes(pio, sm, data, 9);
uint8_t crc = crc8(data, 9);
if (crc != 0)
return -2000;
int t1 = data[0];
int t2 = data[1];
int16_t temp1 = (t2 << 8 | t1);
volatile float temp = (float)temp1 / 16;
return temp;
}
uint DS18Initalize(PIO pio, int gpio)
{
uint offset = pio_add_program(pio, &DS1820_program);
uint sm = pio_claim_unused_sm(pio, true);
pio_gpio_init(pio, gpio);
pio_sm_config c = DS1820_program_get_default_config(offset);
sm_config_set_clkdiv_int_frac(&c, 255, 0);
sm_config_set_set_pins(&c, gpio, 1);
sm_config_set_out_pins(&c, gpio, 1);
sm_config_set_in_pins(&c, gpio);
sm_config_set_in_shift(&c, true, true, 8);
pio_sm_init(pio0, sm, offset, &c);
pio_sm_set_enabled(pio0, sm, true);
return sm;
}
int main()
{
stdio_init_all();
uint sm = DS18Initalize(pio0, 2);
float t;
for (;;)
{
do
{
t = getTemperature(pio0, sm);
} while (t < -999);
printf("temperature %f\r\n", t);
sleep_ms(500);
};
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
include(pico_sdk_import.cmake)
project(ds18 C CXX ASM)
pico_sdk_init()
add_executable(ds18
DS1820.c
)
pico_generate_pio_header(ds18 ${CMAKE_CURRENT_LIST_DIR}/DS1820.pio)
target_link_libraries(ds18 pico_stdlib hardware_gpio hardware_pio)
pico_add_extra_outputs(ds18)
Page 322
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
int main()
{
stdio_init_all();
uart_init(uart1, 9600);
gpio_set_function(4, GPIO_FUNC_UART);
gpio_set_function(5, GPIO_FUNC_UART);
uart_set_format(uart1, 8, 1, UART_PARITY_EVEN);
uint8_t SendData[] = "Hello World";
uint8_t RecData[20];
uart_write_blocking(uart1, SendData, 11);
uart_read_blocking(uart1, RecData, 11);
RecData[11] = 0;
printf("%s", RecData);
}
Page 334
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#define Debug true
int initWiFi()
{
uart_init(uart1, 115200);
gpio_set_function(4, GPIO_FUNC_UART);
gpio_set_function(5, GPIO_FUNC_UART);
uart_set_format(uart1, 8, 1, UART_PARITY_NONE);
sleep_ms(100);
return 0;
}
int getBlock(uint8_t buf[], int len)
{
int count = 0;
while (count < len - 1)
{
if (uart_is_readable_within_us(uart1, 10000))
{
buf[count++] = uart_getc(uart1);
if (Debug)
uart_putc(uart0, buf[count - 1]);
}
else
{
break;
}
}
buf[count] = 0;
return count;
}
int ATWiFi(uint8_t buf[], int len)
{
uint8_t SendData[] = "AT\r\n";
uart_write_blocking(uart1, SendData, 4);
return getBlock(buf, len);
}
int main()
{
stdio_init_all();
initWiFi();
uint8_t buf[512];
ATWiFi(buf, 512);
sleep_ms(1000);
}
Page 347
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include <string.h>
#define Debug true
int initWiFi()
{
uart_init(uart1, 115200);
gpio_set_function(4, GPIO_FUNC_UART);
gpio_set_function(5, GPIO_FUNC_UART);
uart_set_format(uart1, 8, 1, UART_PARITY_NONE);
uart_set_translate_crlf(uart0, true);
sleep_ms(100);
return 0;
}
int getBlock(uint8_t buf[], int len)
{
int count = 0;
while (count < len - 1)
{
if (uart_is_readable_within_us(uart1, 10000))
{
buf[count++] = uart_getc(uart1);
if (Debug)
uart_putc(uart0, buf[count - 1]);
}
else
{
break;
}
}
buf[count] = 0;
return count;
}
int ATWiFi(uint8_t buf[], int len)
{
uint8_t SendData[] = "AT\r\n";
uart_write_blocking(uart1, SendData, 4);
return getBlock(buf, len);
}
int getVersionWiFi(uint8_t buf[], int len)
{
uint8_t SendData[] = "AT+GMR\r\n";
uart_write_blocking(uart1, SendData, 8);
return getBlock(buf, len);
}
int resetWiFi(uint8_t buf[], int len)
{
uint8_t SendData[] = "AT+RST\r\n";
uart_write_blocking(uart1, SendData, 8);
return getBlock(buf, len);
}
int setUARTWiFi(uint8_t buf[], int len)
{
uint8_t SendData[] = "AT+UART_CUR=115200,8,1,0,0\r\n";
uart_write_blocking(uart1, SendData, 28);
return getBlock(buf, len);
}
int modeWiFi(uint8_t buf[], int len, int mode)
{
uint8_t command[32];
int count = snprintf(command, 32, "AT+CWMODE_CUR=%d\r\n", mode);
uart_write_blocking(uart1, command, count);
return getBlock(buf, len);
}
int getBlocks(uint8_t buf[], int len, int num, char target[])
{
for (int i = 0; i < num; i++)
{
if (uart_is_readable_within_us(uart1, 1000 * 1000))
{
getBlock(buf, len);
if (strstr(buf, target))
return i;
}
}
return -1;
}
int scanWiFi(uint8_t buf[], int len)
{
uint8_t SendData[] = "AT+CWLAP\r\n";
uart_write_blocking(uart1, SendData, 18);
return getBlocks(buf, len, 20, "OK");
}
int connectWiFi(uint8_t buf[], int len, char ssid[], char pass[])
{
uint8_t command[128];
int count = snprintf(command, 128, "AT+CWJAP_CUR=\"%s\",\"%s\"\r\n", ssid, pass);
uart_write_blocking(uart1, command, count);
return getBlocks(buf, len, 20, "OK");
}
int getIPWiFi(uint8_t buf[], int len)
{
uint8_t SendData[] = "AT+CIFSR\r\n";
uart_write_blocking(uart1, SendData, 10);
return getBlocks(buf, len, 20, "OK");
}
int getWebPageWiFi(uint8_t buf[], int len, char URL[], char page[])
{
uint8_t command[128];
int count = snprintf(command, 128, "AT+CIPSTART=\"TCP\",\"%s\",80\r\n", URL);
uart_write_blocking(uart1, command, count);
if (getBlocks(buf, len, 20, "OK") < 0)
return -1;
char http[150];
sprintf(http, "GET %s HTTP/1.1\r\nHost:%s\r\n\r\n", page, URL);
count = snprintf(command, 128, "AT+CIPSEND=%d\r\n", strlen(http));
uart_write_blocking(uart1, command, count);
if (getBlocks(buf, len, 20, ">") < 0)
return -1;
uart_write_blocking(uart1, http, strlen(http));
return getBlocks(buf, len, 20, "</html>");
}
int startServerWiFi(uint8_t buf[], int len)
{
char temp[256];
char id[10];
uart_write_blocking(uart1, "AT+CIPMUX=1\r\n", 13);
if (getBlocks(buf, len, 10, "OK") < 0)
return -1;
uart_write_blocking(uart1, "AT+CIPSERVER=1,80\r\n", 19);
if (getBlocks(buf, len, 10, "OK") < 0)
return -1;
for (;;)
{
if (getBlocks(buf, len, 1, "+IPD") < 0)
continue;
char *b = strstr(buf, "+IPD");
b += 5;
strncpy(temp, b, sizeof(temp));
char *e = strstr(temp, ",");
int d = e - temp;
memset(id, '\0', sizeof(id));
strncpy(id, temp, d);
char data[] = "HTTP/1.0 200 OK\r\nServer: Pico\r\nContent-type: text/html\r\n\r\n<html><head><title>Temperature</title></head><body><p>{\"humidity\":81%,\"airtemperature\":23.5C}</p></body></html>\r\n";
uint8_t command[128];
int count = snprintf(command, 128, "AT+CIPSEND=%s,%d\r\n", id, strlen(data));
uart_write_blocking(uart1, command, count);
if (getBlocks(buf, len, 10, ">") < 0)
return -1;
uart_write_blocking(uart1, data, strlen(data));
if (getBlocks(buf, len, 10, "OK") < 0)
return -1;
count = snprintf(command, 128, "AT+CIPCLOSE=%s\r\n", id);
uart_write_blocking(uart1, command, count);
if (getBlocks(buf, len, 10, "OK") < 0)
return -1;
}
return 0;
}
int main()
{
stdio_init_all();
uint8_t buf[512];
initWiFi();
modeWiFi(buf, 512, 1);
connectWiFi(buf, 512, "ssid", "password");
getIPWiFi(buf, 512);
startServerWiFi(buf, 512);
sleep_ms(1000);
}