mirror of
https://github.com/Theaninova/Arduino-IRremote.git
synced 2025-12-11 00:46:14 +00:00
Add Lego Power Functions send protocol
This commit is contained in:
@@ -19,6 +19,7 @@ env:
|
||||
- PLATFORMIO_CI_SRC=examples/IRtest PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6"
|
||||
- PLATFORMIO_CI_SRC=examples/IRtest2 PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6"
|
||||
- PLATFORMIO_CI_SRC=examples/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC"
|
||||
- PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF"
|
||||
- PLATFORMIO_CI_SRC=examples/IRremoteInfo
|
||||
|
||||
install:
|
||||
|
||||
14
IRremote.h
14
IRremote.h
@@ -56,7 +56,7 @@
|
||||
#define SEND_AIWA_RC_T501 1
|
||||
|
||||
#define DECODE_LG 1
|
||||
#define SEND_LG 1
|
||||
#define SEND_LG 1
|
||||
|
||||
#define DECODE_SANYO 1
|
||||
#define SEND_SANYO 0 // NOT WRITTEN
|
||||
@@ -76,6 +76,9 @@
|
||||
#define DECODE_PRONTO 0 // This function doe not logically make sense
|
||||
#define SEND_PRONTO 1
|
||||
|
||||
#define DECODE_LEGO_PF 0 // NOT WRITTEN
|
||||
#define SEND_LEGO_PF 1
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// When sending a Pronto code we request to send either the "once" code
|
||||
// or the "repeat" code
|
||||
@@ -115,6 +118,7 @@ typedef
|
||||
SHARP,
|
||||
DENON,
|
||||
PRONTO,
|
||||
LEGO_PF,
|
||||
}
|
||||
decode_type_t;
|
||||
|
||||
@@ -243,6 +247,10 @@ class IRrecv
|
||||
# if DECODE_DENON
|
||||
bool decodeDenon (decode_results *results) ;
|
||||
# endif
|
||||
//......................................................................
|
||||
# if DECODE_LEGO_PF
|
||||
bool decodeLegoPowerFunctions (decode_results *results) ;
|
||||
# endif
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -327,6 +335,10 @@ class IRsend
|
||||
# if SEND_PRONTO
|
||||
void sendPronto (char* code, bool repeat, bool fallback) ;
|
||||
# endif
|
||||
//......................................................................
|
||||
# if SEND_LEGO_PF
|
||||
void sendLegoPowerFunctions (uint16_t data, bool repeat = true) ;
|
||||
# endif
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* LegoPowerFunctionsSendDemo: LEGO Power Functions
|
||||
* Copyright (c) 2016 Philipp Henkel
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
#include <IRremoteInt.h>
|
||||
|
||||
IRsend irsend;
|
||||
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Send repeated command "channel 1, blue forward, red backward"
|
||||
irsend.sendLegoPowerFunctions(0x197);
|
||||
delay(2000);
|
||||
|
||||
// Send single command "channel 1, blue forward, red backward"
|
||||
irsend.sendLegoPowerFunctions(0x197, false);
|
||||
delay(2000);
|
||||
}
|
||||
@@ -80,6 +80,11 @@ int IRrecv::decode (decode_results *results)
|
||||
if (decodeDenon(results)) return true ;
|
||||
#endif
|
||||
|
||||
#if DECODE_LEGO_PF
|
||||
DBG_PRINTLN("Attempting Lego Power Functions");
|
||||
if (decodeLegoPowerFunctions(results)) return true ;
|
||||
#endif
|
||||
|
||||
// decodeHash returns a hash on any input.
|
||||
// Thus, it needs to be last in the list.
|
||||
// If you add any decodes, add them before this.
|
||||
@@ -145,8 +150,8 @@ void IRrecv::blink13 (int blinkflag)
|
||||
|
||||
//+=============================================================================
|
||||
// Return if receiving new IR signals
|
||||
//
|
||||
bool IRrecv::isIdle ( )
|
||||
//
|
||||
bool IRrecv::isIdle ( )
|
||||
{
|
||||
return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false;
|
||||
}
|
||||
|
||||
130
ir_Lego_PF.cpp
Normal file
130
ir_Lego_PF.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
#include "IRremote.h"
|
||||
#include "IRremoteInt.h"
|
||||
|
||||
//==============================================================================
|
||||
// L EEEEEE EEEE OOOO
|
||||
// L E E O O
|
||||
// L EEEE E EEE O O
|
||||
// L E E E O O LEGO Power Functions
|
||||
// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016 Philipp Henkel
|
||||
//==============================================================================
|
||||
|
||||
//+=============================================================================
|
||||
//
|
||||
#if SEND_LEGO_PF
|
||||
|
||||
class BitStreamEncoder {
|
||||
private:
|
||||
uint16_t data;
|
||||
bool repeatMessage;
|
||||
int messageBitIdx;
|
||||
int repeatCount;
|
||||
int messageLength;
|
||||
|
||||
// HIGH data bit = IR mark + high pause
|
||||
// LOW data bit = IR mark + low pause
|
||||
static const int LOW_BIT_DURATION = 421;
|
||||
static const int HIGH_BIT_DURATION = 711;
|
||||
static const int START_BIT_DURATION = 1184;
|
||||
static const int STOP_BIT_DURATION = 1184;
|
||||
static const int IR_MARK_DURATION = 158;
|
||||
static const int HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION;
|
||||
static const int LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION;
|
||||
static const int START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION;
|
||||
static const int STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION;
|
||||
static const int MESSAGE_BITS = 18;
|
||||
static const int MAX_MESSAGE_LENGTH = 16000;
|
||||
|
||||
public:
|
||||
void reset(uint16_t data, bool repeatMessage) {
|
||||
this->data = data;
|
||||
this->repeatMessage = repeatMessage;
|
||||
messageBitIdx = 0;
|
||||
repeatCount = 0;
|
||||
messageLength = getMessageLength();
|
||||
}
|
||||
|
||||
int getChannelId() const { return 1 + ((data >> 12) & 0x3); }
|
||||
|
||||
int getMessageLength() const {
|
||||
// Sum up all marks
|
||||
int length = MESSAGE_BITS * IR_MARK_DURATION;
|
||||
|
||||
// Sum up all pauses
|
||||
length += START_PAUSE_DURATION;
|
||||
for (unsigned long mask = 1UL << 15; mask; mask >>= 1) {
|
||||
if (data & mask) {
|
||||
length += HIGH_PAUSE_DURATION;
|
||||
} else {
|
||||
length += LOW_PAUSE_DURATION;
|
||||
}
|
||||
}
|
||||
length += STOP_PAUSE_DURATION;
|
||||
return length;
|
||||
}
|
||||
|
||||
boolean next() {
|
||||
messageBitIdx++;
|
||||
if (messageBitIdx >= MESSAGE_BITS) {
|
||||
repeatCount++;
|
||||
messageBitIdx = 0;
|
||||
}
|
||||
if (repeatCount >= 1 && !repeatMessage) {
|
||||
return false;
|
||||
} else if (repeatCount >= 5) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int getMarkDuration() const { return IR_MARK_DURATION; }
|
||||
|
||||
int getPauseDuration() const {
|
||||
if (messageBitIdx == 0)
|
||||
return START_PAUSE_DURATION;
|
||||
else if (messageBitIdx < MESSAGE_BITS - 1) {
|
||||
return getDataBitPause();
|
||||
} else {
|
||||
return getStopPause();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int getDataBitPause() const {
|
||||
const int pos = MESSAGE_BITS - 2 - messageBitIdx;
|
||||
const bool isHigh = data & (1 << pos);
|
||||
return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION;
|
||||
}
|
||||
|
||||
int getStopPause() const {
|
||||
if (repeatMessage) {
|
||||
return getRepeatStopPause();
|
||||
} else {
|
||||
return STOP_PAUSE_DURATION;
|
||||
}
|
||||
}
|
||||
|
||||
int getRepeatStopPause() const {
|
||||
if (repeatCount == 0 || repeatCount == 1) {
|
||||
return STOP_PAUSE_DURATION + 5 * MAX_MESSAGE_LENGTH - messageLength;
|
||||
} else if (repeatCount == 2 || repeatCount == 3) {
|
||||
return STOP_PAUSE_DURATION
|
||||
+ (6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength;
|
||||
} else {
|
||||
return STOP_PAUSE_DURATION;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void IRsend::sendLegoPowerFunctions(uint16_t data, bool repeat)
|
||||
{
|
||||
enableIROut(38);
|
||||
static BitStreamEncoder bitStreamEncoder;
|
||||
bitStreamEncoder.reset(data, repeat);
|
||||
do {
|
||||
mark(bitStreamEncoder.getMarkDuration());
|
||||
space(bitStreamEncoder.getPauseDuration());
|
||||
} while (bitStreamEncoder.next());
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user