Advertisement
Guest User

Untitled

a guest
May 21st, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.67 KB | None | 0 0
  1. /*
  2. build: gcc -O3 -std=gnu11 -o max31855 max31855.c
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <stdint.h>
  7. #include <fcntl.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include <sys/ioctl.h>
  11. #include <linux/spi/spidev.h>
  12. #include <errno.h>
  13. #include <time.h>
  14. #include <sys/timerfd.h>
  15. #include <signal.h>
  16.  
  17. #define OPEN_CIRCUIT_ERROR 1
  18. #define SHORT_CIRCUIT_TO_GND_ERROR 2
  19. #define SHORT_CIRCUIT_TO_VCC_ERROR 3
  20.  
  21. /* perform SPI read and convert to temperature */
  22. int read_temps(int,float*,float*);
  23.  
  24. /* handle to timer for periodic tasks */
  25. int create_timer(unsigned int);
  26.  
  27. /* gracefully stop "infinite" while loop */
  28. void stop(int);
  29.  
  30. /* whether to execute while loop (updated by stop()) */
  31. volatile int run = 1;
  32.  
  33. /* time between thermocouple reads (microseconds) */
  34. #define PERIOD_US 100000
  35.  
  36. int read_temps(int fd, float* internal, float* thermocouple)
  37. {
  38. int ret;
  39. uint16_t internal_word, thermocouple_word;
  40. uint8_t rx[4];
  41.  
  42. ret = read(fd,rx,sizeof(rx));
  43. if (ret < 0)
  44. {
  45. perror("unable to read SPI bus!!!");
  46. return ret;
  47. }
  48.  
  49. thermocouple_word = (((uint16_t)rx[0] << 8) | (uint16_t)rx[1]) >> 2;
  50. internal_word = (((uint16_t)rx[2] << 8) | (uint16_t)rx[3]) >> 4;
  51.  
  52. if (rx[3] & 0x01)
  53. {
  54. fprintf(stderr, "open circuit!");
  55. return OPEN_CIRCUIT_ERROR;
  56. }
  57. else if (rx[3] & 0x02)
  58. {
  59. fprintf(stderr, "short circuit to ground!");
  60. return SHORT_CIRCUIT_TO_GND_ERROR;
  61. }
  62. else if (rx[3] & 0x04)
  63. {
  64. fprintf(stderr, "short circuit to Vcc!");
  65. return SHORT_CIRCUIT_TO_VCC_ERROR;
  66. }
  67.  
  68. *internal = ((float)((int16_t)internal_word)) * 0.0625;
  69. *thermocouple = ((float)((int16_t)thermocouple_word)) * 0.25;
  70. return 0;
  71. }
  72.  
  73. int create_timer(unsigned int period_us)
  74. {
  75. int fd;
  76. unsigned int period_ns;
  77. struct itimerspec loop_time;
  78.  
  79. period_ns = period_us * 1000;
  80. loop_time.it_interval.tv_sec = period_ns / 1000000000;
  81. loop_time.it_interval.tv_nsec = period_ns % 1000000000;
  82. loop_time.it_value.tv_sec = period_ns / 1000000000;
  83. loop_time.it_value.tv_nsec = period_ns % 1000000000;
  84.  
  85. fd = timerfd_create(CLOCK_MONOTONIC, 0);
  86. if (fd < 0)
  87. {
  88. perror("failed to create timer");
  89. exit(0);
  90. }
  91. if (timerfd_settime(fd, 0, &loop_time, NULL) < 0)
  92. {
  93. perror("failed to set timer");
  94. exit(0);
  95. }
  96. return fd;
  97. }
  98.  
  99. void stop(int signum)
  100. {
  101. run = 0;
  102. }
  103.  
  104. int main(int argc, char const *argv[])
  105. {
  106. char* soc = "/dev/spidev0.0";
  107. int fd, fd_tmr;
  108. float internal, thermocouple;
  109.  
  110. signal(SIGINT, stop);
  111. signal(SIGKILL, stop);
  112.  
  113. fd = open(soc,O_RDWR);
  114. if (fd < 0)
  115. {
  116. perror("failed to open SPI bus!");
  117. exit(EXIT_FAILURE);
  118. }
  119.  
  120. fd_tmr = create_timer(PERIOD_US);
  121.  
  122. printf(" Timestamp | Intrnl | Thmcpl |\n");
  123. printf(" Seconds | °C | °C |\n");
  124. while (run)
  125. {
  126. struct timespec t = {0,0};
  127. unsigned long long missed_ticks;
  128. int rc;
  129.  
  130. if(read(fd_tmr, &missed_ticks, sizeof(missed_ticks)) < 0)
  131. {
  132. perror("timer failed");
  133. exit(EXIT_FAILURE);
  134. }
  135.  
  136. if (missed_ticks > 1)
  137. {
  138. fprintf(stderr, "WARNING: %d missed ticks.\n");
  139. }
  140.  
  141. rc = read_temps(fd, &internal, &thermocouple);
  142. if (rc < 0)
  143. {
  144. perror("Error with SPI bus\n");
  145. EXIT_FAILURE;
  146. }
  147. else if (rc > 0)
  148. {
  149. fprintf(stderr, "failed to read temp data! Error code: %d\n", rc);
  150. }
  151.  
  152. clock_gettime(CLOCK_REALTIME, &t);
  153. printf("%10d.%03d, %07.4f, %06.2f\n",t.tv_sec, t.tv_nsec / 1000000, internal, thermocouple);
  154. }
  155. printf("Exited main loop.\n");
  156. return EXIT_SUCCESS;
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement