Raspberry Pi IoT In C Using Linux Drivers

Second Edition

Programs

 

DriverC2E360

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 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 26

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
    printf("Hello C World");
    int test = 42;
    printf("%d\n", test);
    return (EXIT_SUCCESS);
}


Page 44

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
    int fd = open("/sys/class/leds/ACT/trigger", O_WRONLY);
    write(fd, "none",4);
    close(fd);
    fd = open("/sys/class/leds/ACT/brightness", O_WRONLY);
    while (1)
    {
        write(fd, "0",1);
        sleep(2);
        write(fd, "1",1);
        sleep(2);
    }
}

Page 45

#include <stdio.h>
import io
from time import sleep

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

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

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

 


Page 54

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int res;
int main(int argc, char **argv) {
    for (;;) {
         res = gpiod_ctxless_set_value("0", 4, 1, 1,  "output test", NULL, NULL);
         res = gpiod_ctxless_set_value("0", 4, 0, 1,  "output test", NULL, NULL);
    }
}
 

 Remember to change "0" to "4" if running on a Pi 5.

Page 55 

#define _DEFAULT_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int res;

int delayms(int ms)
{
    struct timespec delay = {0, ms * 1000 * 1000};
    return nanosleep(&delay, NULL);
}

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

    for (;;)
    {
        res = gpiod_ctxless_set_value("0", 4, 1, 1, "output test", (gpiod_ctxless_set_value_cb)delayms, (void *)100);
        res = gpiod_ctxless_set_value("0", 4, 0, 1, "output test", (gpiod_ctxless_set_value_cb)delayms, (void *)100);
    }
}

 Remember to change "0" to "4" if running on a Pi 5.

Page 56 

#define _DEFAULT_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int res;
int delayms(int ms)
{
    struct timespec delay = {0, ms * 1000 * 1000};
    return nanosleep(&delay, NULL);
}
int main(int argc, char **argv)
{
    int offsets[] = {4, 17};
    int state1[] = {1, 0};
    int state2[] = {0, 1};
    for (;;)
    {
        gpiod_ctxless_set_value_multiple("0", offsets, state1, 2, 1, "output test", (gpiod_ctxless_set_value_cb)delayms, (void *)1);
        gpiod_ctxless_set_value_multiple("0", offsets, state2, 2, 1, "output test", (gpiod_ctxless_set_value_cb)delayms, (void *)2);
    }
}
 
 Remember to change "0" to "4" if running on a Pi 5.

Page 58

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

int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    const char *name = gpiod_chip_name(chip);
    int num = gpiod_chip_num_lines(chip);
    printf("%s %d", name, num);
    gpiod_chip_close(chip);

 Remember to change chip number 0 to 4 if running on a Pi 5.

Page 60 

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

int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);
    res = gpiod_line_request_output(line4, "test output", 0);

    for (;;)
    {
        res = gpiod_line_set_value(line4, 1);
        res = gpiod_line_set_value(line4, 0);
    };

 Remember to change chip number 0 to 4 if running on a Pi 5.

 

Page 64

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

int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line_bulk bulk;
    gpiod_line_bulk_init(&bulk);
    gpiod_line_bulk_add(&bulk, gpiod_chip_get_line(chip, 4));
    gpiod_line_bulk_add(&bulk, gpiod_chip_get_line(chip, 17));

    res = gpiod_line_request_bulk_output(&bulk, "test", 0);
    for (;;)
    {
        gpiod_line_set_value_bulk(&bulk, (int[2]){0, 1});
        gpiod_line_set_value_bulk(&bulk, (int[2]){1, 0});
    };
}
 

 Remember to change chip number 0 to 4 if running on a Pi 5.

 

Page 66 

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void gpiod_line_release(struct gpiod_line *line);

int main(int argc, char **argv)
{
    int res;
    struct timespec delay = {0, 10 * 1000 * 1000};
    struct timespec time1, time2;

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_input(line4, "RMeasure");
    nanosleep(&delay, NULL);
    gpiod_line_release(line4);

    res = gpiod_line_request_output(line4, "RMeasure", 0);
    nanosleep(&delay, NULL);
    gpiod_line_release(line4);

    clock_gettime(CLOCK_REALTIME, &time1);
    gpiod_line_request_input(line4, "RMeasure");
    while (gpiod_line_get_value(line4) == 0)
    {
    };
    clock_gettime(CLOCK_REALTIME, &time2);
    printf("Time=%d", (time2.tv_nsec - time1.tv_nsec) / 1000);
}  
 

 Remember to change chip number 0 to 4 if running on a Pi 5.


 

Page 70

#define __ARM_PCS_VFP
#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;
}
 

If you run this on a Pi 5 change gpiochip0 to gpiochip4.

Page 73

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

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 74 

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

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 75 

#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/gpio.h>
#include <sys/ioctl.h>
#include <time.h>
int main(int argc, char **argv)
{
    int fd, ret;
    struct timespec delay = {0, 10 * 1000 * 1000};
    struct timespec time1, time2;
    fd = open("/dev/gpiochip0", O_RDONLY);
    struct gpiohandle_request req;
    req.lineoffsets[0] = 4;
    strcpy(req.consumer_label, "RC Measure");
    req.lines = 1;

    req.flags = GPIOHANDLE_REQUEST_INPUT;
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    nanosleep(&delay, NULL);
    close(req.fd);

    req.flags = GPIOHANDLE_REQUEST_OUTPUT;
    struct gpiohandle_data data;
    data.values[0] = 0;
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
    nanosleep(&delay, NULL);
    close(req.fd);

    req.flags = GPIOHANDLE_REQUEST_INPUT;
    clock_gettime(CLOCK_REALTIME, &time1);
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);

    while (data.values[0] == 0)
    {
        ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data)
    }
    clock_gettime(CLOCK_REALTIME, &time2);
    printf("Time=%d", (time2.tv_nsec - time1.tv_nsec) / 1000);
    return 0;

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.


 

Page 83

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

int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);
    gpiod_line_request_both_edges_events(line4, "event test");
    gpiod_line_event_wait(line4, NULL);
    printf("Event on line 4");
}

Page 84

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void gpiod_line_release(struct gpiod_line *line);
int main(int argc, char **argv)
{
    int res;

    struct timespec delay = {0, 10 * 1000 * 1000};
    struct timespec time1;

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_input(line4, "RMeasure");
    nanosleep(&delay, NULL);
    gpiod_line_release(line4);

    res = gpiod_line_request_output(line4, "RMeasure", 0);
    nanosleep(&delay, NULL);
    gpiod_line_release(line4);
    clock_gettime(CLOCK_REALTIME, &time1);

    gpiod_line_request_rising_edge_events(line4, "RMeasuret");
    struct gpiod_line_event event;
    gpiod_line_event_read(line4, &event);
    printf("Event on line 4 %d, %d", event.event_type,  (event.ts.tv_nsec - time1.tv_nsec) / 1000);
}

 

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 85

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void gpiod_line_release(struct gpiod_line *line);
int main(int argc, char **argv)
{
    int res;
    struct timespec time1;

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_both_edges_events(line4, "Measure");

    struct gpiod_line_event event;
    while (true)
    {
        do
        {
            res = gpiod_line_event_read(line4, &event);
        } while (event.event_type != GPIOD_LINE_EVENT_RISING_EDGE);

        time1.tv_nsec = event.ts.tv_nsec;

        do
        {
            res = gpiod_line_event_read(line4, &event);
        } while (event.event_type != GPIOD_LINE_EVENT_FALLING_EDGE);

        printf("Pulse Width %d \r\n",
               (event.ts.tv_nsec - time1.tv_nsec) / 1000);
        fflush(stdout);
    }

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

 

Page 86

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void gpiod_line_release(struct gpiod_line *line);
int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_input(line4, "button");
    printf("Press button \n\r");
    fflush(stdout);
    sleep(20);
    if (gpiod_line_get_value(line4) == 1)
    {
        printf("button pressed");
    }
    else
    {
        printf("button not pressed");
    }
}

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 87

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void gpiod_line_release(struct gpiod_line *line);
int main(int argc, char **argv)
{
    int res;
    struct timespec timeout = {0, 0};

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_both_edges_events(line4, "button");

    printf("Press button \n\r");
    fflush(stdout);
    sleep(20);
    struct gpiod_line_event event;

    res = gpiod_line_event_wait(line4, &timeout);
    if (res > 0)
    {
        res = gpiod_line_event_read(line4, &event);
        printf("button pressed %d", event.ts.tv_nsec);
    }
    else
    {
        printf("button not pressed");
    }

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 88

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

int gpiod_line_event_poll(struct gpiod_line *line, struct gpiod_line_event *event);

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

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_both_edges_events(line4, "button");

    struct gpiod_line_event event;

    while (true)
    {
        res = gpiod_line_event_poll(line4, &event);
        if (res > 0)
        {
            gpiod_line_event_read(line4, &event);
            printf("Event on line 4 %d,%d \n\r ",  event.event_type, event.ts);
            fflush(stdout);
        }
    }
}

int gpiod_line_event_poll(struct gpiod_line *line,   struct gpiod_line_event *event)
{
    struct timespec timeout = {0, 0};
    int res = gpiod_line_event_wait(line, &timeout);
    if (res > 0)
        res = gpiod_line_event_read(line, event);
    if (res == 0)
        res = 1;
    return res;
}

 

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 92

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

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 93

#define _GNU_SOURCE
#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 <gpiod.h>

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

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_rising_edge_events(line4, "button");
    int fd = gpiod_line_event_get_fd(line4);

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

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

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 97

#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <gpiod.h>
#include <sys/epoll.h>
#include <pthread.h>

typedef void (*eventHandler)(struct gpiod_line_event *);
typedef struct
{
    struct gpiod_line *line;
    eventHandler func;
} intVec;
void myHandler(struct gpiod_line_event *event)
{
    printf("%d,%d \n\r", event->event_type,
           event->ts.tv_nsec / 1000);
    fflush(stdout);
}

void *waitInterrupt(void *arg)
{
    intVec *intData = (intVec *)arg;
    struct gpiod_line_event event;
    while (true)
    {
        int res = gpiod_line_event_read(intData->line, &event);
        if (res == 0)
            intData->func(&event);
    }
}

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

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_rising_edge_events(line4, "button");

    intVec intData;
    intData.line = line4;
    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);
    }

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 100

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

int event_cb(int event, unsigned int offset, const struct timespec *timestamp, void *unused)
{
   printf("[%ld.%09ld] %s\n", timestamp->tv_sec, timestamp->tv_nsec,
     (event == GPIOD_CTXLESS_EVENT_CB_RISING_EDGE)? "rising" :
     (event == GPIOD_CTXLESS_EVENT_CB_FALLING_EDGE)? "falling" :
     (event == GPIOD_CTXLESS_EVENT_CB_TIMEOUT) ? "timeout" : "??");
     fflush(stdout);
     return GPIOD_CTXLESS_EVENT_CB_RET_OK;
}


int main(int argc, char **argv) {
    int res;
    struct timespec time;
    time.tv_nsec=0;
    time.tv_sec=20;
    res = gpiod_ctxless_event_monitor("0",
            GPIOD_CTXLESS_EVENT_BOTH_EDGES, 4, 0, "monitor test",
               &time, NULL, event_cb, NULL);
}

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

 


Page 110 

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
    char buffer[25];

    int fd = open("/sys/bus/iio/devices/iio:device0/name", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    printf("%s", buffer);

    fd = open("/sys/bus/iio/devices/iio:device0/in_temp_input", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    int temp;
    sscanf(buffer, "%d", &temp);

    printf("%f\n\r", temp / 1000.0);
    fd = open("/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    int hum;
    sscanf(buffer, "%d", &hum);
    printf("%f\n\r", hum / 1000.0);
}

Page 112

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

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkDht11()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "dht11  gpiopin=4";
    char command[] = "sudo dtoverlay dht11 gpiopin=4";
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
        }
    }
    if (txfound == 0)
    {
        fd = doCommand(command);
    }

    pclose(fd);
}

int main(int argc, char **argv)
{
    char buffer[25];
    checkDht11();
    int fd = open( "/sys/bus/iio/devices/iio:device0/name", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    printf("%s", buffer);

    fd = open( "/sys/bus/iio/devices/iio:device0/in_temp_input", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    int temp;
    sscanf(buffer, "%d", &temp);

    printf("%f\n\r", temp / 1000.0);

    fd = open("/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    int hum;
    sscanf(buffer, "%d", &hum);
    printf("%f\n\r", hum / 1000.0);

 


 

Page 133

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void pwm(struct gpiod_line *line, int);

int main(int argc, char **argv)
{
    int period = 20;
    int duty = 25;
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);
    res = gpiod_line_request_output(line4, "test output", 0);

    struct timespec ontime = {0, 0};
    struct timespec offtime = {0, 0};
    ontime.tv_nsec = period * duty * 10 * 1000;
    offtime.tv_nsec = (period - period * duty / 100) * 1000 * 1000;

    for (;;)
    {
        res = gpiod_line_set_value(line4, 1);
        nanosleep(&ontime, NULL);
        res = gpiod_line_set_value(line4, 0);
        nanosleep(&offtime, NULL);
    };
}
 

Remember to change "0" to "4" if you are running on a Pi 5.

Page  134

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>

struct pwmargs
{
    struct gpiod_line *line;
    struct timespec ontime;
    struct timespec offtime;
};

void *pwmrun(void *arg)
{
    struct pwmargs *pwmdata = (struct pwmargs *)arg;
    int res;
    for (;;)
    {
        res = gpiod_line_set_value(pwmdata->line, 1);
        nanosleep(&(pwmdata->ontime), NULL);
        res = gpiod_line_set_value(pwmdata->line, 0);
        nanosleep(&(pwmdata->offtime), NULL);
    };
}

int pwm(struct gpiod_line *line, int period, int duty)
{
    static struct pwmargs pwmdata;
    pwmdata.line = line;
    pwmdata.ontime.tv_sec = 0;
    pwmdata.ontime.tv_nsec = period * duty * 10;
    pwmdata.offtime.tv_sec = 0;
    pwmdata.offtime.tv_nsec = (period - period * duty / 100) * 1000;

    pthread_t pwmThread;
    if (pthread_create(&pwmThread, NULL, pwmrun, (void *)&pwmdata))
    {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    return 0;
};

int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);
    res = gpiod_line_request_output(line4, "test output", 0);

    pwm(line4, 20 * 1000, 25);
    for (;;)
    {
    };
}
 

Remember to change "0" to "4" if you are running on a Pi 5.

Page 137

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

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkPWM()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "pwm-2chan";
    char command[] = "sudo dtoverlay pwm-2chan";
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
        }
    }
    if (txfound == 0)
    {
        fd = doCommand(command);
        sleep(2);
    }

    pclose(fd);
}

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

    int fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY);
    write(fd, "0", 1);
    close(fd);
    sleep(2);
    fd = open("/sys/class/pwm/pwmchip0/pwm0/period", O_WRONLY);
    write(fd, "10000000", 8);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip0/pwm0/duty_cycle", O_WRONLY);
    write(fd, "8000000", 7);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip0/pwm0/enable", O_WRONLY);
    write(fd, "1", 1);
    close(fd);
}

 

Remember to change "0" to "4" if you are running on a Pi 5.

Page 139

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

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkPWM()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "pwm";
    char command[] = "sudo dtoverlay pwm-2chan, pin=18 func=2 pin2=12 func2=4" ;
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
            printf("Overlay already loaded\n\r");
        }
    }
    if (txfound == 0)
    {
        fd = doCommand(command);
        sleep(2);
    }

    pclose(fd);
}

int main(int argc, char **argv)
{
    checkPWM();  
    int fd = open("/sys/class/pwm/pwmchip2/export", O_WRONLY);
    write(fd, "0", 1);
    close(fd);
    sleep(2);
    fd = open("/sys/class/pwm/pwmchip2/pwm0/period", O_WRONLY);
    write(fd, "10000001", 8);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip2/pwm0/duty_cycle", O_WRONLY);
    write(fd, "4000000", 7);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip2/pwm0/enable", O_WRONLY);
    write(fd, "1", 1);
    close(fd);
   
    fd = open("/sys/class/pwm/pwmchip2/export", O_WRONLY);
    write(fd, "2", 1);
    close(fd);
    sleep(2);
    fd = open("/sys/class/pwm/pwmchip2/pwm2/period", O_WRONLY);
    write(fd, "10000001", 8);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip2/pwm2/duty_cycle", O_WRONLY);
    write(fd, "5000000", 7);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip2/pwm2/enable", O_WRONLY);
    write(fd, "1", 1);
    close(fd);
}
 

Page 141 - full listing of finished program on Page 155

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

 #define Pi5

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkPWM()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "pwm-2chan";
    char command[] = "sudo dtoverlay pwm-2chan pin=12 func=4 pin2=13 func2=4";
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
        }
    }
    if (txfound == 0)
    {
        pclose(fd);
        fd = doCommand(command);
    }

    pclose(fd);
}
enum pwm
{
    OpenChan,
    SetFreq,
    SetDuty,
    EnableChan,
    DisableChan,
    CloseChan,
    InvertChan
};

int pwmAction(enum pwm action, int chan, ...)
{
    static int fdf[2];
    static int fdd[2];

    int fd;
    char buf[150];
    char schan[6];
    va_list params;
    int param;

    if (chan != 0 && chan != 1)
        return -1;

#if defined(Pi5)
    char path[] = "/sys/class/pwm/pwmchip2/";
#else
    char path[] = "/sys/class/pwm/pwmchip0/";
#endif
    char chanNum[2];
    snprintf(schan, 6, "%s%d", "pwm", chan);
    snprintf(chanNum, 2, "%d", chan);

    int L;

    switch (action)
    {
    case OpenChan:
        checkPWM();
        snprintf(buf, 150, "%s%s", path, "export");
        fd = open(buf, O_WRONLY);
        write(fd, chanNum, 1);
        close(fd);
        sleep(2);
        snprintf(buf, 150, "%s%s%s", path, schan, "/period");
        fdf[chan] = open(buf, O_WRONLY);
        snprintf(buf, 150, "%s%s%s", path, schan, "/duty_cycle");
        fdd[chan] = open(buf, O_WRONLY);
        break;

    case SetFreq:
        va_start(params, chan);
        param = va_arg(params, int);
        L = snprintf(buf, 150, "%d", param);
        write(fdf[chan], buf, L);
        break;
    case SetDuty:
        va_start(params, chan);
        param = va_arg(params, int);
        L = snprintf(buf, 150, "%d", param);
        write(fdd[chan], buf, L);
        break;
    case EnableChan:
        snprintf(buf, 150, "%s%s%s", path, schan, "/enable");
        fd = open(buf, O_WRONLY);
        write(fd, "1", 1);
        close(fd);
        break;
    case DisableChan:
        snprintf(buf, 150, "%s%s%s", path, schan, "/enable");
        fd = open(buf, O_WRONLY);
        write(fd, "0", 1);
        close(fd);
        break;
    case CloseChan:
        close(fdf[chan]);
        close(fdd[chan]);
        snprintf(buf, 150, "%s%s%s", path, "/unexport");
        printf("%s\n", buf);
        fd = open(buf, O_WRONLY);
        write(fd, chanNum, 1);
        close(fd);
        break;

    case InvertChan:
        va_start(params, chan);
        param = va_arg(params, int);
        snprintf(buf, 150, "%s%s%s", path, schan, "/polarity");
        fd = open(buf, O_WRONLY);
        if (param == 0)
        {
            L = snprintf(buf, 150, "%s", "normal");
            write(fd, buf, L);
        }
        if (param == 1)
        {
            L = snprintf(buf, 150, "%s", "inversed");
            write(fd, buf, L);
        }
        close(fd);
        break;
    }

    return 0;
}

int main(int argc, char **argv)
{
    pwmAction(OpenChan, 0, 0);
   

    int t = 20 * 1000000;
    pwmAction(SetFreq, 0, t);
    int d1 = t * 2.5 / 100;
    int d2 = t * 12 / 100;
   
    pwmAction(EnableChan, 0, 0);

    for (;;)
    {
        pwmAction(SetDuty, 0, d1);
        sleep(1);
        pwmAction(SetDuty, 0, d2);
        sleep(1);
    }
}

 


