Raspberry Pi IoT In C - 1-Wire Via Serial
Written by Harry Fairhead   
Monday, 28 December 2020
Article Index
Raspberry Pi IoT In C - 1-Wire Via Serial
The Listing

The complete program

#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");
    float temp=getTemperature(sfd);
    printf("%f \n\r", temp);
    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; }

Of course you can use the readBit and writeBit functions within other one-wire functions with minor modifications.

You can use the UART approach whenever a signaling protocol uses an initial start bit to signal that data bits follow using a fixed size “cell”. However, you cannot use the UART approach to the DHT22 temperature and humidity sensor because although it sends each bit with a start bit, the time to the next start bit varies.


  • The serial port is one of the oldest ways of connecting devices together, but it is still very much in use.

  • The serial protocol is asynchronous, but simple. A start bit gives the timing for the entire exchange.

  • There are many control lines once used with telephone equipment that are mostly ignored in computer use. Similarly, the original ±12V signaling has been mostly replaced by 5V, and even 3.3V, signaling.

  • The standard hardware that implements a serial connection is usually called a UART.

  • The Raspberry Pi Zero, 1, 2, and 3 each contain two UARTs and the Raspberry Pi 4 has both these plus four additional ones.

  • If you want to use a UART within your program, you first have to configure things so that Linux isn’t using it as command console.

  • The serial port is used in C programs as if it was a file, but there are are many ways to configure it using the ioctl function.

  • The ioctl function is too low-level for most applications and termios is a better way to do the job.

  • Termios can be used to set the protocol, baud rate, parity, etc and to determine how the software interacts with the UART, timeout etc.

  • You can use a UART to input data in blocking mode or non-blocking mode or something between the two.

  • The UART can be repurposed to work with any asynchronous signaling where the time to transmit a single bit is constant.


Raspberry Pi And The IoT In C Second Edition

By Harry Fairhead


Buy from Amazon.


  1. Why Pi For IoT?
  2. Getting Started
  3. Getting Started With The GPIO
  4. Simple Output
  5. Some Electronics
  6. Simple Input
  7. GPIO The Linux Way
  8. Advanced Input – Events, Threads, Interrupts
        Extract 1: Events & Interrupts 
  9. Pulse Width Modulation - Servos And More
  10. Using The I2C Bus
  11. The DHT22 Sensor Implementing A Custom Protocol
  12. Exploring 1‑Wire Bus Basics
  13. Using iButtons
  14. DS18B20 Temperature Sensor
  15. The Multidrop 1‑Wire Bus
  16. The Serial Port
        Extract 1: 1-wire Via Serial ***NEW!
  17. Getting Started With The SPI Bus
  18. A to D With The SPI Bus
  19. Connecting With The Web - Sockets
  20. Memory-Mapped GPIO
  21. Almost Real-Time Linux
  22. Appendix I GPIO Sysfs Interface



To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on, Twitter, Facebook or Linkedin.


Jacob Ziv Awarded IEEE Medal of Honor For Data Compression

This year's IEEE Medal of Honor has been awarded to Jacob Ziv, who, with  Abraham Lempel, created two lossless compression methods (LZ-77 and LZ-78) which are the basis of a wide range  [ ... ]

How Is JavaScript Doing?

The results of the 2020 State of JavaScript Survey have been released. What do they tell us about developers attitude towards JavaScript and its ever-expanding ecosystem?

More News





or email your comment to: comments@i-programmer.info


Last Updated ( Monday, 28 December 2020 )