readTemps.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "freertos/FreeRTOS.h"
  2. #include "freertos/task.h"
  3. #include "driver/gpio.h"
  4. #include "esp32/rom/ets_sys.h"
  5. #include "esp_log.h"
  6. #include "config.h"
  7. #include "readTemps.h"
  8. #include "mqtt.h"
  9. #include "owb.h"
  10. #include "owb_rmt.h"
  11. #include "ds18b20.h"
  12. #ifdef ENABLE_DS18B20
  13. #define GPIO_DS18B20_0 (ONE_WIRE_BUS_IO)
  14. #define MAX_DEVICES (8)
  15. #define DS18B20_RESOLUTION (DS18B20_RESOLUTION_12_BIT)
  16. #define SAMPLE_PERIOD (1000) // milliseconds
  17. // 0x28,0x41,0x2e,0x7b,0x0d,0x00,0x00,0x2a
  18. void readTemps() {
  19. // Create a 1-Wire bus, using the RMT timeslot driver
  20. OneWireBus * owb;
  21. owb_rmt_driver_info rmt_driver_info;
  22. owb = owb_rmt_initialize(&rmt_driver_info, GPIO_DS18B20_0, RMT_CHANNEL_1, RMT_CHANNEL_0);
  23. owb_use_crc(owb, true); // enable CRC check for ROM code
  24. // Find all connected devices
  25. printf("Find devices:\n");
  26. OneWireBus_ROMCode device_rom_codes[MAX_DEVICES] = {0};
  27. int num_devices = 0;
  28. OneWireBus_SearchState search_state = {0};
  29. bool found = false;
  30. owb_search_first(owb, &search_state, &found);
  31. while (found)
  32. {
  33. char rom_code_s[17];
  34. owb_string_from_rom_code(search_state.rom_code, rom_code_s, sizeof(rom_code_s));
  35. printf(" %d : %s\n", num_devices, rom_code_s);
  36. device_rom_codes[num_devices] = search_state.rom_code;
  37. ++num_devices;
  38. owb_search_next(owb, &search_state, &found);
  39. }
  40. printf("Found %d device%s\n", num_devices, num_devices == 1 ? "" : "s");
  41. if (num_devices == 1)
  42. {
  43. // For a single device only:
  44. OneWireBus_ROMCode rom_code;
  45. owb_status status = owb_read_rom(owb, &rom_code);
  46. if (status == OWB_STATUS_OK)
  47. {
  48. char rom_code_s[OWB_ROM_CODE_STRING_LENGTH];
  49. owb_string_from_rom_code(rom_code, rom_code_s, sizeof(rom_code_s));
  50. printf("Single device %s present\n", rom_code_s);
  51. }
  52. else
  53. {
  54. printf("An error occurred reading ROM code: %d", status);
  55. }
  56. }
  57. else
  58. {
  59. // Search for a known ROM code (LSB first):
  60. // For example: 0x1502162ca5b2ee28
  61. OneWireBus_ROMCode known_device = {
  62. .fields.family = { 0x28 },
  63. .fields.serial_number = { 0xee, 0xb2, 0xa5, 0x2c, 0x16, 0x02 },
  64. .fields.crc = { 0x15 },
  65. };
  66. char rom_code_s[OWB_ROM_CODE_STRING_LENGTH];
  67. owb_string_from_rom_code(known_device, rom_code_s, sizeof(rom_code_s));
  68. bool is_present = false;
  69. owb_status search_status = owb_verify_rom(owb, known_device, &is_present);
  70. if (search_status == OWB_STATUS_OK)
  71. {
  72. printf("Device %s is %s\n", rom_code_s, is_present ? "present" : "not present");
  73. }
  74. else
  75. {
  76. printf("An error occurred searching for known device: %d", search_status);
  77. }
  78. }
  79. // Create DS18B20 devices on the 1-Wire bus
  80. DS18B20_Info * devices[MAX_DEVICES] = {0};
  81. for (int i = 0; i < num_devices; ++i)
  82. {
  83. DS18B20_Info * ds18b20_info = ds18b20_malloc(); // heap allocation
  84. devices[i] = ds18b20_info;
  85. if (num_devices == 1)
  86. {
  87. printf("Single device optimisations enabled\n");
  88. ds18b20_init_solo(ds18b20_info, owb); // only one device on bus
  89. }
  90. else
  91. {
  92. ds18b20_init(ds18b20_info, owb, device_rom_codes[i]); // associate with bus and device
  93. }
  94. ds18b20_use_crc(ds18b20_info, true); // enable CRC check on all reads
  95. ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION);
  96. }
  97. // Read temperatures more efficiently by starting conversions on all devices at the same time
  98. int errors_count[MAX_DEVICES] = {0};
  99. int sample_count = 0;
  100. if (num_devices > 0)
  101. {
  102. TickType_t last_wake_time = xTaskGetTickCount();
  103. while (1)
  104. {
  105. ds18b20_convert_all(owb);
  106. // In this application all devices use the same resolution,
  107. // so use the first device to determine the delay
  108. ds18b20_wait_for_conversion(devices[0]);
  109. // Read the results immediately after conversion otherwise it may fail
  110. // (using printf before reading may take too long)
  111. float readings[MAX_DEVICES] = { 0 };
  112. DS18B20_ERROR errors[MAX_DEVICES] = { 0 };
  113. for (int i = 0; i < num_devices; ++i)
  114. {
  115. errors[i] = ds18b20_read_temp(devices[i], &readings[i]);
  116. }
  117. // Print results in a separate loop, after all have been read
  118. printf("\nTemperature readings (degrees C): sample %d\n", ++sample_count);
  119. for (int i = 0; i < num_devices; ++i)
  120. {
  121. if (errors[i] != DS18B20_OK)
  122. {
  123. ++errors_count[i];
  124. }
  125. printf(" %d: %.1f %d errors\n", i, readings[i], errors_count[i]);
  126. }
  127. vTaskDelayUntil(&last_wake_time, SAMPLE_PERIOD / portTICK_PERIOD_MS);
  128. }
  129. }
  130. else
  131. {
  132. printf("\nNo DS18B20 devices detected!\n");
  133. }
  134. // clean up dynamically allocated data
  135. for (int i = 0; i < num_devices; ++i)
  136. {
  137. ds18b20_free(&devices[i]);
  138. }
  139. owb_uninitialize(owb);
  140. printf("Restarting now.\n");
  141. fflush(stdout);
  142. vTaskDelay(10000 / portTICK_PERIOD_MS);
  143. esp_restart();
  144. }
  145. #endif