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