IOT Raspberry Pi Programs

FrontCover300

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. 

 

Note: The VS Code task listings are at the very end of this page.

The only downside is that you have to create a project to paste the code into.

To do this follow the instructionin the book- in particular remember to add the bcm2835 library and also any library references that may be needed. 

All of the programs below were copy and pasted from working programs in the IDE.

If anything you consider important is missing or if you have any requests or comments  contact me

This email address is being protected from spambots. You need JavaScript enabled to view it.

 

Page 32

#include <stdio.h>
#include <stdlib.h> 
int main(int argc, char** argv) {
    printf("Hello C World");
    return(EXIT_SUCCESS); 
}
 

Page 38

#include <bcm2835.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    while (1)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_delay(500);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
        bcm2835_delay(500);
    }
    bcm2835_close();
    return 0;
}
 

Page 50

#include <bcm2835.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    for (;;)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}
 

Page 54

#define _DEFAULT_SOURCE
#include <bcm2835.h>
#include <stdio.h>
#include <time.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    volatile int i;
    struct timespec delay = {0, 10 * 1000};
    for (;;)
    {
        bcm2835_gpio_set(RPI_BPLUS_GPIO_J8_07);
        nanosleep(&delay, NULL);
        bcm2835_gpio_clr(RPI_BPLUS_GPIO_J8_07);
        nanosleep(&delay, NULL);
    }
    bcm2835_close();
    return 0;
}
 

Page 56

#include <bcm2835.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    volatile int i;
    int n = 10;
    for (;;)
    {
        for (i = 0; i < n; i++)
        {
        };
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        for (i = 0; i < n; i++)
        {
        };
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}
 

Page 57

 
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <time.h> 

#define BILLION 1000000000L 

int main(int argc, char** argv) {
    struct timespec btime, etime;

    volatile int i;
    clock_gettime(CLOCK_REALTIME, &btime);
    for (i = 0; i < 10000000; i++) {
    };
    clock_gettime(CLOCK_REALTIME, &etime);
    double nseconds =  (double) ((etime.tv_sec - btime.tv_sec)* BILLION)+(double) (etime.tv_nsec - btime.tv_nsec);
    int n = (int) 10 /nseconds * BILLION + 0.5;
    printf("time = %f (s)  \n \r",nseconds / BILLION);
    printf("n= %d \n\r", n);
    return (EXIT_SUCCESS);
}

Page 58

 
#include <bcm2835.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07,
                      BCM2835_GPIO_FSEL_OUTP);
    for (;;)
    {
        bcm2835_gpio_set(RPI_BPLUS_GPIO_J8_07);
        bcm2835_delayMicroseconds(1);
        bcm2835_gpio_clr(RPI_BPLUS_GPIO_J8_07);
        bcm2835_delayMicroseconds(1);
    }
    bcm2835_close();
    return 0;
}
 

Page 59

 
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07,
                      BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11,
                      BCM2835_GPIO_FSEL_OUTP);
    volatile int i;
    for (;;)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    }
    return (EXIT_SUCCESS);
}
 

Page 60

 
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    uint32_t mask = (1 << RPI_BPLUS_GPIO_J8_07) | (1 << RPI_BPLUS_GPIO_J8_11);
    for (;;)
    {
        bcm2835_gpio_set_multi(mask);
        bcm2835_gpio_clr_multi(mask);
    }

    return (EXIT_SUCCESS);
}
 

 Page 81

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);

    while (1)
    {
        if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
        {
            printf("Line Low \n\r");
            fflush(stdout);
        };
    }
    return 0;
}
 

Page 82

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);

    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
            ;
        bcm2835_delayMicroseconds(1000);
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
            ;
        bcm2835_delayMicroseconds(1000);
        printf("Button Push \n\r");
        fflush(stdout);
    }
    return 0;
}
 

Page 83

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    uint64_t t;
    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
            ;
        t = bcm2835_st_read();
        bcm2835_delayMicroseconds(1000);
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
            ;
        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000);
        if (t > 5000000)
        {
            printf("Putton held \n\r");
        }
        else
        {
            printf("Button Push \n\r");
        }
        fflush(stdout);
    }
    return 0;
}
 

Page 84

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{

    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);

    volatile int i;
    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
            ;
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
            ;
        for (i = 0; i < 5000; i++)
        {
            if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        printf("%d\n\r", i);
        fflush(stdout);
    }
    return (EXIT_SUCCESS);
}
 

Page 85

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    volatile int i;
    uint64_t t;
    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
            ;
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
            ;
        t = bcm2835_st_read();
        for (i = 0; i < 5000; i++)
        {
            if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        t = bcm2835_st_read() - t;
        printf("%d,%llu\n\r", i, t);
        fflush(stdout);
    }
    return (EXIT_SUCCESS);
}
 

Page 86

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);

    uint64_t t;
    while (1)
    {
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
            ;
        t = bcm2835_st_read();
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
            ;
        t = bcm2835_st_read() - t;
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    }
    return (EXIT_SUCCESS);
}
 

 Page 89

 
 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    uint64_t t;
    int s = 0;
    int i;
    while (1)
    {
        t = bcm2835_st_read();
        i = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);
        switch (s)
        {
        case 0: //Button not pushed
            if (!i)
            {
                s = 1;
                printf("Button Push \n\r");
                fflush(stdout);
            }
            break;
        case 1: //Button pushed
            if (i)
            {
                s = 0;
            }
            break;
        default:
            s = 0;
        }
        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000 - t);
    }
    return 0;
}

Page 91

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    uint64_t t, tpush = 0;
    int s = 0, i;
    while (1)
    {
        t = bcm2835_st_read();
        i = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);
        switch (s)
        {
        case 0: //Button not pushed
            if (!i)
            {
                s = 1;
                tpush = t;
            }
            break;
        case 1: //Button pushed
            if (i)
            {
                s = 0;
                if ((t - tpush) > 5000000)
                {
                    printf("Button held \n\r");
                }
                else
                {
                    printf("Button pushed \n\r");
                }
                fflush(stdout);
            }
            break;
        default:
            s = 0;
        }
        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000 - t);
    }
    return 0;
}
 

Page 92

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_13, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_15, BCM2835_GPIO_FSEL_OUTP);

    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, LOW);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, LOW);

    uint64_t t;

    int buttonState = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);

    int state = 0;
    while (1)
    {

        t = bcm2835_st_read();
        int buttonNow = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);
        int edge = buttonState - buttonNow;
        buttonState = buttonNow;

        switch (state)
        {
        case 0:
            if (edge)
            {
                state = 1;
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, HIGH);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, LOW);
            }
            break;
        case 1:
            if (edge)
            {
                state = 2;
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, HIGH);
            }
            break;
        case 2:
            if (edge)
            {
                state = 0;
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, LOW);
            }
            break;
        }

        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000 - t);
    }
    return 0;
}
 

Page 103

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>

int main(int argc, char **argv)
{
    int fd;
    struct gpiochip_info info;

    fd = open("/dev/gpiochip0", O_RDONLY);

    int ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &info);
    close(fd);
    printf("label: %s\n name: %s\n number of lines: %u\n", info.label, info.name, info.lines);
    return 0;
}
 

Page 106

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>

int main(int argc, char **argv)
{
    int fd, ret;

    struct gpiohandle_request req;
    req.lineoffsets[0] = 4;
    req.lineoffsets[1] = 17;
    req.flags = GPIOHANDLE_REQUEST_OUTPUT;
    req.default_values[0] = 0;
    req.default_values[1] = 0;
    strcpy(req.consumer_label, "Output test");
    req.lines = 2;

    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    close(fd);

    struct gpiohandle_data data;
    data.values[0] = 0;
    data.values[1] = 1;
    while (1)
    {
        data.values[0] = !data.values[0];
        data.values[1] = !data.values[1];
        ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
    }
    return 0;
}
 

Page 107

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>

int main(int argc, char **argv)
{
    int fd, ret;

    struct gpiohandle_request req;
    req.lineoffsets[0] = 4;
    req.lineoffsets[1] = 17;
    req.flags = GPIOHANDLE_REQUEST_INPUT;
    strcpy(req.consumer_label, "Input test");
    req.lines = 2;

    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    close(fd);

    struct gpiohandle_data data;
    ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
    printf("%hhu , %hhu", data.values[0], data.values[1]);
    close(req.fd);
    return 0;
}
 

Page 114

Note a full program just a function definition
 
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

void checkIRQ()
{
    FILE *fp = popen("sudo dtparam -l", "r");
    if (fp == NULL)
    {
        printf("Failed to run command\n\r");
        exit(1);
    }
    char output[1024];
    int txfound = 0;
    while (fgets(output, sizeof(output), fp) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, "gpio-no-irq") != NULL)
        {
            txfound = 1;
        }
    }
    pclose(fp);

    if (txfound == 0)
    {
        fp = popen("sudo dtoverlay gpio-no-irq", "r");
        if (fp == NULL)
        {
            printf("Failed to run command\n\r");
            exit(1);
        }
        pclose(fp);
    }
}
 

Page 118

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_ren(RPI_BPLUS_GPIO_J8_07);

    volatile int i;
    uint64_t t;
    while (1)
    {
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        while (0 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07))
            ;
        t = bcm2835_st_read();
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        for (i = 0; i < 5000; i++)
        {
            if (1 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        t = bcm2835_st_read() - t;
        printf("%d,%llu\n\r", i, t);
        fflush(stdout);
    }
    return (EXIT_SUCCESS);
}
 

Page 119

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_clr_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);

    uint64_t t;
    while (1)
    {
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        t = bcm2835_st_read();
        for (;;)
        {
            if (1 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        t = bcm2835_st_read() - t;
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    }
    return (EXIT_SUCCESS);
}
 

 Page 120

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    printf("Press button \n\r");
    fflush(stdout);
    sleep(20);
    if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
    {
        printf("Button pressed \n\r");
    }
    else
    {
        printf("No Button press\n\r");
    };
    return 0;
}
 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
    printf("Press button \n\r");
    fflush(stdout);
    sleep(20);
    if (bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07))
    {
        printf("Button pressed \n\r");
    }
    else
    {
        printf("No Button press\n\r");
    };
    return 0;
}
 

 Page 124

 
#include <string.h>
#include <stdio.h> 
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>
#include <sys/epoll.h>

int main(int argc, char **argv) {
    int fd, ret;

    struct gpioevent_request req;
    req.lineoffset = 4;
    req.handleflags = GPIOHANDLE_REQUEST_INPUT;
    req.eventflags = GPIOEVENT_REQUEST_RISING_EDGE;
    strcpy(req.consumer_label, "Event test");

    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
    close(fd);

    static struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = req.fd;
    int epfd = epoll_create(1);
    int res = epoll_ctl(epfd, EPOLL_CTL_ADD, req.fd, &ev);

    int nfds = epoll_wait(epfd, &ev, 1, 20000);
    if (nfds != 0) {
        struct gpioevent_data edata;
        read(req.fd, &edata, sizeof edata);
        printf("%u,%llu", edata.id, edata.timestamp);
    }
}
 

Page 129

 
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>
#include <sys/epoll.h>

#include <pthread.h>
uint64_t t[20];
typedef void (*eventHandler)(int);

typedef struct
{
    int epfd;
    int fd;
    eventHandler func;
} intVec;

void myHandler(int fd)
{
    struct gpioevent_data edata;
    read(fd, &edata, sizeof edata);
    printf("%u,%llu \n\r", edata.id, edata.timestamp);
    fflush(stdout);
}
void *waitInterrupt(void *arg)
{
    intVec *intData = (intVec *)arg;
    struct epoll_event ev;
    for (;;)
    {
        int nfds = epoll_wait(intData->epfd, &ev, 1, 20000);

        if (nfds != 0)
        {
            intData->func(intData->fd);
        }
    }
}
int main(int argc, char **argv)
{
    int fd, ret;
    struct gpioevent_request req;
    req.lineoffset = 4;
    req.handleflags = GPIOHANDLE_REQUEST_INPUT;
    req.eventflags = GPIOEVENT_REQUEST_RISING_EDGE;
    strcpy(req.consumer_label, "Event test");

    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
    close(fd);
    static struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = req.fd;
    int epfd = epoll_create(1);
    int res = epoll_ctl(epfd, EPOLL_CTL_ADD, req.fd, &ev);
    intVec intData;
    intData.epfd = epfd;
    intData.fd = req.fd;
    intData.func = &myHandler;
    pthread_t intThread;
    if (pthread_create(&intThread, NULL, waitInterrupt,
                       (void *)&intData))
    {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    for (;;)
    {
        printf("Working\n\r");
        fflush(stdout);
        sleep(2);
    }
}
 

page 131

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <bcm2835.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>

#define BUFFER_MAX 50

typedef void (*eventHandler)();

int openGPIO(int pin, int direction);
int writeGPIO(int gpio, int value);
int readGPIO(int gpio);
int setEdgeGPIO(int gpio, char *edge);
void *waitInterrupt(void *arg);
int attachGPIO(int gpio, char *edge, eventHandler func);

int fd[32] = {0};
typedef struct
{
    int fd;
    int gpio;
    eventHandler func;
} intVec;

intVec intData;
static int count;

void myIntHandler()
{
    count++;
};
int main(int argc, char **argv)
{
    attachGPIO(4, "both", myIntHandler);
    for (;;)
    {
        printf("Interrupt %d\n\r", count);
        fflush(stdout);
    };
    return 0;
}

int openGPIO(int gpio, int direction)
{
    if (gpio < 0 || gpio > 31)
        return -1;
    if (direction < 0 || direction > 1)
        return -2;
    int len;
    char buf[BUFFER_MAX];
    if (fd[gpio] != 0)
    {
        close(fd[gpio]);
        fd[gpio] = open("/sys/class/gpio/unexport", O_WRONLY);
        len = snprintf(buf, BUFFER_MAX, "%d", gpio);
        write(fd[gpio], buf, len);
        close(fd[gpio]);
        fd[gpio] = 0;
    }

    fd[gpio] = open("/sys/class/gpio/export", O_WRONLY);
    len = snprintf(buf, BUFFER_MAX, "%d", gpio);
    write(fd[gpio], buf, len);
    close(fd[gpio]);
    len = snprintf(buf, BUFFER_MAX,
                   "/sys/class/gpio/gpio%d/direction", gpio);
    fd[gpio] = open(buf, O_WRONLY);
    if (direction == 1)
    {
        write(fd[gpio], "out", 4);
        close(fd[gpio]);
        len = snprintf(buf, BUFFER_MAX,
                       "/sys/class/gpio/gpio%d/value", gpio);
        fd[gpio] = open(buf, O_WRONLY);
    }
    else
    {
        write(fd[gpio], "in", 3);
        close(fd[gpio]);
        len = snprintf(buf, BUFFER_MAX,
                       "/sys/class/gpio/gpio%d/value", gpio);
        fd[gpio] = open(buf, O_RDONLY);
    }
    return 0;
}

int writeGPIO(int gpio, int b)
{
    if (b == 0)
    {
        write(fd[gpio], "0", 1);
    }
    else
    {
        write(fd[gpio], "1", 1);
    }

    lseek(fd[gpio], 0, SEEK_SET);
    return 0;
}

int readGPIO(int gpio)
{
    char value_str[3];
    int c = read(fd[gpio], value_str, 3);
    lseek(fd[gpio], 0, SEEK_SET);

    if (value_str[0] == '0')
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

int setEdgeGPIO(int gpio, char *edge)
{
    char buf[BUFFER_MAX];
    int len = snprintf(buf, BUFFER_MAX,
                       "/sys/class/gpio/gpio%d/edge", gpio);
    int fd = open(buf, O_WRONLY);
    write(fd, edge, strlen(edge) + 1);
    close(fd);
    return 0;
}

int attachGPIO(int gpio, char *edge, eventHandler func)
{
    openGPIO(gpio, 0);
    setEdgeGPIO(gpio, edge);
    readGPIO(gpio);
    intData.fd = fd[gpio];
    intData.gpio = gpio;
    intData.func = func;
    pthread_t intThread;
    if (pthread_create(&intThread,
                       NULL, waitInterrupt, (void *)&intData))
    {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    return 0;
}
void *waitInterrupt(void *arg)
{

    intVec *intData = (intVec *)arg;
    int gpio = intData->gpio;
    struct pollfd fdset[1];
    fdset[0].fd = intData->fd;
    fdset[0].events = POLLPRI;
    fdset[0].revents = 0;
    for (;;)
    {
        int rc = poll(fdset, 1, -1);
        if (fdset[0].revents & POLLPRI)
        {
            intData->func();
            lseek(fdset[0].fd, 0, SEEK_SET);
            readGPIO(gpio);
        }
    }
    pthread_exit(0);
}

Page 143

#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 2);
    bcm2835_pwm_set_data(0, 1);
    return (0);
}
 

Page 144

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_gpio_fsel(13, BCM2835_GPIO_FSEL_ALT0);
    bcm2835_pwm_set_clock(2);

    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 2);
    bcm2835_pwm_set_data(0, 1);

    bcm2835_pwm_set_mode(1, 1, 1);
    bcm2835_pwm_set_range(1, 8);
    bcm2835_pwm_set_data(1, 2);
    return (EXIT_SUCCESS);
}
 

Page 145

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 256);
    for (;;)
    {
        bcm2835_pwm_set_data(0, 16);
        bcm2835_delayMicroseconds((int)26.666 * 8);
        bcm2835_pwm_set_data(0, 128);
        bcm2835_delayMicroseconds((int)26.666 * 8);
    }
    return (EXIT_SUCCESS);
}
 

Page 147

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 256);
    for (;;)
    {
        bcm2835_pwm_set_data(0, 16);
        bcm2835_delayMicroseconds((int)26.666 * 8);
        bcm2835_pwm_set_data(0, 128);
        bcm2835_delayMicroseconds((int)26.666 * 8);
    }
    return (EXIT_SUCCESS);
}
 

Page 148

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    int C = 34091;
    bcm2835_pwm_set_range(0, C);
    bcm2835_pwm_set_data(0, C / 2);
    return (EXIT_SUCCESS);
}

Page 150

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv){
    if (!bcm2835_init())
            return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);
    int w = 1;
    int inc = 1;
    for (;;)
    {
        bcm2835_pwm_set_data(0, w);
        w = w + inc;
        if (w > 1024 || w <= 0)
            inc = -inc;
        bcm2835_delayMicroseconds(5000);
    }
    return (EXIT_SUCCESS);
}
    bcm2835_delayMicroseconds(5000);
    }
    return (EXIT_SUCCESS);
}
 

Page 151

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);
    int w = 0;
    int inc = 1;
    for (;;)
    {
        bcm2835_pwm_set_data(0, w * w * w);
        w = w + inc;
        if (w > 10 || w <= 0)
            inc = -inc;
        bcm2835_delayMicroseconds(50000);
    }
    return (EXIT_SUCCESS);
}
 

Page 152

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);
    int w = 0;
    int inc = 1;

    for (;;)
    {
        bcm2835_pwm_set_data(0, (w * w * w) >> 3);
        w = w + inc;
        if (w > 20 || w <= 0)
            inc = -inc;
        bcm2835_delayMicroseconds(50000);
    }
    return (EXIT_SUCCESS);
}
 

Page 155

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(375);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);

    for (;;)
    {
        bcm2835_pwm_set_data(0, 25);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 50);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 128);
        bcm2835_delayMicroseconds(2000000);
    }
    return (EXIT_SUCCESS);
}
 

Page 156 

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(375);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);

    for (;;)
    {
        bcm2835_pwm_set_data(0, 52 * 0 / 180 + 920);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 52 * 90 / 180 + 920);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 52 * 180 / 180 + 920);
        bcm2835_delayMicroseconds(2000000);
    }
    return (EXIT_SUCCESS);
}

Page 158

Function only - needs to run as root.
 
void bcm2835_pwm_set_clock_source(
    uint32_t source,
    uint32_t divisorI,
    uint32_t divisorF)
{
    divisorI &= 0xfff;
    divisorF &= 0xfff;
    source &= 0xf;
    uint8_t mask = bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0xffffffef;
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | mask);
    while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0)
    {
    };
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisorI << 12) | divisorF);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | source | 0x200);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x210 | source);
}
 

Page 160

 This needs to be run as root.
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <bcm2835.h>

void bcm2835_pwm_set_clock_source(uint32_t source,uint32_t divisorI,uint32_t divisorF)
{
    divisorI &= 0xfff;
    divisorF &= 0xfff;
    source &= 0xf;
    uint8_t mask = bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) &  0xffffffef;
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL,  BCM2835_PWM_PASSWRD | mask);
    while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0)
    {
    };
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisorI << 12) | divisorF);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | source | 0x200);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x210 | source);
}

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock_source(6, 2, 0);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 256);
    int i;
    for (;;)
    {
        for (i = 0; i < 256; i = i + 10)
        {
            bcm2835_pwm_set_data(0, i);
            bcm2835_delayMicroseconds(2);
        }
    }
    return (EXIT_SUCCESS);
}
 

