1-Wire tester, shows ROM code and temperature on an LCD screen

main.c 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include <avr/io.h> // register definitions
  2. #include <avr/pgmspace.h> // storing data in program memory
  3. #include <avr/interrupt.h> // interrupt vectors
  4. #include <util/delay.h> // delay functions
  5. #include <stdint.h> // C header for int types like uint8_t
  6. #include <stdbool.h> // C header for the bool type
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. // Include stuff from the library
  10. #include "lib/iopins.h"
  11. #include "lib/usart.h"
  12. #include "lcd.h"
  13. #include "onewire.h"
  14. // Pins
  15. #define LED 13
  16. #define OW_PIN D9
  17. void _lcd_wait_bf();
  18. void _lcd_write_byte(uint8_t bb);
  19. #if 0
  20. // UART receive handler
  21. ISR(USART_RX_vect)
  22. {
  23. // "ECHO" function:
  24. uint8_t b = usart_rx();
  25. usart_tx(b); // send back
  26. }
  27. #endif
  28. void main()
  29. {
  30. #if 0
  31. usart_init(BAUD_115200);
  32. usart_isr_rx_enable(true); // enable RX interrupt handler
  33. #endif
  34. // configure pins
  35. as_output(LED);
  36. lcd_init();
  37. lcd_clear();
  38. lcd_puts("");
  39. // globally enable interrupts (for the USART_RX handler)
  40. sei();
  41. uint8_t addr[8];
  42. char charbuf[21];
  43. int dots = 0;
  44. bool signal = false, last_signal;
  45. while (1) {
  46. last_signal = signal;
  47. signal = ow_reset(OW_PIN);
  48. if (signal) {
  49. ow_write(OW_PIN, 0x33);
  50. ow_read_arr(OW_PIN, addr, 8);
  51. // check if valid
  52. if (addr[0] == 0x00 || (crc8(addr, 7) != addr[7])) {
  53. signal = false;
  54. }
  55. }
  56. if (!signal) {
  57. if (last_signal) {
  58. lcd_clear();
  59. }
  60. lcd_puts_xy(0,0,"No 1-Wire detected..");
  61. dots = 0;
  62. } else {
  63. if (!last_signal) {
  64. lcd_clear();
  65. }
  66. // Show chip type
  67. switch (addr[0]) {
  68. case 0x10:
  69. sprintf(charbuf, "18S20 ");
  70. break;
  71. case 0x28:
  72. sprintf(charbuf, "18B20 ");
  73. break;
  74. case 0x01:
  75. sprintf(charbuf, "iButton");
  76. break;
  77. default:
  78. sprintf(charbuf, "UNKNOWN");
  79. break;
  80. }
  81. lcd_puts_xy(12, 0, charbuf);
  82. // Show address
  83. char *p = charbuf;
  84. for(uint8_t i = 0; i < 4; i++) {
  85. p += sprintf(p, "%02X", addr[i]);
  86. if (i < 3) *p++ = ':';
  87. }
  88. lcd_puts_xy(0, 0, charbuf);
  89. p = charbuf;
  90. for(uint8_t i = 0; i < 4; i++) {
  91. p += sprintf(p, "%02X", addr[4+i]);
  92. if (i < 3) *p++ = ':';
  93. }
  94. lcd_puts_xy(0, 1, charbuf);
  95. // Measure temperature
  96. int16_t cels;
  97. if (addr[0] == 0x10 || addr[0] == 0x28) {
  98. ds18x20_single_measure(OW_PIN);
  99. if (addr[0] == 0x10) {
  100. // 18S20
  101. cels = ds18s20_read_temp_c(OW_PIN);
  102. } else {
  103. // 18B20
  104. cels = ds18b20_read_temp_c(OW_PIN);
  105. }
  106. if (cels == TEMP_ERROR || cels == 850) {
  107. lcd_xy(12, 1);
  108. for (uint8_t i = 0; i <= dots; i++) {
  109. lcd_putc('.');
  110. }
  111. dots = (dots + 1) % 3;
  112. }
  113. else {
  114. p = charbuf;
  115. if (cels < 0) {
  116. *p++ = '-';
  117. cels = -cels;
  118. }
  119. p += sprintf(p, "%d", cels / 10);
  120. *p++ = '.';
  121. p += sprintf(p, "%d", cels % 10);
  122. *p++ = 0xDF; // ring symbol
  123. *p++ = 'C';
  124. *p++ = ' '; // padding to prevent artifacts if the number shrinks (we're not clearing screen when 1w is connected)
  125. *p++ = ' ';
  126. *p++ = ' ';
  127. *p = 0;
  128. lcd_puts_xy(12, 1, charbuf);
  129. }
  130. }
  131. }
  132. pin_toggle(13); // blink the LED
  133. _delay_ms(100);
  134. }
  135. }