Skip to content

Commit

Permalink
Experimental basic support for Tornado/Sanyo 88 bit A/C protocol
Browse files Browse the repository at this point in the history
* Basic support added via `sendSanyoAc88()` & `decodeSanyoAc88()`
* Unit test coverage for the additions/changes.
Note: Bit ordering has NOT been determined. Data values may change in future.

For #1503
  • Loading branch information
crankyoldgit committed Aug 1, 2021
1 parent b6368bd commit d04aa35
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/IRrecv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,10 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
DPRINTLN("Attempting Kelon decode");
if (decodeKelon(results, offset)) return true;
#endif // DECODE_KELON
#if DECODE_SANYO_AC88
DPRINTLN("Attempting SanyoAc88 decode");
if (decodeSanyoAc88(results, offset)) return true;
#endif // DECODE_SANYO_AC88
// Typically new protocols are added above this line.
}
#if DECODE_HASH
Expand Down
6 changes: 6 additions & 0 deletions src/IRrecv.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,12 @@ class IRrecv {
const uint16_t nbits = kSanyoAcBits,
const bool strict = true);
#endif // DECODE_SANYO_AC
#if DECODE_SANYO_AC88
bool decodeSanyoAc88(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSanyoAc88Bits,
const bool strict = true);
#endif // DECODE_SANYO_AC88
#if DECODE_MITSUBISHI
bool decodeMitsubishi(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiBits,
Expand Down
15 changes: 13 additions & 2 deletions src/IRremoteESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,13 @@
#define SEND_SANYO_AC _IR_ENABLE_DEFAULT_
#endif // SEND_SANYO_AC

#ifndef DECODE_SANYO_AC88
#define DECODE_SANYO_AC88 _IR_ENABLE_DEFAULT_
#endif // DECODE_SANYO_AC88
#ifndef SEND_SANYO_AC88
#define SEND_SANYO_AC88 _IR_ENABLE_DEFAULT_
#endif // SEND_SANYO_AC88

#ifndef DECODE_MITSUBISHI
#define DECODE_MITSUBISHI _IR_ENABLE_DEFAULT_
#endif // DECODE_MITSUBISHI
Expand Down Expand Up @@ -782,7 +789,7 @@
DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3 || \
DECODE_HITACHI_AC344 || DECODE_CORONA_AC || DECODE_SANYO_AC || \
DECODE_VOLTAS || DECODE_MIRAGE || DECODE_HAIER_AC176 || \
DECODE_TEKNOPOINT || DECODE_KELON || \
DECODE_TEKNOPOINT || DECODE_KELON || DECODE_SANYO_AC88 || \
false)
// Add any DECODE to the above if it uses result->state (see kStateSizeMax)
// you might also want to add the protocol to hasACState function
Expand Down Expand Up @@ -926,8 +933,9 @@ enum decode_type_t {
HAIER_AC176,
TEKNOPOINT,
KELON,
SANYO_AC88,
// Add new entries before this one, and update it to point to the last entry.
kLastDecodeType = KELON,
kLastDecodeType = SANYO_AC88,
};