Page 178 

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    char buf[] = {0xE7};
    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_148);
    bcm2835_i2c_setSlaveAddress(0x40);
    bcm2835_i2c_write(buf, 1);
    bcm2835_i2c_read(buf, 1);
    printf("User Register = %X \r\n", buf[0]);
    bcm2835_i2c_end();
    return (EXIT_SUCCESS);
}
 

 Page 178

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

void setTimeout(uint32_t timeout) {
    volatile uint32_t* stimeout = bcm2835_bsc1 + BCM2835_BSC_CLKT / 4;
    bcm2835_peri_write(stimeout, timeout);
}

int main(int argc, char** argv) {
    if (!bcm2835_init())
        return 1;

    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_150);
    setTimeout(0);
    char buf[4] = {0xE3};
    uint8_t status = bcm2835_i2c_read_register_rs(buf, buf, 3);
    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);
    bcm2835_i2c_end();
    return (EXIT_SUCCESS);
}
 

Page 180 

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

void setTimeout(uint32_t timeout)
{
    volatile uint32_t *stimeout = bcm2835_bsc1 + BCM2835_BSC_CLKT / 4;
    bcm2835_peri_write(stimeout, timeout);
}

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_2500);
    setTimeout(20000);
    char buf[3] = {0xE3};
    uint8_t status = bcm2835_i2c_read_register_rs(buf, buf, 3);
    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);
    bcm2835_i2c_end();
    return (EXIT_SUCCESS);
}
 

Page 184

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

void setTimeout(uint16_t timeout);
uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check);
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_2500);
    setTimeout(20000);
    char buf[4] = {0xE3};
    uint8_t status = bcm2835_i2c_read_register_rs(buf, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];

    printf("crc = %d\n\r", crcCheck(msb, lsb, check));
    unsigned int data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    float temp = (float)(-46.85 + (175.72 * data16 / (float)65536));
    printf("Temperature %f C \n\r", temp);

    buf[0] = 0xF5;
    bcm2835_i2c_write(buf, 1);
    while (bcm2835_i2c_read(buf, 3) == BCM2835_I2C_REASON_ERROR_NACK)
    {
        bcm2835_delayMicroseconds(500);
    };
    msb = buf[0];
    lsb = buf[1];
    check = buf[2];
    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);
    bcm2835_i2c_end();

    return (EXIT_SUCCESS);
}

void setTimeout(uint16_t timeout)
{
    volatile uint32_t *stimeout = bcm2835_bsc1 + BCM2835_BSC_CLKT / 4;
    bcm2835_peri_write(stimeout, timeout);
}

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;
}
 

Page 195 

#include <bcm2835.h>
#include <stdio.h>
#include <sched.h>
#include <sys/mman.h>

uint8_t getByte(int b, int buf[]);
void GetDHT22data(uint8_t pin);

int main(int argc, char **argv)
{
    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    mlockall(MCL_CURRENT | MCL_FUTURE);
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(1000);
    GetDHT22data(RPI_BPLUS_GPIO_J8_07);
    return 0;
}

void GetDHT22data(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(1000);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    int i;
    for (i = 1; i < 2000; i++)
    {
        if (bcm2835_gpio_lev(pin) == 0)
            break;
    };
    uint64_t t;
    int buf[41];
    int j;
    bcm2835_delayMicroseconds(1);
    for (j = 0; j < 41; j++)
    {
        for (i = 1; i < 2000; i++)
        {
            if (bcm2835_gpio_lev(pin) == 1)
                break;
        };
        t = bcm2835_st_read();
        for (i = 1; i < 2000; i++)
        {
            if (bcm2835_gpio_lev(pin) == 0)
                break;
        }
        buf[j] = (bcm2835_st_read() - t) > 50;
    }

    int byte1 = getByte(1, buf);
    int byte2 = getByte(2, buf);
    int byte3 = getByte(3, buf);
    int byte4 = getByte(4, buf);
    int byte5 = getByte(5, buf);
    printf("Checksum %d %d \n\r", byte5, (byte1 + byte2 + byte3 + byte4) & 0xFF);
    float humidity = (float)(byte1 << 8 | byte2) / 10.0;
    printf("Humidity= %f \n\r", humidity);
    float temperature;
    int neg = byte3 & 0x80;
    byte3 = byte3 & 0x7F;
    temperature = (float)(byte3 << 8 | byte4) / 10.0;
    if (neg > 0)
        temperature = -temperature;
    printf("Temperature= %f \n\r", temperature);
    return;
}

uint8_t getByte(int b, int buf[])
{
    int i;
    uint8_t result = 0;
    b = (b - 1) * 8 + 1;
    for (i = b; i <= b + 7; i++)
    {
        result = result << 1;
        result = result | buf[i];
    }
    return result;
}
 

Page 216

 
#include <bcm2835.h>
#include <stdio.h>
#include <sched.h>
#include <sys/mman.h>

int presence(uint8_t pin);
void writeByte(uint8_t pin, int byte);
uint8_t crc8(uint8_t *data, uint8_t len);
int readByte(uint8_t pin);
int readiButton(uint8_t pin, uint8_t *data);

int main(int argc, char **argv)
{
    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    mlockall(MCL_CURRENT | MCL_FUTURE);

    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);

    int i;
    uint8_t code[8];
    for (;;)
    {
        int p = readiButton(RPI_BPLUS_GPIO_J8_07, code);
        if (p == 1)
        {
            for (i = 0; i < 8; i++)
            {
                printf("%hhX ", code[i]);
            }
            printf("\n\r");
            fflush(stdout);
        }
        bcm2835_delayMicroseconds(100000);
    };
    bcm2835_close();
    return 0;
}

int presence(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(480);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(70);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(410);
    return b;
}

void writeBit(uint8_t pin, int b)
{

    int delay1, delay2;
    if (b == 1)
    {
        delay1 = 6;
        delay2 = 64;
    }
    else
    {
        delay1 = 80;
        delay2 = 10;
    }
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(delay1);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(delay2);
}

uint8_t readBit(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(6);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(9);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(55);
    return b;
}

void writeByte(uint8_t pin, int byte)
{
    int i;
    for (i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(pin, 1);
        }
        else
        {
            writeBit(pin, 0);
        }
        byte = byte >> 1;
    }
}

int readByte(uint8_t pin)
{
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++)
    {
        byte = byte | readBit(pin) << i;
    };
    return byte;
}
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;
}

int readiButton(uint8_t pin, uint8_t *data)
{
    int b = presence(pin);
    if (b != 0)
        return 0;
    writeByte(pin, 0x33);
    int i;
    for (i = 0; i < 8; i++)
    {
        data[i] = readByte(pin);
    }
    uint8_t crc = crc8(data, 8);
    if (crc == 0)
        return 1;
    return 0;
}
 

 Page 227

#include <bcm2835.h>
#include <stdio.h>

int presence(uint8_t pin);
void writeBit(uint8_t pin, int b);
void writeByte(uint8_t pin, int byte);
uint8_t readBit(uint8_t pin);
int convert(uint8_t pin);
int readByte(uint8_t pin);
float getTemperature(uint8_t pin);
uint8_t crc8(uint8_t *data, uint8_t len);

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    if (presence(RPI_BPLUS_GPIO_J8_07) == 1)
    {
        printf("No device \n");
    }
    else
    {
        printf("Device present \n");
    }
    fflush(stdout);
    float t;
    for (;;)
    {
        do
        {
            t = getTemperature(RPI_BPLUS_GPIO_J8_07);
        } while (t < -999);
        printf("%f\r\n", t);
        fflush(stdout);
    };
    bcm2835_close();

    return 0;
}

int presence(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(480);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(70);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(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;
    }
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(delay1);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(delay2);
}

void writeByte(uint8_t pin, int byte)
{
    int i;
    for (i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(pin, 1);
        }
        else
        {

            writeBit(pin, 0);
        }
        byte = byte >> 1;
    }
}

uint8_t readBit(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(8);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(2);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(60);
    return b;
}

int convert(uint8_t pin)
{
    int i;
    writeByte(pin, 0x44);
    for (i = 0; i < 5000; i++)
    {
        bcm2835_delayMicroseconds(100000);
        if (readBit(pin) == 1)
            break;
    }
    return i;
}

float getTemperature(uint8_t pin)
{
    if (presence(pin) == 1)
        return -1000;
    writeByte(pin, 0xCC);
    if (convert(pin) == 5000)
        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 readByte(uint8_t pin)
{
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++)
    {
        byte = byte | readBit(pin) << i;
    };
    return byte;
}

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;
}
 

Page 243

function only - needs a main program to call it

int oneWireScan(uint8_t pin, uint64_t serial[])
{
    static int bitcount = 0;
    static int deviceCount = 0;

    if (bitcount > 63)
    {
        bitcount = 0;
        deviceCount++;
        return deviceCount;
    }

    if (bitcount == 0)
    {
        if (presence(pin) == 1)
        {
            bitcount = 0;
            return deviceCount;
        }
        deviceCount = 0;
        serial[deviceCount] = 0;
        writeByte(pin, 0xF0);
    };

    int b1 = readBit(pin);
    int b2 = readBit(pin);

    if (b1 == 0 && b2 == 1)
    {
        serial[deviceCount] >>= 1;
        writeBit(pin, 0);
        bitcount++;
        oneWireScan(pin, serial);
    };

    if (b1 == 1 && b2 == 0)
    {
        serial[deviceCount] >>= 1;
        serial[deviceCount] |= 0x8000000000000000LL;
        writeBit(pin, 1);
        bitcount++;
        oneWireScan(pin, serial);
    };

    if (b1 == 1 && b2 == 1)
    {
        bitcount = 0;
        return deviceCount;
    };
    if (b1 == 0 && b2 == 0)
    {
        serial[deviceCount] >>= 1;
        writeBit(pin, 0);
        int bitposition = bitcount;
        bitcount++;
        oneWireScan(pin, serial);

        bitcount = bitposition;
        if (presence(pin) == 1)
        {
            bitposition = 0;
            return 0;
        }

        writeByte(pin, 0xF0);
        uint64_t temp = serial[deviceCount - 1] | (0x1LL << (bitcount));
        int i;
        uint64_t bit;
        for (i = 0; i < bitcount + 1; i++)
        {
            bit = temp & 0x01LL;
            temp >>= 1;
            b1 = readBit(pin);
            b2 = readBit(pin);
            writeBit(pin, bit);
            serial[deviceCount] >>= 1;
            serial[deviceCount] |= (bit << 63);
        }
        bitcount++;
        oneWireScan(pin, serial);
    };

    return deviceCount;
}
 

Page 265

#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv)
{
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    return 0;
}
 

Page 266

#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    char buf[] = "hello world";
    char buf2[11];
    int count = write(sfd, buf, 11);
    count = read(sfd, buf2, 11);
    buf2[11] = 0;
    printf("%s", buf2);
    close(sfd);
    return 0;
}

Page 275

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>

int main(int argc, char **argv)
{
    int sfd = open("/dev/ttyAMA1", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    cfmakeraw(&options);
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 0;
    options.c_cc[VMIN] = 1;
    tcsetattr(sfd, TCSANOW, &options);
    char buf[] = "hello world";
    char buf2[11];
    int count = write(sfd, buf, 11);
    count = read(sfd, buf2, 11);
    buf2[11] = 0;
    printf("%s", buf2);
    close(sfd);
    return 0;
}
 

Page 276

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>

int main(int argc, char **argv)
{
    system("sudo systemctl stop serial-getty@serial0 .service");
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    cfmakeraw(&options);
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 1;
    options.c_cc[VMIN] = 100;
    tcsetattr(sfd, TCSANOW, &options);
    char buf[] = "hello world";
    char buf2[100];
    int count = write(sfd, buf, strlen(buf));
    usleep(100000);
    int bytes;
    ioctl(sfd, FIONREAD, &bytes);
    if (bytes != 0)
    {
        count = read(sfd, buf2, 100);
    }
    printf("%s\n\r", buf2);
    close(sfd);
    return (EXIT_SUCCESS);
}
 

Page 278

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>

int main(int argc, char **argv)
{
    system("sudo systemctl stop serial-getty@serial0 .service");
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };

    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    cfmakeraw(&options);
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 0;
    options.c_cc[VMIN] = 0;
    tcsetattr(sfd, TCSANOW, &options);

    char buf[] = "hello world";
    char buf2[100];
    char c;
    int count = write(sfd, buf, strlen(buf) + 1);

    int i = 0;
    while (1)
    {
        count = read(sfd, &c, 1);
        if (count != 0)
        {
            buf2[i] = c;
            i++;
            if (c == 0)
                break;
        };
    };
    printf("%s\n\r", buf2);
    close(sfd);
    return (EXIT_SUCCESS);
}
 

Page 284

 
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <stdint.h>

int openPort(char port[]);
int presence(int sfd);
void writeBit(int sfd, int b);
uint8_t readBit(int sfd);
void writeByte(int sfd, int byte);
int readByte(int sfd);
int readByte(int sfd);
float getTemperature(int sfd);
int convert(int sfd);

uint8_t crc8(uint8_t *data, uint8_t len);

int main(int argc, char **argv)
{
    int sfd = openPort("/dev/ttyAMA1");
    if (presence(sfd) == 0)
    {
        printf("Device Present\n\r");
    }
    else
    {
        printf("No Device\n\r");
    }
    for (;;)
    {
        float temp = getTemperature(sfd);
        printf("%f \n\r", temp);

        fflush(stdout);
    }
    close(sfd);
    return 0;
}

int openPort(char port[])
{
    int sfd = open(port, O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B115200);
    cfmakeraw(&options);
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_cflag |= PARENB;
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 0;
    options.c_cc[VMIN] = 1;
    tcsetattr(sfd, TCSADRAIN, &options);
    return sfd;
}

int presence(int sfd)
{
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    tcsetattr(sfd, TCSADRAIN, &options);

    char buf = 0xF0;
    int count = write(sfd, &buf, 1);
    count = read(sfd, &buf, 1);

    tcgetattr(sfd, &options);
    cfsetspeed(&options, B115200);
    tcsetattr(sfd, TCSADRAIN, &options);
    if (buf == 0xF0)
        return -1;
    return 0;
}

void writeBit(int sfd, int b)
{
    char buf;
    if (b == 0)
    {
        buf = 0x00;
    }
    else
    {
        buf = 0xFF;
    }
    int count = write(sfd, &buf, 1);
    count = read(sfd, &buf, 1);
}

uint8_t readBit(int sfd)
{
    char buf;
    buf = 0xFF;
    int count = write(sfd, &buf, 1);
    count = read(sfd, &buf, 1);
    if (buf == 0xFF)
        return 1;
    return 0;
}

void writeByte(int sfd, int byte)
{
    for (int i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(sfd, 1);
        }
        else
        {
            writeBit(sfd, 0);
        }
        byte = byte >> 1;
    }
}

int readByte(int sfd)
{
    int byte = 0;
    for (int i = 0; i < 8; i++)
    {
        byte = byte | readBit(sfd) << i;
    };
    return byte;
}

int convert(int sfd)
{
    int i;
    writeByte(sfd, 0x44);
    for (i = 0; i < 5000; i++)
    {
        usleep(100000);
        if (readBit(sfd) != 0)
            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(int sfd)
{
    if (presence(sfd) == -1)
        return -1000;
    writeByte(sfd, 0xCC);
    if (convert(sfd) == 5000)
        return -3000;

    presence(sfd);
    writeByte(sfd, 0xCC);
    writeByte(sfd, 0xBE);

    uint8_t data[9];
    for (int i = 0; i < 9; i++)
    {
        data[i] = readByte(sfd);
    }

    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;
}
 

Page 299

 
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
    {
        return 1;
    }
    if (!bcm2835_spi_begin())
    {
        return 1;
    }

    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536);
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
    uint8_t read_data = bcm2835_spi_transfer(0xAA);
    if (read_data == 0xAA)
    {
        printf("data received correctly");
    }
    else
    {
        printf("data error");
    };
    bcm2835_spi_end();
    bcm2835_close();
    return (EXIT_SUCCESS);
}
 

 Page 308

 
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
    {
        return 1;
    }
    if (!bcm2835_spi_begin())
    {
        return 1;
    }
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_8192);
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);

    char buf[] = {0x01, 0x80, 0x00};
    char readBuf[3];
    bcm2835_spi_transfernb(buf, readBuf, 3);
    int data = ((int)readBuf[1] & 0x03) << 8 | (int)readBuf[2];
    float volts = (float)data * 3.3f / 1023.0f;

    printf("%f", volts);
    bcm2835_spi_end();
    bcm2835_close();
    return (EXIT_SUCCESS);
}

Page 320

#include <stdio.h>
#include <stdlib.h>

#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(80);
    addr.sin_addr.s_addr = 0x22d8b85d;
    if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
        return -1;
    char header[] = "GET /index.html HTTP/1.1\r\nHost:example.org\r\n\r\n";
    int n = write(sockfd, header, strlen(header));
    char buffer[2048];
    n = read(sockfd, buffer, 2048);
    printf("%s", buffer);
    return (EXIT_SUCCESS);
}
 

Page 322

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netdb.h>

int main(int argc, char **argv)
{
    struct addrinfo hints;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    struct addrinfo *servinfo;
    int status = getaddrinfo("www.example.com", "80", &hints, &servinfo);
    int sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
    connect(sockfd, servinfo->ai_addr, servinfo->ai_addrlen);
    char header[] = "GET /index.html HTTP/1.1\r\nHost:example.org\r\n\r\n";
    int n = write(sockfd, header, strlen(header));
    char buffer[2048];
    n = read(sockfd, buffer, 2048);
    printf("%s", buffer);
    return (EXIT_SUCCESS);
}
 

Page 327

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <time.h>

int main(int argc, char **argv)
{
    struct addrinfo hints, *server;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    getaddrinfo(NULL, "80", &hints, &server);
    int sockfd = socket(server->ai_family, server->ai_socktype | SOCK_NONBLOCK, server->ai_protocol);
    bind(sockfd, server->ai_addr, server->ai_addrlen);
    listen(sockfd, 10);

    char buffer[2048];
    char html[] = "<html><head><title>Temperature</title></head><body><p>{\"humidity\":81%, \"airtemperature\":23.5C}</p></body></html>\r\n";

    char headers[1024] = {0};

    char Status[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nServer:CPi\r\n";

    char Date[100];
    time_t now = time(NULL);
    struct tm *t = gmtime(&now);
    strftime(Date, sizeof(Date), "Date: %a, %d %b %Y %k:%M:%S %Z\r\n", t);

    char ContLen[100] = {0};
    snprintf(ContLen, sizeof ContLen, "Content-Length:%d \r\n", strlen(html));

    snprintf(headers, sizeof headers, "%s%s%s\r\n", Status, Date, ContLen);

    char data[2048] = {0};
    snprintf(data, sizeof data, "%s%s", headers, html);

    for (;;)
    {
        struct sockaddr_storage client_addr;
        socklen_t addr_size = sizeof client_addr;

        int client_fd = accept(sockfd, (struct sockaddr *)&client_addr, &addr_size);
        if (client_fd > 0)
        {
            int n = read(client_fd, buffer, 2048);
            printf("%s", buffer);
            fflush(stdout);
            n = write(client_fd, data, strlen(data));
            close(client_fd);
        }
    }
    return (EXIT_SUCCESS);
}
 

Page 346

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    uint32_t *map = (uint32_t *)mmap(
        NULL,
        4 * 1024,
        (PROT_READ | PROT_WRITE),
        MAP_SHARED,
        memfd,
        (off_t)bcm2835_peripherals_base + BCM2835_GPIO_BASE);
    if (map == MAP_FAILED)
        printf("mmap failed: %s\n", strerror(errno));
    close(memfd);
    volatile uint32_t *paddr = map;
    *paddr = 0x1000;
    volatile uint32_t *paddr1 = map + 0x1C / 4;
    volatile uint32_t *paddr2 = map + 0x28 / 4;
    for (;;)
    {
        *paddr1 = 0x10;
        *paddr2 = 0x10;
    };
    return (EXIT_SUCCESS);
}
 

Page 351

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    uint32_t *gpioBASE = bcm2835_regbase(BCM2835_REGBASE_GPIO);
    bcm2835_peri_write(gpioBASE, 0x1000);
    for (;;)
    {
        bcm2835_peri_write(gpioBASE + BCM2835_GPSET0 / 4, 0x10);
        bcm2835_peri_write(gpioBASE + BCM2835_GPCLR0 / 4, 0x10);
    }
    return 0;
}
 

Page 365

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

#define CLK_GP0_CTL 28
#define CLK_GP0_DIV 29
void bcm2835_GPIO4_set_clock_source(uint32_t, uint32_t, uint32_t);

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(4, BCM2835_GPIO_FSEL_ALT0);
    bcm2835_GPIO4_set_clock_source(6, 50, 0);
}