Page 167 

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <stdint.h>

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkSPI0()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "spi=on";
    char command[] = "sudo dtparam spi=on";
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
        }
    }
    if (txfound == 0)
    {
        fd = doCommand(command);
        sleep(2);
    }

    pclose(fd);
}

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

    uint8_t tx[] = {0xAA};
    uint8_t rx[] = {0};

    struct spi_ioc_transfer tr =
        {
            .tx_buf = (unsigned long)tx,
            .rx_buf = (unsigned long)rx,
            .len = 1,
            .delay_usecs = 0,
            .speed_hz = 500000,
            .bits_per_word = 8,
        };

    int fd = open("/dev/spidev0.0", O_RDWR);  
    int status = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    if (status < 0)
        printf("can't send data");
    printf("%X,%X\n", tx[0],rx[0]);
    close(fd);
}

 

Page 177

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <stdint.h>

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkSPI0()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "spi=on";
    char command[] = "sudo dtparam spi=on";
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
        }
    }
    if (txfound == 0)
    {
        fd = doCommand(command);
        sleep(2);
    }

    pclose(fd);
}

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

    uint8_t tx[] = {0x01, 0x80, 0x00};
    uint8_t rx[3];

    struct spi_ioc_transfer tr =
        {
            .tx_buf = (unsigned long)tx,
            .rx_buf = (unsigned long)rx,
            .len = 3,
            .delay_usecs = 0,
            .speed_hz = 0,
            .bits_per_word = 0,
        };

    int fd = open("/dev/spidev0.0", O_RDWR);

    static uint8_t mode = 0;
    int status = ioctl(fd, SPI_IOC_WR_MODE, &mode);
    if (status == -1)
        printf("can't set spi mode");

    static uint8_t bits = 8;
    status = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    if (status == -1)
        printf("can't set bits per word");

    static uint32_t speed = 100000;
    status = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
    if (status == -1)
        printf("can't set max speed hz");

    status = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    if (status < 0)
        printf("can't send data");

    int data = ((int)rx[1] & 0x03) << 8 | (int)rx[2];
    float volts = (((float)data) * 3.3f) / 1023.0f;
    printf("%f V\n\r", volts);

    close(fd);

 

Page 197

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>

void checkI2CBus();
FILE *doCommand(char *cmd);

int main(int argc, char **argv)
{
    checkI2CBus();
    int i2cfd = open("/dev/i2c-1", O_RDWR);
    ioctl(i2cfd, I2C_SLAVE, 0x40);
    char buf[4] = {0xE7};
    write(i2cfd, buf, 1);
    read(i2cfd, buf, 1);
    close(i2cfd
    return (EXIT_SUCCESS);
}

Page 206

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>

void checkI2CBus();
FILE *doCommand(char *cmd);
uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check);

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

    checkI2CBus();

    int i2cfd = open("/dev/i2c-1", O_RDWR);
    ioctl(i2cfd, I2C_SLAVE, 0x40);
    char buf[3] = {0xF3};
    write(i2cfd, buf, 1);

    while (1)
    {
        int result = read(i2cfd, buf, 3);
        if (result > 0)
            break;
        usleep(10 * 1000);
    }
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\rlsb %d \n\rchecksum %d \n\r", 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);
    printf("crc = %d\n\r", crcCheck(msb, lsb, check));
    buf[0] = 0xF5;
    write(i2cfd, buf, 1);

    while (1)
    {
        int result = read(i2cfd, buf, 3);
        if (result > 0)
            break;
        usleep(10 * 1000);
    }
    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);
    close(i2cfd);
    return (EXIT_SUCCESS);
}

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

void checkI2CBus()
{
    FILE *fd = doCommand("sudo dtparam -l");
    char output[1024];
    int txfound = 0;
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, "i2c_arm=on") != NULL)
        {
            txfound = 1;
        }
        if (strstr(output, "i2c_arm=off") != NULL)
        {
            txfound = 0;
        }
    }
    pclose(fd);
    if (txfound == 0)
    {
        fd = doCommand("sudo dtparam i2c_arm=on");
        pclose(fd);
    }
}

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}

 

Page 219

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>


void checkI2CBus();


int main(int argc, char **argv)
{
    int i2cfd = open("/dev/i2c-1", O_RDWR);
    ioctl(i2cfd, I2C_SLAVE, 0x40);
    char buf[3] = {0xE3};
    write(i2cfd, buf, 1);
    int result = read(i2cfd, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\rlsb %d \n\rchecksum %d \n\r", msb, lsb, check);
}

Page 222

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>

void checkI2CBus();
int i2cReadRegister(int i2cfd, uint8_t slaveaddr, uint8_t reg, uint8_t *buf, int len);

int main(int argc, char **argv)
{
    checkI2CBus();
    int i2cfd = open("/dev/i2c-1", O_RDWR);
    char buf2[1] = {0};
    i2cReadRegister(i2cfd, 0x40, 0xE7, buf2, 1);
    printf("%d \n\r", buf2[0]);
    return (EXIT_SUCCESS);
}

 


Page 227

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

int main(int argc, char **argv)
{
    int fd = open("/sys/class/hwmon/hwmon0/temp1_input", O_RDONLY);
    char buf[100] = {0};
    read(fd, buf, 100);
    printf("%s\n\r", buf);
    float temp;
    sscanf(buf, "%f", &temp);
    temp = temp / 1000;
    printf("%f\n\r", temp);
}

Page 234

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>

void loadHTU21();

int main(int argc, char **argv)
{
    loadHTU21();
    float temp;
    float hum;

    {
        char output[1024] = {0};
        int fdtemp = open("/sys/bus/iio/devices/iio:device0/in_temp_input", O_RDWR);
        read(fdtemp, output, sizeof(output));
        close(fdtemp);
        printf("%s\n\r", output);
        sscanf(output, "%f", &temp);
        temp = temp / 1000;
        fflush(stdout);
    }

    {
        char output[1024] = {0};
        int fdhum = open("/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", O_RDWR);
        read(fdhum, output, sizeof(output));
        close(fdhum);
        printf("%s\n\r", output);
        sscanf(output, "%f", &hum);
        hum = hum / 1000;
        fflush(stdout);
    }
    printf("%f\n\r", temp);
    printf("%f\n\r", hum);

    return (EXIT_SUCCESS);
}

void loadHTU21()
{
    FILE *fd = doCommand("sudo dtparam -l");
    char output[1024];
    int txfound = 0;
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, "i2c-sensor  htu21=true") != NULL)
        {
            txfound = 1;
        }
    }
    pclose(fd);
    if (txfound == 0)
    {
        fd = doCommand("sudo dtoverlay i2c-sensor htu21");
        pclose(fd);
    }
}

 

Page 248

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

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}

void load1w(int pin)
{
    FILE *fd = doCommand("sudo dtparam -l");
    char output[1024];
    int txfound = 0;
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, "w1-gpio") != NULL)
        {
            txfound = 1;
        }
    }
    pclose(fd);
    if (txfound == 0)
    {
        char cmd[100];
        snprintf(cmd, 100, "sudo dtoverlay w1-gpio gpiopin=%d", pin);

        fd = doCommand(cmd);
        pclose(fd);
    }
}

int getDevices(char path[][100], int *num)
{
    char buffer[500];
    int fd = open("/sys/bus/w1/drivers/w1_master_driver/w1_bus_master1/w1_master_slaves", O_RDONLY);
    read(fd, buffer, 500);
    close(fd);
    *num = 0;
    for (char *p = strtok(buffer, "\n"); p != NULL; p = strtok(NULL, "\n"))
    {
        snprintf(path[(*num)++], 100, "/sys/bus/w1/devices/%s", p);
    }
    num--;
}

int getData(char path[], char name[], char data[], int n)
{
    char file[100];
    snprintf(file, 100, "%s/%s", path, name);
    int fd = open(file, O_RDONLY);
    int c = read(fd, data, n);
    close(fd);
    data[c] = 0;
    return c;
}

int main(int argc, char **argv)
{
    load1w(4);
    char path[10][100];
    int num;
    getDevices(path, &num);
    printf("%d  %s\n\r", num, path[0]);
    if (num < 1)
        exit(-1);

    char output[1024] = {0};
    char file[100];

    getData(path[0], "name", output, 100);
    printf("Name %s\n\r", output);

    getData(path[0], "resolution", output, 100);
    printf("Resolution %s\n\r", output);

    getData(path[0], "w1_slave", output, 100);
    printf("w1_slave %s\n\r", output);

    getData(path[0], "temperature", output, 100);
    printf("temperature %s\n\r", output);
    float temp;
    sscanf(output, "%f", &temp);
    temp = temp / 1000;
    printf("temperature %f C\n\r", temp);

    getData(path[0], "alarms", output, 100);
    printf("alarms %s\n\r", output);
}


 

Page 269

launch.json

{
  "configurations": [    
    {
      "name": "Remote C Debug",
      "type": "cppdbg",
      "request": "launch",
      "program": "${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}",
      "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",
     }
  ]
}

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}'",
         "problemMatcher": [],
         "presentation": {
            "showReuseMessage": false,
            "clear": false
         }
      },
      {
         "label": "runRemote",
         "type": "shell",
         "command": "ssh ${config:sshUser}@${config:sshEndpoint} '${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}'",
         "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}'",
         "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
         }
      },
   ],
}

c_cpp_properties.json for Mingw 

{
    "configurations": [
      {
        "name": "Win32",
        "includePath": [
                  "${workspaceFolder}/**",
                  "C:/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/i686-w64-mingw32/include"
                  ],
        "defines": [
                  "_DEBUG",
                  "UNICODE",
                  "_UNICODE"
                  ],
        "cStandard": "c99",
        "intelliSenseMode": "gcc-arm"
      }
    ],
   "version": 4
  }

 

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
}
},
],
}
 
 
 
 

Programming the ESP32 in MicroPython

 esppython360

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 Thonny or Pycharm 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 44

from machine import Pin
import time

pin = Pin(2, Pin.OUT)
while True:
    pin.value(1)
    time.sleep(1)
    pin.value(0)
    time.sleep(1)

Page 46

from machine import Pin
import time
def toggle(pin):
    temp = pin.value()
    temp = not temp
    pin.value(temp)

pin = Pin(2,Pin.OUT)
while True:
    toggle(pin)
    time.sleep(1)

 

Page 50

from machine import  Pin
pin = Pin(6, Pin.OUT)
while True:
    pin.value(1)
    pin.value(0)
 

Page 51

from machine import  Pin
def flash():
    pin = Pin(2, Pin.OUT)
    while True:
        pin.value(1)
        pin.value(0)
flash()

Page 51

from machine import Pin

@micropython.native
def flash():
    pin = Pin(2, Pin.OUT)
    while True:
        pin.value(1)
        pin.value(0)
flash()

Page 52

from machine import Pin
import time
pin = Pin(2, Pin.OUT)
while True:
    pin.value(1)
    time.sleep(0.5)
    pin.value(0)
    time.sleep(0.5)
 

Page 53

from machine import Pin
import time
pin = Pin(2, Pin.OUT)
while True:
    pin.value(1)
    time.sleep_us(10)
    pin.value(0)
    time.sleep_us(10)

Page 53

from machine import Pin
import time
pin = Pin(2, Pin.OUT)
n = 10
while True:
    for i in range(n):
        pass
    pin.value(1)
    for i in range(n):
        pass
    pin.value(0)

Page 54

from machine import Pin
import time
pin = Pin(2, Pin.OUT)
n = 5
while True:
    t = time.ticks_add(time.ticks_us(), 1000)
    pin.value(1)
    for i in range(n):
        pass

    while time.ticks_us() < t:
        pass
    pin.value(0)

Page 56

import time
from time import sleep
import esp32
from machine import Pin
import machine
pin = Pin(2,Pin.OUT,value=0)
buf = bytearray(b"\x55\x55")
print(buf)
machine.bitstream(pin,0,(80,90,100,110),buf)
 

Page 58

import esp32
from machine import Pin
import machine
pin=Pin(2,Pin.OUT,value=0)
rmt=esp32.RMT(0,pin=pin)
rmt.write_pulses((1000,400,200,300,200,300),1)

Page 59

from machine import Pin

pin1 = Pin(2, Pin.OUT)
pin2 = Pin(4, Pin.OUT)
while True:
    pin1.value(1)
    pin2.value(0)
    pin1.value(0)
    pin2.value(1)

Page 61  

from machine import Pin
import machine

def gpio_set(value, mask):
    machine.mem32[0x3FF44004] = machine.mem32[0x3FF44004] & ~mask | value & mask

pin = Pin(2, Pin.OUT)
pin = Pin(4, Pin.OUT)
value1 = 1 << 2 | 0 << 4
value2 = 0 << 2 | 1 << 4
mask = 1 << 2 | 1 << 4
while True:
    gpio_set(value1, mask)
    gpio_set(value2, mask)

Page 83

from machine import Pin
import time
pinIn = Pin(4, Pin.IN,Pin.PULL_UP)
pinLED = Pin(2, Pin.OUT)

while True:
    if pinIn.value():
        pinLED.on()
    else:
        pinLED.off()
    time.sleep(0.5)

Page 84

from machine import Pin
import time

pinIn = Pin(4, Pin.IN,Pin.PULL_DOWN)
pinLED = Pin(2, Pin.OUT)

while True:
    while pinIn.value()==0:
        pass
    while pinIn.value()==1:
        pass
    pinLED.on()
    time.sleep_ms(1)
    pinLED.off()

Page 85

from machine import Pin
import time
pinIn = Pin(4, Pin.IN,Pin.PULL_DOWN)
pinLED = Pin(2, Pin.OUT)

while True:
    while pinIn.value() == 0:
        pass
    t = time.ticks_ms()
    time.sleep_ms(1)
    while pinIn.value() == 1:
        pass
    t = time.ticks_diff(time.ticks_ms(),t)
    if t<2000:
        pinLED.on()
        time.sleep(1)
        pinLED.off()
    else:
        for i in range(10):
            pinLED.on()
            time.sleep_ms(100)
            pinLED.off()
            time.sleep_ms(100)

Page 86

from machine import Pin
import time
pinIn = Pin(4, Pin.IN)

while True:
    while pinIn.value()==1:
        pass
    while pinIn.value()==0:
        pass

    t=time.ticks_us()
    while pinIn.value()==1:
        pass
    t=time.ticks_diff(time.ticks_us(),t)
    print(t)
    time.sleep(1)

Page 87

import time
import machine

pinIn = machine.Pin(4, machine.Pin.IN)

while True:
    t = machine.time_pulse_us(pinIn, 1)
    print(t)
    time.sleep(1)

Page 87

import time
import machine

pinIn = machine.Pin(4, machine.Pin.IN)

while True:
    while pinIn.value() == 1:
        pass
    t = machine.time_pulse_us(pinIn, 1)
    print(t)
    time.sleep(1)

Page 90

from machine import Pin
import time

pinIn = Pin(4, Pin.IN)

s = 0
count = 0
while True:
    I = pinIn.value()
    t = time.ticks_add(time.ticks_us(),1000*100)
    if s == 0:   #button not pushed
        if i:
            s = 1
            count=count+1
            print("Button Push ",count)
    elif s == 1: #button pushed
        if not i:
            s = 0
    else:
        s = 0
    while time.ticks_us()<t:
        pass

Page 92

from machine import Pin
import time
pinIn = Pin(4, Pin.IN)

s = 0
while True:
    I = pinIn.value()
    t = time.ticks_add(time.ticks_us(),1000*100)
    if s == 0:       #button not pushed
        if i:
            s = 1
        tpush = t
    elif s == 1:     #button pushed
        if not i:
            s = 0
            if time.ticks_diff(t, tpush) > 2000000:
                print("Button held \n\r")                
            else:
                print("Button pushed \n\r")
    else:
        s = 0
    while time.ticks_us()<t:
        pass

Page 93

from machine import Pin
import time
pinIn = Pin(4, Pin.IN)
pinLED1 = Pin(2, Pin.OUT)
pinLED2 = Pin(16, Pin.OUT)
pinLED3 = Pin(17, Pin.OUT)
pinLED1.on()
pinLED2.off()
pinLED3.off()
s = 0
buttonState = pinIn.value()
while True:
    buttonNow = pinIn.value()
    edge = buttonState-buttonNow
    buttonState = buttonNow
    t = time.ticks_add(time.ticks_us(), 1000*100)
    if s == 0:
        if edge == 1:
            s = 1
            pinLED1.off()
            pinLED2.on()
            pinLED3.off()

    elif s == 1:
        if edge == 1:
            s = 2
            pinLED1.off()
            pinLED2.off()
            pinLED3.on()
    elif s == 2:
        if edge == 1:
            s = 0
            pinLED1.on()
            pinLED2.off()
            pinLED3.off()
    else:
        s = 0
    while time.ticks_us() < t:
        pass

Page 100
 
def HelloIRQ1(pin):
    print("IRQ1")
   
def HelloIRQ2(pin):
    print("IRQ2")

pin1=Pin(4,Pin.IN,Pin.PULL_DOWN)
pin2=Pin(5,Pin.IN,Pin.PULL_DOWN)

pin1.irq(HelloIRQ1,Pin.IRQ_RISING)
pin2.irq(HelloIRQ2,Pin.IRQ_RISING)

Page 101

import time
from machine import Pin
t = 0
def myHandler(pin):
    global t
    temp = time.ticks_us()
    print(time.ticks_diff(temp,t))
    t = temp
    time.sleep(1.5)  
    return

pin = Pin(4, Pin.IN, Pin.PULL_DOWN)
pin.irq(myHandler, Pin.IRQ_FALLING)

Page 101

import time
from machine import Pin
t = 0
def myHandler(pin):
    global t
    pin.irq(None, Pin.IRQ_FALLING)
    temp = time.ticks_us()
    print(time.ticks_diff(temp,t))
    t = temp
    time.sleep(1.5)
    pin.irq(myHandler, Pin.IRQ_FALLING)
    return
pin = Pin(4, Pin.IN, Pin.PULL_DOWN)
pin.irq(myHandler, Pin.IRQ_FALLING)

Page 104

import time
from machine import Pin

data = bytearray(b'\xf0\xf1\xf2')

def myHandler(pin):
    global data
    for i in range(3):
        data[i]=0

pin = Pin(4, Pin.IN, Pin.PULL_DOWN)
pin.irq(myHandler, Pin.IRQ_RISING)

while True:
    for i in range(3):
        data[i] = 255
    if data[0]!=data[1] or data[1]!=data[2] or data[2]!=data[0]:
        print(data)

Page 105

from machine import Pin

data=bytearray(b'\xf0\xf1\xf2')
def myHandler(pin):
    global data
    for i in range(3):
        data[i] = 0
    print(data)

pin = Pin(4, Pin.IN, Pin.PULL_DOWN)
pin.irq(myHandler, Pin.IRQ_RISING)
while True:
    pin.irq(None, Pin.IRQ_RISING)
    for i in range(3):
        data[i] = 255

    if data[0]!=data[1] or data[1]!=data[2] or data[2]!=data[0]:
        print(data)
    pin.irq(myHandler, Pin.IRQ_RISING)

Page 106

import time

from time import sleep 

from machine import Pin
pin=Pin(4,Pin.IN,Pin.PULL_DOWN)
event=0
def rise(pin):
    global event
    event=1

def fall(pin):
    global event
    event=2

while True:
    pin.irq(rise, Pin.IRQ_RISING)
    while  not(event==1):
        pass
    t=time.ticks_us()
    pin.irq(fall, Pin.IRQ_FALLING)
    while  not(event==2):
        pass
    t=time.ticks_diff(time.ticks_us(),t)
    print(t)
    sleep(1)
 

Page 114
import esp32
from machine import Pin
import machine
pin=Pin(4,Pin.OUT,value=0)
rmt=esp32.RMT(0,pin=pin)
t=20000000 # pulse repetition in us
d=[10,20,30,40,50] #duty cycles in percent

times=[]
for p in d:
    times.append(int(t*p/100))
    times.append(int((t*(100-p)/100)))

rmt.loop(True)
rmt.write_pulses(times,1)

Page 117

from machine import Pin, PWM
import array
import math

wave = array.array('H', [0]*256)
for i in range(256):
    wave[i] = int(65535//2 +  (math.sin(i * 2.0 * 3.14159 / 256.0) * 65535//2))

pwm1 = PWM(Pin(4),freq=300000)
print(pwm1)
while(True):
    for i in range(256):
        pwm1.duty_u16(wave[i])

print(pwm_get_wrap(0))
while(True):
    for i in range(256):
        pwm16.duty_u16(wave[i])

Page 119

from machine import Pin, PWM
from time import sleep_ms
pwm1 = PWM(Pin(4),freq=2000)

while True:
    for d in range(0,65535,655):
        pwm1.duty_u16(d)
        sleep_ms(50)

Page 120

from utime import sleep_ms
from machine import Pin, PWM

pwm1 = PWM(Pin(4),freq=2000)

while True:
    for b in range(0,100):
        pwm1.duty_u16(int(65535*b*b*b/1000000))
        sleep_ms(50)

Page 131

from machine import Pin, PWM
from time import sleep
class Motor:
    def __init__(self, pinNo):
        self.pwm1 = PWM(Pin(pinNo), freq=2000, duty_u16=0)
        self.gpio = pinNo
        self._on = False
        self.speed=0
    def setSpeed(self,s):
        self._on=True
        self.speed=s
        self.pwm1.duty_u16(int(65535*s/100))
    def off(self):
        self._on=False
        self.pwm1.duty_u16(0)
    def on(self):
        self._on=True
        self.pwm1.duty_u16(int(65535*self.speed/100))

motor=Motor(4)
sleep(1)
motor.setSpeed(50)
sleep(1)
motor.off()
sleep(1)
motor.setSpeed(90)
sleep(1)
motor.off()

Page 136

from machine import Pin, PWM
from time import sleep
class Motor:
    def __init__(self, pinNo):
        self.pwm1 = PWM(Pin(pinNo), freq=2000, duty_u16=0)
        self.gpio = pinNo
        self._on = False
        self.speed=0
    def setSpeed(self,s):
        self._on=True
        self.speed=s
        self.pwm1.duty_u16(int(65535*s/100))
    def off(self):
        self._on=False
        self.pwm1.duty_u16(0)
    def on(self):
        self._on=True
        self.pwm1.duty_u16(int(65535*self.speed/100))

class BiMotor(Motor):
    def __init__(self, pinNo1,pinNo2):
        super().__init__(pinNo1)
        self.forward = True
        self.pwm2 = PWM(Pin(pinNo2),freq=2000,duty_u16=0)

    def setForward(self, forward):
        if self.forward == forward:
            return
        self.pwm1.duty_u16(0)
        self.pwm1, self.pwm2 = self.pwm2, self.pwm1
        self.forward = forward
        self.pwm1.duty_u16(int(65535 * self.speed / 100))


motor = BiMotor(16,17)
sleep(1)
motor.setSpeed(50)
sleep(1)
motor.setForward(False)
sleep(1)
motor.setSpeed(90)
sleep(1)
motor.setForward(True)
motor.off()

Page 139

from machine import Pin, PWM
from time import sleep
class Servo:
    def __init__(self, pinNo):
        self.pwm = PWM(Pin(pinNo),freq=50,duty_u16= int(65535*2.5/100))
    def setPosition(self, p):
        self.position = p
        self.pwm.duty_u16(int(65535*p/1000 + 65535*2.5/100))
    def off(self):
        self.pwm.deinit()
servo=Servo(4)
sleep(1)
servo.setPosition(100.0)
sleep(1)
servo.setPosition(50.0)
sleep(1)
servo.setPosition(0)
sleep(1)
servo.off()

Page 146

from machine import Pin, mem32
from time import sleep_ms
class StepperBi4():
    def __init__(self, pinA):
        self.phase = 0
        self.pinA = pinA
        self.gpios = tuple([Pin(pinA, Pin.OUT),
                            Pin(pinA + 1, Pin.OUT),
                            Pin(pinA + 2, Pin.OUT),
                            Pin(pinA + 3, Pin.OUT)])
        self.gpios[0].on()
        self.gpioMask = 0xF << self.pinA
        self.halfstepSeq = [0x1, 0x3, 0x2, 0x6, 0x4, 0xC, 0x8, 0x9]

    #   [
    #             [0,0,0,1],
    #             [0,0,1,1],
    #             [0,0,1,0],
    #             [0,1,1,0],
    #             [0,1,0,0],
    #             [1,1,0,0],
    #             [1,0,0,0],
    #             [1,0,0,1]
    #    ]

    def _gpio_set(self,value, mask):
        mem32[0x3FF44004] = mem32[0x3FF44004] & ~mask | value & mask

    def setPhase(self, phase):
        value = self.halfstepSeq[phase] << self.pinA
        self._gpio_set(value, self.gpioMask)
        self.phase = phase

    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(16)
step.setPhase(0)

while True:
    step.stepForward()
    sleep_ms(1)

Page 151

from machine import Pin, mem32, Timer
from time import sleep_ms
class StepperBi4():
    def __init__(self, pinA):
        self.phase = 0
        self.pinA = pinA
        self.gpios = tuple([Pin(pinA, Pin.OUT),
                            Pin(pinA + 1, Pin.OUT),
                            Pin(pinA + 2, Pin.OUT),
                            Pin(pinA + 3, Pin.OUT)])
        self.gpios[0].on()
        self.gpioMask = 0xF << self.pinA
        self.halfstepSeq = [0x1, 0x3, 0x2, 0x6, 0x4, 0xC, 0x8, 0x9]
        self.timer = None
        self.forward = True
    #   [
    #             [0,0,0,1],
    #             [0,0,1,1],
    #             [0,0,1,0],
    #             [0,1,1,0],
    #             [0,1,0,0],
    #             [1,1,0,0],
    #             [1,0,0,0],
    #             [1,0,0,1]
    #    ]

    def _gpio_set(self,value, mask):
        mem32[0x3FF44004] = mem32[0x3FF44004] & ~mask | value & mask

    def setPhase(self, phase):
        value = self.halfstepSeq[phase] << self.pinA
        self._gpio_set(value, self.gpioMask)
        self.phase = phase


    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 doRotate(self, timer):
        if self.forward:
            self.stepForward()
        else:
            self.stepReverse()

    def rotate(self, forward, speed):
        self.forward = forward
        self.speed = speed
        if speed == 0:
            self.timer.deinit()
            self.timer = None
            return
        if self.timer == None:
            self.timer = Timer(0)
        self.timer.init(freq = speed, mode = Timer.PERIODIC, callback = self.doRotate)


step=StepperBi4(16)
step.setPhase(0)
while True:
    step.rotate(True,100)
    sleep_ms(500)
    step.rotate(True,0)
    sleep_ms(500)
 

Page 160

from machine import Pin, SPI
spi=SPI(1,sck=Pin(14),miso=Pin(12),mosi=Pin(13))
spi.init(baudrate=500_000,bits=8, polarity=0,phase=0,firstbit=SPI.MSB )
read = bytearray(3)
write = bytearray([0xAA,0xAA,0xAA])
spi.write_readinto(write,read)
print(read,write)
spi.deinit()

Page 168

from utime import sleep_ms
from machine import Pin, SPI

spi=SPI(1,sck=Pin(14),miso=Pin(12),mosi=Pin(13))
spi.init(baudrate=500_000, bits=8, polarity=0, phase=0,firstbit=SPI.MSB)
CS = Pin(15, Pin.OUT)
CS.on()
sleep_ms(1)
CS.off()
write=bytearray([0x01, 0x80, 0x00])
read=bytearray(3)
spi.write_readinto(write,read)
CS.on()
data =  (read[1] & 0x03) << 8 |  read[2]
volts =  data * 3.3 / 1023.0
print(volts)
spi.deinit()

Page 169

from utime import sleep_ms
from machine import Pin, SPI
class spiADC:
    def __init__(self,spi,sckNo,misoNo,mosiNo,CSNo):
        self.spi = SPI(spi, sck=Pin(sckNo), miso=Pin(misoNo), mosi=Pin(mosiNo))
        self.spi.init(baudrate=500_000, bits=8, polarity=0,phase=0, firstbit=SPI.MSB)
        self.CS = Pin(CSNo, Pin.OUT)
        self.CS.on()
        sleep_ms(1)

    def read(self,chan):
        write=bytearray([0x01, (0x08 | chan) << 4 , 0x00])
        self.CS.off()
        read=bytearray(3)
        self.spi.write_readinto(write,read)
        self.CS.on()
        data =  (read[1] & 0x03) << 8 |  read[2]
        volts =  data * 3.3 / 1023.0
        return volts

adc=spiADC(1,14,12,13,15)
volts=adc.read(1)
print(volts)

 


Page 173

from machine import mem32
def getVCal():
    VC=(mem32[0x3FF5_A010]>>8)& 0x1F
    if(VC & 0x10 ):
        VC=-(VC & 0x0F)
    return 1100+VC*7

print(getVCal())

Page 177

from machine import ADC,Pin
import time
adc = ADC(Pin(32),atten=ADC.ATTN_11DB)

t = time.ticks_us()
for i in range(10000):
    pass
print(time.ticks_diff(time.ticks_us(), t)/10000)

t = time.ticks_us()
for i in range(10000):
    m=adc.read()
print(time.ticks_diff(time.ticks_us(), t)/10000)

t = time.ticks_us()
for i in range(10000):
    m=adc.read_u16()
print(time.ticks_diff(time.ticks_us(), t)/10000)

t = time.ticks_us()
for i in range(10000):
    m=adc.read_uv()
print(time.ticks_diff(time.ticks_us(), t)/10000)

Page 178

import esp32
import time
while(True):
    m = esp32.hall_sensor()+esp32.hall_sensor()+esp32.hall_sensor()+esp32.hall_sensor()
    m = m/4
    print(m)
    time.sleep(0.5)

Page 181

from machine import Pin, DAC
import math
dac1 = DAC(Pin(26))
wave = []
for i in range(0,255):
    wave.append(int(127*math.sin(2*math.pi/256*i))+128)
while(True):
     for i in range(0,255):
         dac1.write(wave[i])

Page 181

from machine import Pin, DAC, mem32
from time import sleep

def _gpio_get(adr):
    return mem32[adr]

def _gpio_set( adr,value, mask):
    mem32[adr] = mem32[adr] & ~mask | value & mask


def enableSin(chan,f):
    if chan<1 or chan>2:
        return
    setFreq(chan, f)
    setPhase(chan,0x2)
    #enable tone
    _gpio_set(0x3FF48898, 0x10000, 0x10000)
    #select channel
    if chan==1:
        _gpio_set(0x3FF4889c, 1<<24,0x1<<24)
    else:
        _gpio_set(0x3FF4889c, 1<<25, 0x1 <<25)
    #set pad
    pad=0x3FF48484+4*(chan-1)
    _gpio_set(pad, 0x20200, 0x23A00)

def setFreq(chan,f):
    if chan<1 or chan>2:
        return
    step=int(f*65536/8000000) & 0xFFFF
    _gpio_set(0x3FF48898, step, 0x000FF)
def setPhase(chan,p):
    _gpio_set(0x3FF4889c, p << (20 + 2 * (chan – 1)),0x03 << (20 + 2 * (chan - 1)))

def setScale(chan,s):
    _gpio_set(0x3FF4889c, s << (16 + 2 * (chan – 1)),0x03 << (16 + 2 * (chan - 1)))

def setOff(chan,off):
    _gpio_set(0x3FF4889c, off << (8 * (chan – 1)), 0xFF << (8 * (chan - 1)))

dac1 = DAC(Pin(26))

enableSin(2,30000)
setScale(2,0x0)
setOff(2,0x0)
while(True):
    sleep(0.001)
    setPhase(2,0x3)
    sleep(.001)
    setPhase(2, 0x2)

 

Page 197

from machine import Pin,I2C

i2c0 = I2C(0,scl=Pin(18),sda=Pin(19),freq=100000)

buf = bytearray([0xE7])
i2c0.writeto( 0x40, buf, True)
read= i2c0.readfrom(0x40, 1, True)
print("User Register =",read)

Page 199

from machine import Pin,I2C
i2c0 = I2C(0,scl=Pin(18),sda=Pin(19),freq=100000)
buf = bytearray([0xE3])
i2c0.writeto( 0x40, buf, True)
read = i2c0.readfrom(0x40, 3, True)
msb = read[0]
lsb = read[1]
check = read[2]
print("msb lsb checksum =", msb, lsb, check)

Page 200

from machine import Pin,SoftI2C
i2c0 = SoftI2C(scl=Pin(18),sda=Pin(19),freq=100000)
buf = bytearray([0xE3])
i2c0.writeto( 0x40, buf, False)
read= i2c0.readfrom(0x40, 3, True)
msb = read[0]
lsb = read[1]
check = read[2]
print("msb lsb checksum =", msb, lsb, check)

Page 201

from machine import Pin,I2C

i2c0=I2C(0,scl=Pin(18),sda=Pin(19),freq=100000)

buf = bytearray([0xF3])
i2c0.writeto( 0x40, buf, True)

while True:
    try:
        read= i2c0.readfrom(0x40, 3, False)
        break
    except:
        continue

msb = read[0]
lsb = read[1]
check = read[2]
print("msb lsb checksum =", msb, lsb, check)

Page 202

from machine import Pin,SoftI2C
from time import sleep_ms

i2c0 = SoftI2C(scl=Pin(18),sda=Pin(19),freq=100000)

buf = bytearray([0xF3])
i2c0.writeto( 0x40, buf, False)

while True:
    sleep_ms(5)
    try:
        read = i2c0.readfrom(0x40, 3, True)
        break
    except:
        continue

msb = read[0]
lsb = read[1]
check = read[2]
print("msb lsb checksum =", msb, lsb, check)

Page 206

from machine import Pin,I2C

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

i2c0=I2C(0,scl=Pin(18),sda=Pin(19),freq=100000)
buf = bytearray([0xF3])
i2c0.writeto( 0x40, buf, False)
while True:
    try:
        read= i2c0.readfrom(0x40, 3, True)
        break
    except:
        continue
msb = read[0]
lsb = read[1]
check = read[2]
print("msb lsb checksum =", msb, lsb, check)
data16= (msb << 8) |  (lsb & 0xFC)
temp = (-46.85 +(175.72 * data16 /(1<<16)))
print("Temperature C ", temp)
print("Checksum=",crcCheck(msb,lsb,check))

buf = bytearray([0xF5])
i2c0.writeto( 0x40, buf, True)
read=bytearray(3)
while True:
    try:
        i2c0.readfrom_into(0x40,read, True)
        break
    except:
        continue
msb = read[0]
lsb = read[1]
check = read[2]
print("msb lsb checksum =", msb, lsb, check)
data16 = (msb << 8) | (lsb & 0xFC)
hum = -6 + (125.0 * data16) / 65536
print("Humidity ", hum)
print("Checksum=",crcCheck(msb,lsb,check))

 

Page 212

import dht
from machine import Pin
from time import sleep

dht = dht.DHT22(Pin(23))
while True:
    dht.measure()
    temp = dht.temperature()
    print(temp,"C")
    hum = dht.humidity()
    print(hum,"%")
    sleep(1)

Page 213

from machine import Pin
from utime import sleep_ms
DHT = Pin(23,mode=Pin.OUT,value=1)
sleep_ms(1)
DHT.off()
sleep_ms(1)
DHT.init(mode=Pin.IN)

Page 217

from machine import Pin,time_pulse_us
from utime import sleep_ms

class DHT22():
    def __init__(self,gpio):
        self.pin = Pin(gpio, mode=Pin.IN)
        self.checksum = 0
        self.temperature = 0
        self.humidity=0
        sleep_ms(1)
       
    @micropython.native
    def getReading(self):
        data = 0
        checksum = 0
        DHT=self.pin  
        DHT.init(mode=Pin.OUT,value=0)
        sleep_ms(1)
        DHT.init(mode=Pin.IN)
        t = time_pulse_us(DHT, 0, 1000)
        t = time_pulse_us(DHT, 1, 1000)        
             
        for i in range(32):
            t = time_pulse_us(DHT, 1, 1000)
            data = data << 1
            data = data | (t > 50)          
       
        for i in range(8):
            t = time_pulse_us(DHT, 1, 1000)
            checksum = checksum << 1
            checksum = checksum |(t > 50)
 
        byte1 = (data >> 24 & 0xFF)
        byte2 = (data >> 16 & 0xFF)
        byte3 = (data >> 8 & 0xFF)
        byte4 = (data & 0xFF)
        self.checksum =(checksum ==(byte1+byte2+byte3+byte4)&0xFF)
        self.humidity = ((byte1 <<8)| byte2) / 10.0
        neg = byte3 & 0x80
        byte3 = byte3 & 0x7F
        self.temperature = (byte3 << 8 | byte4) / 10.0
        if neg > 0:
            self.temperature = -self.temperature

dht = DHT22(23)
dht.getReading()
print("Checksum",dht.checksum)
print("Humidity= ", dht.humidity)
print("Temperature=", dht.temperature)

Page 223

from machine import Pin
import onewire,ds18x20

ow = onewire.OneWire(Pin(23))
presence=ow.reset()
if presence:
    print("Device present")
else:
    print("No device")
   
ds = ds18x20.DS18X20(ow)    
roms = ds.scan()
t = ds.read_temp(roms[0])
print(t)

Page 230

from machine import Pin
import onewire

class DS18B20:
    def __init__(self,pin):
        self.ow = onewire.OneWire(Pin(pin))    
       
    def __convert(self):
        self.ow.write([0xCC,0x44])
        for i in range(500):
            sleep_ms(10)
            if self.ow.readbit() == 1:
                j = i
                break
        return j
   
    def getTemp(self):
        if not self.ow.reset:
            return -1000
        if self.__convert()==500:
            return -3000
        self.ow.reset()
        self.ow.write([0xCC,0xBE])
        data = bytearray(9)
        self.ow.readinto(data)
        if self.ow.crc8(data)!=0:
            return -2000
        t1 = data[0]
        t2 = data[1]
        temp1 = (t2 << 8 | t1)
        if t2 & 0x80:
            temp1=temp1 | 0xFFFF0000
        return temp1/16

dS18B20=DS18B20(23)
print(dS18B20.getTemp())

 

Page 239

from machine import UART,Pin
uart = UART(1,baudrate=9600,bits=8,parity=None,rx=23,tx=22)
SendData = bytearray("Hello World \n","utf-8")
uart.write(SendData)
RecData = uart.read()
print(RecData)

Page 242

from machine import UART,Pin, Timer
from utime import sleep_ms,sleep, time_ns
uart = UART(1,baudrate=9600,bits=8,parity=None,rx=23,tx=22,txbuf=256,rxbuf=16*1024)
test="A"*252
s = time_ns()
uart.write(test)
print((time_ns()-s)/1000000)

Page 242

from machine import UART,Pin, Timer
from utime import sleep_ms,sleep, time_ns
uart = UART(1,baudrate=9600,bits=8,parity=None, rx=23,tx=22, txbuf=16*1024,rxbuf=512)
test="A"*1000
s = time_ns()
uart.write(test)
print((time_ns()-s)/1000000)
sleep_ms(4000)
RecData = uart.read()
print(RecData)

Page 243

from machine import UART,Pin, Timer
from utime import sleep_ms,sleep, time_ns
uart = UART(1,baudrate=9600,bits=8,parity=None,rx=23,tx=22, txbuf=4*1024,rxbuf=512)
test = ""
for i in range(280):
   test=test + str(i)+","
print(test)
print(len(test))
s = time_ns()
uart.write(test)
print((time_ns()-s)/1000000)
sleep_ms(4000)
RecData = uart.read()
print(RecData)
print(len(RecData))

Page 247

from machine import UART,Pin
from utime import sleep_ms, time_ns

uart = UART(1,baudrate=9600,bits=8,parity=None, rx=23,tx=22,rts=21,cts=19, timeout=0,timeout_char=0,txbuf=2000,rxbuf=256,flow=UART.RTS|UART.CTS)

test = "A"*1000
s = time_ns()
uart.write(test)
print((time_ns()-s)/1000000)

RecData = bytes()
while len(RecData)<1000:
    sleep_ms(500)
    if uart.any():
            RecData = RecData + uart.read()
            print(RecData)
            print(len(RecData))

 


Page 257

import network
from machine import Pin, Timer
from time import sleep_ms
def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi

Page 261

from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO


class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):

    def sendResponse(self, cmd):
        content_length = int(self.headers['Content-Length'])
        body = self.rfile.read(content_length)
        self.send_response(200)
        self.end_headers()
        response = BytesIO()
        response.write(b'This is a '+bytes(cmd, 'utf-8')+ b' request. ')
        response.write(b'Received: ')
        response.write(body)
        self.wfile.write(response.getvalue())

    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'Hello, world!')


    def do_HEAD(self):
        self.send_response(200)
        self.end_headers()

   
    def do_POST(self):
        self.sendResponse("POST")

    def do_PUT(self):
        self.sendResponse("PUT")

    def do_DELETE(self):
        self.sendResponse("DELETE")

    def do_PATCH(self):
        self.sendResponse("PATCH")


