Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- build: gcc -O3 -std=gnu11 -o max31855 max31855.c
- */
- #include <stdio.h>
- #include <stdint.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- #include <linux/spi/spidev.h>
- #include <errno.h>
- #include <time.h>
- #include <sys/timerfd.h>
- #include <signal.h>
- #define OPEN_CIRCUIT_ERROR 1
- #define SHORT_CIRCUIT_TO_GND_ERROR 2
- #define SHORT_CIRCUIT_TO_VCC_ERROR 3
- /* perform SPI read and convert to temperature */
- int read_temps(int,float*,float*);
- /* handle to timer for periodic tasks */
- int create_timer(unsigned int);
- /* gracefully stop "infinite" while loop */
- void stop(int);
- /* whether to execute while loop (updated by stop()) */
- volatile int run = 1;
- /* time between thermocouple reads (microseconds) */
- #define PERIOD_US 100000
- int read_temps(int fd, float* internal, float* thermocouple)
- {
- int ret;
- uint16_t internal_word, thermocouple_word;
- uint8_t rx[4];
- ret = read(fd,rx,sizeof(rx));
- if (ret < 0)
- {
- perror("unable to read SPI bus!!!");
- return ret;
- }
- thermocouple_word = (((uint16_t)rx[0] << 8) | (uint16_t)rx[1]) >> 2;
- internal_word = (((uint16_t)rx[2] << 8) | (uint16_t)rx[3]) >> 4;
- if (rx[3] & 0x01)
- {
- fprintf(stderr, "open circuit!");
- return OPEN_CIRCUIT_ERROR;
- }
- else if (rx[3] & 0x02)
- {
- fprintf(stderr, "short circuit to ground!");
- return SHORT_CIRCUIT_TO_GND_ERROR;
- }
- else if (rx[3] & 0x04)
- {
- fprintf(stderr, "short circuit to Vcc!");
- return SHORT_CIRCUIT_TO_VCC_ERROR;
- }
- *internal = ((float)((int16_t)internal_word)) * 0.0625;
- *thermocouple = ((float)((int16_t)thermocouple_word)) * 0.25;
- return 0;
- }
- int create_timer(unsigned int period_us)
- {
- int fd;
- unsigned int period_ns;
- struct itimerspec loop_time;
- period_ns = period_us * 1000;
- loop_time.it_interval.tv_sec = period_ns / 1000000000;
- loop_time.it_interval.tv_nsec = period_ns % 1000000000;
- loop_time.it_value.tv_sec = period_ns / 1000000000;
- loop_time.it_value.tv_nsec = period_ns % 1000000000;
- fd = timerfd_create(CLOCK_MONOTONIC, 0);
- if (fd < 0)
- {
- perror("failed to create timer");
- exit(0);
- }
- if (timerfd_settime(fd, 0, &loop_time, NULL) < 0)
- {
- perror("failed to set timer");
- exit(0);
- }
- return fd;
- }
- void stop(int signum)
- {
- run = 0;
- }
- int main(int argc, char const *argv[])
- {
- char* soc = "/dev/spidev0.0";
- int fd, fd_tmr;
- float internal, thermocouple;
- signal(SIGINT, stop);
- signal(SIGKILL, stop);
- fd = open(soc,O_RDWR);
- if (fd < 0)
- {
- perror("failed to open SPI bus!");
- exit(EXIT_FAILURE);
- }
- fd_tmr = create_timer(PERIOD_US);
- printf(" Timestamp | Intrnl | Thmcpl |\n");
- printf(" Seconds | °C | °C |\n");
- while (run)
- {
- struct timespec t = {0,0};
- unsigned long long missed_ticks;
- int rc;
- if(read(fd_tmr, &missed_ticks, sizeof(missed_ticks)) < 0)
- {
- perror("timer failed");
- exit(EXIT_FAILURE);
- }
- if (missed_ticks > 1)
- {
- fprintf(stderr, "WARNING: %d missed ticks.\n");
- }
- rc = read_temps(fd, &internal, &thermocouple);
- if (rc < 0)
- {
- perror("Error with SPI bus\n");
- EXIT_FAILURE;
- }
- else if (rc > 0)
- {
- fprintf(stderr, "failed to read temp data! Error code: %d\n", rc);
- }
- clock_gettime(CLOCK_REALTIME, &t);
- printf("%10d.%03d, %07.4f, %06.2f\n",t.tv_sec, t.tv_nsec / 1000000, internal, thermocouple);
- }
- printf("Exited main loop.\n");
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement