Article Index

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
  }