void bcm2835_GPIO4_set_clock_source(
    uint32_t source,
    uint32_t divisorI,
    uint32_t divisorF)
{
    divisorI &= 0xfff;
    divisorF &= 0xfff;
    source &= 0xf;

    uint8_t mask = bcm2835_peri_read(bcm2835_clk + CLK_GP0_CTL) & 0xffffffef;

    bcm2835_peri_write(bcm2835_clk + CLK_GP0_CTL, BCM2835_PWM_PASSWRD | mask);

    while ((bcm2835_peri_read(bcm2835_clk + CLK_GP0_CTL) & 0x80) != 0)
    {
    };

    bcm2835_peri_write(bcm2835_clk + CLK_GP0_DIV, BCM2835_PWM_PASSWRD | (divisorI << 12) | divisorF);
    bcm2835_peri_write(bcm2835_clk + CLK_GP0_CTL, BCM2835_PWM_PASSWRD | source | 0x200);
    bcm2835_peri_write(bcm2835_clk + CLK_GP0_CTL, BCM2835_PWM_PASSWRD | 0x0210 | source);
}
 

Page 358 

#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>

#define BCM2835_SPI6_BASE 0x204C00
volatile uint32_t *bcm2835_spiOLD;

int bcm2835_spi6_begin(void)
{
    volatile uint32_t *paddr;
    bcm2835_spiOLD = bcm2835_spi0;
    bcm2835_spi0 = bcm2835_peripherals + BCM2835_SPI6_BASE / 4;

    bcm2835_gpio_fsel(27, BCM2835_GPIO_FSEL_ALT3); /* CE1 */
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT3); /* CE0 */
    bcm2835_gpio_fsel(19, BCM2835_GPIO_FSEL_ALT3); /* MISO */
    bcm2835_gpio_fsel(20, BCM2835_GPIO_FSEL_ALT3); /* MOSI */
    bcm2835_gpio_fsel(21, BCM2835_GPIO_FSEL_ALT3); /* CLK */

    paddr = bcm2835_spi0 + BCM2835_SPI0_CS / 4;
    bcm2835_peri_write(paddr, 0); /* All 0s */

    bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR);
    return 1;
}

void bcm2835_spi6_end(void)
{
    bcm2835_spi0 = bcm2835_spiOLD;
    /* Set all the SPI0 pins back to input */
    bcm2835_gpio_fsel(27, BCM2835_GPIO_FSEL_INPT); /* CE1 */
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_INPT); /* CE0 */
    bcm2835_gpio_fsel(19, BCM2835_GPIO_FSEL_INPT); /* MISO */
    bcm2835_gpio_fsel(20, BCM2835_GPIO_FSEL_INPT); /* MOSI */
    bcm2835_gpio_fsel(21, BCM2835_GPIO_FSEL_INPT); /* CLK */
}

int main(int argc, char **argv)
{
    if (!bcm2835_init())
    {
        return 1;
    }

    if (!bcm2835_spi6_begin())
    {
        return 1;
    }

    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_8192);
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);

    char buf[] = {0x01, 0x80, 0x00};
    char readBuf[3];
    bcm2835_spi_transfernb(buf, readBuf, 3);
    int data = ((int)readBuf[1] & 0x03) << 8 | (int)readBuf[2];
    float volts = (float)data * 3.3f / 1023.0f;

    printf("%f \n \r", volts);
    bcm2835_spi6_end();
    bcm2835_close();
    return (EXIT_SUCCESS);
}
 

Page 370

 
#include <bcm2835.h>
#include <stdio.h>
#include <sched.h>
int main(int argc, char **argv)
{
    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    while (1)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}

Page  375

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <linux/sched.h>
#include <pthread.h>
#include <stdint.h>

struct sched_attr
{
    uint32_t size;
    uint32_t sched_policy;
    uint64_t sched_flags;
    int32_t sched_nice;
    uint32_t sched_priority;
    uint64_t sched_runtime;
    uint64_t sched_deadline;
    uint64_t sched_period;
};

int sched_setattr(pid_t pid, const struct sched_attr *attr,
                  unsigned int flags)
{
    return syscall(__NR_sched_setattr, pid, attr, flags);
}

void *threadA(void *p)
{
    struct sched_attr attr = {
        .size = sizeof(attr),
        .sched_policy = SCHED_DEADLINE,
        .sched_runtime = 10 * 1000 * 1000,
        .sched_period = 2 * 1000 * 1000 * 1000,
        .sched_deadline = 11 * 1000 * 1000};
    sched_setattr(0, &attr, 0);
    for (;;)
    {
        printf("sensor\n");
        fflush(0);
        sched_yield();
    };
}

int main(int argc, char **argv)
{
    pthread_t pthreadA;
    pthread_create(&pthreadA, NULL, threadA, NULL);
    pthread_exit(0);
    return (EXIT_SUCCESS);
}
 

Page 379

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>

#include <pthread.h>
#include <sched.h>
#include <unistd.h>

volatile int j;
volatile int i;

void *threadA(void *p)
{
    for (i = 0;; i++)
    {
    };
}

void *threadB(void *p)
{
    for (j = 0;; j++)
    {
    };
}

int main(int argc, char **argv)
{
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(1, &cpuset);

    pthread_t pthreadA;
    pthread_create(&pthreadA, NULL, threadA, NULL);
    pthread_setaffinity_np(pthreadA, sizeof(cpu_set_t), &cpuset);

    CPU_ZERO(&cpuset);
    CPU_SET(2, &cpuset);
    pthread_t pthreadB;
    pthread_create(&pthreadB, NULL, threadB, NULL);
    pthread_setaffinity_np(pthreadB, sizeof(cpu_set_t), &cpuset);

    sleep(5);

    printf("%d %d", i, j);
    return (EXIT_SUCCESS);
}
 

 Page 382

 
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <unistd.h>
#include <bcm2835.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(3, &cpuset);
    int res = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset);

    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    while (1)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}
 

Page 386

#include <stdio.h>
#include <string.h>
 int main(int argc, char** argv) {
    int gpio = 4;
    FILE* fd = fopen("/sys/class/gpio/export", "w");
    fprintf(fd, "%d", gpio);
    fclose(fd);
    return 0;
}
 

Page 387


#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
    int gpio = 4;
    char buf[100];

    FILE *fd = fopen("/sys/class/gpio/export", "w");
    fprintf(fd, "%d", gpio);
    fclose(fd);

    sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
    fd = fopen(buf, "w");
    fprintf(fd, "out");
    fclose(fd);

    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    fd = fopen(buf, "w");

    for (;;)
    {
        fd = fopen(buf, "w");
        fprintf(fd, "1");
        fclose(fd);
        fd = fopen(buf, "w");
        fprintf(fd, "0");
        fclose(fd);
    }
    return 0;
}
 

Appendix II

All files have to be stored in the .vscode folder

settings,json

 
{
    "sshUser": "root",
    "sshEndpoint": "192.168.11.151",
    "remoteDirectory": "/home/pi/Documents/${workspaceFolderBasename}",
    "std": "c99",
    "libs":"-lbcm2835",
    "header":"/usr/local/include/bcm2835.h"
}
 

launch.json

 
{
    "configurations": [
     
        {
            "name": "Remote C Debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${config:remoteDirectory}/${relativeFileDirname}",
            "environment": [],
            "externalConsole": false,
            "pipeTransport": {
                "debuggerPath": "/usr/bin/gdb",
                "pipeProgram": "C:/Windows/System32/OpenSSH/ssh",
                "pipeArgs": [
                    "${config:sshUser}@${config:sshEndpoint}"
                ],
                "pipeCwd": "${workspaceFolder}"
            },
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "sourceFileMap": {
                "${config:remoteDirectory}/${relativeFileDirname}": "${fileDirname}"
            },
            "preLaunchTask": "CopyBuildRemote",
        }
    ]
}
 

c_cpp_properties.json

 
{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "C:/MinGW/include"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "cStandard":"c99",
            "intelliSenseMode":"gcc-arm" 
                }
    ],
    "version": 4
}
 
 

tasks.json

 
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "copyToRemote",
            "type": "shell",
            "command": "scp -r ${fileDirname} ${config:sshUser}@${config:sshEndpoint}:${config:remoteDirectory}/",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
                "clear": true
            }
        },
        {
            "label": "copyHeader",
            "type": "shell",
            "command": "mkdir ${workspaceFolder}/headers/ ;scp -r  ${config:sshUser}@${config:sshEndpoint}:${config:header} ${workspaceFolder}/headers/ ",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
                "clear": true
            }
        },
        {
            "label": "buildRemote",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} 'gcc  -g -std=${config:std} ${config:remoteDirectory}/${relativeFileDirname}/${fileBasename} ${config:libs}  -o${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}.exe'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
                "clear": false
            }
        },
        {
            "label": "runRemote",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} '${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}.exe'",
            "problemMatcher": [
                "$gcc"
            ],
            "presentation": {
                "showReuseMessage": true,
                "clear": false
            }
        },
        {
            "label": "CopyBuildRunRemote",
            "dependsOrder": "sequence",
            "dependsOn": [
                "copyToRemote",
                "buildRemote",
                "runRemote"
            ],
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "CopyBuildRemote",
            "dependsOrder": "sequence",
            "dependsOn": [
                "copyToRemote",
                "buildRemote",
            ],
            "problemMatcher": [],
        },
        {
            "label": "StopREmoteC",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} ;'pkill ${fileBasenameNoExtension}.exe'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": true,
            }
        },
        {
            "label": "copyARMheaders",
            "type": "shell",
            "command": "mkdir ${workspaceFolder}/include/;scp -r  ${config:sshUser}@${config:sshEndpoint}:/usr/include ${workspaceFolder}/include/ ",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": true,
                "clear": true
            }
        },
    ],
}
"presentation": {
"showReuseMessage": true,
}
},
{
"label": "copyARMheaders",
"type": "shell",
"command": "mkdir ${workspaceFolder}/include/;scp -r  ${config:sshUser}@${config:sshEndpoint}:/usr/include ${workspaceFolder}/include/ ",
"problemMatcher": [],
"presentation": {
"showReuseMessage": true,
"clear": true
}
},
],
}
 
 
 
 

 

IOT Raspberry Pi Programs

pyIoT360cover

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. 

 

Note: The VS Code task listings are at the very end of this page.

The only downside is that you have to create a project to paste the code into.

To do this follow the instructionin the book- in particular remember to add the bcm2835 library and also any library references that may be needed. 

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:

This email address is being protected from spambots. You need JavaScript enabled to view it. 

Page 29

from gpiozero import LED
from time import sleep

led = LED(4)

while True:
    led.on()
    sleep(1)
    led.off()
    sleep(1)
 

Page 54

from gpiozero import LED
from signal import pause

led = LED(4)
led.blink(on_time=1,off_time=1,n=100)
print("Program Complete")
pause()

Page 55

from gpiozero import LED
from time import sleep

led = LED(4)

while True:
    led.toggle()
    sleep(1)
    led.toggle()
    sleep(1)
 

Page 57

from gpiozero import Buzzer
from signal import pause

buzz = Buzzer(4)
buzz.beep(on_time=1,off_time=1,n=100)
print("Program Complete")
pause()
 

Page 58

from gpiozero import DigitalOutputDevice
class Lock(DigitalOutputDevice):
  def __init__(self,*args,**kwargs):
      if 'active_high' in kwargs:
          raise TypeError("active_high not supported")
      super().__init__(*args,**kwargs)            
  def lock(self):
      super().on()
  def unlock(self):
      super().off()
  def on(self):
      raise AttributeError("'Lock' object has no attribute 'on'")
  def off(self):
      raise AttributeError("'Lock' object has no attribute 'off'")
  def blink(self):
      raise AttributeError("'Lock' object has no attribute 'blink'")
 

Page 59

from gpiozero import LED
led1 = LED(4)
led2 = LED(17)
while True:
    led1.on()
    led2.on()
    led1.off()
    led2.off()
  

Page 65

from gpiozero import Device
from time import sleep
Device()
pin=Device.pin_factory.pin(4)
pin._set_function('output')
while True:
    pin.state=1
    sleep(1)
    pin.state=0
    sleep(1) 

Page 92

from gpiozero import Button
from signal import pause
button = Button(4, bounce_time=0.25)


def pressed():
    print(“Button pressed”)


def released():
    print(“Button released”)


button.when_pressed = pressed
button.when_released = released
pause()

Page 95

from gpiozero import Button
from gpiozero import LED
from time import sleep

button = Button(4)
led1 = LED(17, initial_value=True)
led2 = LED(27)
led3 = LED(22)

state = 0
buttonState = button.value
while True:
    buttonNow = button.value
    buttonDelta = buttonNow-buttonState
    buttonState = buttonNow
    if state == 0:
        if buttonDelta == 1:
            state = 1
            led1.off()
            led2.on()
            led3.off()

        continue
    if state == 1:
        if buttonDelta == 1:
            state = 2
            led1.off()
            led2.on()
            led3.off()
        continue
    if state == 2:
        if buttonDelta == 1:
            state = 0
            led1.on()
            led2.off()
            led3.off()
        continue
    sleep(0.1)

 

Page 96

 

from gpiozero import Button
from time import perf_counter_ns

button = Button(4)
while True:
    button.wait_for_press()
button.wait_for_release()
t1 = perf_counter_ns()
button.wait_for_press()
t2 = perf_counter_ns()
print((t2-t1)/1000000)

 

 

Page 97

 
from gpiozero import Button
from time import perf_counter_ns
button = Button(4)
while True:
    while not button.value:
        pass
    while button.value:
        pass
    t1 = perf_counter_ns()
    while not button.value:
        pass
    t2 = perf_counter_ns()
    print((t2-t1)/1000000)
 

Page 97

from gpiozero import DigitalInputDevice
from time import perf_counter_ns
pulse = DigitalInputDevice(4)
while True:
    while not pulse.value:
        pass
    while pulse.value:
        pass
    t1 = perf_counter_ns()
    while not pulse.value:
        pass
    t2 = perf_counter_ns()
    print((t2-t1)/1000000)
 

Page 98

 
from gpiozero import Device
from time import perf_counter_ns

Device()
pulse = Device.pin_factory.pin(4)
pulse.input_with_pull("up")
while True:
    while not pulse.state:
        pass
    while pulse.state:
        pass
    t1 = perf_counter_ns()
    while not pulse.state:
        pass
    t2 = perf_counter_ns()
    print((t2-t1)/1000000)
 

Page 98/99

from gpiozero import DigitalInputDevice


class Door(DigitalInputDevice):
    def __init__(self, pin=None, pull_up=True, active_state=None,
                 bounce_time=None, pin_factory=None):
        super(Door, self).__init__(
            pin, pull_up=pull_up, active_state=active_state,
            bounce_time=bounce_time, pin_factory=pin_factory)

    @property
    def value(self):
        return super(Door, self).value


Door.is_closed = Door.is_active
Door.when_open = Door.when_deactivated
Door.when_closed = Door.when_activated
Door.wait_for_open = Door.wait_for_inactive
Door.wait_for_close = Door.wait_for_active
 

Page 110

 
from gpiozero import LightSensor


class Moisture(LightSensor):
    def __init__(self, pin=None, queue_len=5, charge_time_limit=0.01, threshold=0.1, partial=False, pin_factory=None):
        super(Moisture, self).__init__(pin, threshold=threshold, queue_len=queue_len,
                                       charge_time_limit=charge_time_limit, pin_factory=pin_factory)


Moisture.wait_for_dry = Moisture.wait_for_light
Moisture.wait_for_wet = Moisture.wait_for_dark
Moisture.when_dry = Moisture.when_light
Moisture.when_wet = Moisture.when_dark

Page 114

from gpiozero import PWMLED, DistanceSensor
from gpiozero.tools import inverted
from signal import pause
led = PWMLED(4)
dist = DistanceSensor(5, 6)
led.source = inverted(dist)
pause

Page 115

 
from gpiozero import PWMLED, DistanceSensor
from gpiozero.tools import inverted, averaged
from signal import pause

led = PWMLED(4)
front = DistanceSensor(5, 6)
back = DistanceSensor(7, 8)
led.source = averaged(front, back)
pause

Page 116

from signal import pause
from gpiozero import PWMLED, DistanceSensor
from gpiozero.tools import _normalize


def mined(*values):
    values = [_normalize(v) for v in values]
    for v in zip(*values):
        yield min(v)


led = PWMLED(4)
front = DistanceSensor(5, 6)
back = DistanceSensor(7, 8)
led.source = mined(front, back)
pause

Page 117

def PWM_values(period=360, duty=0.5):
    _ontime = int(period*duty)
    _offtime = period-_ontime
    data = [1]*_ontime+[0]*_offtime
    while True:
        for i in range(_ontime):
            print(1)
            yield 1
        for i in range(_offtime):
            print(0)
            yield 0

Page 119

import io
from gpiozero import InternalDevice


class MemoryFree(InternalDevice):
    def __init__(self, threshold=0.9, memfile='/proc/meminfo',
                 pin_factory=None):
        super(MemoryFree, self).__init__(pin_factory=pin_factory)
        self._fire_events(self.pin_factory.ticks(), None)
        self.memfile = memfile
        self.threshold = threshold
        self._totalmem = 0
        self._availablemem = 0

    @property
    def free_mem(self):
        with io.open(self.memfile, 'r') as f:
            self._totalmem = int(f.readline().strip().split()[1])
            freemem = int(f.readline().strip().split()[1])
            self._availablemem =
            int(f.readline().strip().split()[1])
            return freemem

    @property
    def value(self):
        return self.free_mem/self._availablemem

    @property
    def is_active(self):
        return self.value < 1-self.threshold

Page 126

from gpiozero import PWMOutputDevice
from signal import pause
pwm = PWMOutputDevice(4)
pwm.frequency = 10000
pwm.value = 0.5
pause()

Page 129

from gpiozero import PWMOutputDevice
pwm = PWMOutputDevice(4)
pwm.frequency = 1000
while True:
    pwm.value = 0.1
    pwm.value = 0.9

Page 129

from gpiozero import PWMOutputDevice
from time import sleep
pwm = PWMOutputDevice(4)
pwm.frequency = 1000
pwm.value = 0.1
while True:
    sleep(0.5)
    pwm.toggle()

Page 131

from gpiozero import PWMOutputDevice
from time import sleep

pwm = PWMOutputDevice(4)
pwm.frequency = 1000
steps = 8
delay = 0.01
while True:
    for d in range(steps):
        pwm.value = d/steps
    sleep(delay)

for d in range(steps):
    pwm.value = (steps-d)/steps
    sleep(delay)

Page 138

from gpiozero import PWMOutputDevice
from time import sleep

pwm = PWMOutputDevice(4)
pwm.frequency = 1000
steps = 8
delay = 0.001
while True:
    for d in range(steps):
        pwm.value = d/steps
        sleep(delay)

    for d in range(steps):
        pwm.value = (steps-d)/steps
        sleep(delay)

Page 145

class uniMotor(PWMOutputDevice):
    def __init__(self, pin=None, active_high=True, initial_value=0, pin_factory=None):
        super(uniMotor, self).__init__(pin, active_high,
                                       initial_value, pin_factory=pin_factory)

    def speed(self, value):
        self._write(value)


motor = uniMotor(4)
motor.speed(0.5)
sleep(10)

Page 154

from gpiozero import Servo
from time import sleep

servo = Servo(4)

while True:
    servo.min()
    sleep(0.5)
    servo.mid()
    sleep(0.5)
    servo.max()
    sleep(0.5)

Page 155

from gpiozero import Servo


class ServoInvert(Servo):


@Servo.value.setter
  def value(self, value):
       if value is None:
            self.pwm_device.pin.frequency = None
        elif -1 <= value <= 1:
            self.pwm_device.pin.frequency = int(1 / self.frame_width)
            self.pwm_device.value = (self._min_dc + self._dc_range *((value - self._min_value) / self._value_range))
        else:
            raise OutputDeviceBadValue(
                "Servo value must be between -1 and 1, or None")

Page 164

from gpiozero import DigitalOutputDevice
from time import sleep


class StepperBi4():
    def __init__(self, A=None, Am=None, B=None, Bm=None):
        self.phase = 0
        self.gpios = tuple(DigitalOutputDevice(pin) for pin in (A, B, Am, Bm))
        self.halfstepSeq = [
            [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]
        ]

    def setPhase(self, phase):
        self.phase = phase
        for gpio, state in zip(self.gpios, self.halfstepSeq[phase]):
            gpio.value = state

    def stepForward(self):
        self.phase = (self.phase+1) % 8
        self.setPhase(self.phase)

    def stepReverse(self):
        self.phase = (self.phase-1) % 8
        self.setPhase(self.phase)


step = StepperBi4(4, 17, 27, 22)
step.setPhase(0)
while True:
    sleep(0.001)
    step.stepForward()

Page 170

from gpiozero import LED
from time import sleep


