MAX31855.c 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. Unitemp - Universal temperature reader
  3. Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "MAX31855.h"
  16. const SensorType MAX31855 = {
  17. .typename = "MAX31855",
  18. .altname = "MAX31855 (Thermocouple)",
  19. .interface = &SPI,
  20. .datatype = UT_TEMPERATURE,
  21. .pollingInterval = 1000,
  22. .allocator = unitemp_MAX31855_alloc,
  23. .mem_releaser = unitemp_MAX31855_free,
  24. .initializer = unitemp_MAX31855_init,
  25. .deinitializer = unitemp_MAX31855_deinit,
  26. .updater = unitemp_MAX31855_update};
  27. bool unitemp_MAX31855_alloc(Sensor* sensor, char* args) {
  28. UNUSED(sensor);
  29. UNUSED(args);
  30. return true;
  31. }
  32. bool unitemp_MAX31855_free(Sensor* sensor) {
  33. UNUSED(sensor);
  34. return true;
  35. }
  36. bool unitemp_MAX31855_init(Sensor* sensor) {
  37. SPISensor* instance = sensor->instance;
  38. furi_hal_spi_bus_handle_init(instance->spi);
  39. UNUSED(instance);
  40. return true;
  41. }
  42. bool unitemp_MAX31855_deinit(Sensor* sensor) {
  43. UNUSED(sensor);
  44. return true;
  45. }
  46. UnitempStatus unitemp_MAX31855_update(Sensor* sensor) {
  47. SPISensor* instance = sensor->instance;
  48. furi_hal_spi_acquire(instance->spi);
  49. furi_hal_gpio_write(instance->CS_pin->pin, false);
  50. uint8_t buff[4] = {0};
  51. furi_hal_spi_bus_rx(instance->spi, buff, 4, 0xFF);
  52. furi_hal_spi_release(instance->spi);
  53. uint32_t raw = (buff[0] << 24) | (buff[1] << 16) | (buff[2] << 8) | buff[3];
  54. //Определение состояния термопары
  55. uint8_t state = raw & 0b111;
  56. //Обрыв
  57. if(state == 0x01) {
  58. UNITEMP_DEBUG("%s has thermocouple open circuit", sensor->name);
  59. return UT_SENSORSTATUS_ERROR;
  60. }
  61. //Короткое замыкание к земле
  62. if(state == 0x02) {
  63. UNITEMP_DEBUG("%s has thermocouple short to GND", sensor->name);
  64. return UT_SENSORSTATUS_ERROR;
  65. }
  66. //Короткое замыкание к питанию
  67. if(state == 0x04) {
  68. UNITEMP_DEBUG("%s has thermocouple short to VCC", sensor->name);
  69. return UT_SENSORSTATUS_ERROR;
  70. }
  71. raw = (raw >> 16) & 0xFFFC;
  72. sensor->temp = (int16_t)(raw) / 16.0f;
  73. return UT_SENSORSTATUS_OK;
  74. }