ir_Electra.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2018 David Conran
  2. #include "IRrecv.h"
  3. #include "IRsend.h"
  4. #include "IRutils.h"
  5. // EEEEEEE LL EEEEEEE CCCCC TTTTTTT RRRRRR AAA
  6. // EE LL EE CC C TTT RR RR AAAAA
  7. // EEEEE LL EEEEE CC TTT RRRRRR AA AA
  8. // EE LL EE CC C TTT RR RR AAAAAAA
  9. // EEEEEEE LLLLLLL EEEEEEE CCCCC TTT RR RR AA AA
  10. // Electra A/C added by crankyoldgit
  11. //
  12. // Equipment it seems compatible with:
  13. // * <Add models (A/C & remotes) you've gotten it working with here>
  14. // Ref:
  15. // https://github.com/markszabo/IRremoteESP8266/issues/527
  16. // Constants
  17. const uint16_t kElectraAcHdrMark = 9166;
  18. const uint16_t kElectraAcBitMark = 646;
  19. const uint16_t kElectraAcHdrSpace = 4470;
  20. const uint16_t kElectraAcOneSpace = 1647;
  21. const uint16_t kElectraAcZeroSpace = 547;
  22. const uint32_t kElectraAcMessageGap = 100000; // Completely made-up guess.
  23. #if SEND_ELECTRA_AC
  24. // Send a Electra message
  25. //
  26. // Args:
  27. // data: Contents of the message to be sent. (Guessing MSBF order)
  28. // nbits: Nr. of bits of data to be sent. Typically kElectraAcBits.
  29. // repeat: Nr. of additional times the message is to be sent.
  30. //
  31. // Status: Alpha / Needs testing against a real device.
  32. //
  33. void IRsend::sendElectraAC(uint8_t data[], uint16_t nbytes, uint16_t repeat) {
  34. for (uint16_t r = 0; r <= repeat; r++)
  35. sendGeneric(kElectraAcHdrMark, kElectraAcHdrSpace, kElectraAcBitMark,
  36. kElectraAcOneSpace, kElectraAcBitMark, kElectraAcZeroSpace,
  37. kElectraAcBitMark, kElectraAcMessageGap, data, nbytes,
  38. 38000, // Complete guess of the modulation frequency.
  39. true, 0, 50);
  40. }
  41. #endif
  42. #if DECODE_ELECTRA_AC
  43. // Decode the supplied Electra A/C message.
  44. //
  45. // Args:
  46. // results: Ptr to the data to decode and where to store the decode result.
  47. // nbits: The number of data bits to expect. Typically kElectraAcBits.
  48. // strict: Flag indicating if we should perform strict matching.
  49. // Returns:
  50. // boolean: True if it can decode it, false if it can't.
  51. //
  52. // Status: Alpha / Needs testing against a real device.
  53. //
  54. bool IRrecv::decodeElectraAC(decode_results *results, uint16_t nbits,
  55. bool strict) {
  56. if (nbits % 8 != 0) // nbits has to be a multiple of nr. of bits in a byte.
  57. return false;
  58. if (strict) {
  59. if (nbits != kElectraAcBits)
  60. return false; // Not strictly a ELECTRA_AC message.
  61. }
  62. // The protocol sends the data normal + inverted, alternating on
  63. // each byte. Hence twice the number of expected data bits.
  64. if (results->rawlen < 2 * nbits + kHeader + kFooter - 1)
  65. return false; // Can't possibly be a valid ELECTRA_AC message.
  66. uint16_t offset = kStartOffset;
  67. // Message Header
  68. if (!matchMark(results->rawbuf[offset++], kElectraAcHdrMark)) return false;
  69. if (!matchSpace(results->rawbuf[offset++], kElectraAcHdrSpace)) return false;
  70. // Data Section
  71. match_result_t data_result;
  72. uint16_t dataBitsSoFar = 0;
  73. // Keep reading bytes until we either run out of section or state to fill.
  74. for (uint16_t i = 0; offset <= results->rawlen - 16 && i < nbits / 8;
  75. i++, dataBitsSoFar += 8, offset += data_result.used) {
  76. data_result = matchData(&(results->rawbuf[offset]), 8, kElectraAcBitMark,
  77. kElectraAcOneSpace, kElectraAcBitMark,
  78. kElectraAcZeroSpace, kTolerance, 0, true);
  79. if (data_result.success == false) return false; // Fail
  80. results->state[i] = data_result.data;
  81. }
  82. // Message Footer
  83. if (!matchMark(results->rawbuf[offset++], kElectraAcBitMark)) return false;
  84. if (offset <= results->rawlen &&
  85. !matchAtLeast(results->rawbuf[offset++], kElectraAcMessageGap))
  86. return false;
  87. // Compliance
  88. if (strict && dataBitsSoFar != nbits) return false;
  89. // Success
  90. results->decode_type = ELECTRA_AC;
  91. results->bits = dataBitsSoFar;
  92. // No need to record the state as we stored it as we decoded it.
  93. // As we use result->state, we don't record value, address, or command as it
  94. // is a union data type.
  95. return true;
  96. }
  97. #endif // DECODE_ELECTRA_AC