class TriLED():
    def __init__(self, pin1=None, pin2=None, pin3=None):
        self.LEDs = (LED(pin1), LED(pin2), LED(pin3))

    def AllOn(self):
        self.LEDs[0].on()
        self.LEDs[1].on()
        self.LEDs[2].on()

    def AllOff(self):
        self.LEDs[0].off()
        self.LEDs[1].off()
        self.LEDs[2].off()

Page 171

 class TriLED(CompositeDevice):
       def __init__(self, pin1=None, pin2=None, pin3=None):
            super(TriLED, self).__init__(LED(pin1), LED(pin2), LED(pin3))

        def AllOn(self):
            self[0].on()
            self[1].on()
            self[2].on()

        def AllOff(self):
            self[0].off()
            self[1].off()
            self[2].off()

Page 183

from gpiozero import DigitalOutputDevice, CompositeDevice


class StepperBi4(CompositeDevice):
    def __init__(self, A=None, Am=None, B=None, Bm=None):
        if not all(p is not None for p in [A, Am, B, Bm]):
            raise GPIOPinMissing(
                'Four GPIO pins must be provided'
            )
        super(StepperUni4, self).__init__(DigitalOutputDevice(A), DigitalOutputDevice(
            B), DigitalOutputDevice(Am), DigitalOutputDevice(Bm))
        self.phase = 0
        self.halfstepSeq = [
            [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]
        ]

    def setPhase(self, phase):
        self.phase = phase
        for gpio, state in zip(self, self.halfstepSeq[phase]):
            gpio.pin._set_state(state)

    def stepForward(self):
        self.phase = (self.phase+1) % 8
        self.setPhase(self.phase)

    def stepReverse(self):
        self.phase = (self.phase-1) % 8
        self.setPhase(self.phase)

Page 186

from gpiozero import DigitalOutputDevice, CompositeDevice
from time import sleep
from gpiozero.threads import GPIOThread


class StepperBi4(CompositeDevice):
    def __init__(self, A=None, Am=None, B=None, Bm=None):
        if not all(p is not None for p in [A, Am, B, Bm]):
            raise GPIOPinMissing('Four GPIO pins must be provided')
        super(StepperUni4, self).__init__(DigitalOutputDevice(A), DigitalOutputDevice(
            B), DigitalOutputDevice(Am), DigitalOutputDevice(Bm))
        self.phase = 0
        self._rotate_thread = None
        self.halfstepSeq = [
            [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]
        ]

    def setPhase(self, phase):
        self.phase = phase
        for gpio, state in zip(self, self.halfstepSeq[phase]):
            gpio.pin._set_state(state)

    def stepForward(self):
        self.phase = (self.phase+1) % 8
        self.setPhase(self.phase)

    def stepReverse(self):
        self.phase = (self.phase-1) % 8
        self.setPhase(self.phase)

    def forward(self, speed=0):
        self._stop_rotate()
        if speed == 0:
            return
        self._rotate_thread = GPIOThread(
            target=self._rotate, args=(+1, speed))
        self._rotate_thread.start()

    def reverse(self, speed=1):
        self._stop_rotate()
        if speed == 0:
            return
        self._rotate_thread = GPIOThread(
            target=self._rotate,   args=(-1, speed))
        self._rotate_thread.start()

    def _rotate(self, dir, speed):
        delay = 60/(speed*400)-0.001
        while True:
            if dir == 1:
                self.stepForward()
            if dir == -1:
                self.stepReverse()
            if self._rotate_thread.stopping.wait(delay):
                break

    def _stop_rotate(self):
        if getattr(self, '_rotate_thread', None):
            self._rotate_thread.stop()
        self._rotate_thread = None
 
Page 186
 
import subprocess
temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
output = str(temp.communicate())
print(output)
lastSPI = output.rfind("spi")
if lastSPI != -1:
    lastSPI = output.find("spi=on", lastSPI)
    if lastSPI == -1:
        temp = subprocess.Popen(
            ["sudo", "dtparam", "spi=on"], stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print("adding", output)
else:
    temp = subprocess.Popen(
        ["sudo", "dtparam", "spi=on"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print("adding", output)
 
 Page 190
 
import subprocess
temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
output = str(temp.communicate())
print(output)
lastSPI = output.rfind("spi")
if lastSPI != -1:
    lastSPI = output.find("spi=on", lastSPI)
    if lastSPI == -1:
        temp = subprocess.Popen(
            ["sudo", "dtparam", "spi=on"], stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print("adding", output)
else:
    temp = subprocess.Popen(
        ["sudo", "dtparam", "spi=on"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print("adding", output)
 Page 207
from gpiozero import SPIDevice
Dev = SPIDevice()
Dev.clock_mode = 0
Dev.select_high = False
Dev._spi._interface.max_speed_hz = 60000

words = Dev._spi.transfer([0x01, 0x80, 0x00])
data = (words[1] & 0x03) << 8 | words[2]
volts = data * 3.3 / 1023.0
print(volts)
Dev.close()
 Page 212
class DS3234rtc(SPIDevice):
    def __init__(self):
        super(DS3234rtc, self).__init__()
        self.clock_mode = 1
        self.select_high = False
        self._spi._interface.max_speed_hz = 5000000

    def setDateTime(self, dateTime):
        datetimetuple = dateTime.timetuple()
        datetimetuple = (datetimetuple[0]-2000,)+datetimetuple[1:3] + \
            (dateTime.isoweekday(),)+datetimetuple[3:6]
        datetimetuple = datetimetuple[::-1]
        for i in range(0, 7):
            data = datetimetuple[i]
            data = (data//10) << 4 | (data % 10)
            words = self._spi.transfer([0x80+i, data])

    def getDateTime(self):
        datetimelist = []
        for i in range(7):
            words = self._spi.transfer([i, 0x00])
            if i == 3:
                continue
            byte = words[1]
            data = (byte & 0x0F)+(byte >> 4)*10
            datetimelist.insert(0, data)
        datetimelist[0] += 2000
        return datetime(*datetimelist)
 Page 227 Appendix

settings.json

{
    "sshUser": "pi",
    "sshEndpoint": "192.168.11.170",
    "remoteDirectory": "/home/pi/Documents/${workspaceFolderBasename}", 
 
}

tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "copyToRemote",
            "type": "shell",
            "command": "scp -r ${fileDirname} ${config:sshUser}@${config:sshEndpoint}:${config:remoteDirectory}/",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
                "clear": true
            }
        },
        {
            "label": "makeRemoteWorkSpace",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} ;'mkdir  ${config:remoteDirectory}'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "RunR",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} ;'python3 ${config:remoteDirectory}/${relativeFileDirname}/${fileBasename}'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "RunRemote",
            "dependsOrder": "sequence",
            "dependsOn": [
                "copyToRemote",
                "RunR"
            ],
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            },
        },
        
        {
            "label": "StopRemotePython",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} ;'pkill python3'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": true,
            }
        },
        {
            "label": "wait",
            "type": "shell",
            "command": "timeout 10"
        },
        {
            "label": "tunnel",
            "type": "shell",
            "command": "ssh -2 -L 5678:localhost:5678 ${config:sshUser}@${config:sshEndpoint}",
            "problemMatcher": [],
            "presentation": {                
                "showReuseMessage": false,             
            }
        },
        {
            "label": "startDebug",
            "type": "shell",
            "command": "ssh -2 ${config:sshUser}@${config:sshEndpoint} ; 'nohup python3 -m debugpy --listen 0.0.0.0:5678 --wait-for-client ${config:remoteDirectory}/${relativeFileDirname}/${fileBasename} > /dev/null 2>&1 &'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "copyAndDebug",
            "dependsOrder": "sequence",
            "dependsOn": [
                "copyToRemote", 
                "startDebug",
                "wait"
            ],
            "presentation": {               
                "showReuseMessage": false,                
            },
        },
    ]
}
 
 
 
 

Micro:bit IoT In C Second Edition

microbite2360

 

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:

This email address is being protected from spambots. You need JavaScript enabled to view it. 

Page 29

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.display.setDisplayMode(DISPLAY_MODE_GREYSCALE);
    for (;;)
    {
        uBit.display.image.setPixelValue(2, 2, 255);
        uBit.sleep(1000);
        uBit.display.image.setPixelValue(2, 2, 0);
        uBit.sleep(1000);
    }
}

 

Page 38 

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.io.P0.setDigitalValue(1);
}

#include "MicroBit.h"
    int main()
{
    MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0,
                   PIN_CAPABILITY_ALL);
    P0.setDigitalValue(1);
}

Page 44

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    while (1)
    {
        uBit.io.P0.setDigitalValue(1);
        uBit.io.P0.setDigitalValue(0);
    }
}

Page 45

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    while (1)
    {
        uBit.io.P0.setDigitalValue(1);
        uBit.sleep(9);
        uBit.io.P0.setDigitalValue(0);
        uBit.sleep(9);
    }
}

Page 46

MicroBit uBit;
int main()
{
    uBit.init();
    while (1)
    {
        uBit.io.P0.setDigitalValue(1);
        wait_us(20);
        uBit.io.P0.setDigitalValue(0);
        wait_us(20);
    }
}

Page 46

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    int i;
    int n = 57;
    while (1)
    {
        for (i = 0; i < n; i++)
        {
        };
        uBit.io.P0.setDigitalValue(1);
        for (i = 0; i < n; i++)
        {
        };
        uBit.io.P0.setDigitalValue(0);
    }
}

Page 47

#include "MicroBit.h"

MicroBit uBit;
int main()
{
    int i;
    uBit.init();
    while (1)
    {
        uBit.io.P0.setDigitalValue(1);
        uBit.io.P1.setDigitalValue(0);
        uBit.io.P0.setDigitalValue(0);
        uBit.io.P1.setDigitalValue(1);
    }
}

Page 49

#include "MicroBit.h"

MicroBit uBit;
int main()
{
    int i;
    uBit.init();
    while (1)
    {
        for (i = 0; i < 100; i++)
        {
        };
        uBit.io.P0.setDigitalValue(1);
        uBit.io.P1.setDigitalValue(0);
        for (i = 0; i < 100; i++)
        {
        };
        uBit.io.P0.setDigitalValue(0);
        uBit.io.P1.setDigitalValue(1);
    }
}

Page 52

#include "MicroBit.h"

MicroBit uBit;
int main()
{
    int i;
    uBit.init();
    while (1)
    {
        while (1 == uBit.io.P0.getDigitalValue())
            ;
        while (0 == uBit.io.P0.getDigitalValue())
            ;
        for (i = 0; i < 1000; i++)
        {
            if (0 == uBit.io.P0.getDigitalValue())
                break;
        }
        uBit.serial.printf("%d\n\r", i);
    }
}

Page 54

#include "MicroBit.h"

MicroBit uBit;
int main()
{
    uBit.init();
    uint64_t t;

    volatile int i;

    while (1)
    {
        while (1 == uBit.io.P0.getDigitalValue())
            ;
        while (0 == uBit.io.P0.getDigitalValue())
            ;
        t = system_timer_current_time_us();
        for (i = 0; i < 1000; i++)
        {
            if (0 == uBit.io.P0.getDigitalValue())
                break;
        }
        t = system_timer_current_time_us() - t;

        uBit.serial.printf("%d,%d\n\r", i, (int)t);
    }
}

Page 56

#include "MicroBit.h"
MicroBit uBit;
uint64_t t[20];
uint64_t temp = 0;
int i = 0;
void onPulseEdge(MicroBitEvent evt)
{
    t[i] = (evt.timestamp - temp);
    i++;
    temp = evt.timestamp;
    if (i < 20)
        return;
    uBit.io.P0.eventOn(MICROBIT_PIN_EVENT_NONE);
}

int main()
{
    uBit.init();
    uBit.messageBus.listen(MICROBIT_ID_IO_P0,
                           MICROBIT_PIN_EVT_RISE,
                           onPulseEdge,
                           MESSAGE_BUS_LISTENER_IMMEDIATE);
    uBit.messageBus.listen(MICROBIT_ID_IO_P0,
                           MICROBIT_PIN_EVT_FALL,
                           onPulseEdge,
                           MESSAGE_BUS_LISTENER_IMMEDIATE);
    uBit.io.P0.eventOn(MICROBIT_PIN_EVENT_ON_EDGE);
}
uBit.sleep(1000);
for (i = 1; i < 20; i++)
{
    printf("%d\n\r", (int)t[i]);
}

Page 63

int main()
{
    int GPIO = 3;
    // GPIO=2; //Uncomment for V2
    volatile unsigned int *dirset = (unsigned int *)(0x50000000UL + 0x518);
    volatile unsigned int *outset = (unsigned int *)(0x50000000UL + 0x508);
    volatile unsigned int *outclr = (unsigned int *)(0x50000000UL + 0x50C);

    unsigned int mask = 1 << GPIO;
    *dirset = mask;
    for (;;)
    {
        *outset = mask;
        *outclr = mask;
    }
}

Page 64

int main()
{

    int GPIO = 3;
    //GPIO = 2; // Uncomment for V2
    volatile unsigned int *dirset = (unsigned int *)(0x50000000UL + 0x518);
    volatile unsigned int *outset = (unsigned int *)(0x50000000UL + 0x508);
    volatile unsigned int *outclr = (unsigned int *)(0x50000000UL + 0x50C);
    unsigned int mask = 1 << GPIO;

    *dirset = mask;
    volatile int i;
    int n = 200;
    for (;;)
    {
        for (i = 0; i < n; i++)
        {
        };
        *outset = mask;
        for (i = 0; i < n; i++)
        {
        };
        *outclr = mask;
    }
}

Page 65

int main()
{

    volatile unsigned int *dirset = (unsigned int *)(0x50000000UL + 0x518);
    volatile unsigned int *outset = (unsigned int *)(0x50000000UL + 0x508);
    volatile unsigned int *outclr = (unsigned int *)(0x50000000UL + 0x50C);

    volatile int i;
    int n = 200;
    unsigned int mask = 1 << 2 | 1 << 3;
    *dirset = mask;
    for (;;)
    {
        *outset = mask;
        for (i = 0; i < n; i++)
        {
        };
        *outclr = mask;
        for (i = 0; i < n; i++)
        {
        };
    }
}

Page 66

int main()
{

    volatile unsigned int *dirset = (unsigned int *)(0x50000000UL + 0x518);
    volatile unsigned int *outset = (unsigned int *)(0x50000000UL + 0x508);
    volatile unsigned int *outclr = (unsigned int *)(0x50000000UL + 0x50C);

    volatile int i;
    int n = 200;
    unsigned int mask = 1 << 3 | 1 << 2;
    unsigned int mask1 = 1 << 3;
    unsigned int mask2 = 1 << 2;
    *dirset = mask;
    for (;;)
    {
        *outset = mask1;
        *outclr = mask2;
        for (i = 0; i < n; i++)
        {
        };
        *outclr = mask1;
        *outset = mask2;
        for (i = 0; i < n; i++)
        {
        };
    }
}

Page 67

int main()
{

    volatile unsigned int *dirset = (unsigned int *)(0x50000000UL + 0x518);
    volatile unsigned int *out = (unsigned int *)(0x50000000UL + 0x504);
    volatile int i;
    int n = 200;
    unsigned int mask1 = 1 << 2;
    unsigned int mask2 = 1 << 3;
    *dirset = (1 << 2) | (1 << 3);
    for (;;)
    {
        *out = mask1;
        for (i = 0; i < n; i++)
        {
        };
        *out = mask2;
        for (i = 0; i < n; i++)
        {
        };
    }
}

Page 68

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    int GPIO = 3;
    GPIO = 2; // Uncomment for V2
    volatile unsigned int *in = (unsigned int *)(0x50000000UL + 0x510);
    volatile unsigned int *pinDir =
        (unsigned int *)(0x50000000UL + 0x700 + GPIO * 4);
    unsigned int mask = 1 << GPIO;
    *pinDir = 0x0;
    volatile int i;
    uBit.serial.printf("Ready\n\r");
    while (1)
    {
        while (mask == ((*in) & mask))
        {
        };
        while (mask != ((*in) & mask))
        {
        };
        for (i = 0; i < 5000; i++)
        {
            if (mask != ((*in) & mask))
                break;
        }
        uBit.serial.printf("%d\n\r", i);
    }
    return 0;
}

Page 74

#include "MicroBit.h"

MicroBit uBit;
int main() { 
 uBit.init();
 uBit.io.P0.setAnalogValue(511);
 uBit.io.P0.setAnalogPeriod(1);
 release_fiber();
 return 0;

Page 75

#include "MicroBit.h"
MicroBit uBit;

int main()
{
    uBit.init();
    uBit.io.P0.setAnalogValue(200);
    uBit.io.P1.setAnalogValue(511);
    uBit.io.P2.setAnalogValue(800);

    uBit.io.P0.setAnalogPeriod(1);
    uBit.io.P1.setAnalogPeriod(1);
    uBit.io.P2.setAnalogPeriod(1);

    release_fiber();
    return 0;
}

Page 76

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    volatile int i;
    uBit.init();

    uBit.io.P0.setAnalogValue(200);
    uBit.io.P0.setAnalogPeriodUs(50);

    for (;;)
    {
        for (i = 1; i < 100; i++)
        {
        };
        uBit.io.P0.setAnalogValue(200);
        for (i = 1; i < 100; i++)
        {
        };
        uBit.io.P0.setAnalogValue(800);
    }
}

Page 78

#include "MicroBit.h"

//#define wait_us system_timer_wait_us // uncomment for V2
MicroBit uBit;

int main()
{
    int i;
    uBit.init();
    uBit.io.P0.setAnalogValue(200);
    uBit.io.P0.setAnalogPeriodUs(50);
    for (;;)
    {
        for (i = 0; i < 1024; i = i + 10)
        {
            uBit.io.P0.setAnalogValue(i);
            wait_us(100);
        }
    }
    release_fiber();
    return 0;
}

Page 82

#include "MicroBit.h"
//#define wait_us system_timer_wait_us // uncomment for V2
MicroBit uBit;

int main()
{
    uBit.init();
    uBit.io.P0.setAnalogValue(511);
    uBit.io.P0.setAnalogPeriodUs(1000);
    int w = 1;
    int inc = 1;
    for (;;)
    {
        uBit.io.P0.setAnalogValue(w);
        w = w + inc;
        if (w > 1024 || w <= 0)
            inc = -inc;
        wait_us(5000);
    }
    release_fiber();
    return 0;
}

Page 83

#include "MicroBit.h"
//#define wait_us system_timer_wait_us // uncomment for V2
MicroBit uBit;

int main()
{
    uBit.init();
    uBit.io.P0.setAnalogValue(511);
    uBit.io.P0.setAnalogPeriodUs(1000);

    int w = 0;
    int inc = 1;
    for (;;)
    {
        uBit.io.P0.setAnalogValue(w * w * w);
        w = w + inc;
        if (w > 10 || w <= 0)
            inc = -inc;
        wait_us(50000);
    }
    release_fiber();
    return 0;
}

Page 86

#include "MicroBit.h"

MicroBit uBit;

int main()
{
    uBit.init();
    for (;;)
    {
        uBit.io.P0.setServoValue(0);
        uBit.sleep(1000);
        uBit.io.P0.setServoValue(90);
        uBit.sleep(1000);
        uBit.io.P0.setServoValue(180);
        uBit.sleep(1000);
    }
    release_fiber();
    return 0;
}

Page 87

#include "MicroBit.h"
MicroBit uBit;

int main()
{
    uBit.init();
    uBit.io.P0.setAnalogValue(0);
    uBit.io.P0.setAnalogPeriod(20);
    for (;;)
    {
        uBit.io.P0.setAnalogValue(52 * 0 / 180 + 920);
        uBit.sleep(1000);
        uBit.io.P0.setAnalogValue(52 * 90 / 180 + 920);
        uBit.sleep(1000);
        uBit.io.P0.setAnalogValue(52 * 180 / 180 + 920);
        uBit.sleep(1000);
    }
    release_fiber();
    return 0;
}

Page 90

#include "MicroBit.h"
MicroBit uBit;

int main()
{
    uBit.init();
    for (;;)
    {
        uBit.io.P0.setServoValue(0, 1000);
        uBit.sleep(1000);
        uBit.io.P0.setServoValue(90, 1000);
        uBit.sleep(1000);
        uBit.io.P0.setServoValue(180, 1000);
        uBit.sleep(1000);
    }
    release_fiber();
    return 0;
}

Page 102

#include "MicroBit.h"
MicroBit uBit;

int main()
{
    uBit.init();
    char buf[] = {0x07};
    uBit.i2c.write(0x1C, buf, 1, true);
    uBit.i2c.read(0x1C, buf, 1);
    printf("Id %X\r\n", (int)buf[0]);
    release_fiber();
    return 0;
}

Page 104

#include "MicroBit.h"

#define LSM303_ADDR 0x32
#define LSM303_WHO 0x0F
#define LSM303_VAL 0x33

