oregon2.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved
  2. * See the LICENSE file for information about the license.
  3. *
  4. * Oregon remote termometers. Usually 443.92 Mhz OOK.
  5. *
  6. * The protocol is described here:
  7. * https://wmrx00.sourceforge.net/Arduino/OregonScientific-RF-Protocols.pdf
  8. * This implementation is not very complete. */
  9. #include "../app.h"
  10. static bool decode(uint8_t* bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo* info) {
  11. if(numbits < 32) return false;
  12. const char* sync_pattern = "01100110"
  13. "01100110"
  14. "10010110"
  15. "10010110";
  16. uint64_t off = bitmap_seek_bits(bits, numbytes, 0, numbits, sync_pattern);
  17. if(off == BITMAP_SEEK_NOT_FOUND) return false;
  18. FURI_LOG_E(TAG, "Oregon2 preamble+sync found");
  19. info->start_off = off;
  20. off += 32; /* Skip preamble. */
  21. uint8_t buffer[8], raw[8] = {0};
  22. uint32_t decoded =
  23. convert_from_line_code(buffer, sizeof(buffer), bits, numbytes, off, "1001", "0110");
  24. FURI_LOG_E(TAG, "Oregon2 decoded bits: %lu", decoded);
  25. if(decoded < 11 * 4) return false; /* Minimum len to extract some data. */
  26. info->pulses_count = (off + 11 * 4 * 4) - info->start_off;
  27. char temp[3] = {0}, hum[2] = {0};
  28. uint8_t deviceid[2];
  29. for(int j = 0; j < 64; j += 4) {
  30. uint8_t nib[1];
  31. nib[0] =
  32. (bitmap_get(buffer, 8, j + 0) | bitmap_get(buffer, 8, j + 1) << 1 |
  33. bitmap_get(buffer, 8, j + 2) << 2 | bitmap_get(buffer, 8, j + 3) << 3);
  34. if(DEBUG_MSG) FURI_LOG_E(TAG, "Not inverted nibble[%d]: %x", j / 4, (unsigned int)nib[0]);
  35. raw[j / 8] |= nib[0] << (4 - (j % 4));
  36. switch(j / 4) {
  37. case 1:
  38. deviceid[0] |= nib[0];
  39. break;
  40. case 0:
  41. deviceid[0] |= nib[0] << 4;
  42. break;
  43. case 3:
  44. deviceid[1] |= nib[0];
  45. break;
  46. case 2:
  47. deviceid[1] |= nib[0] << 4;
  48. break;
  49. case 10:
  50. temp[0] = nib[0];
  51. break;
  52. /* Fixme: take the temperature sign from nibble 11. */
  53. case 9:
  54. temp[1] = nib[0];
  55. break;
  56. case 8:
  57. temp[2] = nib[0];
  58. break;
  59. case 13:
  60. hum[0] = nib[0];
  61. break;
  62. case 12:
  63. hum[1] = nib[0];
  64. break;
  65. }
  66. }
  67. float tempval = ((temp[0] - '0') * 10) + (temp[1] - '0') + ((float)(temp[2] - '0') * 0.1);
  68. int humval = (hum[0] - '0') * 10 + (hum[1] - '0');
  69. fieldset_add_bytes(info->fieldset, "Sensor ID", deviceid, 4);
  70. fieldset_add_float(info->fieldset, "Temperature", tempval, 1);
  71. fieldset_add_uint(info->fieldset, "Humidity", humval, 7);
  72. return true;
  73. }
  74. ProtoViewDecoder Oregon2Decoder =
  75. {.name = "Oregon2", .decode = decode, .get_fields = NULL, .build_message = NULL};