Merge pull request #309 from henkel/lego_power_functions

Add Lego Power Functions send protocol
This commit is contained in:
Rafi Khan
2016-05-20 19:58:58 -06:00
7 changed files with 184 additions and 9 deletions

View File

@@ -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:

View File

@@ -1,5 +1,5 @@
## Contributors
These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions.
These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions.
- [z3t0](https://github.com/z3t0) : Active Contributor and currently also the main contributor.
* Email: zetoslab@gmail.com
@@ -15,7 +15,6 @@ These are the active contributors of this project that you may contact if there
- [Sebazzz](https://github.com/sebazz): Contributor
- [lumbric](https://github.com/lumbric): Contributor
- [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor
- [henkel](https://github.com/henkel): Contributor
Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed.

View File

@@ -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

View File

@@ -1,3 +1,6 @@
## 2.1.1 - 2016/05/04
- Added Lego Power Functions Protocol [PR #309](https://github.com/z3t0/Arduino-IRremote/pull/309)
## 2.1.0 - 2016/02/20
- Improved Debugging [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258)
- Display TIME instead of TICKS [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258)
@@ -15,7 +18,7 @@
## 2.0.1 - 2015/07/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA)
### Changes
- Updated README
- Updated Contributors
- Updated Contributors
- Fixed #110 Mess
- Created Gitter Room
- Added Gitter Badge
@@ -35,7 +38,7 @@
- Added Denon Protocol
- Added Pronto Support
- Added Library Properties
- Added Template For New Protocols
- Added Template For New Protocols
- Added this changelog
- Added Teensy LC Support
- Added ATtiny84 Support
@@ -44,7 +47,7 @@
### Deletions
- Removed (Fixed) #110
- Broke Teensy 3 / 3.1 Support
- Broke Teensy 3 / 3.1 Support
### Not Working
- Teensy 3 / 3.1 Support is in Development

View File

@@ -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);
}

View File

@@ -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;
}

133
ir_Lego_PF.cpp Normal file
View File

@@ -0,0 +1,133 @@
#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
//==============================================================================
// Supported Devices
// LEGO® Power Functions IR Receiver 8884
//+=============================================================================
//
#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