#define FXOS8700_ADDR 0x3C
#define FXOS8700_WHO 0x0D
#define FXOS8700_VAL 0xC7
MicroBit uBit;

int main()
{
    uBit.init();
    uint8_t data[1];
    int status = 0;

    status = uBit._i2c.readRegister(LSM303_ADDR, LSM303_WHO, data, 1);
    if (data[0] == LSM303_VAL)
        uBit.serial.printf("LSM303 \n\r");

    status = uBit._i2c.readRegister(FXOS8700_ADDR, FXOS8700_WHO, data, 1);
    if (data[0] == FXOS8700_VAL)
        uBit.serial.printf("FXOS8700 \n\r");
    return 0;
}

Page 105

#include "MicroBit.h"

#define LSM303_ADDR 0x32
#define LSM303_WHO 0x0F
#define LSM303_VAL 0x33

#define FXOS8700_ADDR 0x3C
#define FXOS8700_WHO 0x0D
#define FXOS8700_VAL 0xC7
MicroBit uBit;

int main()
{
    uBit.init();
    uint8_t data[2];
    int status = 0;
    uBit.compass.requestUpdate();
    int x = uBit.compass.getX();
    uBit.serial.printf("X %d \n\r", x);
    int y = uBit.compass.getY();
    uBit.serial.printf("Y %d \n\r", y);
    int z = uBit.compass.getZ();
    uBit.serial.printf("Z %d \n\r", z);

    status = uBit._i2c.readRegister(0x3C, 0x68, &data[0], 1);
    status = uBit._i2c.readRegister(0x3C, 0x69, &data[1], 1);
    int16_t X = data[1] << 8 | data[0];
    uBit.serial.printf("X %d \n\r", X);

    status = uBit._i2c.readRegister(0x3C, 0x6A, &data[0], 1);
    status = uBit._i2c.readRegister(0x3C, 0x6B, &data[1], 1);
    int16_t Y = data[1] << 8 | data[0];
    uBit.serial.printf("Y %d \n\r", Y);

    status = uBit._i2c.readRegister(0x3C, 0x6C, &data[0], 1);
    status = uBit._i2c.readRegister(0x3C, 0x6D, &data[1], 1);
    int16_t Z = data[1] << 8 | data[0];
    uBit.serial.printf("Z %d \n\r", Z);

    return 0;
}

Page 111

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uint8_t buf[] = {0xE7};
    uBit.i2c.write(0x80, buf, 1);
    uBit.i2c.read(0x80, buf, 1);
    uBit.serial.printf("User Register = %X \r\n", buf[0]);
    return 0;
}

Page 112

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uint8_t buf[] = {0};
    uBit.i2c.readRegister(0x80, 0xE7, buf, 1);
    uBit.serial.printf("User Register = %X \r\n", buf[0]);
    return 0;
}

Page 114

#include "MicroBit.h"
MicroBit uBit;

int main()
{
    uBit.init();
    uint8_t buf[3] = {0};
    uBit.i2c.readRegister(0x80, 0xE3, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    uBit.serial.printf("msb %d \n lsb %d \n checksum %d \n\r",
                       msb, lsb, check);
    return 0;
}

Page 117

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uint8_t buf[3] = {0};
    uBit.i2c.readRegister(0x80, 0xE3, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];

    unsigned int data16 = ((unsigned int)msb << 8) |
                          (unsigned int)(lsb & 0xFC);
    int temp = -4685 + ((17572 * data16) >> 16);
    uBit.serial.printf("Temperature %d.%d C \n\r",
                       temp / 100, temp % 100);
    return 0;
}

Page 119

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;
}

Page 121

#include "MicroBit.h"
MicroBit uBit;

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()
{
    uBit.init();
    uint8_t buf[3] = {0};
    uBit.i2c.readRegister(0x80, 0xE3, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];

    unsigned int data16 = ((unsigned int)msb << 8) |
                          (unsigned int)(lsb & 0xFC);
    int temp = -4685 + ((17572 * data16) >> 16);
    uBit.serial.printf("\n\rmsb %d \n\rlsb %d \n\rchecksum %d \n\r",
                       msb, lsb, check);
    uBit.serial.printf("Temperature %d.%d C \n\r",
                       temp / 100, temp % 100);
    uBit.serial.printf("crc %d \n ", crcCheck(msb, lsb, check));

    uBit.i2c.readRegister(0x80, 0xE5, buf, 3);
    msb = buf[0];
    lsb = buf[1];
    check = buf[2];
    uBit.serial.printf("\n\rmsb %d \n\rlsb %d \n\rchecksum %d \n\r",
                       msb, lsb, check);
    data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    int hum = -600 + ((12500 * data16) >> 16);
    uBit.serial.printf("Humidity %d.%d %% \n\r",
                       hum / 100, hum % 100);
    uBit.serial.printf("crc %d \n ", crcCheck(msb, lsb, check));

    return 0;
}

Page 128

#include "MicroBit.h"
MicroBit uBit;
MicroBitPin P0 = uBit.io.P0;

int main()
{
    int n = 1200;
    //n = 4400; // Uncomment for V2
    volatile int i;
    uBit.init();
    P0.setDigitalValue(1);
    P0.setDigitalValue(0);
    for (i = 0; i < n; i++)
    {
    };
    P0.setDigitalValue(1);
    int b = P0.getDigitalValue();
}

Page 134

#include "MicroBit.h"
#include <cstdio>

MicroBit uBit;
MicroBitPin P0 = uBit.io.P0;

uint32_t getByte(int b, int buf[])
{
    int i;
    uint32_t result = 0;
    b = (b - 1) * 8 + 1;
    for (i = b; i <= b + 7; i++)
    {
        result = result << 1;
        result = result | buf[i];
    }
    return result;
}

int main()
{
    int n = 800;
    int threshold = 11;
    threshold = 40; // uncomment for V2

    volatile int i;
    uBit.init();
    P0.setDigitalValue(1);
    for (;;)
    {
        P0.setDigitalValue(0);
        uBit.sleep(1);
        P0.getDigitalValue();
        for (i = 1; i < n; i++)
        {
            if (P0.getDigitalValue() == 0)
                break;
        };
        int buf[41];
        int j;
        __disable_irq();
        for (j = 0; j < 41; j++)
        {
            for (i = 1; i < n; i++)
            {
                if (P0.getDigitalValue() == 1)
                    break;
            };
            for (i = 1; i < n; i++)
            {
                if (P0.getDigitalValue() == 0)
                    break;
            }
            buf[j] = 0;
            if (i > threshold)
                buf[j] = 1;
        }
        __enable_irq();

        uint32_t byte1 = getByte(1, buf);
        uint32_t byte2 = getByte(2, buf);
        uint32_t byte3 = getByte(3, buf);
        uint32_t byte4 = getByte(4, buf);
        uint32_t byte5 = getByte(5, buf);

        int16_t humidity = (byte1 << 8) | byte2;
        int16_t temperature = (byte3 << 8) | byte4;
        if (temperature & 0x8000)
            temperature = -(temperature & 0x7FFF);

        uBit.serial.printf("Checksum %X %X \n\r", byte5,
                           (byte1 + byte2 + byte3 + byte4) & 0xFF);
        uBit.serial.printf("Humidity %d.%d%%\n\r",
                           humidity / 10, abs(humidity % 10));
        uBit.serial.printf("Temperature %d.%dC\n\r",
                           temperature / 10, abs(temperature % 10));
        char buff[10];
        sprintf(buff, "%d.%d%%", humidity / 10, abs(humidity % 10));
        uBit.display.scroll(buff, 200);
        sprintf(buff, "%hd.%dC", temperature / 10,
                abs(temperature % 10));
        uBit.display.scroll(buff, 200);
        uBit.sleep(2500);
    }
}

Page 150

#include "MicroBit.h"
#include <cstdio>

MicroBit uBit;
MicroBitPin P0 = uBit.io.P0;
MicroBitPin P1 = uBit.io.P1;

int init()
{
    int reset = 700;
    //reset = 2250; // uncomment V2
    int gap = 60;
    //gap = 200; // uncomment V2
    volatile int i;

    P0.setDigitalValue(1);
    P0.setPull(Pull - up);
    // P0.setPull(PullMode::Up); //V2

    P1.getDigitalValue();
    P0.setDigitalValue(0);
    __disable_irq();
    for (i = 0; i < reset; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 0; i < gap; i++)
    {
    };
    int b = P1.getDigitalValue();
    for (i = 0; i < reset - gap; i++)
    {
    };
    __enable_irq();
    return b;
}

void sendZero()
{
    int zero = 75;
    //zero = 240; // uncomment for V2
    int slot = 30;
    //slot = 300;// uncomment for V2
    volatile int i;
    P0.setDigitalValue(0);
    for (i = 1; i < zero; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 1; i < slot - zero; i++)
    {
    };
}

void sendOne()
{
    int one = 1;
    //one = 8; // uncomment for V2
    int slot = 30;
    //slot = 300; // uncomment for V2
    volatile int i;
    P0.setDigitalValue(0);
    for (i = 1; i < one; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 1; i < slot - one; i++)
    {
    };
}

int readBit()
{
    volatile int i;
    int sample = 20;
    //sample = 55; // uncomment for V2
    int pulse = 1;
    //pulse = 8; // uncomment for V2
    int slot = 30;
    //slot = 300; // uncomment for V2
    __disable_irq();
    P0.setDigitalValue(0);
    for (i = 1; i < pulse; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 1; i < sample; i++)
    {
    };
    int b = P1.getDigitalValue();
    __enable_irq();
    for (i = 1; i < slot - sample - pulse; i++)
    {
    };
    return b;
}

void writeBit(int b)
{
    int zero = 75;
    //zero = 240; // uncomment for V2
    int one = 1;
    //one = 8; // uncomment for V2
    int slot = 30;
    //slot = 300; // uncomment for V2
    volatile int i;
    int delay1, delay2;
    if (b == 1)
    {
        delay1 = one;
    }
    else
    {
        delay1 = zero;
    }
    delay2 = slot - delay1;
    __disable_irq();
    P0.setDigitalValue(0);
    for (i = 1; i < delay1; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 1; i < delay2; i++)
    {
    };
    __enable_irq();
}

void writeByte(int byte)
{
    int i;
    for (i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(1);
        }
        else
        {
            writeBit(0);
        }
        byte = byte >> 1;
    }
}
int readByte()
{
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++)
    {
        byte = byte | readBit() << i;
    };
    return byte;
}
void convert()
{
    writeByte(0x44);
    uBit.sleep(900);
}
int main()
{
    uBit.init();

    if (init() == 1)
    {
        uBit.serial.printf("No device \n\r");
    }
    else
    {
        uBit.serial.printf("Device detected \n\r");
    }

    while (1)
    {
        init();
        writeByte(0xCC);
        convert();
        init();
        writeByte(0xCC);
        writeByte(0xBE);
        int b1 = readByte();
        int b2 = readByte();
        uBit.serial.printf("bytes %X,%X\n\r", b1, b2);
        int16_t temp = (b2 << 8 | b1);
        temp = temp * 100 / 16;
        uBit.serial.printf("Temperature %d.%d\n\r",
                           temp / 100, abs(temp % 100));
        char buff[10];
        sprintf(buff, "%d.%d", temp / 100, abs(temp % 100));
        uBit.display.scroll(buff, 200);
        uBit.sleep(2000);
    }
}

Page 154

int readBit()
{
    volatile int i;
    int sample = 20;
    sample = 55; // uncomment for V2
    int pulse = 1;
    pulse = 8; // uncomment for V2
    int slot = 30;
    slot = 300; // uncomment for V2
    __disable_irq();
    P0.setDigitalValue(0);
    for (i = 1; i < pulse; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 1; i < sample; i++)
    {
    };

    *pinDir = 0x0;
    unsigned int b = (*inp) & mask;
    b = b >> GPIO;
    *pinDir = 0x1;
    __enable_irq();
    for (i = 1; i < slot - sample - pulse; i++)
    {
    };
    return b;
}

Page 162

int SPItransfer(uint8_t *txBuffer, uint32_t txSize,
                uint8_t *rxBuffer, uint32_t rxSize)
{
    CS.setDigitalValue(0);
    uint32_t i;
    for (i = 0; i < txSize; i++)
    {
        if (i < rxSize)
        {
            rxBuffer[i] = spi.write(txBuffer[i]);
        }
        else
        {
            spi.write(txBuffer[i]);
        }
    }
    CS.setDigitalValue(1);
    return 0;
}

Page 164

#include "MicroBit.h"

MicroBit uBit;
SPI spi(MOSI, MISO, SCK);

MicroBitPin CS(MICROBIT_ID_IO_P16, MICROBIT_PIN_P16,
               PIN_CAPABILITY_DIGITAL);
//Used by V1 only
int SPItransfer(uint8_t *txBuffer, uint32_t txSize, uint8_t *rxBuffer, uint32_t rxSize)
{
    CS.setDigitalValue(0);
    uint32_t i;
    for (i = 0; i < txSize; i++)
    {
        if (i < rxSize)
        {
            rxBuffer[i] = spi.write(txBuffer[i]);
        }
        else
        {
            spi.write(txBuffer[i]);
        }
    }
    CS.setDigitalValue(1);
    return 0;
}
int main()
{
    CS.setDigitalValue(1);
    spi.format(8, 0);
    spi.frequency(1000000);
    uint8_t buf[1] = {0xAA};
    while (1)
    {
        CS.setDigitalValue(0);
        SPItransfer(buf, 1, buf, 1); //comment out for V2
                                     // spi.transfer(buf, 1, buf, 1); //uncomment for V1

        CS.setDigitalValue(1);

        uBit.serial.printf("data %X\n\r", buf[0]);
        if (buf[0] == 0xAA)
            uBit.serial.printf("data received correctly\n\r");
    };
    release_fiber();
    return 0;
}

Page 174

#include "MicroBit.h"
MicroBit uBit;

SPI spi(MOSI, MISO, SCK);

MicroBitPin CS(MICROBIT_ID_IO_P16, MICROBIT_PIN_P16,
               PIN_CAPABILITY_DIGITAL);
//SPItransfer function is only needed for V1
int SPItransfer(uint8_t *txBuffer, uint32_t txSize,
                uint8_t *rxBuffer, uint32_t rxSize)
{
    CS.setDigitalValue(0);
    uint32_t i;
    for (i = 0; i < txSize; i++)
    {
        if (i < rxSize)
        {
            rxBuffer[i] = spi.write(txBuffer[i]);
        }
        else
        {
            spi.write(txBuffer[i]);
        }
    }
    CS.setDigitalValue(1);
    return 0;
}

int main()
{
    CS.setDigitalValue(1);
    spi.format(8, 0);
    spi.frequency(1000000);

    uint8_t buf[] = {0x01, 0x80, 0x00};
    uint8_t readBuf[3];
    CS.setDigitalValue(0);
    SPItransfer(buf, 3, readBuf, 3); // comment out for V2
    //spi.transfer(buf, 3, readBuf, 3); //uncomment for V2
    //uBit.sleep(1);//uncomment for V2
    CS.setDigitalValue(1);
    int data = ((int)readBuf[1] & 0x03) << 8 | (int)readBuf[2];
    int volts = data * 330 / 1023;
    uBit.serial.printf("data %d\n\r", volts);

    release_fiber();
    return 0;
}

Page 175

int readADC(uint8_t chan)
{
    uint8_t buf[] = {0x01, (0x08 | chan) << 4, 0x00};
    uint8_t readBuf[3];
    CS.setDigitalValue(0);
    SPItransfer(buf, 3, readBuf, 3); //Comment out for V2

    //spi.transfer(buf, 3, readBuf, 3); //uncomment for V2
    //uBit.sleep(1);//uncomment for V2
    CS.setDigitalValue(1);
    return (readBuf[1] & 0x03) << 8 | readBuf[2];
}

Page 177

volatile unsigned int *outset = (unsigned int *)(0x50000000UL + 0x508);
volatile unsigned int *outclr = (unsigned int *)(0x50000000UL + 0x50C);
unsigned int mask = 1 << 16;

void transferBytes(int *buf, int *readBuf, int len)
{
    *outclr = mask;
    readBuf[0] = spi.write(buf[0]);
    readBuf[1] = spi.write(buf[1]);
    readBuf[2] = spi.write(buf[2]);
    *outset = mask;
}

Page 182

#include "MicroBit.h"
//#define baud setBaudrate // Uncomment for V2
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.serial.baud(115200);
    uBit.serial.send("A\r\n");
}

Page 182

#include "MicroBit.h"
/* Uncomment for V2
#define baud setBaudrate
#define USBTX MICROBIT_PIN_UART_TX
#define USBRX MICROBIT_PIN_UART_RX
*/
MicroBitSerial serial(USBTX, USBRX);

int main()
{
    serial.baud(115200);
    serial.send("A\r\n");
    release_fiber();
}

Page 189

#include "MicroBit.h"
//#define baud setBaudrate //uncomment for V2

void onChar(MicroBitEvent e)
{
    ManagedString s = uBit.serial.read(1);
    uBit.serial.clearRxBuffer();
    uBit.display.scroll(s);
    uBit.serial.eventAfter(1);
};

MicroBit uBit;

int main()
{
    uBit.init();
    uBit.serial.(20);
    uBit.messageBus.listen(MICROBIT_ID_SERIAL,
                           MICROBIT_SERIAL_EVT_HEAD_MATCH, onChar);
    uBit.serial.eventAfter(1);
    while (1)
        uBit.sleep(1000);
    release_fiber();
}

Page 198

#include "MicroBit.h"

MicroBit uBit;

void initWiFi();
int ATWiFi();
int find(ManagedString c, ManagedString s);
void debug(ManagedString s);
//Comment out for V2
#define Tx MICROBIT_PIN_P0
#define Rx MICROBIT_PIN_P1
//

/* Uncomment For V2
#define baud setBaudrate
#define USBTX uBit.io.usbTx
#define USBRX uBit.io.usbRx
#define Tx  uBit.io.P0
#define Rx  uBit.io.P1
*/
#define DEBUG 1

int main()
{
    initWiFi();
    ATWiFi();
    while (1)
        uBit.sleep(1000);
    release_fiber();
}
void initWiFi()
{
    uBit.serial.redirect(Tx, Rx);
    uBit.serial.baud(115200);
    uBit.serial.setRxBufferSize((uint8_t) + 500);
}

int ATWiFi()
{
    uBit.serial.send("AT\r\n", SYNC_SPINWAIT);
    uBit.sleep(150);
    ManagedString s = uBit.serial.read(500, ASYNC);
    if (DEBUG)
        debug("\n\rAT \n\r" + s + "\n\r");
    return find("OK", s);
}

void debug(ManagedString s)
{
    uBit.serial.redirect(USBTX, USBRX);
    uBit.serial.send(s, SYNC_SPINWAIT);
    uBit.serial.redirect(Tx, Rx);
}

int find(ManagedString c, ManagedString s)
{
    int i;

    for (i = 0; i < (s.length() - c.length()); i++)
    {
        if (c == s.substring(i, c.length()))
            break;
    }

    if (i == (s.length() - c.length()))
        return 0;
    return 1;
}

Page 211

#include "MicroBit.h"

MicroBit uBit;

void initWiFi();
int ATWiFi();
int find(ManagedString c, ManagedString s);
void debug(ManagedString s);
//Comment out for V2
#define Tx MICROBIT_PIN_P0
#define Rx MICROBIT_PIN_P1
//
/*  Uncomment for V2
#define baud setBaudrate
#define USBTX uBit.io.usbTx
#define USBRX uBit.io.usbRx
#define Tx uBit.io.P0
#define Rx uBit.io.P1
*/
#define DEBUG 1
#include "MicroBit.h"

void initWiFi();
int ATWiFi();
int resetWiFi();
int setUARTWiFi();
int scanWiFi();
int getIPWiFi();
int modeWiFi(int mode);
int connectWiFi(ManagedString ssid, ManagedString pass);
int getWebPageWiFi(ManagedString URL, ManagedString page);
int getVersionWiFi();
int startServerWiFi();

int waitForWiFi(ManagedString target, int retry, int pause);
int find(ManagedString c, ManagedString s);
void debug(ManagedString s);

int main()
{
    uBit.init();
    initWiFi();
    modeWiFi(1);
    connectWiFi("ssid", "password");
    getIPWiFi();
    startServerWiFi();
    release_fiber();
}

void initWiFi()
{
    uBit.serial.redirect(Tx, Rx);
    uBit.serial.baud(115200);
    uBit.serial.setRxBufferSize((uint8_t) + 500);
}

