mirror of
https://github.com/Theaninova/Arduino-IRremote.git
synced 2025-12-12 17:36:15 +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/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/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/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC"
|
||||||
|
- PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF"
|
||||||
- PLATFORMIO_CI_SRC=examples/IRremoteInfo
|
- PLATFORMIO_CI_SRC=examples/IRremoteInfo
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
|||||||
14
IRremote.h
14
IRremote.h
@@ -56,7 +56,7 @@
|
|||||||
#define SEND_AIWA_RC_T501 1
|
#define SEND_AIWA_RC_T501 1
|
||||||
|
|
||||||
#define DECODE_LG 1
|
#define DECODE_LG 1
|
||||||
#define SEND_LG 1
|
#define SEND_LG 1
|
||||||
|
|
||||||
#define DECODE_SANYO 1
|
#define DECODE_SANYO 1
|
||||||
#define SEND_SANYO 0 // NOT WRITTEN
|
#define SEND_SANYO 0 // NOT WRITTEN
|
||||||
@@ -76,6 +76,9 @@
|
|||||||
#define DECODE_PRONTO 0 // This function doe not logically make sense
|
#define DECODE_PRONTO 0 // This function doe not logically make sense
|
||||||
#define SEND_PRONTO 1
|
#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
|
// When sending a Pronto code we request to send either the "once" code
|
||||||
// or the "repeat" code
|
// or the "repeat" code
|
||||||
@@ -115,6 +118,7 @@ typedef
|
|||||||
SHARP,
|
SHARP,
|
||||||
DENON,
|
DENON,
|
||||||
PRONTO,
|
PRONTO,
|
||||||
|
LEGO_PF,
|
||||||
}
|
}
|
||||||
decode_type_t;
|
decode_type_t;
|
||||||
|
|
||||||
@@ -243,6 +247,10 @@ class IRrecv
|
|||||||
# if DECODE_DENON
|
# if DECODE_DENON
|
||||||
bool decodeDenon (decode_results *results) ;
|
bool decodeDenon (decode_results *results) ;
|
||||||
# endif
|
# endif
|
||||||
|
//......................................................................
|
||||||
|
# if DECODE_LEGO_PF
|
||||||
|
bool decodeLegoPowerFunctions (decode_results *results) ;
|
||||||
|
# endif
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -327,6 +335,10 @@ class IRsend
|
|||||||
# if SEND_PRONTO
|
# if SEND_PRONTO
|
||||||
void sendPronto (char* code, bool repeat, bool fallback) ;
|
void sendPronto (char* code, bool repeat, bool fallback) ;
|
||||||
# endif
|
# endif
|
||||||
|
//......................................................................
|
||||||
|
# if SEND_LEGO_PF
|
||||||
|
void sendLegoPowerFunctions (uint16_t data, bool repeat = true) ;
|
||||||
|
# endif
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
#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 ;
|
if (decodeDenon(results)) return true ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if DECODE_LEGO_PF
|
||||||
|
DBG_PRINTLN("Attempting Lego Power Functions");
|
||||||
|
if (decodeLegoPowerFunctions(results)) return true ;
|
||||||
|
#endif
|
||||||
|
|
||||||
// decodeHash returns a hash on any input.
|
// decodeHash returns a hash on any input.
|
||||||
// Thus, it needs to be last in the list.
|
// Thus, it needs to be last in the list.
|
||||||
// If you add any decodes, add them before this.
|
// If you add any decodes, add them before this.
|
||||||
@@ -145,8 +150,8 @@ void IRrecv::blink13 (int blinkflag)
|
|||||||
|
|
||||||
//+=============================================================================
|
//+=============================================================================
|
||||||
// Return if receiving new IR signals
|
// Return if receiving new IR signals
|
||||||
//
|
//
|
||||||
bool IRrecv::isIdle ( )
|
bool IRrecv::isIdle ( )
|
||||||
{
|
{
|
||||||
return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false;
|
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