oregon2.c 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /* Oregon remote termometers. Usually 443.92 Mhz OOK.
  2. *
  3. * The protocol is described here:
  4. * https://wmrx00.sourceforge.net/Arduino/OregonScientific-RF-Protocols.pdf
  5. * This implementation is not very complete. */
  6. #include "../app.h"
  7. static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
  8. if (numbits < 32) return false;
  9. const char *sync_pattern = "01100110" "01100110" "10010110" "10010110";
  10. uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
  11. if (off == BITMAP_SEEK_NOT_FOUND) return false;
  12. FURI_LOG_E(TAG, "Oregon2 preamble+sync found");
  13. info->start_off = off;
  14. off += 32; /* Skip preamble. */
  15. uint8_t buffer[8], raw[8] = {0};
  16. uint32_t decoded =
  17. convert_from_line_code(buffer,sizeof(buffer),bits,numbytes,off,"1001","0110");
  18. FURI_LOG_E(TAG, "Oregon2 decoded bits: %lu", decoded);
  19. if (decoded < 11*4) return false; /* Minimum len to extract some data. */
  20. info->pulses_count = (off+11*4*4) - info->start_off;
  21. char temp[3] = {0}, deviceid[2] = {0}, hum[2] = {0};
  22. for (int j = 0; j < 64; j += 4) {
  23. uint8_t nib[1];
  24. nib[0] = (bitmap_get(buffer,8,j+0) |
  25. bitmap_get(buffer,8,j+1) << 1 |
  26. bitmap_get(buffer,8,j+2) << 2 |
  27. bitmap_get(buffer,8,j+3) << 3);
  28. if (DEBUG_MSG) FURI_LOG_E(TAG, "Not inverted nibble[%d]: %x", j/4, (unsigned int)nib[0]);
  29. raw[j/8] |= nib[0] << (4-(j%4));
  30. switch(j/4) {
  31. case 1: deviceid[0] |= nib[0]; break;
  32. case 0: deviceid[0] |= nib[0] << 4; break;
  33. case 3: deviceid[1] |= nib[0]; break;
  34. case 2: deviceid[1] |= nib[0] << 4; break;
  35. case 10: temp[0] = nib[0]; break;
  36. /* Fixme: take the temperature sign from nibble 11. */
  37. case 9: temp[1] = nib[0]; break;
  38. case 8: temp[2] = nib[0]; break;
  39. case 13: hum[0] = nib[0]; break;
  40. case 12: hum[1] = nib[0]; break;
  41. }
  42. }
  43. snprintf(info->name,sizeof(info->name),"%s","Oregon v2.1");
  44. /* The following line crashes the Flipper because of broken
  45. * snprintf() implementation. */
  46. snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X",
  47. raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
  48. raw[6],raw[7]);
  49. snprintf(info->info1,sizeof(info->info1),"Sensor ID %02X%02X",
  50. deviceid[0], deviceid[1]);
  51. snprintf(info->info2,sizeof(info->info2),"Temperature %d%d.%d",
  52. temp[0],temp[1],temp[2]);
  53. snprintf(info->info3,sizeof(info->info3),"Humidity %d%d",
  54. hum[0],hum[1]);
  55. return true;
  56. }
  57. ProtoViewDecoder Oregon2Decoder = {
  58. "Oregon2", decode
  59. };