int ATWiFi()
{
    uBit.serial.send("AT\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 150, 10);
}

int getVersionWiFi()
{
    uBit.serial.send("AT+GMR\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 200, 10);
}

int resetWiFi()
{
    uBit.serial.send("AT+RST\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 1000, 10);
}

int setUARTWiFi()
{
    uBit.serial.send("AT+UART_CUR=115200,8,1,0,0\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 200, 10);
}

int scanWiFi()
{
    uBit.serial.send("AT+CWLAP\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 500, 50);
}

int modeWiFi(int mode)
{
    ManagedString cmd = "AT+CWMODE_CUR=" + ManagedString(mode) + "\r\n";
    uBit.serial.send(cmd, SYNC_SPINWAIT);
    return waitForWiFi("OK", 200, 10);
}

int connectWiFi(ManagedString ssid, ManagedString pass)
{
    ManagedString cmd = "AT+CWJAP_CUR=\"" + ssid + "\",\"" + pass + "\"\r\n";
    uBit.serial.send(cmd, SYNC_SPINWAIT);
    return waitForWiFi("OK", 200, 20);
}

int getIPWiFi()
{
    uBit.serial.send("AT+CIFSR\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 200, 10);
}

int getWebPageWiFi(ManagedString URL, ManagedString page)
{
    ManagedString cmd = "AT+CIPSTART=\"TCP\",\"" + URL + "\",80\r\n";
    uBit.serial.send(cmd, SYNC_SPINWAIT);
    if (waitForWiFi("OK", 100, 20) == 0)
        return 0;

    ManagedString http = "GET " + page + "HTTP/1.0\r\nHost:" + URL + "\r\n\r\n";
    cmd = "AT+CIPSEND=" + ManagedString(http.length()) + "\r\n";
    uBit.serial.send(cmd, SYNC_SPINWAIT);
    int retry;
    ManagedString s;
    s = "";
    retry = 40;
    do
    {
        uBit.sleep(100);
        s = s + uBit.serial.read(500, ASYNC);
        retry--;
    } while (find(">", s) == 0 && retry != 0);

    uBit.serial.send(http, SYNC_SPINWAIT);
    retry = 100;
    do
    {
        uBit.sleep(100);
        s = s + uBit.serial.read(500, ASYNC);
        retry--;
    } while (s.length() < 500 && retry != 0);

    if (DEBUG)
        debug("\n\rPage\n\r" + s + "\n\r");
    return 1;
}

int startServerWiFi()
{
    uBit.serial.send("AT+CIPMUX=1\r\n", SYNC_SPINWAIT);
    if (waitForWiFi("OK", 100, 20) == 0)
        return 0;

    uBit.serial.send("AT+CIPSERVER=1,80\r\n", SYNC_SPINWAIT);
    if (waitForWiFi("OK", 100, 20) == 0)
        return 0;

    ManagedString s;

    for (;;)
    {
        s = "";
        do
        {
            uBit.sleep(100);
            if (s > 500)
                s = "";
            s = uBit.serial.read(500, ASYNC);
        } while (find("+IPD", s) == 0);
        if (DEBUG)
            debug("\n\rClient Connected\n\r" + s + "\n\r");

        int b = find("+IPD", s);
        s = s.substring(b + 1, s.length());
        b = find(",", s);
        s = s.substring(b + 1, s.length());
        b = find(",", s);
        ManagedString id = s.substring(0, b);
        if (DEBUG)
            debug("\n\rTCP id:" + id + "\n\r");

        ManagedString headers = "HTTP/1.0 200 OK\r\n";
        headers = headers + "Server: micro:bit\r\n";
        headers = headers + "Content-type: text/html\r\n\r\n";

        ManagedString html =
            "<html><head><title>Temperature</title></"
            "head><body>{\"humidity\":81%,\"airtemperature\":23.5C}</p></body></html>\r\n";
        ManagedString data = headers + html;

        ManagedString cmd = "AT+CIPSEND=" + id + "," + ManagedString(data.length()) + "\r\n";
        uBit.serial.send(cmd, SYNC_SPINWAIT);
        s = "";
        int retry = 40;
        do
        {
            uBit.sleep(100);
            s = s + uBit.serial.read(500, ASYNC);
            retry--;
        } while (find(">", s) == 0 && retry != 0);

        uBit.serial.send(data, SYNC_SPINWAIT);

        if (waitForWiFi("OK", 100, 100) == 0)
            return 0;
        if (DEBUG)
            debug("\n\rData Sent\n\r");

        cmd = "AT+CIPCLOSE=" + id + "\r\n";
        uBit.serial.send(cmd, SYNC_SPINWAIT);
        if (waitForWiFi("OK", 100, 100) == 0)
            return 0;
    }
}

void debug(ManagedString s)
{
    uBit.serial.redirect(USBTX, USBRX);
    uBit.serial.send(s, SYNC_SPINWAIT);
    uBit.serial.redirect(Tx, Rx);
}

int find(ManagedString c, ManagedString s)
{
    int i;

    for (i = 0; i < (s.length() - c.length()); i++)
    {
        if (c == s.substring(i, c.length()))
            break;
    }

    if (i == (s.length() - c.length()))
        return 0;
    return i;
}

int waitForWiFi(ManagedString target, int retry, int pause)
{
    ManagedString s;
    do
    {
        uBit.sleep(pause);
        if (s.length() > 500)
            s = "";
        s = s + uBit.serial.read(500, ASYNC);
        retry--;
    } while (find(target, s) == 0 && retry != 0);
    if (DEBUG)
        debug("\n\r" + s + "\n\r");
    return retry;
}

Page 222

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.display.disable();

    DigitalOut col3(P0_6, 0);
    DigitalOut row2(P0_14);
    while (1)
    {
        row2 = 1;
        wait(0.2);
        row2 = 0;
        wait(0.2);
    }

    release_fiber();
    return 0;
}

Page 224

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.display.disable();
    uBit.io.row3.setDigitalValue(1);

    while (1)
    {
        uBit.io.col3.setDigitalValue(1);
        uBit.sleep(100);
        uBit.io.col3.setDigitalValue(0);
        uBit.sleep(100);
    }

    release_fiber();
    return 0;
}

Page 224

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.display.disable();

    while (1)
    {

        uBit.io.col1.setDigitalValue(0);
        uBit.io.row1.setDigitalValue(1);
        uBit.sleep(500);
        uBit.io.col1.setDigitalValue(1);
        uBit.io.row1.setDigitalValue(0);
        uBit.io.col2.setDigitalValue(0);
        uBit.io.row2.setDigitalValue(1);
        uBit.sleep(500);
        uBit.io.col2.setDigitalValue(1);
        uBit.io.row2.setDigitalValue(0);
        uBit.io.col3.setDigitalValue(0);
        uBit.io.row3.setDigitalValue(1);
        uBit.sleep(500);
        uBit.io.col3.setDigitalValue(1);
        uBit.io.row3.setDigitalValue(0);
        uBit.io.col4.setDigitalValue(0);
        uBit.io.row4.setDigitalValue(1);
        uBit.sleep(500);
        uBit.io.col4.setDigitalValue(1);
        uBit.io.row4.setDigitalValue(0);
        uBit.io.col5.setDigitalValue(0);
        uBit.io.row5.setDigitalValue(1);
        uBit.sleep(500);
        uBit.io.col5.setDigitalValue(1);
        uBit.io.row5.setDigitalValue(0);
    }

    release_fiber();
    return 0;
}

Page 228

#include "MicroBit.h"

MicroBit uBit;
int clickCount = 0;

void startGame();
int playGame();
void endGame(int position);
void countDown();
void drawPlayArea();
void flashMan(int x, int y, int p, int vx, int vy);
void setUpButton();
void moveHorizontal();
void moveVertical(int x, int h);
void buttonClickCount(MicroBitEvent e);

int main()
{
    uBit.init();
    startGame();
    int position = playGame();
    endGame(position);
    release_fiber();
    return 0;
}

void startGame()
{
    countDown();
    uBit.display.setDisplayMode(DISPLAY_MODE_GREYSCALE);
    drawPlayArea();
    setUpButton();
}

void countDown()
{
    int t;
    for (t = 5; t >= 0; t--)
    {
        uBit.display.scroll(t);
    }
    uBit.display.scroll("!");
}

void drawPlayArea()
{
    uBit.display.clear();
    int y;
    for (y = 1; y <= 5; y++)
    {
        uBit.display.image.setPixelValue(2, y, 255);
    }
}

int playGame()
{
    int position = 4;
    clickCount = 0;
    int t1 = uBit.systemTime();

    while (uBit.systemTime() - t1 < 20000)
    {
        flashMan(4, position, clickCount, 0, -1);
        if (clickCount > 10)
        {
            position = position - 1;
            clickCount = 0;
            if (position == 0)
                break;
        }
    }
    return position;
}

void endGame(int position)
{
    if (position == 0)
    {
        moveHorizontal();
        moveVertical(0, 0);
    }
    else
    {
        moveVertical(4, position);
    }
}

void setUpButton()
{
    uBit.buttonB.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS);
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_B,
                           MICROBIT_BUTTON_EVT_CLICK,
                           buttonClickCount);
}

void buttonClickCount(MicroBitEvent e)
{
    clickCount++;
}

void flashMan(int x, int y, int p, int vx, int vy)
{
    uBit.display.image.setPixelValue(x, y, 0);
    uBit.display.image.setPixelValue(x + vx, y + vy, 0);
    uBit.sleep(100);
    uBit.display.image.setPixelValue(x, y, 25 * (10 - p));
    uBit.display.image.setPixelValue(x + vx, y + vy, 25 * p);
    uBit.sleep(100);
}

void moveHorizontal()
{
    int x, fraction;
    for (x = 4; x >= 0; x--)
    {
        for (fraction = 0; fraction <= 10; fraction++)
        {
            flashMan(x, 0, fraction, -1, 0);
        }
    }
}

void moveVertical(int x, int h)
{
    int y, fraction;
    if (h != 0)
        uBit.display.image.setPixelValue(x, h - 1, 0);
    for (y = h; y <= 4; y++)
    {
        for (fraction = 0;
             fraction <= 10; fraction++)
        {
            flashMan(x, y, fraction, 0, 1);
        }
    }
}

Page 238

void onData(MicroBitEvent e)
{
    uBit.display.print("Click");
    return;
}

int main()
{
    uBit.init();
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_A,
                           MICROBIT_BUTTON_EVT_CLICK, onData);
    uBit.radio.enable();
    while (1)
    {
        uBit.sleep(1000);
    }
}

Page 239

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.radio.enable();
    uBit.display.print("TX");
    while (1)
    {
        if (uBit.buttonA.isPressed())
        {
            uBit.display.print("1");
            uBit.radio.datagram.send("1");
        }

        uBit.sleep(100);
        uBit.display.clear();
    }
    return 0;
}

Page 239

#include "MicroBit.h"
MicroBit uBit;

void onData(MicroBitEvent e)
{
    ManagedString s = uBit.radio.datagram.recv();
    uBit.display.print(s);
}

int main()
{
    uBit.init();

    uBit.messageBus.listen(MICROBIT_ID_RADIO,
                           MICROBIT_RADIO_EVT_DATAGRAM, onData);
    uBit.radio.enable();
    uBit.display.print("RX");
    while (1)
    {
        uBit.sleep(100);
        uBit.display.clear();
    }
}

Page 243

#include "MicroBit.h"
MicroBit uBit;
ManagedString setSound(ManagedString audio,
                       ManagedString data, int s)
{
    return audio.substring(0, s) + data +
           audio.substring(s + data.length(),
                           audio.length() - s - data.length());
}

int main()
{
    uBit.init();
    // 72 characters
    static ManagedString soundData(
       "000000000000000000000000000000000000
                     000000000000000000000000000000000000");

    soundData = setSound(soundData, "0", 0);     // Wave
    soundData = setSound(soundData, "1023", 1);  // volume start
    soundData = setSound(soundData, "1023", 26); // volume end
    soundData = setSound(soundData, "1000", 5);  // frequency start
    soundData = setSound(soundData, "1000", 18); // frequency end
    soundData = setSound(soundData, "00", 13);   // shape
    
    soundData = setSound(soundData, "500", 9);   // duration
    soundData = setSound(soundData, "0128", 30); // steps

    uBit.audio.soundExpressions.play(soundData);

    return 0;
}

Page 245

#include "MicroBit.h"

MicroBit uBit;

void beepOn(MicroBitEvent e)
{
    uBit.io.P0.setAnalogValue(512);
    uBit.io.P0.setAnalogPeriodUs(1000000 / 500);
    uBit.display.image.setPixelValue(2, 2, 255);
}

void beepOff(MicroBitEvent e)
{
    uBit.io.P0.setAnalogValue(0);
    uBit.display.image.setPixelValue(2, 2, 0);
}

int main()
{
    uBit.init();
    uBit.display.setDisplayMode(DISPLAY_MODE_GREYSCALE);
    uBit.radio.enable();

    uBit.radio.event.listen(MICROBIT_ID_BUTTON_A,
                            MICROBIT_BUTTON_EVT_DOWN);
    uBit.radio.event.listen(MICROBIT_ID_BUTTON_A,
                            MICROBIT_BUTTON_EVT_UP);
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_A,
                           MICROBIT_BUTTON_EVT_DOWN, beepOn);
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_A,
                           MICROBIT_BUTTON_EVT_UP, beepOff);
    while (1)
    {
        uBit.sleep(100);
    }
}

 

Raspberry Pi IoT In Python Using Linux Drivers

Programs

Cdrivers360

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. 

 

Note: The VS Code task listings are at the very end of this page.

The only downside is that you have to create a project to paste the code into.

To do this follow the instructionin the book-- in particular make sure you have added any libraries to the link step and are running as root if required. 

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:

This email address is being protected from spambots. You need JavaScript enabled to view it. 

Page 32

import io
from time import sleep

fd = io.open("/sys/class/leds/led0/trigger", "w")
fd.write("none")
fd.close()

fd = io.open("/sys/class/leds/led0/brightness", "w")
while(True):
    fd.write("0")
    fd.flush()
    sleep(1)
    fd.write("1")
    fd.flush()
    sleep(1)

 

Page 33

import io
from time import sleep

fd = io.open("/sys/class/leds/led0/trigger", "w")
fd.write("timer")
fd.close()

fd = io.open("/sys/class/leds/led0/delay_on", "w")
fd.write("2000")
fd.close()

fd = io.open("/sys/class/leds/led0/delay_off", "w")
fd.write("3000")
fd.close()

Page 42

import gpiod
chip = gpiod.Chip("0")
print(chip.label())
print(chip.name())
print(chip.num_lines())
chip.close()

Page 45

import gpiod

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py",
             type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])
while(True):
    line.set_value(1)
    line.set_value(0)

Page 46

import gpiod

chip = gpiod.Chip("0")
lines = chip.get_lines([4, 17])

lines.request(consumer="myprog.py", type=gpiod.LINE_REQ_DIR_OUT,
              default_vals=[0, 1])
while(True):
    lines.set_values([1, 0])
    lines.set_values([0, 1])

Page 48

import gpiod
from time import sleep, time_ns

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="resistor.py", type=gpiod.LINE_REQ_DIR_IN)
sleep(0.010)
line.release()

line.request(consumer="resistor.py", type=gpiod.LINE_REQ_DIR_OUT,
             default_vals=[0])
sleep(0.010)
line.release()

line.request(consumer="resistor.py", type=gpiod.LINE_REQ_DIR_IN)
t = time_ns()
while(line.get_value() == 0):
    pass
print((time_ns()-t)/1000)

 

Page 55

import fcntl
import struct
import io
GPIO_GET_CHIPINFO_IOCTL = 0x8044B401

f = io.open("/dev/gpiochip0", "rb", buffering=0)

gpiochip_info = struct.Struct("32s 32s L")
buffer = gpiochip_info.pack(b' ', b' ', 0)

result = fcntl.ioctl(f, GPIO_GET_CHIPINFO_IOCTL, buffer)

name, label, lines = gpiochip_info.unpack(result)

print(name.rstrip(b'\0').decode("utf-8"))
print(label.rstrip(b'\0').decode("utf-8"))
print(lines)

Page 59

import fcntl
import struct
import io

GPIO_GET_CHIPINFO_IOCTL = 0x8044B401
GPIO_GET_LINEHANDLE_IOCTL = 0xC16CB403
GPIOHANDLE_SET_LINE_VALUES_IOCTL = 0xC040B409
GPIOHANDLE_GET_LINE_VALUES_IOCTL = 0xC040B408

GPIOHANDLE_REQUEST_OUTPUT = 0x02
GPIOHANDLE_REQUEST_INPUT = 0x01
GPIOHANDLE_REQUEST_ACTIVE_LOW = 0x04
GPIOHANDLE_REQUEST_OPEN_DRAIN = 0x08
GPIOHANDLE_REQUEST_OPEN_SOURCE = 0x10

gpiochip_info = struct.Struct("32s 32s L")
gpiohandle_request = struct.Struct("64L L 64B 32s L L")
gpiohandle_data = struct.Struct("64B")

lines = [0]*64
lines[0] = 4
lines[1] = 17
values = [0]*64
buffer = gpiohandle_request.pack(*lines, GPIOHANDLE_REQUEST_OUTPUT,
                                 *values, b"Output test", 2, 0)

f = io.open("/dev/gpiochip0", "rb", buffering=0)
result = fcntl.ioctl(f, GPIO_GET_LINEHANDLE_IOCTL, buffer)
f.close()
fL = struct.unpack_from("L", buffer, 360)[0]

values[0] = 1
values[1] = 0
state1 = gpiohandle_data.pack(*values)

values[0] = 0
values[1] = 1
state2 = gpiohandle_data.pack(*values)

while(True):
    result = fcntl.ioctl(fL, GPIOHANDLE_SET_LINE_VALUES_IOCTL, state1)
    result = fcntl.ioctl(fL, GPIOHANDLE_SET_LINE_VALUES_IOCTL, state2)

Page 60

import fcntl
import struct
import io
import os

GPIO_GET_CHIPINFO_IOCTL = 0x8044B401
GPIO_GET_LINEHANDLE_IOCTL = 0xC16CB403
GPIOHANDLE_SET_LINE_VALUES_IOCTL = 0xC040B409
GPIOHANDLE_GET_LINE_VALUES_IOCTL = 0xC040B408

GPIOHANDLE_REQUEST_OUTPUT = 0x02
GPIOHANDLE_REQUEST_INPUT = 0x01
GPIOHANDLE_REQUEST_ACTIVE_LOW = 0x04
GPIOHANDLE_REQUEST_OPEN_DRAIN = 0x08
GPIOHANDLE_REQUEST_OPEN_SOURCE = 0x10

gpiochip_info = struct.Struct("32s 32s L")
gpiohandle_request = struct.Struct("64L L 64B 32s L L")
gpiohandle_data = struct.Struct("64B")

lines = [0]*64
lines[0] = 4
lines[1] = 17
values = [0]*64
buffer = gpiohandle_request.pack(*lines, GPIOHANDLE_REQUEST_INPUT,
                                 *values, b"Input test", 2, 0)

f = io.open("/dev/gpiochip0", "rb", buffering=0)
result = fcntl.ioctl(f, GPIO_GET_LINEHANDLE_IOCTL, buffer)
f.close()
fL = struct.unpack_from("L", result, 360)[0]
inputBuffer = gpiohandle_data.pack(*values)
result = fcntl.ioctl(fL, GPIOHANDLE_GET_LINE_VALUES_IOCTL,
                     inputBuffer)
os.close(fL)
print(result[0], result[1])

Page 61

import fcntl
import struct
import io
import os
from time import sleep, time_ns
GPIO_GET_CHIPINFO_IOCTL = 0x8044B401
GPIO_GET_LINEHANDLE_IOCTL = 0xC16CB403
GPIOHANDLE_SET_LINE_VALUES_IOCTL = 0xC040B409
GPIOHANDLE_GET_LINE_VALUES_IOCTL = 0xC040B408

GPIOHANDLE_REQUEST_OUTPUT = 0x02
GPIOHANDLE_REQUEST_INPUT = 0x01
GPIOHANDLE_REQUEST_ACTIVE_LOW = 0x04
GPIOHANDLE_REQUEST_OPEN_DRAIN = 0x08
GPIOHANDLE_REQUEST_OPEN_SOURCE = 0x10

gpiochip_info = struct.Struct("32s 32s L")
gpiohandle_request = struct.Struct("64L L 64B 32s L L")
gpiohandle_data = struct.Struct("64B")

lines = [0]*64
lines[0] = 4
values = [0]*64

buffer = gpiohandle_request.pack(*lines, GPIOHANDLE_REQUEST_INPUT,
                                 *values, b"Resistance test", 1, 0)

f = io.open("/dev/gpiochip0", "rb", buffering=0)
result = fcntl.ioctl(f, GPIO_GET_LINEHANDLE_IOCTL, buffer)
fL = struct.unpack_from("L", result, 360)[0]
state = gpiohandle_data.pack(*values)
result = fcntl.ioctl(fL, GPIOHANDLE_GET_LINE_VALUES_IOCTL, state)
sleep(0.01)
os.close(fL)

buffer = gpiohandle_request.pack(*lines, GPIOHANDLE_REQUEST_OUTPUT,
                                 *values, b"Resistance test", 1, 0)
