oregon2.c 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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" "01100110" "10010110" "10010110";
  13. uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
  14. if (off == BITMAP_SEEK_NOT_FOUND) return false;
  15. FURI_LOG_E(TAG, "Oregon2 preamble+sync found");
  16. info->start_off = off;
  17. off += 32; /* Skip preamble. */
  18. uint8_t buffer[8], raw[8] = {0};
  19. uint32_t decoded =
  20. convert_from_line_code(buffer,sizeof(buffer),bits,numbytes,off,"1001","0110");
  21. FURI_LOG_E(TAG, "Oregon2 decoded bits: %lu", decoded);
  22. if (decoded < 11*4) return false; /* Minimum len to extract some data. */
  23. info->pulses_count = (off+11*4*4) - info->start_off;
  24. char temp[3] = {0}, hum[2] = {0};
  25. uint8_t deviceid[2];
  26. for (int j = 0; j < 64; j += 4) {
  27. uint8_t nib[1];
  28. nib[0] = (bitmap_get(buffer,8,j+0) |
  29. bitmap_get(buffer,8,j+1) << 1 |
  30. bitmap_get(buffer,8,j+2) << 2 |
  31. bitmap_get(buffer,8,j+3) << 3);
  32. if (DEBUG_MSG) FURI_LOG_E(TAG, "Not inverted nibble[%d]: %x", j/4, (unsigned int)nib[0]);
  33. raw[j/8] |= nib[0] << (4-(j%4));
  34. switch(j/4) {
  35. case 1: deviceid[0] |= nib[0]; break;
  36. case 0: deviceid[0] |= nib[0] << 4; break;
  37. case 3: deviceid[1] |= nib[0]; break;
  38. case 2: deviceid[1] |= nib[0] << 4; break;
  39. case 10: temp[0] = nib[0]; break;
  40. /* Fixme: take the temperature sign from nibble 11. */
  41. case 9: temp[1] = nib[0]; break;
  42. case 8: temp[2] = nib[0]; break;
  43. case 13: hum[0] = nib[0]; break;
  44. case 12: hum[1] = nib[0]; break;
  45. }
  46. }
  47. float tempval = ((temp[0]-'0')*10) +
  48. (temp[1]-'0') +
  49. ((float)(temp[2]-'0')*0.1);
  50. int humval = (hum[0]-'0')*10 + (hum[1]-'0');
  51. fieldset_add_bytes(info->fieldset,"Sensor ID",deviceid,4);
  52. fieldset_add_float(info->fieldset,"Temperature",tempval,1);
  53. fieldset_add_uint(info->fieldset,"Humidity",humval,7);
  54. return true;
  55. }
  56. ProtoViewDecoder Oregon2Decoder = {
  57. .name = "Oregon2",
  58. .decode = decode,
  59. .get_fields = NULL,
  60. .build_message = NULL
  61. };