httpd = HTTPServer(('', 8080), SimpleHTTPRequestHandler)
httpd.serve_forever()

Page 264

import network
from machine import Pin, Timer
from time import sleep_ms
import urequests

def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi
   
wifi=setup(country, ssid, key)
print("Connected")
r = urequests.get("https://www.example.com")
print(r.content)
r.close()

Page 265

   
import network
from machine import Pin, Timer
from time import sleep_ms
import urequests

def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi


wifi=setup(country, ssid, key)
print("Connected")

url="http://192.168.253.72:8080"
r = urequests.get(url)
print(r.content)
r.close()

buf= b'Hello World'
r=urequests.post(url,data=buf)
print(r.content)
r.close()

r=urequests.put(url,data=buf)
print(r.content)
r.close()

r=urequests.patch(url,data=buf)
print(r.content)
r.close()

r=urequests.head(url)
print(r.content)
print(r.headers)
r.close()

r=urequests.delete(url,data=buf)
print(r.content)
r.close()

Page 266

import network
from machine import Pin, Timer
from time import sleep_ms
import urequests
import onewire
import ds18x20

def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi

wifi=setup(country, ssid, key)
print("Connected")
url = "http://192.168.253.72:8080"
ow = onewire.OneWire(Pin(22))
presence = ow.reset()
if presence:
    print("Device present")
else:
    print("No device")

DS = ds18x20.DS18X20(ow)
roms = DS.scan()

while True:
    DS.convert_temp()
    temp = DS.read_temp(roms[0])
    buf = str(temp).encode("utf-8")
    try:
        r = urequests.put(url, data=buf)
        r.close()
    except:
        print("Server Not Online")
    sleep_ms(500)

Page 267

from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
     
    def log_message(self,*args, **kwargs):
        pass

    def do_PUT(self):
        content_length = int(self.headers['Content-Length'])
        body = self.rfile.read(content_length)
        bodyString= body.decode(encoding="utf-8")
        temp=float(bodyString)
        print(temp)
        self.send_response(200)
        self.end_headers()

httpd = HTTPServer(('', 8080), SimpleHTTPRequestHandler)
httpd.serve_forever()

 

Page 276

import network
import socket
from machine import Pin, Timer
from time import sleep_ms

def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi

wifi=setup(country, ssid, key)
print("Connected")
url = "http://192.168.253.72:8080"
ai = socket.getaddrinfo("www.example.com", 80,socket.AF_INET)
addr = ai[0][-1]
s = socket.socket(socket.AF_INET)
s.connect(addr)

request = b"GET /index.html HTTP/1.1\r\nHost:example.org\r\n\r\n"
s.send(request)
print(s.recv(512))

Page 277

import network
import socket
import ssl
from machine import Pin, Timer
from time import sleep_ms

def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi

wifi=setup(country, ssid, key)
print("Connected")

ai = socket.getaddrinfo("example.com", 443,socket.AF_INET)
addr = ai[0][-1]
s = socket.socket(socket.AF_INET)
s.connect(addr)
sslSock=ssl.wrap_socket(s)
request = b"GET / HTTP/1.1\r\nHost:example.com\r\n\r\n"
sslSock.write(request)
print(sslSock.read(1024))

Page 281

import network
import socket
from time import sleep_ms
from machine import Pin, Timer
import onewire
import ds18x20

def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi

wifi = setup("country", "ssid", "key")
ow = onewire.OneWire(Pin(22))
presence = ow.reset()
if presence:
    print("Device present")
else:
    print("No device")
DS = ds18x20.DS18X20(ow)
roms = DS.scan()
template = """<!DOCTYPE html>
<html>
<head> <title>Temperature</title> </head>
<body> <h1>Current Temperature</h1>
Hello ESP32 Server World <br/>
The Temperature is: <!--#temp--><br/>
</body>
</html>
"""
addr = socket.getaddrinfo('192.168.253.24', 8080)[0][-1]
print(addr)
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(0)
while True:
    cl, addr = s.accept()
    print('client connected from', addr)
    print(cl.recv(512))
    DS.convert_temp()
    temp = DS.read_temp(roms[0])
    html=template.replace("<!--#temp-->",str(temp))
    headers = ("HTTP/1.1 200 OK\r\n"
            "Content-Type: text/html; charset=UTF-8\r\n"
            "Server:ESP32\r\n"
            f"Content-Length:{len(html)}\r\n\r\n"
            )
    buf = headers.encode("utf-8")+html.encode("utf-8")    
    cl.send(buf)  
    cl.close()
s.close()

Page 283

import binascii

with open("iopress.key", 'rb') as f:
    lines = f.readlines()
lines = b"".join(lines[1:-1])
key = binascii.a2b_base64(lines)
print("key=", key)

with open("iopress.crt", 'rb') as f:
    lines = f.readlines()
lines = b"".join(lines[1:-1])
cert = binascii.a2b_base64(lines)
print()
print("cert=", cert)

Page 284

import network
import socket
from time import sleep_ms
from machine import Pin, Timer
import onewire
import ds18x20
import ssl


def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi

wifi=setup(country, ssid, key)
print("Connected")
print(wifi.ifconfig())

key=b'0\x82\x04\xbf\ . . .xabp\xd1'
 
cert=b'0\x82\x03k0\ . . .\x98\x8a'

ow = onewire.OneWire(Pin(22))
presence = ow.reset()
if presence:
 print("Device present")
else:
 print("No device")


DS = ds18x20.DS18X20(ow)
roms = DS.scan()

template = """<!DOCTYPE html>
<html>
<head> <title>Temperature</title> </head>
<body> <h1>Current Temperature</h1>
Hello ESP32 Server World <br/>
The Temperature is: <!--#temp--><br/>
</body>
</html>
"""

addr = socket.getaddrinfo('0.0.0.0', 443)[0][-1]

s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(5)

while True:
    cl, addr = s.accept()
    print('client connected from', addr)
    client_s =None
   
    try:
        client_s = ssl.wrap_socket(cl, server_side=True,
                                          key=key, cert=cert)

        while True:
            h = client_s.readline()
            if h == b"" or h == b"\r\n":
                    break
            print(h.decode(), end="")

        DS.convert_temp()
        temp = DS.read_temp(roms[0])
        html=template.replace("<!--#temp-->",str(temp))
        headers = ("HTTP/1.1 200 OK\r\n"
                "Content-Type: text/html; charset=UTF-8\r\n"
                "Server:ESP32\r\n"
                f"Content-Length:{len(html)}\r\n\r\n"
                )
        buf = headers.encode("utf-8")+html.encode("utf-8")

        client_s.write(buf)
        client_s.close()
    except Exception as e:
       print("exception ",e)
s.close()

 

Page 304

import uasyncio
from machine import Pin

async def blink(led, period_ms):
    while True:
        led.on()
        await uasyncio.sleep_ms(5)
        led.off()
        await uasyncio.sleep_ms(period_ms)

async def main(led1, led2):
    uasyncio.create_task(blink(led1, 700))
    uasyncio.create_task(blink(led2, 400))
    await uasyncio.sleep_ms(10_000)

uasyncio.run(main(Pin(22,Pin.OUT), Pin(23,Pin.OUT)))

Page 305

import uasyncio
from machine import Pin
from time import sleep_ms
async def blink(led, period_ms):
    while True:
        led.on()
        await uasyncio.sleep_ms(5)
        led.off()
        await uasyncio.sleep_ms(period_ms)

async def timewaste():
    while True:
        sleep_ms(10)
        await uasyncio.sleep_ms(0)


async def main(led1, led2):
    uasyncio.create_task(blink(led1, 700))
    uasyncio.create_task(blink(led2, 400))
    uasyncio.create_task(timewaste())
    await uasyncio.sleep_ms(10_000)

uasyncio.run(main(Pin(22,Pin.OUT), Pin(23,Pin.OUT)))

Page 307

import uasyncio
from time import sleep_ms
from machine import Pin, Timer
import network

def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi

async def main():
    reader,writer= await uasyncio.open_connection("www.example.com",80)
    request = b"GET /index.html HTTP/1.1\r\nHost:example.org\r\n\r\n"
    writer.write(request)
    await writer.drain()
    print(await reader.read(512))
    reader.close()
wifi=setup(country, ssid, key)
print("Connected")
print(wifi.ifconfig())
uasyncio.run(main())

Page 310



import uasyncio
import network
from machine import Pin, Timer
from time import sleep_ms
import onewire
import ds18x20

def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi

wifi=setup(country, ssid, key)
print("Connected")
print(wifi.ifconfig())

ow = onewire.OneWire(Pin(22))
presence = ow.reset()
if presence:
    print("Device present")
else:
    print("No device")

DS = ds18x20.DS18X20(ow)
roms = DS.scan()

template = """<!DOCTYPE html>
<html>
<head> <title>Temperature</title> </head>
<body> <h1>Current Temperature</h1>
Hello ESP32 Server World <br/>
The Temperature is: <!--#temp--><br/>
</body>
</html>
"""
async def serve_client(reader,writer):
    print("client")
    print(await reader.read(512))
    DS.convert_temp()
    temp = DS.read_temp(roms[0])
    html=template.replace("<!--#temp-->",str(temp))
    headers = ("HTTP/1.1 200 OK\r\n"
            "Content-Type: text/html; charset=UTF-8\r\n"
            "Server:ESP32\r\n"
            f"Content-Length:{len(html)}\r\n\r\n"
            )
    buf = headers.encode("utf-8")+html.encode("utf-8")
    writer.write(buf)
    await writer.drain()
    writer.close()
    await writer.wait_closed()

async def main():
    await uasyncio.start_server(serve_client, '192.168.253.24', 80,backlog=5)
    while True:
        print("heartbeat")
        await uasyncio.sleep(1)

uasyncio.run(main())

 

Page 315

from machine import mem32,Pin
from time import sleep_ms

led = Pin(2,mode=Pin.OUT)
GPIOSet = 0x3FF44008
GPIOClear = 0x3FF4400C
mask = 1<<2
while True:
    mem32[GPIOSet] = mask
    sleep_ms(500)
    mem32[GPIOClear] = mask
    sleep_ms(500)

Page 315

from machine import mem32,Pin
from time import sleep_ms

@micropython.native
def blink():
    GPIOSet = 0x3FF44008
    GPIOClear = 0x3FF4400C
    mask = 1<<2
    while True:
        mem32[GPIOSet] = mask
        mem32[GPIOClear] = mask

led = Pin(2,mode=Pin.OUT)
blink()

Page 318

from machine import Pin
import machine

def gpio_setgroup(value, mask):
    machine.mem32[0x3FF44004] = machine.mem32[0x3FF44004] & ~mask | value & mask

pin = Pin(2, Pin.OUT)
pin = Pin(4, Pin.OUT)
value1 = 1 << 2 | 0 << 4
value2 = 0 << 2 | 1 << 4
mask = 1 << 2 | 1 << 4
while True:
    gpio_setgroup(value1, mask)
    gpio_setgroup(value2, mask)

Page 323

from machine import Pin, DAC, mem32
from time import sleep

def _reg_get(adr):
    return mem32[adr]

def _reg_set( adr,value, mask):
    mem32[adr] = mem32[adr] & ~mask | value & mask

def enableSin(chan,f):
    if chan<1 or chan>2:
        return
    setFreq(chan, f)
    setPhase(chan,0x2)
    #enable tone
    _reg_set(0x3FF48898, 0x10000, 0x10000)
    #select caannel
    if chan==1:
        _reg_set(0x3FF4889c, 1<<24,0x1<<24)
    else:
        _reg_set(0x3FF4889c, 1<<25, 0x1 <<25)


def setFreq(chan,f):
    if chan<1 or chan>2:
        return
    step = int(f*65536/8000000) & 0xFFFF
    _reg_set(0x3FF48898, step, 0x000FF)

def setPhase(chan,p):
    _reg_set(0x3FF4889c, p << (20 + 2 * (chan – 1)), 0x03 << (20 + 2 * (chan - 1)))


def setScale(chan,s):
    _reg_set(0x3FF4889c, s << (16 + 2 * (chan - 1)),0x03 << (16 + 2 * (chan - 1)))

def setOff(chan,off):
    _reg_set(0x3FF4889c, off << (8 * (chan - 1)),0xFF << (8 * (chan - 1)))

dac1 = DAC(Pin(26))

enableSin(2,30000)
setScale(2,0x0)
setOff(2,0x0)
while(True):
    sleep(0.001)
    setPhase(2,0x3)
    sleep(.001)
    setPhase(2, 0x2)

Page 324

import ntptime
from machine import RTC
import network
from machine import Pin, Timer
from time import sleep_ms

def setup(country, ssid, key):
    network.country(country)
    wifi = network.WLAN(network.STA_IF)
    wifi.active(True)
    wifi.disconnect()
    LED = Pin(2, Pin.OUT)
    LED.on()
    timeout = 20000
    wifi.connect(ssid,key)
    timer = Timer(1)
    timer.init(period=200, mode=Timer.PERIODIC,callback=lambda t:LED.value(not LED.value()))    
    s = network.STAT_IDLE
    while timeout>0:
        print("connecting",s)
        s = wifi.status()
        if s != network.STAT_CONNECTING:
            break
        sleep_ms(100)
        timeout = timeout-100    
    if(s==network.STAT_GOT_IP):
         timer.init(period=1000, mode=Timer.PERIODIC, callback=lambda t:LED.value(not LED.value()))        
    else:
        timer.deinit()
        LED.on()
    return wifi

wifi=setup(country, ssid, key)
print("Connected")
print(wifi.ifconfig())

ntptime.host="pool.ntp.org"
ntptime.timeout=1000
try:
    ntptime.settime()
except Exception:
    print("NTP server not available")
    pass
rtc = RTC()
print(rtc.datetime())

Page 326

from machine import lightsleep
from time import sleep
for i in range(10):
    print("starting sleep",i)
    lightsleep(1000)
    print ("back from sleep",i)

Page 327

from machine import deepsleep
from time import sleep
for i in range(10):
    print("starting sleep",i)
sleep(2)
print('I am going to sleep')
deepsleep(1000)

Page 327

from machine import deepsleep, RTC
from time import sleep
sleep(3)
rtc = RTC()
if len(rtc.memory())==0:
    start=0
else:
    start = int.from_bytes(rtc.memory(),"big")
for i in range(start,start+10):
    print(i)
print("starting sleep")
rtc.memory((i+1).to_bytes(4,"big"))
deepsleep(1000)

Page 329

from machine import lightsleep,Pin
import esp32

wakePin = Pin(2,Pin.IN,pull=None)
esp32.wake_on_ext0(wakePin,esp32.WAKEUP_ANY_HIGH)
for i in range(10):
    print("starting sleep",i)
    lightsleep()
    print ("back from sleep",i)

Page 331

from machine import WDT
from time import sleep
sleep(4)
print("starting")
wdt = WDT(timeout=4000)
wdt.feed()
while True:
    sleep(0.1)
    print("still running")
    pass

Page 336

from machine import deepsleep
from time import sleep
from esp32 import NVS
sleep(3)
start = 0
nvsState = NVS("state")
try:
    start = nvsState.get_i32("start")
except OSError:
    pass
for i in range(start,start+10):
    print(i)
print("starting sleep")
nvsState.set_i32("start",i+1)
nvsState.commit()
deepsleep(1000)

 

Programs

Raspberry Pi IoT in C Third Edition

 

piciot3e360

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 VS Code project.  

Note: The VS Code task listings are in Appendix II.

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 - in particular remember to add the bcm2835 library and also any library references that may be needed. The majority of the programs also need to be run with root permissions.

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.


Chapter  2

Page 28

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
    printf("Hello C World");
    int test = 42;
    printf("%d\n", test);
    return (EXIT_SUCCESS);
}
 

Chapter  3

Page 47

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

Chapter  4

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 62

#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 64

#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 65

 
#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 66

 
#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 67

 
#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 68

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

Chapter 6

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

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

Page 90

#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 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;
    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 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);

    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 93

#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 94

#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 97 

 
#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 99

#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 100

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

Chapter 7

 

Page 111

#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 114

#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 116

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

Chapter 8

Page 122

Not 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 126

 
#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 127

 
#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 128

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

Page 129

#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 132

 
#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 137 

#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 140

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

Chapter 9

Page 151

#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 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_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 153

#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 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(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 256);
    for (;;) {
        for (int i = 0; i < 256; i = i + 10) {
            bcm2835_pwm_set_data(0, i);
            bcm2835_delayMicroseconds(100);
        }
    }
    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(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 158

#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 159

#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 160

#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 163 

#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 164 

 
#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 166

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 168

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

Chapter 10

Page 184 

 
#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 186

 
#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 188 

#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 192

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

Chapter 11

Page 203 

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

Chapter 13 

Page 223

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

Chapter 14

 Page 233

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

Chapter 15

Page 246

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

Chapter 16

Page 268

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

#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 268

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

This loopback most likely wont work unless the serial port is already configured - see next program.

 

#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 278

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

#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/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] = 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 279

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

 
#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 281

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

 
#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 287

 

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

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

Chapter 17

Page 303 

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

Chapter 18

 Page 312

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

 

Chapter 19

Page 324

#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 326

#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 331

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

Chapter 20

Page 350

#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 355

#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 360

 
#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 362 

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

Chapter 21

Page  372

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>

typedef struct{
    uint32_t status;
    uint32_t ctrl;
}GPIOregs;

#define GPIO ((GPIOregs*)GPIOBase)

typedef struct
{
    uint32_t Out;
    uint32_t OE;
    uint32_t In;
    uint32_t InSync;
} rioregs;

#define rio ((rioregs *)RIOBase)
#define rioXOR ((rioregs *)(RIOBase + 0x1000 / 4))
#define rioSET ((rioregs *)(RIOBase + 0x2000 / 4))
#define rioCLR ((rioregs *)(RIOBase + 0x3000 / 4))


int main(int argc, char **argv)
{
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    uint32_t *map = (uint32_t *)mmap(
        NULL,
        64 * 1024 * 1024,
        (PROT_READ | PROT_WRITE),
        MAP_SHARED,
        memfd,
        0x1f00000000
    );
    if (map == MAP_FAILED)
    {
        printf("mmap failed: %s\n", strerror(errno));
        return (-1);
    };
    close(memfd);

    uint32_t *PERIBase = map;
    uint32_t *GPIOBase = PERIBase + 0xD0000 / 4;
    uint32_t *RIOBase = PERIBase + 0xe0000 / 4;
    uint32_t *PADBase = PERIBase + 0xf0000 / 4;
    uint32_t *pad = PADBase + 1;  
   
    uint32_t pin = 2;
    uint32_t fn = 5;

    GPIO[pin].ctrl=fn;
    pad[pin] = 0x10;
    rioSET->OE = 0x01<<pin;
    rioSET->Out = 0x01<<pin;
   
    for (;;)
    {
        rioXOR->Out = 0x04;
    }
    return (EXIT_SUCCESS);
}
 

Page  378

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

typedef struct
{
    uint32_t status;
    uint32_t ctrl;
} GPIOregs;

#define GPIO ((GPIOregs *)GPIOBase)

typedef struct{
    uint32_t Ctrl;
    uint32_t Range;
    uint32_t Phase;
    uint32_t Duty;
} PWMregs;

#define PWM ((PWMregs *) (PWMBase+0x14/4))

typedef struct
{
    uint32_t Out;
    uint32_t OE;
    uint32_t In;
    uint32_t InSync;
} rioregs;

#define rio ((rioregs *)RIOBase)
#define rioXOR ((rioregs *)(RIOBase + 0x1000 / 4))
#define rioSET ((rioregs *)(RIOBase + 0x2000 / 4))
#define rioCLR ((rioregs *)(RIOBase + 0x3000 / 4))

uint32_t *PERIBase;
uint32_t *GPIOBase;
uint32_t *RIOBase;
uint32_t *PADBase;
uint32_t *pad;
uint32_t *PWMBase;


int rp1_Init()
{
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    uint32_t *map = (uint32_t *)mmap(
        NULL,
        64 * 1024 * 1024,
        (PROT_READ | PROT_WRITE),
        MAP_SHARED,
        memfd,
        0x1f00000000);
    if (map == MAP_FAILED)
    {

        return (-1);
    };
    close(memfd);
    PERIBase = map;
    GPIOBase = PERIBase + 0xD0000 / 4;
    RIOBase = PERIBase + 0xe0000 / 4;
    PADBase = PERIBase + 0xf0000 / 4;
    PWMBase = PERIBase + 0x98000 / 4;
    pad = PADBase + 1;
    return 0;
};


int main(int argc, char **argv)
{
    if (rp1_Init())
        return (1);
    GPIO[12].ctrl = 0x0;
    pad[12] = 0x10;
    PWM[0].Ctrl=0x1;
    PWM[0].Range=0xFFFFF;
    PWM[0].Duty=0x8FFFF;
    PWM[0].Phase=0x0;
    *PWMBase=0x80000001;
    return (EXIT_SUCCESS);
}

Chapter 22

Page  395

#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 399

#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 402

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

Appendix I

 

Page 406

#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 407


#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 (typical) 

{
    "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}",
            "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 for Mingw

 
{
    "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}'",
            "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}'",
            "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
}
},
],
}
 
 
 
 