result = fcntl.ioctl(f, GPIO_GET_LINEHANDLE_IOCTL, buffer)
fL = struct.unpack_from("L", result, 360)[0]
fcntl.ioctl(fL, GPIOHANDLE_SET_LINE_VALUES_IOCTL, state)
sleep(0.01)
os.close(fL)

buffer = gpiohandle_request.pack(*lines, GPIOHANDLE_REQUEST_INPUT,
                                 *values, b"Resistance test", 1, 0)
result = fcntl.ioctl(f, GPIO_GET_LINEHANDLE_IOCTL, buffer)
fL = struct.unpack_from("L", result, 360)[0]
t = time_ns()
result = fcntl.ioctl(fL, GPIOHANDLE_GET_LINE_VALUES_IOCTL, state)
while(result[0] == 0):
    result = fcntl.ioctl(fL, GPIOHANDLE_GET_LINE_VALUES_IOCTL, state)
print((time_ns()-t)/1000)
os.close(fL)
f.close()

Page 68

import gpiod

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)

event = line.event_wait(sec=1)
if event:
    print("Event on line 4")
else:
    print("Time out")

Page 69

import gpiod
from time import sleep, time_ns

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="resistor.py", type=gpiod.LINE_REQ_DIR_IN)
sleep(0.010)
line.release()

line.request(consumer="resistor.py",
             type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])
sleep(0.010)
line.release()

line.request(consumer="resistor.py",
             type=gpiod.LINE_REQ_EV_RISING_EDGE)
t = time_ns()
event = line.event_read()
print((event.sec*1000000000+event.nsec-t)/1000)

Page 70

import gpiod

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)

while(True):
    while True:
        event1 = line.event_read()
        if event1.type == event1.RISING_EDGE:
            break
    while True:
        event2 = line.event_read()
        if event2.type == gpiod.LineEvent.FALLING_EDGE:
            break
    print((event2.sec-event2.sec)*1000000000 +
          (event2.nsec-event1.nsec))

Page 71a

import gpiod
from time import sleep

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_DIR_IN)
print("Press the button", flush=True)
sleep(20)
if line.get_value() == 1:
    print("button pressed")
else:
    print("button not pressed")

Page 71b

import gpiod
from time import sleep

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)
print("Press the button", flush=True)
sleep(20)
event = line.event_wait(sec=0)
if event:
    print("button pressed")
else:
    print("button not pressed")

Page 72

import gpiod


def event_poll(line):
    event = line.event_wait(sec=0)
    if event:
        event = line.event_read()
    return event


chip = gpiod.Chip("0")
line = chip.get_line(4)
line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)
while True:
    event = event_poll(line)
    if event:
        print(event.sec, flush=True)

Page 75

import fcntl
import struct
import io
import os
from time import sleep, time_ns
import select

GPIO_GET_CHIPINFO_IOCTL = 0x8044B401
GPIO_GET_LINEHANDLE_IOCTL = 0xC16CB403
GPIOHANDLE_SET_LINE_VALUES_IOCTL = 0xC040B409
GPIOHANDLE_GET_LINE_VALUES_IOCTL = 0xC040B408
GPIO_GET_LINEEVENT_IOCTL = 0xC030B404

GPIOHANDLE_REQUEST_OUTPUT = 0x02
GPIOHANDLE_REQUEST_INPUT = 0x01
GPIOHANDLE_REQUEST_ACTIVE_LOW = 0x04
GPIOHANDLE_REQUEST_OPEN_DRAIN = 0x08
GPIOHANDLE_REQUEST_OPEN_SOURCE = 0x10

GPIOEVENT_REQUEST_RISING_EDGE = 0x01
GPIOEVENT_REQUEST_FALLING_EDGE = 0x02
GPIOEVENT_REQUEST_BOTH_EDGES = 0x03

gpiochip_info = struct.Struct("32s 32s L")
gpiohandle_request = struct.Struct("64L L 64B 32s L L")
gpiohandle_data = struct.Struct("64B")
gpioevent_request = struct.Struct("L L L 32s L")
gpioevent_data = struct.Struct("Q L")

buffer = gpioevent_request.pack(4, GPIOHANDLE_REQUEST_INPUT,
                                GPIOEVENT_REQUEST_BOTH_EDGES, b"Event test", 0)

f = io.open("/dev/gpiochip0", "rb", buffering=0)
result = fcntl.ioctl(f, GPIO_GET_LINEEVENT_IOCTL, buffer)
f.close()
fL = struct.unpack_from("L", result, 44)[0]

e = select.epoll()
e.register(fL)
while True:
    events = e.poll(1)
    if len(events) > 0:
        buffer = os.read(fL, 100)
        timestamp, id = gpioevent_data.unpack(buffer[0:12])
        print(timestamp, id, flush=True)

Page 76

import gpiod
import struct
import io
import os
import select

gpioevent_data = struct.Struct("Q L")

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)

fL = line.event_get_fd()
e = select.epoll()
e.register(fL)
while True:
    events = e.poll(1)
    if len(events) > 0:
        buffer = os.read(fL, 100)
        timestamp, id = gpioevent_data.unpack(buffer[0:12])
        print(timestamp, id, flush=True)

Page 77

import gpiod
from time import sleep
import threading


def waitForInterrupt(line):
    while(True):
        event = line.event_read()
        print(event.sec*1000000000+event.nsec, flush=True)


chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)

IntThread = threading.Thread(target=waitForInterrupt, args=(line,))
IntThread.start()


while True:
    sleep(2)
    print("running", flush=True)

Page 87

import io

fdr = io.open("/sys/bus/iio/devices/iio:device0/name", "rb", buffering=0)
name = fdr.readline().decode("utf-8")
print("name=", name)
fdr.close()

fdr = io.open("/sys/bus/iio/devices/iio:device0/in_temp_input",
              "rb", buffering=0)
temp = fdr.readline().decode("utf-8")
print("temp=", int(temp)/1000, "C")
fdr.close()

fdr = io.open(
    "/ sys/bus/iio/devices/iio: device0 /in_humidityrelative_input", "rb", buffering=0)
hum = fdr.readline().decode("utf-8")
print("Humidity=", int(hum)/1000, "%")
fdr.close()

Page 89

import subprocess
import io
import fcntl


def checkDht11():
    indicator = "dht11  gpiopin=4"
    command = ["sudo", "dtoverlay", "dht11", "gpiopin=4"]
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output)
    if output.find(indicator) == -1:
        temp = subprocess.Popen(command, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output)
    return


checkDht11()

fdr = io.open("/sys/bus/iio/devices/iio:device0/name", "rb", buffering=0)
name = fdr.readline().decode("utf-8")
print("name=", name)
fdr.close()

fdr = io.open("/sys/bus/iio/devices/iio:device0/in_temp_input",
              "rb", buffering=0)
temp = fdr.readline().decode("utf-8")
print("temp=", int(temp)/1000, "C")
fdr.close()

fdr = io.open(
    "/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", "rb", buffering=0)
hum = fdr.readline().decode("utf-8")
print("Humidity=", int(hum)/1000, "%")
fdr.close()

Page 111a

import gpiod
from time import sleep

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py",
             type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])

period = 20
duty = 25

ontime = period/1000 * duty / 100
offtime = period/1000 - ontime

while(True):
    line.set_value(1)
    sleep(ontime)
    line.set_value(0)
    sleep(offtime)

Page 111b

import gpiod
from time import sleep
import threading


def softPWM(line, period, duty):
    ontime = period/1000 * duty / 100
    offtime = period/1000 - ontime
    while(True):
        line.set_value(1)
        sleep(ontime)
        line.set_value(0)
        sleep(offtime)


chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py",
             type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])

period = 20
duty = 75

IntThread = threading.Thread(target=softPWM, args=(line, period, duty))
IntThread.start()

while(True):
    print("working", flush=True)
    sleep(2)

Page 115

import subprocess
import io


def checkPWM():
    indicator = "pwm-2chan"
    command = ["sudo", "dtoverlay", "pwm-2chan"]
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output)
    if output.find(indicator) == -1:
        temp = subprocess.Popen(command, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output)
    return


checkPWM()

fdw = io.open("/sys/class/pwm/pwmchip0/export", "wb", buffering=0)
fdw.write(b"0")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip0/pwm0/period", "wb", buffering=0)
fdw.write(b"10000000")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip0/pwm0/duty_cycle", "wb", buffering=0)
fdw.write(b"8000000")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip0/pwm0/enable", "wb", buffering=0)
fdw.write(b"1")
fdw.close()

Page 116

import subprocess
import io
from time import sleep
import os


class Pwm:
    def __init__(self, channel, f, duty):
        if not(channel == 0 or channel == 1):
            return
        self.chan = str(channel)
        indicator = "pwm-2chan"
        command = ["sudo", "dtoverlay", "pwm-2chan"]
        temp = subprocess.Popen(
            ["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output, flush=True)
        if output.find(indicator) == -1:
            temp = subprocess.Popen(command, stdout=subprocess.PIPE)
            output = str(temp.communicate())
            print(output, flush=True)

        if not(os.path.exists("/sys/class/pwm/pwmchip0/pwm"+self.chan)):
            fdw = io.open("/sys/class/pwm/pwmchip0/export", "w")
            fdw.write(self.chan)
            fdw.close()

        while not(os.path.exists("/sys/class/pwm/pwmchip0/pwm"+self.chan+"/enable")):
            pass

        self.fdwp = io.open("/sys/class/pwm/pwmchip0/pwm" +
                            self.chan+"/period", "w")
        self.setFreq(f)
        self.fdwd = io.open("/sys/class/pwm/pwmchip0/pwm" +
                            self.chan+"/duty_cycle", "w")
        self.setDuty(duty)

    def setFreq(self, f):
        self.f = int(1000000000/f)
        self.fdwp.write(str(self.f))
        self.fdwp.flush()

    def setDuty(self, duty):
        self.duty = int(self.f*duty/100)
        self.fdwd.write(str(self.duty))
        self.fdwd.flush()

    def enableChan(self):
        fdw = io.open("/sys/class/pwm/pwmchip0/pwm"+self.chan+"/enable", "w")
        fdw.write("1")
        fdw.close()

    def disableChan(self):
        fdw = io.open("/sys/class/pwm/pwmchip0/pwm"+self.chan+"/enable", "w")
        fdw.write("0")
        fdw.close()

    def closeChan(self):
        self.fdwd.close()
        self.fdwp.close()
        fdw = io.open("/sys/class/pwm/pwmchip0/unexport", "w")
        fdw.write(self.chan)
        fdw.close()

Page 127

import subprocess
import io
from time import sleep
import os


class Pwm:
    def __init__(self, channel, f, duty):
        if not(channel == 0 or channel == 1):
            return
        self.chan = str(channel)
        indicator = "pwm-2chan"
        command = ["sudo", "dtoverlay", "pwm-2chan"]
        temp = subprocess.Popen(
            ["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output, flush=True)
        if output.find(indicator) != -1:
            temp = subprocess.Popen(
                ["sudo", "dtoverlay", "-r", "0"], stdout=subprocess.PIPE)
            output = str(temp.communicate())
            print(output, flush=True)

        temp = subprocess.Popen(command, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output, flush=True)

        if os.path.exists("/sys/class/pwm/pwmchip0/pwm"+self.chan):
            fdw = io.open("/sys/class/pwm/pwmchip0/unexport", "w")
            fdw.write(self.chan)
            fdw.close()

        while os.path.exists("/sys/class/pwm/pwmchip0/pwm"+self.chan+"/enable"):
            pass
        fdw = io.open("/sys/class/pwm/pwmchip0/export", "w")
        fdw.write(self.chan)
        fdw.close()

        while not(os.path.exists("/sys/class/pwm/pwmchip0/pwm"+self.chan+"/period")):
            pass

        self.fdwp = io.open("/sys/class/pwm/pwmchip0/pwm" +
                            self.chan+"/period", "w")
        self.setFreq(f)
        self.fdwd = io.open("/sys/class/pwm/pwmchip0/pwm" +
                            self.chan+"/duty_cycle", "w")
        self.setDuty(duty)

    def setFreq(self, f):
        self.fdwp.write("200")
        self.fdwp.flush()
        self.f = int(1000000000/f)
        self.fdwp.write(str(self.f))
        self.fdwp.flush()

    def setDuty(self, duty):
        self.duty = int(self.f*duty/100)
        self.fdwd.write(str(self.duty))
        self.fdwd.flush()

    def enableChan(self):
        fdw = io.open("/sys/class/pwm/pwmchip0/pwm"+self.chan+"/enable", "w")
        fdw.write("1")
        fdw.close()

    def disableChan(self):
        fdw = io.open("/sys/class/pwm/pwmchip0/pwm"+self.chan+"/enable", "w")
        fdw.write("0")
        fdw.close()

    def closeChan(self):
        self.fdwd.close()
        self.fdwp.close()
        fdw = io.open("/sys/class/pwm/pwmchip0/unexport", "w")
        fdw.write(self.chan)
        fdw.close()

    def inverChan(self):
        fdw = io.open("/sys/class/pwm/pwmchip0/pwm"+self.chan+"/polarity", "w")
        fdw.write("inversed")
        fdw.close()

    def normalChan(self):
        fdw = io.open("/sys/class/pwm/pwmchip0/pwm"+self.chan+"/polarity", "w")
        fdw.write("normal")
        fdw.close()

Page 137

import subprocess
import spidev
from time import sleep


def checkSPI():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    lastSPI = output.rfind("spi")
    if lastSPI != -1:
        lastSPI = output.find("spi=on", lastSPI)
    if lastSPI == -1:
        temp = subprocess.Popen(
            ["sudo", "dtparam", "spi=on"], stdout=subprocess.PIPE)
        output = str(temp.communicate())


checkSPI()

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 5000
Data = [0xAA]
print(hex(Data[0]))
data = spi.xfer(Data)
print(hex(Data[0]))
if Data == 0xAA:
    print("match")
spi.close()

Page 146

import subprocess
import spidev


def checkSPI():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    lastSPI = output.rfind("spi")
    if lastSPI != -1:
        lastSPI = output.find("spi=on", lastSPI)
    if lastSPI == -1:
        temp = subprocess.Popen(
            ["sudo", "dtparam", "spi=on"], stdout=subprocess.PIPE)
        output = str(temp.communicate())


checkSPI()

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 100000
spi.mode = 0
spi.bits_per_word = 8

Data = [0x01, 0x80, 0x00]
spi.xfer(Data)
raw = (Data[1] & 0x03) << 8 | Data[2]
print(raw)
volts = raw * 3.3 / 1023.0
print(volts, "V")
spi.close()

Page 165

import subprocess
import io
import fcntl


def checkI2CBus():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"],
                            stdout=subprocess.PIPE)
    output = str(temp.communicate())
    lasti2c = output.rfind("i2c_arm")
    if lasti2c != -1:
        lasti2c = output.find("i2c_arm=on", lasti2c)
    if lasti2c == -1:
        temp = subprocess.Popen(["sudo", "dtparam", "i2c_arm=on"],
                                stdout=subprocess.PIPE)
        output = str(temp.communicate())
    return


checkI2CBus()

I2C_SLAVE = 0x0703

fdr = io.open("/dev/i2c-1", "rb", buffering=0)
fdw = io.open("/dev/i2c-1", "wb", buffering=0)
fcntl.ioctl(fdr, I2C_SLAVE, 0x40)
fcntl.ioctl(fdw, I2C_SLAVE, 0x40)
fdw.write(bytearray([0xE7]))
data = fdr.read(1)
print(data)
fdr.close()
fdw.close()

Page 167

import subprocess
import io
import fcntl
from time import sleep

checkI2CBus()
I2C_SLAVE = 0x0703

fdr = io.open("/dev/i2c-1", "rb", buffering=0)
fdw = io.open("/dev/i2c-1", "wb", buffering=0)
fcntl.ioctl(fdr, I2C_SLAVE, 0x40)
fcntl.ioctl(fdw, I2C_SLAVE, 0x40)

fdw.write(bytearray([0xF3]))
while(True):
    try:
        data = fdr.read(3)
        break
    except:
        sleep(0.01)
msb = data[0]
lsb = data[1]
crc = data[2]
print("msb=", msb, " lsb=", lsb, " crc=", crc)

fdw.close()
fdr.close()

Page 171

import subprocess
import io
import fcntl
from time import sleep


def crcCheck(msb, lsb, check):
    data32 = (msb << 16) | (lsb << 8) | check
    divisor = 0x988000
    for i in range(16):
        if(data32 & 1 << (23 - i)):
            data32 ^= divisor
        divisor >>= 1
    return data32


def checkI2CBus():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"],
                            stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output)
    lasti2c = output.rfind("i2c_arm")
    if lasti2c != -1:
        lasti2c = output.find("i2c_arm=on", lasti2c)
    if lasti2c == -1:
        temp = subprocess.Popen(["sudo", "dtparam", "i2c_arm=on"],
                                stdout=subprocess.PIPE)
        output = str(temp.communicate())
    return


checkI2CBus()
I2C_SLAVE = 0x0703

fdr = io.open("/dev/i2c-1", "rb", buffering=0)
fdw = io.open("/dev/i2c-1", "wb", buffering=0)
fcntl.ioctl(fdr, I2C_SLAVE, 0x40)
fcntl.ioctl(fdw, I2C_SLAVE, 0x40)

fdw.write(bytearray([0xF3]))
while(True):
    try:
        data = fdr.read(3)
        break
    except:
        sleep(0.01)
msb = data[0]
lsb = data[1]
crc = data[2]

data16 = (msb << 8) | (lsb & 0xFC)
temp = -46.85 + (175.72 * data16 / 65536)
print("Temperature=", temp, "C")

fdw.write(bytearray([0xF5]))
while(True):
    try:
        data = fdr.read(3)
        break
    except:
        sleep(0.01)

msb = data[0]
lsb = data[1]
crc = data[2]
data16 = (msb << 8) | (lsb & 0xFC)
hum = -6 + 125.0 * data16 / 65536

print("humidity=", hum, "%")

print(crcCheck(msb, lsb, crc))
fdw.close()
fdr.close()

Page 183

import subprocess
import io
import struct
import fcntl
from time import sleep
import mmap
import os


def setTimeout(timeout):
    # find base address
    peripherals_base = 0x20000000
    try:
        with io.open('/proc/device-tree/soc/ranges', 'rb') as f:
            buf = f.read(16)
            peripherals_base = buf[4] << 24 | buf[5] << 16 | buf[6] << 8 | buf[7] << 0
            if peripherals_base == 0:
                peripherals_base = buf[8] << 24 | buf[9] << 16 | buf[10] << 8 | buf[11] << 0
    except:
        pass
#open /dev/mem
    try:
        memfd = os.open('/dev/mem', os.O_RDWR | os.O_SYNC)
    except OSError:
        print('unable to open /dev/mem upgrade your kernel or run as root')
# map file from start of BCS1 into memory
    mem = mmap.mmap(memfd, 4096, offset=peripherals_base + 0x804000)
    os.close(memfd)

# Write a value to the clock stretch timeout register
    struct.pack_into('<L', mem, 0x1C, timeout)

    mem.flush
    mem.close()


def crcCheck(msb, lsb, check):
    data32 = (msb << 16) | (lsb << 8) | check
    divisor = 0x988000
    for i in range(16):
        if(data32 & 1 << (23 - i)):
            data32 ^= divisor
        divisor >>= 1
    return data32


def checkI2CBus():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"],
                            stdout=subprocess.PIPE)
    output = str(temp.communicate())
    lasti2c = output.rfind("i2c_arm")
    if lasti2c != -1:
        lasti2c = output.find("i2c_arm=on", lasti2c)
    if lasti2c == -1:
        temp = subprocess.Popen(["sudo", "dtparam", "i2c_arm=on"],
                                stdout=subprocess.PIPE)
        output = str(temp.communicate())
    return


checkI2CBus()
I2C_SLAVE = 0x0703
fdr = io.open("/dev/i2c-1", "rb", buffering=0)
fdw = io.open("/dev/i2c-1", "wb", buffering=0)

setTimeout(10000)

fcntl.ioctl(fdr, I2C_SLAVE, 0x40)
fcntl.ioctl(fdw, I2C_SLAVE, 0x40)


fdw.write(bytearray([0xE3]))
data = fdr.read(3)

msb = data[0]
lsb = data[1]
crc = data[2]

data16 = (msb << 8) | (lsb & 0xFC)
temp = -46.85 + (175.72 * data16 / 65536)
print("Temperature=", temp, "C")
print(crcCheck(msb, lsb, crc))

fdw.write(bytearray([0xE5]))
data = fdr.read(3)

msb = data[0]
lsb = data[1]
crc = data[2]
data16 = (msb << 8) | (lsb & 0xFC)
hum = -6 + 125.0 * data16 / 65536

print("humidity=", hum, "%")
print(crcCheck(msb, lsb, crc))
fdw.close()
fdr.close()

Page 186

import subprocess
from ctypes import *
import os
import fcntl
import io


def checkI2CBus():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"],
                            stdout=subprocess.PIPE)
    output = str(temp.communicate())
    lasti2c = output.rfind("i2c_arm")
    if lasti2c != -1:
        lasti2c = output.find("i2c_arm=on", lasti2c)
    if lasti2c == -1:
        temp = subprocess.Popen(["sudo", "dtparam", "i2c_arm=on"],
                                stdout=subprocess.PIPE)
        output = str(temp.communicate())
    return