// Message lengths & required repeat values
Expand Down Expand Up @@ -1113,6 +1121,9 @@ const uint16_t kSamsungAcExtendedBits = kSamsungAcExtendedStateLength * 8;
const uint16_t kSamsungAcDefaultRepeat = kNoRepeat;
const uint16_t kSanyoAcStateLength = 9;
const uint16_t kSanyoAcBits = kSanyoAcStateLength * 8;
const uint16_t kSanyoAc88StateLength = 11;
const uint16_t kSanyoAc88Bits = kSanyoAc88StateLength * 8;
const uint16_t kSanyoAc88MinRepeat = 2;
const uint16_t kSanyoSA8650BBits = 12;
const uint16_t kSanyoLC7461AddressBits = 13;
const uint16_t kSanyoLC7461CommandBits = 8;
Expand Down
9 changes: 9 additions & 0 deletions src/IRsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,8 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) {
return kDishMinRepeat;
case EPSON:
return kEpsonMinRepeat;
case SANYO_AC88:
return kSanyoAc88MinRepeat;
case SONY:
return kSonyMinRepeat;
case SONY_38K:
Expand Down Expand Up @@ -739,6 +741,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
return kSamsungAcBits;
case SANYO_AC:
return kSanyoAcBits;
case SANYO_AC88:
return kSanyoAc88Bits;
case SHARP_AC:
return kSharpAcBits;
case TCL112AC:
Expand Down Expand Up @@ -1246,6 +1250,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state,
sendSanyoAc(state, nbytes);
break;
#endif // SEND_SANYO_AC
#if SEND_SANYO_AC88
case SANYO_AC88:
sendSanyoAc88(state, nbytes);
break;
#endif // SEND_SANYO_AC88
#if SEND_SHARP_AC
case SHARP_AC:
sendSharpAc(state, nbytes);
Expand Down
5 changes: 5 additions & 0 deletions src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@ class IRsend {
const uint16_t nbytes = kSanyoAcStateLength,
const uint16_t repeat = kNoRepeat);
#endif // SEND_SANYO_AC
#if SEND_SANYO_AC88
void sendSanyoAc88(const uint8_t *data,
const uint16_t nbytes = kSanyoAc88StateLength,
const uint16_t repeat = kSanyoAc88MinRepeat);
#endif // SEND_SANYO_AC88
#if SEND_DISH
// sendDISH() should typically be called with repeat=3 as DISH devices
// expect the code to be sent at least 4 times. (code + 3 repeats = 4 codes)
Expand Down
1 change: 1 addition & 0 deletions src/IRtext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,5 +288,6 @@ const PROGMEM char *kAllProtocolNamesStr =
D_STR_HAIER_AC176 "\x0"
D_STR_TEKNOPOINT "\x0"
D_STR_KELON "\x0"
D_STR_SANYO_AC88 "\x0"
///< New protocol strings should be added just above this line.
"\x0"; ///< This string requires double null termination.
1 change: 1 addition & 0 deletions src/IRutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ bool hasACState(const decode_type_t protocol) {
case PANASONIC_AC:
case SAMSUNG_AC:
case SANYO_AC:
case SANYO_AC88:
case SHARP_AC:
case TCL112AC:
case TEKNOPOINT:
Expand Down
81 changes: 80 additions & 1 deletion src/ir_Sanyo.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2009 Ken Shirriff
// Copyright 2016 marcosamarinho
// Copyright 2017-2020 David Conran
// Copyright 2017-2021 David Conran

/// @file
/// @brief Support for Sanyo protocols.
Expand All @@ -13,6 +13,7 @@
/// @see http://slydiman.narod.ru/scr/kb/sanyo.htm
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1211
/// @see https://docs.google.com/spreadsheets/d/1dYfLsnYvpjV-SgO8pdinpfuBIpSzm8Q1R5SabrLeskw/edit?usp=sharing
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1503

#include "ir_Sanyo.h"
#include <algorithm>
Expand Down Expand Up @@ -67,6 +68,15 @@ const uint16_t kSanyoAcZeroSpace = 550; ///< uSeconds
const uint32_t kSanyoAcGap = kDefaultMessageGap; ///< uSeconds (Guess only)
const uint16_t kSanyoAcFreq = 38000; ///< Hz. (Guess only)

const uint16_t kSanyoAc88HdrMark = 5400; ///< uSeconds
const uint16_t kSanyoAc88HdrSpace = 2000; ///< uSeconds
const uint16_t kSanyoAc88BitMark = 500; ///< uSeconds
const uint16_t kSanyoAc88OneSpace = 1500; ///< uSeconds
const uint16_t kSanyoAc88ZeroSpace = 750; ///< uSeconds
const uint32_t kSanyoAc88Gap = 3675; ///< uSeconds
const uint16_t kSanyoAc88Freq = 38000; ///< Hz. (Guess only)
const uint8_t kSanyoAc88ExtraTolerance = 5; /// (%) Extra tolerance to use.

#if SEND_SANYO
/// Construct a Sanyo LC7461 message.
/// @param[in] address The 13 bit value of the address(Custom) portion of the
Expand Down Expand Up @@ -656,3 +666,72 @@ String IRSanyoAc::toString(void) const {
kOffTimerStr);
return result;
}

#if SEND_SANYO_AC88
/// Send a SanyoAc88 formatted message.
/// Status: ALPHA / Completely untested.
/// @param[in] data An array of bytes containing the IR command.
/// @warning data's bit order may change. It is not yet confirmed.
/// @param[in] nbytes Nr. of bytes of data in the array.
/// @param[in] repeat Nr. of times the message is to be repeated.
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1503
void IRsend::sendSanyoAc88(const uint8_t data[], const uint16_t nbytes,
const uint16_t repeat) {
// (Header + Data + Footer) per repeat
sendGeneric(kSanyoAc88HdrMark, kSanyoAc88HdrSpace,
kSanyoAc88BitMark, kSanyoAc88OneSpace,
kSanyoAc88BitMark, kSanyoAc88ZeroSpace,
kSanyoAc88BitMark, kSanyoAc88Gap,
data, nbytes, kSanyoAc88Freq, false, repeat, kDutyDefault);
space(kDefaultMessageGap); // Make a guess at a post message gap.
}
#endif // SEND_SANYO_AC88

#if DECODE_SANYO_AC88
/// Decode the supplied SanyoAc message.
/// Status: ALPHA / Untested.
/// @param[in,out] results Ptr to the data to decode & where to store the decode
/// @warning data's bit order may change. It is not yet confirmed.
/// @param[in] offset The starting index to use when attempting to decode the
/// raw data. Typically/Defaults to kStartOffset.
/// @param[in] nbits The number of data bits to expect.
/// @param[in] strict Flag indicating if we should perform strict matching.
/// @return A boolean. True if it can decode it, false if it can't.
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1503
bool IRrecv::decodeSanyoAc88(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (strict && nbits != kSanyoAc88Bits)
return false;

uint16_t used = 0;
// Compliance
const uint16_t expected_repeats = strict ? kSanyoAc88MinRepeat : 0;

// Handle the expected nr of repeats.
for (uint16_t r = 0; r <= expected_repeats; r++) {
// Header + Data + Footer
used = matchGeneric(results->rawbuf + offset, results->state,
results->rawlen - offset, nbits,
kSanyoAc88HdrMark, kSanyoAc88HdrSpace,
kSanyoAc88BitMark, kSanyoAc88OneSpace,
kSanyoAc88BitMark, kSanyoAc88ZeroSpace,
kSanyoAc88BitMark,
// Expect an inter-message gap, or just the end of msg?
(r < expected_repeats) ? kSanyoAc88Gap
: kDefaultMessageGap,
r == expected_repeats,
_tolerance + kSanyoAc88ExtraTolerance,
kMarkExcess, false);
if (!used) return false; // No match!
offset += used;
}

// Success
results->decode_type = decode_type_t::SANYO_AC88;
results->bits = nbits;
// No need to record the state as we stored it as we decoded it.
// As we use result->state, we don't record value, address, or command as it
// is a union data type.
return true;
}
#endif // DECODE_SANYO_AC88
3 changes: 2 additions & 1 deletion src/ir_Sanyo.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2020 David Conran
// Copyright 2020-2021 David Conran

/// @file
/// @brief Support for Sanyo protocols.
Expand All @@ -11,6 +11,7 @@
/// @see http://slydiman.narod.ru/scr/kb/sanyo.htm
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1211
/// @see https://docs.google.com/spreadsheets/d/1dYfLsnYvpjV-SgO8pdinpfuBIpSzm8Q1R5SabrLeskw/edit?usp=sharing
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1503

// Supports:
// Brand: Sanyo, Model: SA 8650B - disabled
Expand Down
3 changes: 3 additions & 0 deletions src/locale/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,9 @@
#ifndef D_STR_SANYO_AC
#define D_STR_SANYO_AC "SANYO_AC"
#endif // D_STR_SANYO_AC
#ifndef D_STR_SANYO_AC88
#define D_STR_SANYO_AC88 "SANYO_AC88"
#endif // D_STR_SANYO_AC88
#ifndef D_STR_SANYO_LC7461
#define D_STR_SANYO_LC7461 "SANYO_LC7461"
#endif // D_STR_SANYO_LC7461
Expand Down
Loading

0 comments on commit d04aa35

Please sign in to comment.