Extending & Embedding Python Using C

extendPython360

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 an editor. 

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.

Notice that indents have been removed but you can put them back in by auto formatting the code after pasting.

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 23

Hello.c

#include
int main(int argc, char **argv)
{
printf("Hello C World\n");
return 0;
}

tasks.json

{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}

launch.json

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "enter program name, for example ${workspaceFolder}/a.out",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}

 

 

Page 24

arith.c

#define PY_SSIZE_T_CLEAN
#include

static PyObject *add(PyObject *self, PyObject *args)
{
int x, y, sts;
if (!PyArg_ParseTuple(args, "ii", &x, &y))
return NULL;
sts = x + y;
return PyLong_FromLong(sts);
}

static PyMethodDef AddMethods[] = {
{"add", add, METH_VARARGS, "add two numbers"},
{NULL, NULL, 0, NULL} // sentinel
};

static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"arith",
"C library for sum",
-1,
AddMethods};

PyMODINIT_FUNC PyInit_arith(void)
{
return PyModule_Create(&addmodule);
}

tasks.json

{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc-10 build active file",
"command": "/usr/bin/gcc-10",
"args": [
"-fdiagnostics-color=always",
"-g",
"-shared",
"${file}",
"-o",
"arith.so",
"-I/usr/local/include/python3.11"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}

c_cpp_properties.json

{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/local/include/**"
],

"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-arm"
}
],
"version": 4
}

test.py

import arith
print(arith.add(1,2))
print(dir(arith))

Page 30

launch.json

{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "/usr/local/bin/python3.11",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

 


Page 38

 hello.c

#include <stdio.h>

int main(int argc, char **argv)

{

    printf("Hello C World\n");

    return 0;

}

 tasks.json

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: cl.exe build active file",

            "command": "cl.exe",

            "args": [

                "/Zi",

                "/EHsc",

                "/nologo",

                "/Fe${fileDirname}\\${fileBasenameNoExtension}.exe",

                "${file}"

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$msCompile"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

Page 30

Change mike.james in the quoted paths to your own user name

arith.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *add(PyObject *self, PyObject *args)

{

    int x, y, sts;

    if (!PyArg_ParseTuple(args, "ii", &x, &y))

        return NULL;

    sts = x + y;

    return PyLong_FromLong(sts);

}

static PyMethodDef AddMethods[] = {

    {"add", add, METH_VARARGS, "add two numbers"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "arith",

    "C library for sum",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_arith(void)

{

    return PyModule_Create(&addmodule);

}

tasks.json

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: cl.exe build active file",

            "command": "cl.exe",

            "args": [

                "/Zi",

                "/EHsc",

                "/nologo",            

                "/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",              

                "${file}",

                "/link /dll /OUT:arith.pyd /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$msCompile"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

 launch.json

{

    "version": "0.2.0",

    "configurations": [

        {

            "name": "(Windows) Attach",

            "type": "cppvsdbg",

            "request": "attach",

            "processId": "${command:pickProcess}",

            "symbolSearchPath": "C:/Users/mike.james/AppData/Local/Programs/Python/Python-3.11.4",

            "sourceFileMap":{"D:/a/1/s/":"C:/Users/mike.james/AppData/Local/Programs/Python/Python311"},

        },

        {

            "name": "Python: Current File",

            "type": "python",

            "request": "launch",

            "program": "${file}",

            "console": "integratedTerminal"

        }

    ]

}

c_cpp_properties.json

{

    "configurations": [

        {

            "name": "Win32",

            "includePath": [

                "${workspaceFolder}/**",

                "C:/Users/mike.james/AppData/Local/Programs/Python/Python311/include/"

            ],

            "defines": [

                "_DEBUG",

                "UNICODE",

                "_UNICODE"

            ],

            "windowsSdkVersion": "10.0.22000.0",

            "compilerPath": "cl.exe",

            "cStandard": "c17",

            "cppStandard": "c++17",

            "intelliSenseMode": "windows-msvc-x64"

        }

    ],

    "version": 4

}

test.py

import arith

print(arith.add(1,2))

print(dir(arith))

 

 Page 44

launch.json

{

    "version": "0.2.0",

    "configurations": [

        {

            "name": "(Windows) Attach",

            "type": "cppvsdbg",

            "request": "attach",

            "processId": "${command:pickProcess}",

        },

        {

            "name": "Python: Current File",

            "type": "python",

            "request": "launch",

            "program": "${file}",

            "console": "integratedTerminal"

        }

    ]

}


 

 

Page 53

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject * add(PyObject *self, PyObject *args)

{

    int x, y, sts;

    if (!PyArg_ParseTuple(args, "ii", &x, &y))

        return NULL;

    sts = x+y;

    return PyLong_FromLong(sts);

}

static PyMethodDef AddMethods[] = {

    {"add", add, METH_VARARGS, "add two numbers"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

  PyModuleDef_HEAD_INIT,

  "arith",                              

  "C library for sum",  

  -1,                                  

  AddMethods                          

};

PyMODINIT_FUNC PyInit_arith(void) {    

     return PyModule_Create(&addmodule);

}

Page 54 and on

Arith.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject * Pi(PyObject *self, PyObject *args)

{

    int m, n;

    double pi,s;

    if (!PyArg_ParseTuple(args, "ii", &m, &n))

        return NULL;

    pi=0;

    for(int k=m;k<n;k++){

        s=1;

        if(k%2==0)s=-1;

        pi=pi+s/(2*k-1);

    }    

    return PyFloat_FromDouble(4*pi);

}

static PyMethodDef AddMethods[] = {

    {"myPi", Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

  PyModuleDef_HEAD_INIT,

  "Pi",                              

  "C library to compute Pi",  

  -1,                                  

  AddMethods                          

};

PyMODINIT_FUNC PyInit_Pi(void) {    

     return PyModule_Create(&addmodule);

}

tasks.json   LINUX

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: gcc-10 build active file",

            "command": "/usr/bin/gcc-10",

            "args": [

                "-fdiagnostics-color=always",

                "-g",

                "-shared",

                "${file}",

                "-o",

                "Pi.so",

                "-I/usr/local/include/python3.11"  

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$gcc"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

c_cpp_properties.json LINUX

{

    "configurations": [

        {

            "name": "Linux",

            "includePath": [

                "${workspaceFolder}/**",

                "/usr/local/include/**"

            ],

            "defines": [],

            "compilerPath": "/usr/bin/gcc",

            "cStandard": "c17",

            "cppStandard": "gnu++14",

            "intelliSenseMode": "linux-gcc-arm"

        }

    ],

    "version": 4

}

launch.json LINUX

{

    "version": "0.2.0",

    "configurations": [

      {

          "name": "Python: Current File",

          "type": "python",

          "request": "launch",

          "program": "${file}",

          "console": "integratedTerminal"

      },

      {

          "name": "(gdb) Attach",

          "type": "cppdbg",

          "request": "attach",

          "program": "/usr/local/bin/python3.11",

          "processId": "${command:pickProcess}",

          "MIMode": "gdb",

          "setupCommands": [

              {

                  "description": "Enable pretty-printing for gdb",

                  "text": "-enable-pretty-printing",

                  "ignoreFailures": true

              }

          ]

      }

    ]

  }

tasks.json   WINDOWS - CHANGE USER IN PATH

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: cl.exe build active file",

            "command": "cl.exe",

            "args": [

                "/Zi",

                "/EHsc",

                "/nologo",            

                "/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",              

                "${file}",

                "/link /dll /OUT:arith.pyd /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$msCompile"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

 c_cpp_properties.json WINDOWS CHANGE USER IN PATH

{

    "configurations": [

        {

            "name": "Win32",

            "includePath": [

                "${workspaceFolder}/**",

                "C:/Users/mike.james/AppData/Local/Programs/Python/Python311/include/"

            ],

            "defines": [

                "_DEBUG",

                "UNICODE",

                "_UNICODE"

            ],

            "windowsSdkVersion": "10.0.22000.0",

            "compilerPath": "cl.exe",

            "cStandard": "c17",

            "cppStandard": "c++17",

            "intelliSenseMode": "windows-msvc-x64"

        }

    ],

    "version": 4

}

launch.json WINDOWS CHANGE USER IN PATH 

{

    "version": "0.2.0",

    "configurations": [

        {

            "name": "(Windows) Attach",

            "type": "cppvsdbg",

            "request": "attach",

            "processId": "${command:pickProcess}",

            "symbolSearchPath": "C:/Users/mike.james/AppData/Local/Programs/Python/Python-3.11.4",

            "sourceFileMap":{"D:/a/1/s/":"C:/Users/mike.james/AppData/Local/Programs/Python/Python311"},

        },

        {

            "name": "Python: Current File",

            "type": "python",

            "request": "launch",

            "program": "${file}",

            "console": "integratedTerminal"

        }

    ]

}

Py.py

import time

def myPi(m,n):

    pi=0

    for k in range(m,n+1):

        s= 1 if k%2 else -1

        pi += s / (2 * k - 1)

    return 4*pi

if __name__ == '__main__':

    N=10000000

    t1=time.perf_counter()

    pi=myPi(1,N)

    t2=time.perf_counter()

    print((t2-t1)*1000)

    print(pi)

Py1.py

import Pi

import time

if __name__ == '__main__':

    N=10000000

    t1=time.perf_counter()

    pi=Pi.myPi(1,N)

    t2=time.perf_counter()

    print((t2-t1)*1000)

    print(pi)

Page 57

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject* exampleFunction(PyObject *self, PyObject *args)

{  

     //example function code

}

static PyMethodDef AddMethods[] = {

    {"exampleFunction", exampleFunction, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

  PyModuleDef_HEAD_INIT,

  "example",                              

  "C library to test API",  

  -1,                                  

  AddMethods                          

};

PyMODINIT_FUNC PyInit_example(void) {    

     return PyModule_Create(&addmodule);

}

tasks.json LINUX

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: gcc-10 build active file",

            "command": "/usr/bin/gcc-10",

            "args": [

                "-fdiagnostics-color=always",

                "-g",

                "-shared",

                "${file}",

                "-o",

                "example.so",

                "-I/usr/local/include/python3.11"  

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$gcc"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

launch.json LINUX

{

    "version": "0.2.0",

    "configurations": [

      {

          "name": "Python: Current File",

          "type": "python",

          "request": "launch",

          "program": "${file}",

          "console": "integratedTerminal"

      },

      {

          "name": "(gdb) Attach",

          "type": "cppdbg",

          "request": "attach",

          "program": "/usr/local/bin/python3.11",

          "processId": "${command:pickProcess}",

          "MIMode": "gdb",

          "setupCommands": [

              {

                  "description": "Enable pretty-printing for gdb",

                  "text": "-enable-pretty-printing",

                  "ignoreFailures": true

              }

          ]

      }

    ]

  }

c_cpp_properties.json LINUX

{

    "configurations": [

        {

            "name": "Linux",

            "includePath": [

                "${workspaceFolder}/**",

                "/usr/local/include/**"

            ],

            "defines": [],

            "compilerPath": "/usr/bin/gcc",

            "cStandard": "c17",

            "cppStandard": "gnu++14",

            "intelliSenseMode": "linux-gcc-arm"

        }

    ],

    "version": 4

}

tasks.json   WINDOWS - CHANGE USER IN PATH

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: cl.exe build active file",

            "command": "cl.exe",

            "args": [

                "/Zi",

                "/EHsc",

                "/nologo",            

                "/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",              

                "${file}",

                "/link /dll /OUT:example.pyd /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$msCompile"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

 

 c_cpp_properties.json WINDOWS CHANGE USER IN PATH

{

    "configurations": [

        {

            "name": "Win32",

            "includePath": [

                "${workspaceFolder}/**",

                "C:/Users/mike.james/AppData/Local/Programs/Python/Python311/include/"

            ],

            "defines": [

                "_DEBUG",

                "UNICODE",

                "_UNICODE"

            ],

            "windowsSdkVersion": "10.0.22000.0",

            "compilerPath": "cl.exe",

            "cStandard": "c17",

            "cppStandard": "c++17",

            "intelliSenseMode": "windows-msvc-x64"

        }

    ],

    "version": 4

}

 

launch.json WINDOWS CHANGE USER IN PATH 

{

    "version": "0.2.0",

    "configurations": [

        {

            "name": "(Windows) Attach",

            "type": "cppvsdbg",

            "request": "attach",

            "processId": "${command:pickProcess}",

            "symbolSearchPath": "C:/Users/mike.james/AppData/Local/Programs/Python/Python-3.11.4",

            "sourceFileMap":{"D:/a/1/s/":"C:/Users/mike.james/AppData/Local/Programs/Python/Python311"},

        },

        {

            "name": "Python: Current File",

            "type": "python",

            "request": "launch",

            "program": "${file}",

            "console": "integratedTerminal"

        }

    ]

}

 


 

Page 72

example.c

This is the combined code from the chapter - the json files are as for example given ealier

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *stringRaw(PyObject *self, PyObject *args)

{

     char *name;

     if (!PyArg_ParseTuple(args, "s", &name))

          return NULL;

     printf("%s\n", name);

     for (int i = 0; name[i]; i++)

     {

          printf("%02X ", (unsigned char)name[i]);

     }

     printf("\n");

     Py_RETURN_NONE;

}

static PyObject *stringRawLen(PyObject *self, PyObject *args)

{

     char *name;

     Py_ssize_t len;

     if (!PyArg_ParseTuple(args, "s#", &name, &len))

          return NULL;

     printf("%s\n", name);

     printf("%d\n", (int)len);

     for (int i = 0; i < len; i++)

     {

          printf("%02X ", (unsigned char)name[i]);

     }

     printf("\n");

     Py_RETURN_NONE;

}

static PyObject *stringPBuffer(PyObject *self, PyObject *args)

{

     Py_buffer myBuf;

     if (!PyArg_ParseTuple(args, "s*", &myBuf))

          return NULL;

     char *myString = (char *)myBuf.buf;

     printf("%s\n", myString);

     for (int i = 0; i < myBuf.len; i++)

     {

          printf("%02X ", (unsigned char)myString[i]);

     }

     printf("\n");

     PyBuffer_Release(&myBuf);

     Py_RETURN_NONE;

}

static PyObject *stringEncode(PyObject *self, PyObject *args)

{

     char *name = NULL;

     if (!PyArg_ParseTuple(args, "es", "cp1252", &name))

          return NULL;

     printf("%s \n", name);

     for (int i = 0; name[i]; i++)

     {

          printf("%02X ", (unsigned char)name[i]);

     }

     printf("\n");

     PyMem_Free(name);

     Py_RETURN_NONE;

}

static PyObject *stringEncode2(PyObject *self, PyObject *args)

{

     char *name = NULL;

     Py_ssize_t len;

     if (!PyArg_ParseTuple(args, "es#", "utf-16", &name, &len))

          return NULL;

     printf("%s \n", name);

     for (int i = 0; i < len; i++)

     {

          printf("%02X ", (unsigned char)name[i]);

     }

     printf("\n");

     PyMem_Free(name);

     Py_RETURN_NONE;

}

static PyObject *stringEncodeAllocate(PyObject *self,

                                      PyObject *args)

{

     Py_ssize_t len = 25;

     char *name = malloc(sizeof(char) * (len + 1));

     if (!PyArg_ParseTuple(args, "es#", "cp1252", &name, &len))

          return NULL;

     printf("%d\n", (int)len);

     printf("%s \n", name);

     for (int i = 0; i < len; i++)

     {

          printf("%02X ", (unsigned char)name[i]);

     }

     printf("\n");

     free(name);

     Py_RETURN_NONE;

}

static PyObject *sequenceElements(PyObject *self, PyObject *args)

{

     int number;

     double x, y;

     char *name = NULL;

     if (!PyArg_ParseTuple(args, "(idds)", &number, &x, &y, &name))

          return NULL;

     printf("%d %f %f %s \n", number, x, y, name);

     Py_RETURN_NONE;

}

static PyMethodDef AddMethods[] = {

    {"stringRaw", stringRaw, METH_VARARGS, "an example"},

    {"stringRawLen", stringRawLen, METH_VARARGS, "an example"},

    {"stringPBuffer", stringPBuffer, METH_VARARGS, "an example"},

    {"stringEncode", stringEncode, METH_VARARGS, "an example"},

    {"stringEncode2", stringEncode2, METH_VARARGS, "an example"},

    {"stringEncodeAllocate", stringEncodeAllocate, METH_VARARGS, "an example"},

    {"sequenceElements", sequenceElements, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     return PyModule_Create(&addmodule);

}

test.py

import example

example.stringRaw("Hello World")

example.stringRawLen("Hello \0 World")

example.stringPBuffer("Hello \0 World")

example.stringEncode("Hello World")

example.stringEncode("\u2020")

example.stringEncode2("Hello World")

example.stringEncodeAllocate("Hello World")

example.sequenceElements((2,1.2,1.3,"test"))


 Page 81

example.c

This is the combined code from the chapter - the json files are as for example given ealier

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *retInt(PyObject *self, PyObject *args)

{

     int value = -1;

     return Py_BuildValue("I", value);

}

static PyObject *strTostr(PyObject *self, PyObject *args)

{

     char *name = "Brian";

     return Py_BuildValue("s", name);

}

static PyObject *strTostr2(PyObject *self, PyObject *args)

{

     char name[] = "    Brian";

     name[0] = 0xCE;

     name[1] = 0x94;

     return Py_BuildValue("s", name);

}

static PyObject *strTostrLen(PyObject *self, PyObject *args)

{

     char name[] = "   Brian";

     Py_ssize_t len = 5;

     name[0] = 0xCE;

     name[1] = 0x94;

     return Py_BuildValue("s#", name, len);

}

static PyObject *strTobytesLen(PyObject *self, PyObject *args)

{

     char name[] = "   Brian";

     Py_ssize_t len = 5;

     name[0] = 0xCE;

     name[1] = 0x94;

     return Py_BuildValue("y#", name, len);

}

static PyObject *wcharTostrLen(PyObject *self, PyObject *args)

{

     wchar_t name[] = L"   Brian";

     Py_ssize_t len = 5;

     name[0] = 0x0394;

     return Py_BuildValue("u#", name, len);

}

static PyObject *wcharTostrLen2(PyObject *self, PyObject *args)

{

  wchar_t name[] = L"   Brian";

  Py_ssize_t len = 5;

  name[0] = 0xD83E;

  name[1] = 0xDD10;

  return Py_BuildValue("u#", name, len);

}

static PyObject *retTuple(PyObject *self, PyObject *args)

{

  int number = 42;

  double x = 1.2, y = 1.1;

  char *name = "brian";

  return Py_BuildValue("(isdd)", number, name, x, y);

}

static PyObject *retList(PyObject *self, PyObject *args)

{

  int number = 42;

  double x = 1.2, y = 1.1;

  char *name = "brian";

  return Py_BuildValue("[isdd]", number, name, x, y);

}

static PyObject *retDict(PyObject *self, PyObject *args)

{

  int number = 42;

  double x = 1.2, y = 1.1;

  char *name = "brian";

  return Py_BuildValue("{sisssdsd}", "first", number,"second", name,"x", x,"y", y);

}

static PyMethodDef AddMethods[] = {

    {"retInt", retInt, METH_VARARGS, "an example"},

    {"strTostr", strTostr, METH_VARARGS, "an example"},

    {"strTostr2", strTostr2, METH_VARARGS, "an example"},

    {"strTostrLen", strTostrLen, METH_VARARGS, "an example"},

    {"strTobytesLen", strTobytesLen, METH_VARARGS, "an example"},

    {"wcharTostrLen", wcharTostrLen, METH_VARARGS, "an example"},

    {"wcharTostrLen2", wcharTostrLen2, METH_VARARGS, "an example"},

    {"retTuple", retTuple, METH_VARARGS, "an example"},

    {"retList", retList, METH_VARARGS, "an example"},

    {"retDict", retDict, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     return PyModule_Create(&addmodule);

}

test.py

import example
print(example.retInt())
print(example.strTostr())
print(example.strTostr2())
print(example.strTostrLen())
print(example.strTobytesLen())
print(example.wcharTostrLen())
#print(example.wcharTostrLen2())
print(example.retTuple())
print(example.retList())
print(example.retDict())
print("end")


 Page 96

example.c

This is the combined code from the chapter - the json files are as for example given ealier

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *Attributes1(PyObject *self, PyObject *args)

{

     PyObject *myObject;

     if (!PyArg_ParseTuple(args, "O", &myObject))

          return NULL;

     PyObject *attribName = Py_BuildValue("s", "myAttribute1");

     PyObject *myAtt1 = PyObject_GetAttr(myObject, attribName);

     Py_XDECREF(attribName);

     return myAtt1;

}

static PyObject *displayAttributes(PyObject *self, PyObject *args)

{

     PyObject *myObject;

     PyObject *myString;

     if (!PyArg_ParseTuple(args, "OO", &myObject, &myString))

          return NULL;

     PyObject *myAtt1 = PyObject_GetAttr(myObject, myString);

     if (PyUnicode_Check(myAtt1))

     {

          const char *mytext = PyUnicode_AsUTF8(myAtt1);

          printf("%s\n", mytext);

     }

     if (PyLong_Check(myAtt1))

     {

          int myValue = PyLong_AsLong(myAtt1);

          printf("%d\n", myValue);

     }

     return myAtt1;

}

static PyObject *Attributes2(PyObject *self, PyObject *args)

{

     PyObject *myObject;

     if (!PyArg_ParseTuple(args, "O", &myObject))

          return NULL;

     PyObject *newValue = PyLong_FromLong(42);

     if (PyObject_SetAttrString(myObject, "myAttribute1", newValue))

          return NULL;

     Py_RETURN_NONE;

}

static PyObject *Attributes3(PyObject *self, PyObject *args)

{

     PyObject *myObject;

     if (!PyArg_ParseTuple(args, "O", &myObject))

          return NULL;

     if (PyObject_HasAttrString(myObject, "myAttribute1"))

     {

          PyObject *myAtt1 = PyObject_GetAttrString(myObject, "myAttribute1");

          if (PyLong_Check(myAtt1))

          {

               int myValue = PyLong_AsLong(myAtt1);

               printf("%d\n", myValue);

          }

     }

     Py_RETURN_NONE;

}

static PyObject *Attributes4(PyObject *self, PyObject *args)

{

  PyObject *myObject;

  if (!PyArg_ParseTuple(args, "O", &myObject))

    return NULL;

  PyObject *main = PyImport_AddModule("__main__");

  PyObject *maindict = PyModule_GetDict(main);

  PyObject *myclass = PyDict_GetItemString(maindict, "myClass");

  if (PyObject_IsInstance(myObject, myclass))

  {

    PyObject *myAtt1 = PyObject_GetAttrString(myObject, "myAttribute1");

    if (PyLong_Check(myAtt1))

    {

      int myValue = PyLong_AsLong(myAtt1);

      printf("%d\n", myValue);

    }

    Py_XDECREF(myAtt1);

  }

  Py_RETURN_NONE;

}

static PyMethodDef AddMethods[] = {

    {"Attributes1", Attributes1, METH_VARARGS, "an example"},

    {"displayAttributes", displayAttributes, METH_VARARGS, "an example"},

    {"Attributes2", Attributes2, METH_VARARGS, "an example"},

    {"Attributes3", Attributes3, METH_VARARGS, "an example"},

    {"Attributes4", Attributes4, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     return PyModule_Create(&addmodule);

}

test.py

import example

class myClass:

    myAttribute1=10

    myAttribute2="Brian"

myInstance=myClass()

print(example.Attributes1(myInstance))

value=example.displayAttributes(myInstance,"myAttribute1")

print(value)

value=example.displayAttributes(myInstance,"myAttribute2")

print(value)

example.Attributes2(myInstance)

print(myInstance.myAttribute1)

example.Attributes3(myInstance)

example.Attributes4(myInstance)


Page 113

example.c

This is the combined code from the chapter - the json files are as for example given ealier

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *tuple1(PyObject *self, PyObject *args)

{

     PyObject *myTuple = PyTuple_New(10);

     for (int i = 0; i < 10; i++)

     {

          PyObject *item = PyLong_FromLong(i);

          PyTuple_SET_ITEM(myTuple, i, item);

     }

     return myTuple;

}

static PyObject *list1(PyObject *self, PyObject *args)

{

     PyObject *mylist = PyList_New(10);

     for (int i = 0; i < 10; i++)

     {

          PyObject *item = PyLong_FromLong(i);

          PyList_SetItem(mylist, i, item);

     }

     return mylist;

}

static PyObject *list2(PyObject *self, PyObject *args)

{

     PyObject *itemlist = PyList_New(0);

     for (int i = 0; i < 10; i++)

     {

          PyObject *item = PyLong_FromLong(i);

          PyList_Append(itemlist, PyLong_FromLong(i));

          Py_DECREF(PyList_GetItem(itemlist, i));

     }

     return itemlist;

}

static PyObject *dict1(PyObject *self, PyObject *args)

{

     PyObject *mydict = PyDict_New();

     PyObject *val = PyLong_FromLong(42333);

     PyObject *key = PyUnicode_DecodeUTF8("Item0", 5, NULL);

     PyDict_SetItem(mydict, key, val);

     Py_DECREF(val);

     Py_DECREF(key);

     return mydict;

}

static PyObject *tuple2(PyObject *self, PyObject *args)

{

     PyObject *myTuple;

     if (!PyArg_ParseTuple(args, "O", &myTuple))

          return NULL;

     int myarray[10];

     for (int i = 0; i < 10; i++)

     {

          PyObject *item = PyTuple_GetItem(myTuple, i);

          myarray[i] = PyLong_AsLong(item);

          printf("%d ", myarray[i]);

     }

     printf("\n");

     Py_RETURN_NONE;

}

static PyObject *list3(PyObject *self, PyObject *args)

{

     PyObject *mylist;

     if (!PyArg_ParseTuple(args, "O", &mylist))

          return NULL;

     PyObject *itemlist = PyList_New(4);

     PyList_SetItem(itemlist, 0, PyLong_FromLong(10));

     PyList_SetItem(itemlist, 1, PyLong_FromLong(11));

     PyList_SetItem(itemlist, 2, PyLong_FromLong(12));

     PyList_SetItem(itemlist, 3, PyLong_FromLong(13));

     PyList_SetSlice(mylist, 3, 5, itemlist);

     Py_DECREF(itemlist);

     Py_RETURN_NONE;

}

static PyObject *listIterator(PyObject *self, PyObject *args)

{

     PyObject *mylist;

     if (!PyArg_ParseTuple(args, "O", &mylist))

          return NULL;

     PyObject *myIter = PyObject_GetIter(mylist);

     printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));

     printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));

     printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));

     printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));

     printf("\n");

     Py_DECREF(myIter);

     Py_RETURN_NONE;

}

static PyObject *listFor(PyObject *self, PyObject *args)

{

     PyObject *myList;

     if (!PyArg_ParseTuple(args, "O", &myList))

          return NULL;

     PyObject *myIter = PyObject_GetIter(myList);

     for (PyObject *item = PyIter_Next(myIter); item != NULL; item = PyIter_Next(myIter))

     {

          printf("%d ", PyLong_AsLong(item));

          Py_DECREF(item);

     }

     printf("\n");

     Py_DECREF(myIter);

     Py_RETURN_NONE;

}

static PyObject *listWhile(PyObject *self, PyObject *args)

{

     PyObject *myList;

     if (!PyArg_ParseTuple(args, "O", &myList))

          return NULL;

     PyObject *myIter = PyObject_GetIter(myList);

     PyObject *item;

     while (item = PyIter_Next(myIter))

     {

          printf("%d ", PyLong_AsLong(item));

          Py_DECREF(item);

     }

     Py_DECREF(myIter);

     printf("\n");

     Py_DECREF(myIter);

     Py_RETURN_NONE;

}

static PyMethodDef AddMethods[] = {

    {"tuple1", tuple1, METH_VARARGS, "an example"},

    {"list1", list1, METH_VARARGS, "an example"},

    {"list2", list2, METH_VARARGS, "an example"},

    {"dict1", dict1, METH_VARARGS, "an example"},

    {"tuple2", tuple2, METH_VARARGS, "an example"},

    {"list3", list3, METH_VARARGS, "an example"},

    {"listIterator", listIterator, METH_VARARGS, "an example"},

    {"listFor", listFor, METH_VARARGS, "an example"},

    {"listWhile", listWhile, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     return PyModule_Create(&addmodule);

}

test.py

import example

import sys

#print(example.tuple1())

print(example.list1())

myList=example.list2()

print(myList)

print("ref count=",sys.getrefcount(myList[0])-1)

myDict=example.dict1()

print(myDict)

print("ref count=",sys.getrefcount(myDict["Item0"])-1)

print("ref count=",sys.getrefcount(myDict)-1)



myTuple=example.tuple1()

print(myTuple)

example.tuple2(myTuple)

mylist=[0,1,2,3,4,5,6,7,8,9]

example.list3(mylist)

print(myList)

mylist=[0,1,2,3,4,5,6,7,8,9]

example.listIterator(mylist)

example.listFor(mylist)

example.listWhile(mylist)

 


Page 118

 

exception.py

total=0

class MyNumberError(ArithmeticError):

    def __init__(self, message,):

        super(MyNumberError, self).__init__(message)



def myFunc(x,y):

    global total

    total=total+1

    print("in myFunc")

    raise MyNumberError("Number not 42")

    return 1

result=myFunc(1,1)

try:

    result=myFunc(1,1)

except MyNumberError:

    print("Can't divide by zero")

    total=total-1

  #  result=myFunc(1,1)

#print(result)

print(total)

Page 123

example.c

This is the combined code from the chapter - the json files are as for example given ealier

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *exception1(PyObject *self, PyObject *args)

{

     PyObject *x = PyLong_FromLong(1);

     PyObject *y = PyLong_FromLong(0);

     PyObject *ans = PyNumber_TrueDivide(x, y);

     if (ans == NULL)

     {

          Py_DECREF(x);

          Py_DECREF(y);

          return NULL;

     }

     PyObject *z = PyLong_FromLong(1);

     PyObject *ans2 = PyNumber_TrueDivide(x, z);

     Py_DECREF(x);

     Py_DECREF(y);

     Py_DECREF(z);

     return ans;

}

static PyObject *exception2(PyObject *self, PyObject *args)

{

     PyErr_SetString(PyExc_ZeroDivisionError, "A Dummy divide error has occurred");

     return NULL;

}

static PyObject *myCustomException;

static PyObject *exception3(PyObject *self, PyObject *args)

{

     PyErr_SetString(myCustomException, "A Custom error has occurred");

     return NULL;

}

static PyObject *exception4(PyObject *self, PyObject *args)

{

     PyObject *x = PyLong_FromLong(1);

     PyObject *y = PyLong_FromLong(0);

     PyObject *ans = PyNumber_TrueDivide(x, y);

     if (ans == NULL)

     {

          PyErr_Clear();

          PyObject *z = PyLong_FromLong(1);

          ans = PyNumber_TrueDivide(x, z);

          Py_DECREF(z);

     }

     Py_DECREF(x);

     Py_DECREF(y);

     return ans;

}

static PyObject *exception5(PyObject *self, PyObject *args)

{

     PyObject *x = PyLong_FromLong(1);

     PyObject *y = PyLong_FromLong(0);

     PyObject *ans = PyNumber_TrueDivide(x, y);

     if (PyErr_Occurred() != NULL)

     {

          if(PyErr_ExceptionMatches(PyExc_ZeroDivisionError)){

               PyErr_Clear();

               PyObject *z = PyLong_FromLong(1);

               ans = PyNumber_TrueDivide(x, z);

               Py_DECREF(z);

          }

     }

     Py_DECREF(x);

     Py_DECREF(y);

     return ans;

}

static PyObject *list1(PyObject *self, PyObject *args)

{

  PyObject *myList;

  if (!PyArg_ParseTuple(args, "O", &myList))

    return NULL;

  printf("myList %ld\n", Py_REFCNT(myList));

  PyObject *temp = PyList_GetItem(myList, 0);

  printf("item zero %ld\n", Py_REFCNT(temp));

  PyObject *myList2 = PySequence_InPlaceConcat(myList, myList);

  temp = PyList_GetItem(myList, 0);

  temp = PyList_GetItem(myList, 0);

  printf("myList %ld\n", Py_REFCNT(myList));

  printf("item zero %ld\n", Py_REFCNT(temp));

  Py_RETURN_NONE;

}



static PyMethodDef AddMethods[] = {

    {"exception1", exception1, METH_VARARGS, "an example"},

    {"exception2", exception2, METH_VARARGS, "an example"},

    {"exception3", exception3, METH_VARARGS, "an example"},

    {"exception4", exception4, METH_VARARGS, "an example"},

    {"exception5", exception5, METH_VARARGS, "an example"},

    {"list1", list1, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     PyObject *m;

     m = PyModule_Create(&addmodule);

     if (m == NULL)

          return NULL;

     myCustomException = PyErr_NewException("example.myCustomException", NULL, NULL);

     if (PyModule_AddObjectRef(m, "myCustomException", myCustomException) < 0)

     {

          Py_CLEAR(myCustomException);

          Py_DECREF(m);

          return NULL;

     }

     return m;

}

test.py

import example

import gc

#ans=example.exception1()

#print(ans)

#try:

#    ans=example.exception2()

#except ZeroDivisionError as err:

#    print(err)

try:

   ans=example.exception3()

except example.myCustomException as err:

    print(err)



try:

    ans=example.exception4()

except ZeroDivisionError as err:

    print(err)

print(ans)

try:

    ans=example.exception5()

except ZeroDivisionError as err:

    print(err)

print(ans)

print(gc.get_objects())

gc.collect()

myList=[257,1,2,3,4,5,6,7,8,9]

gc.collect()

example.list1(myList)

print(myList)


Page 148

example.c

This is the combined code from the chapter - the json files are as for example given ealier

 

 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *bytes1(PyObject *self, PyObject *args)

{

     char *myString = "Hello World";

     PyObject *myBytes = PyBytes_FromString(myString);

     return myBytes;

}

static PyObject *bytes2(PyObject *self, PyObject *args)

{

     PyObject *myBytes;

     if (!PyArg_ParseTuple(args, "O", &myBytes))

          return NULL;

     Py_ssize_t len = PyBytes_Size(myBytes);

     for (int i = 1; i < len; i++)

     {

          PyObject *item = PySequence_GetItem(myBytes, i);

          char c = (char)PyLong_AsLong(item);

          printf("%X  ", c);

     }

     printf("\n");

     PyObject *myByteArray = PyByteArray_FromStringAndSize(PyBytes_AsString(myBytes), PyBytes_Size(myBytes));

     char *HelloMessage = "Hello World";

     PyObject *insert = PyByteArray_FromStringAndSize(HelloMessage, strlen(HelloMessage));

     PySequence_SetSlice(myByteArray, 3, 7, insert);

     return myByteArray;

}

static PyObject *string1(PyObject *self, PyObject *args)

{

     PyObject *uni1 = PyUnicode_New(10, 255);

     PyUnicode_Fill(uni1, 0, 10, 120);

     PyUnicode_WriteChar(uni1, 0, 72);

     return uni1;

}

static PyObject *string2(PyObject *self, PyObject *args)

{

     PyObject *myString = PyUnicode_FromString("Spam, Spam, Spam, Spam… Lovely Spam! Wonderful Spam!");

     int len = PyUnicode_GET_LENGTH(myString);

     Py_UCS4 *buf = PyMem_Malloc(sizeof(Py_UCS4) * (len + 1));

     PyUnicode_AsUCS4(myString, buf, 100, 1);

     for (int i = 0; buf[i]; i++)

     {

          printf("%04X ", buf[i]);

     }

     PyMem_Free(buf);

     printf("\n\n");

     buf = PyUnicode_AsUCS4Copy(myString);

     for (int i = 0; buf[i]; i++)

     {

          printf("%04X ", buf[i]);

     }

     printf("\n\n");

     PyMem_Free(buf);

     Py_DECREF(myString);

     Py_RETURN_NONE;

}

static PyObject *string3(PyObject *self, PyObject *args)

{

     PyObject *myString = PyUnicode_FromString("Spam, Spam, Spam, Spam… Lovely Spam! Wonderful Spam!");

     int len = PyUnicode_GET_LENGTH(myString);

     PyObject *substr = PyUnicode_FromString("Lovely");

     Py_ssize_t pos = PyUnicode_Find(myString, substr, 0, len, 1);

     printf("position of Lovely = %ld\n", pos);

     pos = PyUnicode_FindChar(myString, 0x0000006D, 0, len, 1);

     printf("position of first m %ld\n", pos);

     substr = PyUnicode_FromString("Spam");

     Py_ssize_t result = PyUnicode_Tailmatch(myString, substr, 0, len, -1);

     printf("prefix match %ld\n", result);

     substr = PyUnicode_FromString("Spam");

     result = PyUnicode_Contains(myString, substr);

     printf("Contains Spam %ld\n", result);

     Py_ssize_t count = PyUnicode_Count(myString, substr, 0, len);

     printf("Count of how many spam(s) %ld\n", count);

     PyObject *test = PyUnicode_FromString("Spam");

     result = PyUnicode_Compare(substr, test);

     printf("compare to Spam %ld\n", result);

     result = PyUnicode_CompareWithASCIIString(substr, "Spam");

     printf("compare to Spam %ld\n", result);

     PyObject *logic = PyUnicode_RichCompare(substr, test, Py_EQ);

     if (Py_IsTrue(logic))

     {

          printf("Strings are equal\n");

     }

     else

     {

          printf("Strings are not equal\n");

     }

     Py_RETURN_NONE;

}

static PyObject *string4(PyObject *self, PyObject *args)

{

     PyObject *myString = PyUnicode_FromString("Spam, Spam, Spam, Spam . . .Lovely Spam! Wonderful Spam!");

     PyObject *bytesUTF8 = PyUnicode_AsUTF8String(myString);

     PyObject *bytesUTF16 = PyUnicode_AsUTF16String(myString);

     PyObject *bytesUTF32 = PyUnicode_AsUTF32String(myString);

     Py_ssize_t len = PyBytes_Size(bytesUTF32);

     for (int i = 0; i < len; i++)

     {

          PyObject *item = PySequence_GetItem(bytesUTF32, i);

          int c = PyLong_AsLong(item);

          printf("%02X  ", c);

     }

     printf("\n");

     char *buffer;

     PyBytes_AsStringAndSize(bytesUTF32, &buffer, &len);

     PyObject *decodeStr = PyUnicode_DecodeUTF32(buffer, len, NULL, NULL);

     return decodeStr;

}

static PyObject *string5(PyObject *self, PyObject *args)

{

     PyObject *myString = PyUnicode_New(1, 1114111);

     PyUnicode_WriteChar(myString, 0, 0x2020);

     PyObject *myBytes = PyUnicode_AsEncodedString(myString, "cp1252", NULL);

     char *buffer;

     Py_ssize_t len;

     PyBytes_AsStringAndSize(myBytes, &buffer, &len);

     printf("%X \n", buffer[0]);

     printf("%s \n", buffer);

     Py_DECREF(myBytes);

     return myString;

}

static PyObject *string6(PyObject *self, PyObject *args)

{

  PyObject *myString = PyUnicode_FromString("† Spam, Spam, Spam, Spam . . .Lovely Spam! Wonderful Spam!");

  PyObject *myBytes = PyUnicode_AsEncodedString(myString, "raw_unicode_escape", NULL);

  Py_DECREF(myString);

  return myBytes;

}

static PyMethodDef AddMethods[] = {

    {"bytes1", bytes1, METH_VARARGS, "an example"},

    {"bytes2", bytes2, METH_VARARGS, "an example"},

    {"string1", string1, METH_VARARGS, "an example"},

    {"string2", string2, METH_VARARGS, "an example"},

    {"string3", string3, METH_VARARGS, "an example"},

    {"string4", string4, METH_VARARGS, "an example"},

    {"string5", string5, METH_VARARGS, "an example"},

    {"string6", string6, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     return PyModule_Create(&addmodule);

}

 test.py

import example
mybytes=example.bytes1()
print(mybytes)
print()

mybytes=example.bytes2(b"My long message")
print(mybytes)

print(example.string1())
print()
example.string2()
print()
example.string3()
print()
print(example.string4())

print()
result=example.string5()
print(result)
print()
result=example.string6()
print(result)


 

Page 157

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *exampleFunction(PyObject *self, PyObject *args)

{

     // example function code

}

static PyMethodDef AddMethods[] = {

    {"exampleFunction", exampleFunction, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static PyObject *myFunc(PyObject *self, PyObject *args)

{

     printf("hello world\n");

     Py_RETURN_NONE;

}

static PyObject *myFunc2(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)

{

     for (int i = 0; i < nargs; i++)

     {

          const char *myString = PyUnicode_AsUTF8(args[i]);

          printf("%s\n", myString);

     }

     Py_ssize_t nKwds = PyTuple_Size(kwnames);

     for (int i = 0; i < nKwds; i++)

     {

          const char *myValue = PyUnicode_AsUTF8(args[i + nargs]);

          const char *myKeyword = PyUnicode_AsUTF8(PyTuple_GetItem(kwnames, i));

          printf("Keyword = %s, Value = %s \n", myKeyword, myValue);

     }

     Py_RETURN_NONE;

}

static PyMethodDef myFunc_def = {

    "myFunc",

    myFunc,

    METH_VARARGS,

    "the doc string"};

static PyMethodDef myFunc2_def = {

    "myFunc2",

    (PyCFunction)myFunc2,

    METH_FASTCALL | METH_KEYWORDS,

    "the doc string"};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

     PyObject *m = PyModule_Create(&myModule);

     if (m == NULL)

          return NULL;

     // Add a int

     PyObject *myValue = PyLong_FromLong(42);

     PyModule_AddObject(m, "myValue", myValue);

     // Add a list

     PyObject *myList = PyList_New(0);

     PyModule_AddObject(m, "myList", myList);

     // Add a function

     PyObject *myPyFun = PyCFunction_New(&myFunc_def, m);

     PyModule_AddObject(m, "myFunc1", myPyFun);

     // Add a fastcall function

     PyObject *myPyFun2 = PyCFunction_New(&myFunc2_def, m);

     PyModule_AddObject(m, "myFunc2", myPyFun2);

     //Add a function in another module

     PyObject *math=PyImport_ImportModule("math");

     PyObject *mathdict = PyModule_GetDict(math);

     PyObject *myFunction = PyDict_GetItemString(mathdict, "sqrt");

     PyModule_AddObject(m, "myFunc3", myFunction);

     return m;

}

test.py

import example
print("module constant",example.myValue)
example.myValue=43
print("module constant",example.myValue)
print(example.myList)
example.myList.append("spam")
print(example.myList)
print(example.myFunc1())
example.myFunc2("Hello","World",MyKeyWord="myValue")
print(example.myFunc3(2))
print(example.myFunc3.__name__)

 

 

Page 160

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

int exec(PyObject *m)

{

  PyObject *myValue = PyLong_FromLong(42);

  PyModule_AddObject(m, "myValue", myValue);

  return 0;

}

PyObject *create(PyObject *spec, PyModuleDef *def)

{

  PyObject *res=PyObject_GetAttrString(spec,"origin");

  printf("%s\n",PyUnicode_AsUTF8(res));

  PyObject *m= PyModule_New("example");

  return m;

}

PyModuleDef_Slot twoPhase[] = {

    {Py_mod_create, create},

    {Py_mod_exec, exec},

    {0, 0}};

static struct PyModuleDef myModuledef = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    0,

    NULL,

    twoPhase};

PyMODINIT_FUNC PyInit_example(void)

{

  return PyModuleDef_Init(&myModuledef);

}

test.py

import example
print(example.myValue)

Page 164

 example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

struct myData

{

  int count;

  char name[20];

};

static struct myData myModuleData = {42, "spam"};

static PyObject *myFunc(PyObject *self, PyObject *args)

{

  printf("module data %d , %s\n", myModuleData.count, myModuleData.name);

  myModuleData.count++;

  struct myData *myModData = (struct myData *)PyModule_GetState(self);

  printf("module data %d , %s\n", myModData->count, myModData->name);

  myModData->count++;

  Py_RETURN_NONE;

}

static PyMethodDef myFunc_def = {

    "myFunc",

    myFunc,

    METH_VARARGS,

    "the doc string"};

int exec(PyObject *m)

{

  struct myData *myModData = (struct myData *)PyModule_GetState(m);

  myModData->count = 42;

  strcpy(myModData->name, "spam");

  PyObject *myValue = PyLong_FromLong(42);

  PyModule_AddObject(m, "myValue", myValue);

  PyObject *myPyFun = PyCFunction_New(&myFunc_def, m);

  PyModule_AddObject(m, "myFunc", myPyFun);

  return 0;

}

PyObject *create(PyObject *spec, PyModuleDef *def)

{

  PyObject *res = PyObject_GetAttrString(spec, "origin");

  printf("%s\n", PyUnicode_AsUTF8(res));

  PyObject *m = PyModule_New("example");  

  return m;

}



void freeModule(void *m){

    struct myData *myModData = (struct myData *)PyModule_GetState(m);

    PyMem_Free(myModData);

}

PyModuleDef_Slot twoPhase[] = {

    {Py_mod_create, create},

    {Py_mod_exec, exec},

    {0, 0}};

static struct PyModuleDef myModuledef = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    sizeof(struct myData),

    NULL,

    twoPhase,

    NULL,

    NULL,

    freeModule};

PyMODINIT_FUNC PyInit_example(void)

{

  return PyModuleDef_Init(&myModuledef);

}

test.py

import example
example.myFunc()
example.myFunc()

 


 Page 172

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyTypeObject MyType1 = {

    PyVarObject_HEAD_INIT(NULL, 0)

    .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT |  Py_TPFLAGS_DISALLOW_INSTANTIATION

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myclass=example.MyClass
print(myclass)
print(myclass.__dict__)

Page 173

example.c
 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyTypeObject MyType1 = {

    PyVarObject_HEAD_INIT(NULL, 0)

    .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(PyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myInst=example.MyClass()
print(myInst)
print(myInst.__dir__())
print(myInst.__sizeof__())

Page 176

exampe.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *myFunc(PyObject *self, PyObject *args)

{

  printf("hello world\n");

  Py_RETURN_NONE;

}

static PyMethodDef myFunc_def = {

    "myFunc",

    myFunc,

    METH_VARARGS,

    "the doc string"};

static PyTypeObject MyType1 = {

    PyVarObject_HEAD_INIT(NULL, 0)

        .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(PyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyObject *mydict = PyDict_New();

  PyObject *val = PyLong_FromLong(42);

  PyDict_SetItemString(mydict, "myValue", val);

  Py_DECREF(val);

  PyObject *myPyFun = PyCFunction_New(&myFunc_def, (PyObject *)&MyType1);

  PyDict_SetItemString(mydict, "myFunc", myPyFun);

  MyType1.tp_dict = mydict;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

 

test.py

import example
example.MyClass.myFunc()
myInst=example.MyClass()
myInst.myFunc()

 Page 177

 example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

typedef struct

{

  PyObject_HEAD

      PyObject *dict;

} MyObject;

static PyObject *myFunc(PyObject *self, PyObject *args)

{

  printf("hello world\n");

  Py_RETURN_NONE;

}

static PyMethodDef myFunc_def = {

    "myFunc",

    myFunc,

    METH_VARARGS,

    "the doc string"};

static PyTypeObject MyType1 = {

    PyVarObject_HEAD_INIT(NULL, 0)

        .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_dictoffset=offsetof(MyObject, dict),

    .tp_new = PyType_GenericNew,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyObject *mydict = PyDict_New();

  PyObject *val = PyLong_FromLong(42);

  PyDict_SetItemString(mydict, "myValue", val);

  Py_DECREF(val);

  PyObject *myPyFun = PyCFunction_New(&myFunc_def, (PyObject *)&MyType1);

  PyDict_SetItemString(mydict, "myFunc", myPyFun);

  MyType1.tp_dict = mydict;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py 

import example
example.MyClass.myFunc()
myInst=example.MyClass()
myInst.myFunc()
myInst.myValue=43
print(myInst.myValue)
myInst.myVal1=42
print(myInst.myVal1)

Page  180

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

typedef struct

{

  PyObject_HEAD

      PyObject *dict;

} MyObject;

static PyObject *myFunc(PyObject *self, PyObject *args)

{

  printf("hello world\n");

  Py_RETURN_NONE;

}

static PyMethodDef myFunc_def = {

    "myFunc",

    myFunc,

    METH_VARARGS,

    "the doc string"};

static PyObject *Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)

{

  MyObject *self;

  self = (MyObject *)type->tp_alloc(type, 0);

  return (PyObject *)self;

}

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  PyObject *myPyFunc = PyCFunction_New(&myFunc_def, (PyObject *)self);

  PyObject *myPyMethod = PyInstanceMethod_New(myPyFunc);

  int res = PyObject_SetAttrString((PyObject *)self, "MyMethod", myPyMethod);

  return 0;

}

static PyTypeObject MyType1 = {

    PyVarObject_HEAD_INIT(NULL, 0)

        .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_dictoffset = offsetof(MyObject, dict),

    .tp_new = Custom_new,

    .tp_init = (initproc)Custom_init,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyObject *mydict = PyDict_New();

  PyObject *val = PyLong_FromLong(42);

  PyDict_SetItemString(mydict, "myValue", val);

  Py_DECREF(val);

  PyObject *myPyFun = PyCFunction_New(&myFunc_def, (PyObject *)&MyType1);

  PyDict_SetItemString(mydict, "myFunc", myPyFun);

  MyType1.tp_dict = mydict;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
example.MyClass.myFunc()
myInst=example.MyClass()
myInst.myFunc()
myInst.myValue=43
print(myInst.myValue)
myInst.myVal1=42
print(myInst.myVal1)
myInst.MyMethod()

Page 185

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD

  int myVal;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};



static PyMemberDef myMemberdef = {

    "MyVar",

    T_INT,

    offsetof(MyObject, myVal),

    0,

    "MyInstanceAttr"};

static PyMethodDef myFunc_def = {

    "myFunc",

    (PyCFunction)myFunc,

    METH_VARARGS,

    "the doc string"};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new =PyType_GenericNew,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyObject *mydict=PyDict_New();

  PyObject *myMethodDesc = PyDescr_NewMethod(&MyType1, &myFunc_def);

  int res = PyDict_SetItemString(mydict, "MyMethod", myMethodDesc);

  PyObject *myMemberDesc = PyDescr_NewMember(&MyType1, &myMemberdef);

  res = PyDict_SetItemString(mydict, "MyVar", myMemberDesc);

  MyType1.tp_dict=mydict;

  res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

 test.py

import example

myInst=example.MyClass()
myInst.MyMethod()
myInst.MyVar=43
print(myInst.MyVar)

Page  187

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD

  int myVal;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};



static PyMemberDef myMemberdef[] = {

   { "MyVar",T_INT,offsetof(MyObject, myVal),0,"MyInstanceAttr"},

   {NULL}

    };

static PyMethodDef myMethodDef[] = {

  {"MyMethod",(PyCFunction)myFunc,METH_VARARGS,"the doc string"},

  {NULL}

    };

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

    .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example

myInst=example.MyClass()
myInst.MyMethod()
myInst.MyVar=43
print(myInst.MyVar)

Page 190

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD

      PyObject *myProp;

} MyObject;

static PyObject *getVal(MyObject *self, void *extra)

{

  return Py_NewRef(self->myProp);

}

int setVal(MyObject *self, PyObject *val, void *extra)

{

  Py_XSETREF(self->myProp, Py_XNewRef(val));

  return 0;

}

static PyGetSetDef myGetSetDef[] = {

    {"myProperty", (getter)getVal, (setter)setVal, "Example get set", NULL},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_getset = myGetSetDef,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example

myInst=example.MyClass()
myInst.myProperty=42
print(myInst.myProperty)


 Page 194

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

     PyObject_HEAD int myVal;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

     printf("destructor called\n");

     Py_TYPE(self)->tp_free((PyObject *)self);

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

     printf("%d\n", self->myVal);

     printf("hello world\n");

     Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_dealloc = (destructor)Custom_dealloc,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

     PyObject *m = PyModule_Create(&myModule);

     if (m == NULL)

          return NULL;

     int res = PyType_Ready(&MyType1);

     PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

     return m;

}

test.py

import example
myinst1=example.MyClass()
myinst1.MyVar=42
print(myinst1.MyVar)
myInst1=None

Page 196

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD

  int myVal;

  PyObject *myAttr;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

     printf("destructor called\n");

     Py_TYPE(self)->tp_free((PyObject *)self);

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

     printf("%d\n", self->myVal);

     printf("hello world\n");

     Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0,"MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0,"MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_dealloc = (destructor)Custom_dealloc,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

     PyObject *m = PyModule_Create(&myModule);

     if (m == NULL)

          return NULL;

     int res = PyType_Ready(&MyType1);

     PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

     return m;

}

 test.py

import example
myInst1=example.MyClass()
myInst1.MyAttr=myInst1
myInst1=None
print("end")
while True:
     pass

Page 197

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

    PyObject_HEAD int myVal;

    PyObject *myAttr;

    PyObject *weaklist;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

    printf("destructor called\n");

    Py_TYPE(self)->tp_free((PyObject *)self);

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

    printf("%d\n", self->myVal);

    printf("hello world\n");

    Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_dealloc = (destructor)Custom_dealloc,

    .tp_weaklistoffset = offsetof(MyObject, weaklist),

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

    PyObject *m = PyModule_Create(&myModule);

    if (m == NULL)

        return NULL;

    int res = PyType_Ready(&MyType1);

    PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

    return m;

}

test.py

import example
import weakref
myInst1=example.MyClass()
myInst1.MyAttr=weakref.ref(myInst1)
myInst1=None
print("end")
while True:
    pass

 Page 199

example.c 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD int myVal;

  PyObject *myAttr;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

  printf("destructor called\n");

  PyObject *error_type,*error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  PyObject_GC_UnTrack(self);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  PyObject_GC_Del(self);

  PyErr_Restore(error_type, error_value, error_traceback);  

}

static int Custom_clear(MyObject *self)

{

  printf("clear called\n");

  Py_CLEAR(self->myAttr);

  return 0;

}

static int Custom_traverse(MyObject *self, visitproc visit, void *arg)

{

  printf("traverse called\n");

  Py_VISIT(self->myAttr);

  return 0;

}

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  self->myVal = 0;

  self->myAttr = Py_None;

  Py_XINCREF(Py_None);

  return 0;

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_init = (initproc)Custom_init,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_clear = (inquiry)Custom_clear,

    .tp_traverse = (traverseproc)Custom_traverse,

    .tp_dealloc = (destructor)Custom_dealloc,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

 

test.py

import example
import gc

myInst1=example.MyClass()
print(gc.is_tracked(myInst1))
myInst1.MyAttr=myInst1
myInst1=None
print(gc.get_count())
gc.collect()
print(gc.get_count())

Page 203

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

static PyTypeObject MyType1;

typedef struct

{

  PyObject_HEAD int myVal;

  PyObject *myAttr;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

  printf("destructor called\n");

  PyObject *error_type,

      *error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  PyObject_GC_UnTrack(self);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  PyObject_GC_Del(self);

  PyErr_Restore(error_type, error_value, error_traceback);

}

static void Custom_finalizer(MyObject *self)

{

  printf("finalizer called\n");

  if (PyObject_GC_IsFinalized((PyObject *)self))

    return;

  PyObject *error_type,

      *error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  PyObject_GC_UnTrack(self);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  PyObject_GC_Del(self);

  PyErr_Restore(error_type, error_value, error_traceback);

}

static int Custom_clear(MyObject *self)

{

  printf("clear called\n");

  Py_CLEAR(self->myAttr);

  return 0;

}

static int Custom_traverse(MyObject *self, visitproc visit, void *arg)

{

  printf("traverse called\n");

  Py_VISIT(self->myAttr);

  return 0;

}

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  self->myVal = 0;

  self->myAttr = Py_None;

  Py_XINCREF(Py_None);

  return 0;

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_init = (initproc)Custom_init,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_clear = (inquiry)Custom_clear,

    .tp_traverse = (traverseproc)Custom_traverse,

    .tp_finalize = (destructor)Custom_finalizer,

    .tp_dealloc = (destructor)Custom_dealloc,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
import gc

myInst1=example.MyClass()
print(gc.is_tracked(myInst1))
myInst1.MyAttr=myInst1
myInst1=None
print(gc.get_count())
gc.collect()
print(gc.get_count())

Page 205

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

     PyObject_HEAD

     int myVal;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

     printf("%d\n", self->myVal);

     printf("hello world\n");

     Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static struct PyModuleDef myModule = {PyModuleDef_HEAD_INIT, "example", "C library to test API", -1, NULL};

PyMODINIT_FUNC PyInit_example(void)

{

     PyObject *m = PyModule_Create(&myModule);

     if (m == NULL)

          return NULL;

     static PyType_Slot mySlots[] = {

         {Py_tp_doc, "My Custom object"},

         {Py_tp_members, myMemberdef},

         {Py_tp_methods, myMethodDef},

         {0, NULL}};

     PyType_Spec mySpec = {

         "example.myObject",

         sizeof(MyObject),

         0,

         Py_TPFLAGS_DEFAULT,

         mySlots};

     PyTypeObject *MyType1 = (PyTypeObject *)PyType_FromSpec(&mySpec);

     PyModule_AddObject(m, "MyClass", (PyObject *)MyType1);

     return m;

}

test.py

import example
myInst1=example.MyClass()
myInst1.MyVar=42
print(myInst1.MyVar)
myInst1.MyMethod()
example.MyClass.myNewVar=43
print(example.MyClass.myNewVar)

 

 

 

Page 206

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD int myVal;

  PyObject *myAttr;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

  printf("destructor called\n");

  PyObject *error_type, *error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  PyObject_GC_UnTrack(self);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  PyObject_GC_Del(self);

  PyErr_Restore(error_type, error_value, error_traceback);

}

static void Custom_finalizer(MyObject *self)

{

  printf("finalizer called\n");

  if (PyObject_GC_IsFinalized((PyObject *)self))

    return;

  PyObject *error_type,

      *error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  PyObject_GC_UnTrack(self);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  PyObject_GC_Del(self);

  PyErr_Restore(error_type, error_value, error_traceback);

}

static int Custom_clear(MyObject *self)

{

  printf("clear called\n");

  Py_CLEAR(self->myAttr);

  return 0;

}

static int Custom_traverse(MyObject *self, visitproc visit, void *arg)

{

  printf("traverse called\n");

  Py_VISIT(self->myAttr);

  return 0;

}

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  self->myVal = 0;

  self->myAttr = Py_None;

  Py_XINCREF(Py_None);

  return 0;

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyType_Slot mySlots[] = {

    {Py_tp_doc, "My Custom object"},

    {Py_tp_members, myMemberdef},

    {Py_tp_methods, myMethodDef},

    {Py_tp_clear, (inquiry)Custom_clear},

    {Py_tp_traverse, (traverseproc)Custom_traverse},

    {Py_tp_dealloc, (destructor)Custom_dealloc},

    {Py_tp_finalize,(destructor)Custom_finalizer},

    {0, NULL}};

PyType_Spec mySpec = {

    "example.myObject",

    sizeof(MyObject),

    0,

    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,

    mySlots};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyTypeObject *MyType1 = (PyTypeObject *)PyType_FromSpec(&mySpec);

  PyModule_AddObject(m, "MyClass", (PyObject *)MyType1);

  return m;

}

test.py

import example
import gc

myInst1=example.MyClass()
print(gc.is_tracked(myInst1))
#myInst1.MyAttr=myInst1
myInst1=None
print(gc.get_count())
gc.collect()
print(gc.get_count())

example.MyClass.myNewVar=43
print(example.MyClass.myNewVar)

Page 209

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyUnicodeObject str;

  int myVal;

  PyObject *myAttr;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  MyType1.tp_base = &PyUnicode_Type;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myInst1=example.MyClass("Hello")
print(len(myInst1))
myInst1.MyVar=42
print(myInst1.MyVar)
myInst1.MyMethod()
print("myInst=",myInst1)

Page 211

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyListObject list;

  int myVal;

  PyObject *myAttr;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  MyType1.tp_base = &PyList_Type;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myInst1=example.MyClass(["brian","spam",42])
print(myInst1)
print(len(myInst1))

Page 213

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyListObject list;

  int myVal;

  PyObject *myAttr;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  int res = Py_TYPE(self)->tp_base->tp_init((PyObject *)self, args, kwds);

  self->myVal = PyList_Size((PyObject *)self);

  return 0;

}

static void Custom_dealloc(MyObject *self)

{

  printf("destructor called\n");

  PyObject *error_type, *error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  Py_TYPE(self)->tp_base->tp_dealloc((PyObject *)self);

  PyErr_Restore(error_type, error_value, error_traceback);

}

static int Custom_clear(MyObject *self)

{

  printf("clear called\n");

  Py_CLEAR(self->myAttr);

  return 0;

}

static int Custom_traverse(MyObject *self, visitproc visit, void *arg)

{

  printf("traverse called\n");

  Py_VISIT(self->myAttr);

  PyList_Type.tp_traverse((PyObject *)self, visit, arg);

  return 0;

}

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_init = (initproc)Custom_init,

    .tp_clear = (inquiry)Custom_clear,

    .tp_traverse = (traverseproc)Custom_traverse,

    .tp_dealloc = (destructor)Custom_dealloc,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  MyType1.tp_base = &PyList_Type;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myInst1=example.MyClass(["brian","spam",42])
print(myInst1)
print(len(myInst1))
print(myInst1.MyVar)

Page 216

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"



static PyObject *myFactory(PyObject *self, PyObject *args)

{

  args = Py_BuildValue("()");

  PyObject *result = PyObject_Call((PyObject *)self, args, NULL);

  return result;

}

static PyMethodDef myFactory_def = {

    "myFactory",

    (PyCFunction)myFactory,

    METH_FASTCALL | METH_KEYWORDS,

    "the doc string"};

typedef struct

{

  PyObject_HEAD

  int myVal;

} MyObject;

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  self->myVal = 0;

  return 0;

};



static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {NULL}};



static PyTypeObject MyType1= {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_init = (initproc)Custom_init,

    .tp_members = myMemberdef,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyObject *myPyFactory = PyCFunction_New(&myFactory_def,(PyObject*) &MyType1);

  PyModule_AddObject(m, "myFactory", myPyFactory);

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myInst=example.myFactory()
print(myInst)
print(myInst.MyVar)
myInst.MyVar=42
print(myInst.MyVar)

Page 217

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *call(PyObject *self, PyObject *args)

{

  PyObject *math = PyImport_AddModule("math");

  PyObject *mathdict = PyModule_GetDict(math);

  PyObject *myFunction = PyDict_GetItemString(mathdict, "sqrt");

  args = Py_BuildValue("(I)", 2);

  PyObject *result = PyObject_Call(myFunction, args, NULL);

  return result;

}



static PyObject *object1(PyObject *self, PyObject *args)

{

  PyObject *main = PyImport_AddModule("__main__");

  PyObject *maindict = PyModule_GetDict(main);

  PyObject *myclass = PyDict_GetItemString(maindict, "myClass");

  args = Py_BuildValue("()");

  PyObject *result = PyObject_Call(myclass, args, NULL);

  PyObject *newValue = PyLong_FromLong(43);

  PyObject_SetAttrString(result, "myAttribute1", newValue);

  return result;

}

static PyMethodDef AddMethods[] = {

    {"call", call, METH_VARARGS, "an example"},

    {"object1", object1, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef myModule = {

  PyModuleDef_HEAD_INIT,

  "example",                              

  "C library to test API",  

  -1,                                  

  AddMethods                          

};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  return m;

}

test.py

import example

import math

class myClass:

    myAttribute1=0

print(example.call())

inst=example.object1()

print(inst)

print(inst.myAttribute1)


Page 226

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#if defined(_WIN32) || defined(_WIN64)

#define SCALE 1000

#else

#define SCALE 1

#endif

static PyObject *Pi(PyObject *self, PyObject *args)

{

     int m, n;

     double pi, s;

     if (!PyArg_ParseTuple(args, "ii", &m, &n))

          return NULL;

     Py_BEGIN_ALLOW_THREADS

     pi = 0;

     for (int k = m; k < n; k++)

     {

          s = 1;

          if (k % 2 == 0)

               s = -1;

          pi = pi + s / (2 * k - 1);

     }

     sleep(5 * SCALE);

     Py_END_ALLOW_THREADS

     return PyFloat_FromDouble(4 * pi);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

     return PyModule_Create(&addmodule);

}

 test.py

import Pi

import time

import concurrent.futures

N=10000000

with concurrent.futures.ThreadPoolExecutor() as executor:

    t1=time.perf_counter()    

    f1 = executor.submit(Pi.myPi,1,N)

    t2=time.perf_counter()

    print("do some additional work")

    print("waiting for result")

    print(f1.result())

    print((t2-t1)*1000)

Page 227 LINUX VERSION

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

typedef struct

{

     int m;

     int n;

} range;

static pthread_mutex_t mutex;

static double PiShared = 0;

void *PartPi(void *args)

{

     range *range1 = (range *)args;

     double pi, s;

     int m = range1->m;

     int n = range1->n;

     pi = 0;

     for (int k = m; k < n; k++)

     {

          s = 1;

          if (k % 2 == 0)

               s = -1;

          pi = pi + s / (2 * k - 1);

     }

     pthread_mutex_lock(&mutex);

     PiShared += pi;

     pthread_mutex_unlock(&mutex);

     return NULL;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

     int m, n;

     if (!PyArg_ParseTuple(args, "ii", &m, &n))

          return NULL;

     Py_BEGIN_ALLOW_THREADS

         range range1 = {m, n / 2};

     range range2 = {n / 2 + 1, n};

     int threadId;

     pthread_mutex_init(&mutex, NULL);

     pthread_t thread1, thread2;

     pthread_create(&thread1, NULL, PartPi, &range1);

     pthread_create(&thread2, NULL, PartPi, &range2);

     pthread_join(thread1, NULL);

     pthread_join(thread2, NULL);

     Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

     return PyModule_Create(&addmodule);

}

Page 229 WINDOWS VERSION

example.c

 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <Windows.h>

typedef struct

{

    int m;

    int n;

} range;

static int *Mutex;

static double PiShared = 0;

int PartPi(void *args)

{

    range *range1 = (range *)args;

    double pi, s;

    int m = range1->m;

    int n = range1->n;

    pi = 0;

    for (int k = m; k < n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }

    WaitForSingleObject(Mutex, INFINITE);

    PiShared += pi;

    ReleaseMutex(Mutex);

    return 0;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    int *handles[2];

    if (!PyArg_ParseTuple(args, "ii", &m, &n))

        return NULL;

    Py_BEGIN_ALLOW_THREADS

        range range1 = {m, n / 2};

    range range2 = {n / 2 + 1, n};

    int threadId;

    Mutex = CreateMutex(NULL, FALSE, NULL);

    handles[0] = CreateThread(NULL, 0, PartPi, (void *)&range1, 0, &threadId);

    handles[1] = CreateThread(NULL, 0, PartPi, (void *)&range2, 0, &threadId);

    WaitForMultipleObjects(2, handles, TRUE, INFINITE);

    Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;

    return m;

}

 

 test.py

import Pi

import time

import concurrent.futures

N=10000000

with concurrent.futures.ThreadPoolExecutor() as executor:

    t1=time.perf_counter()    

    f1 = executor.submit(Pi.myPi,1,N)

    t2=time.perf_counter()

    print("do some additional work")

    print("waiting for result")

    print(f1.result())

    print((t2-t1)*1000)

Page 231 LINUX VERSION

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

typedef struct

{

     int m;

     int n;

} range;

static pthread_mutex_t mutex;

static double PiShared = 0;

void *PartPi(void *args)

{

     range *range1 = (range *)args;

     double pi, s;

     int m = range1->m;

     int n = range1->n;

     pi = 0;

     for (int k = m; k < n; k++)

     {

          s = 1;

          if (k % 2 == 0)

               s = -1;

          pi = pi + s / (2 * k - 1);

     }

     pthread_mutex_lock(&mutex);

     PiShared += pi;

     pthread_mutex_unlock(&mutex);

     PyGILState_STATE gstate = PyGILState_Ensure();

     PyObject *pimod = PyImport_AddModule("Pi");

     PyObject *myVal = PyObject_GetAttrString(pimod, "myValue");

     PyObject *myOne = PyLong_FromLong(1);

     PyObject *myInc = PyNumber_Add(myVal, myOne);

     int res = PyObject_SetAttrString((PyObject *)pimod, "myValue", myInc);

     PyGILState_Release(gstate);

     return NULL;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

     int m, n;

     if (!PyArg_ParseTuple(args, "ii", &m, &n))

          return NULL;

     Py_BEGIN_ALLOW_THREADS

         range range1 = {m, n / 2};

     range range2 = {n / 2 + 1, n};

     pthread_mutex_init(&mutex, NULL);

     pthread_t thread1, thread2;

     pthread_create(&thread1, NULL, PartPi, &range1);

     pthread_create(&thread2, NULL, PartPi, &range2);

     pthread_join(thread1, NULL);

     pthread_join(thread2, NULL);

     Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

     PyObject *m = PyModule_Create(&addmodule);

     if (m == NULL)

          return NULL;

     PyObject *myValue = PyLong_FromLong(42);

     PyModule_AddObject(m, "myValue", myValue);

     return m;

}

Page 233 WINDOWS VERSION

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <Windows.h>

typedef struct

{

    int m;

    int n;

} range;

static int *Mutex;

static double PiShared = 0;

int PartPi(void *args)

{

    range *range1 = (range *)args;

    double pi, s;

    int m = range1->m;

    int n = range1->n;

    pi = 0;

    for (int k = m; k < n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }

    WaitForSingleObject(Mutex, INFINITE);

    PiShared += pi;

    ReleaseMutex(Mutex);

    PyGILState_STATE gstate = PyGILState_Ensure();

    PyObject *pimod = PyImport_AddModule("Pi");

    PyObject *myVal = PyObject_GetAttrString(pimod, "myValue");

    PyObject *myOne = PyLong_FromLong(1);

    PyObject *myInc = PyNumber_Add(myVal, myOne);

    int res = PyObject_SetAttrString((PyObject *)pimod, "myValue", myInc);

    PyGILState_Release(gstate);

    return 0;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    int *handles[2];

    if (!PyArg_ParseTuple(args, "ii", &m, &n))

         return NULL;

    Py_BEGIN_ALLOW_THREADS

    range range1 = {m, n / 2};

    range range2 = {n / 2 + 1, n};

    int threadId;

    Mutex = CreateMutex(NULL, FALSE, NULL);

    handles[0] = CreateThread(NULL, 0, PartPi, (void *)&range1, 0, &threadId);

    handles[1] = CreateThread(NULL, 0, PartPi, (void *)&range2, 0, &threadId);

    WaitForMultipleObjects(2, handles, TRUE, INFINITE);

    Py_END_ALLOW_THREADS

    return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;

    PyObject *myValue = PyLong_FromLong(42);

    PyModule_AddObject(m, "myValue", myValue);

    return m;

}

test.py

import Pi

import time

import concurrent.futures

N=10000000

print("go")

with concurrent.futures.ThreadPoolExecutor() as executor:    

    t1=time.perf_counter()    

    f1 = executor.submit(Pi.myPi,1,N)

    print("do some additional work")

    print("waiting for result")

    r=f1.result()

    t2=time.perf_counter()

    print((t2-t1)*1000)

    print(r)

    print(Pi.myValue)

Page 238 LINUX VERSION

#define PY_SSIZE_T_CLEAN

#include <Python.h>

typedef struct

{

    int m;

    int n;

    double Pi;

    PyObject *cb;

}State;

int Ccb(void *args)

{

    State *state = (State *)args;

    printf("C callback called \n");

    PyObject *pi=Py_BuildValue("(f)",state->Pi);

    PyObject_CallObject((PyObject *)(state->cb), pi);

    free(state);

    return 0;

}

static void *ComputePi(void *args)

{

    State *state = (State *)args;

    double pi, s;

    pi = 0;

    for (int k = state->m; k < state->n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }  

    state->Pi=4*pi;

    int res = Py_AddPendingCall(Ccb, (void *)state);

    return NULL;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    PyObject *cb;

    if (!PyArg_ParseTuple(args, "iiO:myPi", &m, &n, &cb))

        return NULL;

    State *state=(State*)malloc(sizeof(State));

    state->m = m;

    state->n = n;

    state->cb = cb;

    state->Pi = 0;

    pthread_t thread1;

    pthread_create(&thread1, NULL, ComputePi, (void *)state);

    return PyLong_FromLong(0);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;    

    return m;

}

 

Page 238 WINDOWS VERSION

 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <Windows.h>

typedef struct

{

    int m;

    int n;

    double Pi;

    PyObject *cb;

}State;

int Ccb(void *args)

{

    State *state = (State *)args;

    printf("C callback called \n");

    PyObject *pi=Py_BuildValue("(f)",state->Pi);

    PyObject_CallObject((PyObject *)state->cb, pi);

    free(state);

    return 0;

}

static int ComputePi(void *args)

{

    State *state = (State *)args;

    double pi, s;

    pi = 0;

    for (int k = state->m; k < state->n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }  

    state->Pi=4*pi;

    int res = Py_AddPendingCall(Ccb, (void *)state);

    return 0;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    PyObject *cb;

    if (!PyArg_ParseTuple(args, "iiO:myPi", &m, &n, &cb))

        return NULL;

    State *state=(State*)malloc(sizeof(State));

    state->m = m;

    state->n = n;

    state->cb = cb;

    state->Pi = 0;

    int threadId;

    int *handle = CreateThread(NULL, 0, ComputePi, (void *)state, 0, &threadId);

    return PyLong_FromLong(0);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;    

    return m;

}

 test.py

import Pi

import time

def myCallback(pi):

    t2 = time.perf_counter()

    print((t2-t1)*1000)

    print("python callback")

    print(pi)

N = 10000000

t1 = time.perf_counter()    

Pi.myPi(1,N,myCallback)

print("do some additional work")

while True:

    time.sleep(0.00001)


 

 Page 244

main.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>



int main(int argc, char *argv[])

{

      Py_Initialize();

      PyRun_SimpleString("from time import time,ctime\n"

                         "print('Today is', ctime(time()))\n");

      Py_FinalizeEx();    

  return 0;

}

 

 tasks.json WINDOWS

 Change user name

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: cl.exe build active file",

            "command": "cl.exe",

            "args": [

                "/Zi",

                "/EHsc",

                "/nologo",

                "/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",

                "/Fe${fileDirname}\\${fileBasenameNoExtension}.exe",

                "${file}",

                "/link /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$msCompile"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

 tasks.json LINUX

 

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: gcc-10 build active file",

            "command": "/usr/bin/gcc-10",

            "args": [

                "-fdiagnostics-color=always",

                "-g",                

                "${file}",

                "-o",

                "${fileDirname}/${fileBasenameNoExtension}",

                "-I/usr/local/include/python3.11",

                "-L/usr/local/lib/python3.11/config-3.11-arm-linux-gnueabihf",

                "-L/usr/local/lib",

                "-Xlinker",

                "-export-dynamic",

                "-lpython3.11",

                "-lpthread",

                "-ldl",

                "-lutil",

                "-lm",

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$gcc"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

Page 247

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *Pi(PyObject *self, PyObject *args)

{

  int m, n;

  double pi, s;

  if (!PyArg_ParseTuple(args, "ii", &m, &n))

    return NULL;

  pi = 0;

  for (int k = m; k < n; k++)

  {

    s = 1;

    if (k % 2 == 0)

      s = -1;

    pi = pi + s / (2 * k - 1);

  }

  return PyFloat_FromDouble(4 * pi);

};

static PyMethodDef AddMethods[] = {

    {"myPi", Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

  return PyModule_Create(&addmodule);

};

int main(int argc, char *argv[])

{

  PyImport_AppendInittab("Pi", &PyInit_Pi);

  Py_Initialize();

  PyRun_SimpleString("import Pi\n"

    "print(Pi.myPi(1,1000))\n");

  Py_FinalizeEx();

  return 0;

}

Page 248

#define PY_SSIZE_T_CLEAN

#include <Python.h>



int main(int argc, char *argv[])

{

  Py_Initialize();

  PyObject *math =PyImport_ImportModule("math");

  PyObject *mathdict = PyModule_GetDict(math);

  PyObject *myFunction = PyDict_GetItemString(mathdict, "sqrt");

  PyObject *args = Py_BuildValue("(I)", 2);

  PyObject *result = PyObject_Call(myFunction, args, NULL);

  double res=PyFloat_AS_DOUBLE(result);

  printf("%f\n",res);

  PyRun_SimpleString(

    "import math\n"

    "print(math.sqrt(2))\n");

  Py_FinalizeEx();

  return 0;

}

Page 249

#define PY_SSIZE_T_CLEAN

#include <Python.h>

int main(int argc, char *argv[])

{

  Py_Initialize();

  {

    PyObject *g = PyDict_New();

    PyObject *l = PyDict_New();

    PyDict_SetItemString(l, "X", PyLong_FromLong(2));

    PyDict_SetItemString(l, "Y", PyLong_FromLong(2));

    PyObject *pyResult = PyRun_String("X+Y", Py_eval_input, g, l);

    int Cresult = PyLong_AS_LONG(pyResult);

    printf("%d\n", Cresult);

  }

  {

    PyObject *g = PyDict_New();  

    PyObject *l = PyDict_New();

    PyObject *math = PyImport_ImportModule("math");

    PyDict_SetItemString(g, "math", math);

    PyObject *pyResult = PyRun_String("math.sqrt(2)", Py_eval_input, g, l);

    double res2 = PyFloat_AS_DOUBLE(pyResult);

    printf("%f\n", res2);

  }

  Py_FinalizeEx();

  return 0;

}

Page 250

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    double pi, s;

    if (!PyArg_ParseTuple(args, "ii", &m, &n))

        return NULL;

    pi = 0;

    for (int k = m; k < n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }

    return PyFloat_FromDouble(4 * pi);

}

static PyMethodDef AddMethods[] = {

    {"myPi", Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    return PyModule_Create(&addmodule);

}

int main(int argc, char *argv[])

{

    PyImport_AppendInittab("Pi", &PyInit_Pi);

    Py_Initialize();

    PyObject *main = PyImport_AddModule("__main__");

    PyObject *mainDict = PyModule_GetDict(main);

    FILE *fp = fopen("Pi.py", "r");

    PyObject *l = PyDict_New();

    PyObject *result = PyRun_File(fp, "Pi.py", Py_file_input, mainDict, l);

    Py_FinalizeEx();

    return 0;

}

Pi,py

import Pi
import time
N=10000000
t1=time.perf_counter()
pi=Pi.myPi(1,N)
t2=time.perf_counter()
print((t2-t1)*1000)
print(pi)