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
1-Wire
The Listing

The complete program

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

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.

Summary

  • 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

FrontCover800

Buy from Amazon.

Contents

  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
       Extract 1:The Linux GPIO Driver 
  8. Advanced Input – Events, Threads, Interrupts
       Extract 1: Events & Interrupts 
  9. Pulse Width Modulation - Servos And More
       Extract 1:Basic Pulse Width Modulation 
  10. Using The I2C Bus
  11. The DHT22 Sensor Implementing A Custom Protocol
  12. Exploring - 1‑Wire Bus Basics ***NEW!
  13. Using iButtons
  14. DS18B20 Temperature Sensor
      Extract 1: The DS18B20 Temperature Sensor 
  15. The Multidrop 1‑Wire Bus
  16. The Serial Port
      Extract 1: 1-wire Via Serial 
  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

 <ASIN:1871962633>

<ASIN:B08KLNT2JC>

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.

Banner


Apache Lucene Improves Sparce Indexing
22/10/2024

Apache Lucene 10 has been released. The updated version adds a new IndexInput prefetch API, support for sparse indexing on doc values, and upgraded Snowball dictionaries resulting in improved tokeniza [ ... ]



Microsoft Introduces Unified .NET API For AI
14/10/2024

Microsoft has introduced new libraries for integrating AI services into .NET applications and libraries, along with middleware for adding key capabilities.


More News

espbook

 

Comments




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

 



Last Updated ( Monday, 28 December 2020 )