checkI2CBus()
I2C_SLAVE = 0x0703
I2C_FUNCS = 0x0705

I2C_FUNC_I2C = 0x00000001
I2C_FUNC_10BIT_ADDR = 0x00000002
I2C_FUNC_PROTOCOL_MANGLING = 0x00000004
I2C_FUNC_NOSTART = 0x00000010
I2C_FUNC_SLAVE = 0x00000020

i2cfd = os.open("/dev/i2c-1", os.O_RDWR | os.O_SYNC)
support = c_uint32(0)
fcntl.ioctl(i2cfd, I2C_FUNCS, support)
support = support.value
if support & I2C_FUNC_I2C:
    print("I2C Support")
if support & I2C_FUNC_10BIT_ADDR:
    print("10 bit address Support")
if support & I2C_FUNC_PROTOCOL_MANGLING:
    print("I2C Mangling Support")
if support & I2C_FUNC_NOSTART:
    print("I2C Nostart Support")
if support & I2C_FUNC_SLAVE:
    print("I2C Slave Support")

Page 191

import fcntl
import os
from ctypes import *


class Msgs(Structure):
    _fields_ = [("addr", c_uint16),
                ("flags", c_uint16),
                ("len", c_uint16),
                ("buf", POINTER(c_uint8))
                ]


class MsgSet(Structure):
    _fields_ = [("msgs", POINTER(Msgs)),
                ("nmsgs", c_uint32)
                ]


def i2cReadRegister(i2cfd, slaveaddr, reg, n):
    I2C_RDWR = 0x0707
    I2C_M_RD = 0x0001

    msgs = (Msgs*2)()

    msgs[0].addr = c_uint16(slaveaddr)
    msgs[0].flags = c_uint16(0)
    msgs[0].len = c_uint16(1)
    msgs[0].buf = POINTER(c_uint8)(c_uint8(reg))

    msgs[1].addr = c_uint16(slaveaddr)
    msgs[1].flags = c_uint16(I2C_M_RD)
    msgs[1].len = c_uint16(n)
    buf = (c_uint8*n)(0)
    msgs[1].buf = POINTER(c_uint8)(buf)

    msgset = MsgSet()
    msgset.msgs = POINTER(Msgs)(msgs)
    msgset.nmsgs = c_uint32(2)

    libc = CDLL("libc.so.6")
    libc.ioctl(i2cfd, I2C_RDWR, byref(msgset))

    return msgs[1].buf


def crcCheck(msb, lsb, check):
    data32 = (msb << 16) | (lsb << 8) | check
    divisor = 0x988000
    for i in range(16):
        if(data32 & 1 << (23 - i)):
            data32 ^= divisor
        divisor >>= 1
    return data32


i2cfd = os.open("/dev/i2c-1", os.O_RDWR | os.O_SYNC)
data = i2cReadRegister(i2cfd, 0x40, 0xE3, 3)
msb = data[0]
lsb = data[1]
crc = data[2]

data16 = (msb << 8) | (lsb & 0xFC)
temp = -46.85 + (175.72 * data16 / 65536)
print("Temperature=", temp, "C")
print(hex(msb), hex(lsb), hex(crc))
print(crcCheck(msb, lsb, crc))

Page 200

import subprocess
import io


def checkLM75():
    indicator1 = "i2c_arm=on"
    command1 = ["sudo", "dtparam", "i2c_arm=on"]
    indicator2 = "lm75"
    command2 = ["sudo", "dtoverlay", "i2c-sensor", "lm75", "addr=0x48"]
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output, flush=True)
    if output.find(indicator1) == -1:
        temp = subprocess.Popen(command1, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output, flush=True)
    if output.find(indicator2) == -1:
        temp = subprocess.Popen(command2, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output, flush=True)


checkLM75()

fdr = io.open("/sys/class/hwmon/hwmon2/temp1_input", "r")
buf = fdr.read()
print(buf)
temp = int(buf) / 1000
print(temp)
fdr.close()

fdw = io.open("/sys/class/hwmon/hwmon2/temp1_max", "w")
fdw.write("19000")
fdw.close()

fdw = io.open("/sys/class/hwmon/hwmon2/temp1_max_hyst", "w")
fdw.write("18000")
fdw.close()

Page 204

import subprocess
import io


def loadHtu21():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output)
    if output.find("htu21") == -1:
        temp = subprocess.Popen(
            ["sudo", "dtoverlay", "i2c-sensor", "htu21"], stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output)
    return


loadHtu21()

fdrt = io.open("/sys/bus/iio/devices/iio:device0/in_temp_input", "r")
print(int(fdrt.read())/1000)
fdrh = io.open(
    "/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", "r")
print(int(fdrh.read())/1000)

Page 217

import subprocess
import io


def load1w(pin):
    indicator = "w1-gpio"
    command = ["sudo", "dtoverlay", "w1-gpio", "gpiopin="+str(pin)]
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output, flush=True)
    if output.find(indicator) == -1:
        temp = subprocess.Popen(command, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output, flush=True)


def getDevices():
    fdr = io.open(
        "/sys/bus/w1/drivers/w1_master_driver/w1_bus_master1/w1_master_slaves", "r")
    buffer = fdr.read()
    fdr.close()
    return buffer.split()


def getData(dev, name):
    fdr = io.open("/sys/bus/w1/devices/"+dev+"/"+name, "r")
    data = fdr.read()
    fdr.close()
    return data


load1w(4)
devs = getDevices()
name = getData(devs[0], "name")
print("Name ", name)
resolution = getData(devs[0], "resolution")
print("Resolution ", resolution)
w1_slave = getData(devs[0], "w1_slave")
print("w1_slave ", w1_slave)
temperature = getData(devs[0], "temperature")
print("temperature ", temperature)
temperature = int(temperature) / 1000
print("temperature ", temperature, "C")
alarms = getData(devs[0], "alarms")
print("Alarms ", alarms)

Page 228

from ctypes import *
from socket import *
from struct import *
import os
import subprocess
import io
from time import sleep


NLMSG_DONE = 0x3

CN_W1_IDX = 0x3
CN_W1_VAL = 0x1

W1_SLAVE_ADD = 0
W1_SLAVE_REMOVE = 1
W1_MASTER_ADD = 2
W1_MASTER_REMOVE = 3
W1_MASTER_CMD = 4
W1_SLAVE_CMD = 5
W1_LIST_MASTERS = 6

W1_CMD_READ = 0
W1_CMD_WRITE = 1
W1_CMD_SEARCH = 2
W1_CMD_ALARM_SEARCH = 3
W1_CMD_TOUCH = 4
W1_CMD_RESET = 5
W1_CMD_SLAVE_ADD = 6
W1_CMD_SLAVE_REMOVE = 7
W1_CMD_LIST_SLAVES = 8
W1_CMD_MAX = 9

NETLINK_CONNECTOR = 11

nl_seq = 0


class nlmsghdr(Structure):
    _fields_ = [("nlmsg_len", c_uint32),
                ("nlmsg_type", c_uint16),
                ("nlmsg_flags", c_uint16),
                ("nlmsg_seq", c_uint32),
                ("nlmsg_pid", c_uint32)
                ]


cnh = nlmsghdr()
cnh.nlmsg_seq = c_uint32(nl_seq)
nl_seq += 1
cnh.nlmsg_pid = c_uint32(os.getpid())
cnh.nlmsg_type = c_uint16(NLMSG_DONE)
cnh.nlmsg_flags = c_uint16(0)


class cn_msg(Structure):
    _fields_ = [("idx", c_uint32),
                ("val", c_uint32),
                ("seq", c_uint32),
                ("ack", c_uint32),
                ("len", c_uint16),
                ("flags", c_uint16),
                ]


cmsg = cn_msg()
cmsg.idx = c_uint32(CN_W1_IDX)
cmsg.val = c_uint32(CN_W1_VAL)
cmsg.seq = c_uint32(cnh.nlmsg_seq)
cmsg.ack = c_uint32(0)


class w1_netlink_msg(Structure):
    _fields_ = [("type", c_uint8),
                ("status", c_uint8),
                ("len", c_uint16),
                ("id", c_uint8*8),
                ]


msg = w1_netlink_msg()
msg.type = c_uint8(W1_MASTER_CMD)
msg.id = (c_uint8*8).from_buffer_copy(c_uint64(1))


class w1_netlink_cmd(Structure):
    _fields_ = [("cmd", c_uint8),
                ("res", c_uint8),
                ("len", c_uint16),
                ]


w1_cmd = w1_netlink_cmd()
w1_cmd.cmd = c_uint8(W1_CMD_SEARCH)
w1_cmd.len = c_uint16(0)


msg.len = c_uint16(len(bytearray(w1_cmd)) + w1_cmd.len)
cmsg.len = c_uint16(len(bytearray(msg)) + msg.len)
cnh.nlmsg_len = c_uint32(len(bytearray(cnh))+len(bytearray(cmsg))+cmsg.len)


s = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR)
s.connect((0, AF_NETLINK))

buffer = bytearray(cnh)+bytearray(cmsg)+bytearray(msg)+bytearray(w1_cmd)
n = s.send(buffer)
print("Bytes sent", n, flush=True)
buffer2 = s.recv(65535)
print("Bytes received", len(buffer2), flush=True)

p = 0
cn_cnhr = nlmsghdr.from_buffer_copy(buffer2, p)
p = p+len(bytes(cn_cnhr))
cmsgr = cn_msg.from_buffer_copy(buffer2, p)
p = p+len(bytes(cmsgr))
msgr = w1_netlink_msg.from_buffer_copy(buffer2, p)
p = p+len(bytes(msgr))
w1_cmdr = w1_netlink_cmd.from_buffer_copy(buffer2, p)

num = int(w1_cmdr.len/8)
print("number of slaves", num)

p = p+len(bytes(w1_cmdr))
slaves = []
for i in range(num):
    slaves.append(c_uint64.from_buffer_copy(buffer2, p+i*8).value)
print([hex(slave) for slave in slaves])

# GET ACK
buffer2 = s.recv(65535)
print("length of ack received ", len(buffer2), flush=True)

# READ TEMPERATURE
# SET UP SLAVE COMMAND
print()
print("Read Temperature")

msg.type = W1_SLAVE_CMD

id = slaves[0].to_bytes(8, "little")
msg.id = (c_uint8*8).from_buffer_copy(id)


# SETUP AND SEND WRITE 0x44 = CONVERT
w1_cmd.cmd = c_uint8(W1_CMD_WRITE)
w1_cmd_data = c_uint8(0x44)


cnh.nlmsg_seq = c_uint32(nl_seq)
nl_seq += 1
cmsg.seq = c_uint32(cnh.nlmsg_seq)

w1_cmd.len = c_uint16(1)
msg.len = c_uint16(len(bytearray(w1_cmd)) + w1_cmd.len)
cmsg.len = c_uint16(len(bytearray(msg)) + msg.len)
cnh.nlmsg_len = c_uint32(len(bytearray(cnh))+len(bytearray(cmsg))+cmsg.len)

buffer = bytearray(cnh)+bytearray(cmsg)+bytearray(msg) + \
    bytearray(w1_cmd)+bytearray(w1_cmd_data)

n = s.send(buffer)
print("Bytes sent", n, flush=True)
buffer2 = s.recv(65535)
print("length of ack received ", len(buffer2), flush=True)
sleep(1)

# READ SCRATCH PAD
cnh.nlmsg_seq = nl_seq
nl_seq += 1
cmsg.seq = cnh.nlmsg_seq

w1_cmd.cmd = W1_CMD_WRITE
w1_cmd_data = c_uint8(0xBE)

w1_cmd2 = w1_netlink_cmd()
w1_cmd2.cmd = c_uint8(W1_CMD_READ)


w1_cmd.len = c_uint16(1)
w1_cmd2.len = c_uint16(9)
msg.len = c_uint16(len(bytearray(w1_cmd)) +
                   len(bytearray(w1_cmd2)) + w1_cmd.len+w1_cmd2.len)
cmsg.len = c_uint16(len(bytearray(msg)) + msg.len)
cnh.nlmsg_len = c_uint32(len(bytearray(cnh))+len(bytearray(cmsg))+cmsg.len)

w1_cmd2_data = (c_uint8*9)(0)
buffer = bytearray(cnh)+bytearray(cmsg)+bytearray(msg)+bytearray(w1_cmd) + \
    bytearray(w1_cmd_data)+bytearray(w1_cmd2)+bytearray(w1_cmd2_data)
n = s.send(buffer)
print("Bytes sent", n, flush=True)

buffer2 = s.recv(65535)
print("length of ack received ", len(buffer2), flush=True)

buffer2 = s.recv(65535)
print("length of data received ", len(buffer2), flush=True)
p = 0
cn_cnhr = nlmsghdr.from_buffer_copy(buffer2, p)
# print(cn_cnhr.nlmsg_len)
p = p+len(bytes(cn_cnhr))
cmsgr = cn_msg.from_buffer_copy(buffer2, p)
p = p+len(bytes(cmsgr))
msgr = w1_netlink_msg.from_buffer_copy(buffer2, p)
p = p+len(bytes(msgr))
w1_cmdr = w1_netlink_cmd.from_buffer_copy(buffer2, p)
p = p+len(bytes(w1_cmdr))

temp = c_uint16.from_buffer_copy(buffer2, p)

print("number of bytes found ", w1_cmdr.len, flush=True)
print(temp.value/16)

VSCODE TASKS

 

settings.json

which has to be customized to your IP, user name and folder:

{
    "sshUser": "mike",
    "sshEndpoint": "192.168.253.20",
    "remoteDirectory": "/home/mike/Documents/${workspaceFolderBasename}",  
}

tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "copyToRemote",
            "type": "shell",
            "command": "scp -r ${fileDirname} ${config:sshUser}@${config:sshEndpoint}:${config:remoteDirectory}/",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
                "clear": true
            }
        },
        {
            "label": "makeRemoteWorkSpace",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} 'mkdir  ${config:remoteDirectory}'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "RunR",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} 'python3 ${config:remoteDirectory}/${relativeFileDirname}/${fileBasename}'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "RunRemote",
            "dependsOrder": "sequence",
            "dependsOn": [
                "copyToRemote",
                "RunR"
            ],
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            },
        },
        {
            "label": "StopREmotePython",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} 'pkill python3'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": true,
            }
        },
        {
            "label": "wait",
            "type": "shell",
            "command": "timeout 10"
        },
        {
            "label": "tunnel",
            "type": "shell",
            "command": "ssh -2 -L 5678:localhost:5678  ${config:sshUser}@${config:sshEndpoint}",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "startDebug",
            "type": "shell",
            "command": "ssh -2 ${config:sshUser}@${config:sshEndpoint} 'nohup python3 -m debugpy --listen 0.0.0.0:5678 --wait-for-client ${config:remoteDirectory}/${relativeFileDirname}/${fileBasename} > /dev/null 2>&1 &'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "copyAndDebug",
            "dependsOrder": "sequence",
            "dependsOn": [
                "copyToRemote",
                "startDebug",
                "wait"
            ],
            "presentation": {
                "showReuseMessage": false,
            },
        },
    ]
}
launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Remote Attach",
            "type": "python",
            "request": "attach",
            "connect": {
                "host": "localhost",
                "port": 5678
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}/${relativeFileDirname}/",
                    "remoteRoot": "${config:remoteDirectory}/${relativeFileDirname}"
                }
            ],
            "preLaunchTask": "copyAndDebug",
            "postDebugTask": "StopREmotePython"
        }
    ]
}

Programming the Raspberry Pi Pico in C

pico360

 

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:

This email address is being protected from spambots. You need JavaScript enabled to view it. 

Page 28

#include "pico/stdlib.h"

int main() {
    gpio_init(25);
    gpio_set_dir(25, GPIO_OUT);
    while (true) {
        gpio_put(25, 1);
        sleep_ms(500);
        gpio_put(25, 0);
        sleep_ms(500);
    }
}

Page 29

cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)
project(blinky C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_executable(blinky
 blinky.c
)
target_link_libraries(blinky pico_stdlib)
pico_add_extra_outputs(blinky)

Page 34

{
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug",
"cwd": "${workspaceRoot}",
"executable": "${command:cmake.launchTargetPath}",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"gdbPath": "gdb-multiarch",
"device": "RP2040",
"configFiles": [
"interface/raspberrypi-swd.cfg",
"target/rp2040.cfg"
],
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
"runToMain": true,
// Give restart the same functionality as runToMain
"postRestartCommands": [
"break main",
"continue"
]
}
]
}

Page 38

{
    "version": "0.2.0",
    "configurations": [        

        {
            "name": "Pico Debug",
            "cwd": "${workspaceRoot}",
            "executable": "${command:cmake.launchTargetPath}",
            "request": "launch",
            "type": "cortex-debug",
            "servertype": "openocd",
            "gdbPath": "arm-none-eabi-gdb",
            "device": "RP2040",
            "configFiles": [
                "interface/picoprobe.cfg",
                "target/rp2040.cfg"
            ],
            "svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
            "runToMain": true,
            // Work around for stopping at main on restart
            "postRestartCommands": [
                "break main",
                "continue"
            ]
        }
    ]
}

Page 46

#include "pico/stdlib.h"

int main()
{
    gpio_init(22);
    gpio_set_dir(22, true);
    while (true)
    {
        gpio_put(22, 1);
        sleep_ms(1000);
        gpio_put(22, 0);
        sleep_ms(1000);
    }
}

Page 81

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, false);
    gpio_pull_up(21);

    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);

    while (true)
    {
        if (gpio_get(21))
        {
            gpio_put(22, 0);
        }
        else
        {
            gpio_put(22, 1);
        }
    }
}

Page 83

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, false);
    gpio_pull_down(21);

    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);
    gpio_put(22, 0);
    while (true)
    {
        while (gpio_get(21) == 0)
        {
        };
        while (gpio_get(21) == 1)
        {
        };
        gpio_put(22, 1);
        sleep_ms(1000);
        gpio_put(22, 0);
    }
}

Page 84

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, false);
    gpio_pull_down(21);

    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);
    gpio_put(22, 0);

    uint64_t t;

    while (true)
    {
        while (gpio_get(21) == 0)
        {
        };
        t = time_us_64();
        sleep_ms(1);
        while (gpio_get(21) == 1)
        {
        };
        t = (uint64_t)(time_us_64() - t);
        if (t < 2000 * 1000)
        {
            gpio_put(22, 1);
            sleep_ms(1000);
            gpio_put(22, 0);
        }
        else
        {
            for (int i = 0; i < 10; i++)
            {
                gpio_put(22, 1);
                sleep_ms(100);
                gpio_put(22, 0);
                sleep_ms(100);
            }
        }
    }
}

Page 86

#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    uint64_t t;

    while (true)
    {
        while (gpio_get(22) == 1)
        {
        };
        while (gpio_get(22) == 0)
        {
        };
        t = time_us_64();
        while (gpio_get(22) == 1)
        {
        };
        t = (uint64_t)(time_us_64() - t);
        printf("%llu\n", t);
        sleep_ms(1000);
    }
}

Page 89

#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    uint64_t t;
    int s = 0;
    int i;
    int count = 0;
    while (true)
    {
        i = gpio_get(22);
        t = time_us_64() + 100;
        switch (s)
        {
        case 0: //button not pushed
            if (i)
            {
                s = 1;
                count++;
                printf("Button Push %d \n\r", count);
            }
            break;
        case 1: //Button pushed
            if (!i)
            {
                s = 0;
            }
            break;
        default:
            s = 0;
        }
        sleep_until((absolute_time_t){t});
    }
}

Page 91

#include <stdio.h>
#include "pico/stdlib.h"
int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    uint64_t t;
    uint64_t tpush, twait;
    int s = 0, i;
    int count = 0;
    while (true)
    {
        i = gpio_get(22);
        t = time_us_64();
        switch (s)
        {
        case 0: //button not pushed
            if (i)
            {
                s = 1;
                tpush = t;
            }
            break;
        case 1: //Button pushed
            if (!i)
            {
                s = 0;
                if ((t - tpush) > 2000000)
                {
                    printf("Button held \n\r");
                }
                else
                {
                    printf("Button pushed \n\r");
                }
                fflush(stdout);
            }
            break;
        default:
            s = 0;
        }
        sleep_until((absolute_time_t){t + 1000});
    }
}

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  
jmp  again
  
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);
}