Created
April 5, 2016 14:16
-
-
Save matejperejda/c54c15982b41c0573d04dbb34ecf9828 to your computer and use it in GitHub Desktop.
LM74 temperature sensor temperature reading and conversion. Implements negative and positive temperature.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
============================================================================ | |
Name : LM74TemperatureSens.c | |
Author : Matej Perejda | |
Date : 27/09/2015 | |
Description : LM74 temperature sensor temperature reading and conversion. | |
Implements negative and positive temperature. | |
============================================================================ | |
*/ | |
#include <stdint.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <getopt.h> | |
#include <fcntl.h> | |
#include <sys/ioctl.h> | |
#include <linux/types.h> | |
#include <linux/spi/spidev.h> | |
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) | |
#define LSB_CONST 0.0625 | |
static void pabort(const char *s) { | |
perror(s); | |
abort(); | |
} | |
static const char *device = "/dev/spidev0.0"; | |
static uint8_t mode = SPI_MODE_0; | |
static uint8_t bits = 8; | |
static uint32_t speed = /*500000*/ 1000000; | |
static uint16_t delay; | |
float lastTemp = 0.00; | |
static void transfer(int fd) { | |
int ret; | |
uint16_t bitShift; | |
int bitShift_int; | |
uint16_t division; | |
float temperature; | |
// Sending bytes | |
uint8_t tx[] = {0x00, 0x00}; | |
uint8_t rx[ARRAY_SIZE(tx)] = {0, }; | |
struct spi_ioc_transfer tr = { | |
.tx_buf = (unsigned long)tx, | |
.rx_buf = (unsigned long)rx, | |
.len = ARRAY_SIZE(tx), | |
.delay_usecs = delay, | |
.speed_hz = speed, | |
.bits_per_word = bits, | |
// Clock switching from HIGH to LOW | |
// Sensor activation | |
.cs_change = 0, | |
}; | |
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); | |
if (ret < 1) | |
pabort("can't send spi message"); | |
for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { | |
if (!(ret % 6)) { | |
// puts(""); | |
// printf("%.2X ", rx[ret]); | |
} | |
} | |
// puts(""); | |
// Bitshift from rx array | |
uint16_t arrayBoth = ((rx[0] << 8) | rx[1]) ; | |
// If first element in binary is 1 = negative value | |
if (rx[0] & 0x80) { | |
// Inverse 2's complement | |
// We have to subtract one | |
division = arrayBoth - 1; | |
printf("Division: %02X\n", division); | |
// Inverse hex | |
division = ~division; | |
printf("Inverse div: %02X\n", division); | |
// Right bitshift 3 bits | |
bitShift = division >> 3; | |
// Int conversion | |
bitShift_int = (int) bitShift; | |
// Temperature conversion | |
temperature = (float) -1 * (bitShift_int * LSB_CONST); | |
} else { | |
// Right bitshift to remove three last zeroes | |
// 25 degrees: 0000 1100 1000 0000 => 0000 1100 1000 0 | |
bitShift = arrayBoth >> 3; | |
// Conversation from right bitshift to int value | |
bitShift_int = (int) bitShift; | |
// Final temperature | |
temperature = bitShift_int * LSB_CONST; | |
} | |
if (lastTemp != temperature) { | |
printf("Hex: %02X \n", arrayBoth); | |
printf("Shift: %02X\n", bitShift); | |
printf("Int value: %d \n", bitShift_int); | |
printf("Temperature: %.2f°C\n", temperature); | |
lastTemp = temperature; | |
puts(""); | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
int ret = 0; | |
int fd; | |
fd = open(device, O_RDWR); | |
if (fd < 0) | |
pabort("can't open device"); | |
/* | |
* spi mode | |
*/ | |
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); | |
if (ret == -1) | |
pabort("can't set spi mode"); | |
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); | |
if (ret == -1) | |
pabort("can't get spi mode"); | |
/* | |
* bits per word | |
*/ | |
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); | |
if (ret == -1) | |
pabort("can't set bits per word"); | |
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); | |
if (ret == -1) | |
pabort("can't get bits per word"); | |
/* | |
* max speed hz | |
*/ | |
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); | |
if (ret == -1) | |
pabort("can't set max speed hz"); | |
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); | |
if (ret == -1) | |
pabort("can't get max speed hz"); | |
// printf("spi mode: %d\n", mode); | |
// printf("bits per word: %d\n", bits); | |
// printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); | |
while(1) { | |
transfer(fd); | |
sleep(1); // delay while printing | |
} | |
close(fd); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment