Skip to content

Commit bb0323b

Browse files
authored
Merge pull request Arduino-IRremote#336 from henkel/lego_pf_tests
Add Lego Power Functions tests
2 parents 5bd251f + b26b64f commit bb0323b

File tree

8 files changed

+337
-108
lines changed

8 files changed

+337
-108
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ env:
2020
- PLATFORMIO_CI_SRC=examples/IRtest2 PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6"
2121
- PLATFORMIO_CI_SRC=examples/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC"
2222
- PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF"
23+
- PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsTests PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF"
2324
- PLATFORMIO_CI_SRC=examples/IRremoteInfo
2425

2526
install:

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This library enables you to send and receive using infra-red signals on an Ardui
88

99
Tutorials and more information will be made available on [the official homepage](http://z3t0.github.io/Arduino-IRremote/).
1010

11-
## Version - 2.2.0
11+
## Version - 2.2.1
1212

1313
## Installation
1414
1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page.

changelog.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 2.2.1 - 2016/07/27
2+
- Added tests for Lego Power Functions Protocol [PR #336](https://github.com/z3t0/Arduino-IRremote/pull/336)
3+
14
## 2.2.0 - 2016/06/28
25
- Added support for ATmega8535
36
- Added support for ATmega16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/*
2+
* LegoPowerFunctionsTest: LEGO Power Functions Tests
3+
* Copyright (c) 2016 Philipp Henkel
4+
*/
5+
6+
#include <ir_Lego_PF_BitStreamEncoder.h>
7+
8+
void setup() {
9+
Serial.begin(9600);
10+
delay(1000); // wait for reset triggered by serial connection
11+
runBitStreamEncoderTests();
12+
}
13+
14+
void loop() {
15+
}
16+
17+
void runBitStreamEncoderTests() {
18+
Serial.println();
19+
Serial.println("BitStreamEncoder Tests");
20+
static LegoPfBitStreamEncoder bitStreamEncoder;
21+
testStartBit(bitStreamEncoder);
22+
testLowBit(bitStreamEncoder);
23+
testHighBit(bitStreamEncoder);
24+
testMessageBitCount(bitStreamEncoder);
25+
testMessageBitCountRepeat(bitStreamEncoder);
26+
testMessage407(bitStreamEncoder);
27+
testMessage407Repeated(bitStreamEncoder);
28+
testGetChannelId1(bitStreamEncoder);
29+
testGetChannelId2(bitStreamEncoder);
30+
testGetChannelId3(bitStreamEncoder);
31+
testGetChannelId4(bitStreamEncoder);
32+
testGetMessageLengthAllHigh(bitStreamEncoder);
33+
testGetMessageLengthAllLow(bitStreamEncoder);
34+
}
35+
36+
void logTestResult(bool testPassed) {
37+
if (testPassed) {
38+
Serial.println("OK");
39+
}
40+
else {
41+
Serial.println("FAIL ############");
42+
}
43+
}
44+
45+
void testStartBit(LegoPfBitStreamEncoder& bitStreamEncoder) {
46+
Serial.print(" testStartBit ");
47+
bitStreamEncoder.reset(0, false);
48+
int startMark = bitStreamEncoder.getMarkDuration();
49+
int startPause = bitStreamEncoder.getPauseDuration();
50+
logTestResult(startMark == 158 && startPause == 1184-158);
51+
}
52+
53+
void testLowBit(LegoPfBitStreamEncoder& bitStreamEncoder) {
54+
Serial.print(" testLowBit ");
55+
bitStreamEncoder.reset(0, false);
56+
bitStreamEncoder.next();
57+
int lowMark = bitStreamEncoder.getMarkDuration();
58+
int lowPause = bitStreamEncoder.getPauseDuration();
59+
logTestResult(lowMark == 158 && lowPause == 421-158);
60+
}
61+
62+
void testHighBit(LegoPfBitStreamEncoder& bitStreamEncoder) {
63+
Serial.print(" testHighBit ");
64+
bitStreamEncoder.reset(0xFFFF, false);
65+
bitStreamEncoder.next();
66+
int highMark = bitStreamEncoder.getMarkDuration();
67+
int highPause = bitStreamEncoder.getPauseDuration();
68+
logTestResult(highMark == 158 && highPause == 711-158);
69+
}
70+
71+
void testMessageBitCount(LegoPfBitStreamEncoder& bitStreamEncoder) {
72+
Serial.print(" testMessageBitCount ");
73+
bitStreamEncoder.reset(0xFFFF, false);
74+
int bitCount = 1;
75+
while (bitStreamEncoder.next()) {
76+
bitCount++;
77+
}
78+
logTestResult(bitCount == 18);
79+
}
80+
81+
boolean check(LegoPfBitStreamEncoder& bitStreamEncoder, int markDuration, int pauseDuration) {
82+
bool result = true;
83+
result = result && bitStreamEncoder.getMarkDuration() == markDuration;
84+
result = result && bitStreamEncoder.getPauseDuration() == pauseDuration;
85+
return result;
86+
}
87+
88+
boolean checkNext(LegoPfBitStreamEncoder& bitStreamEncoder, int markDuration, int pauseDuration) {
89+
bool result = bitStreamEncoder.next();
90+
result = result && check(bitStreamEncoder, markDuration, pauseDuration);
91+
return result;
92+
}
93+
94+
boolean checkDataBitsOfMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) {
95+
bool result = true;
96+
result = result && checkNext(bitStreamEncoder, 158, 263);
97+
result = result && checkNext(bitStreamEncoder, 158, 263);
98+
result = result && checkNext(bitStreamEncoder, 158, 263);
99+
result = result && checkNext(bitStreamEncoder, 158, 263);
100+
result = result && checkNext(bitStreamEncoder, 158, 263);
101+
result = result && checkNext(bitStreamEncoder, 158, 263);
102+
result = result && checkNext(bitStreamEncoder, 158, 263);
103+
result = result && checkNext(bitStreamEncoder, 158, 553);
104+
result = result && checkNext(bitStreamEncoder, 158, 553);
105+
result = result && checkNext(bitStreamEncoder, 158, 263);
106+
result = result && checkNext(bitStreamEncoder, 158, 263);
107+
result = result && checkNext(bitStreamEncoder, 158, 553);
108+
result = result && checkNext(bitStreamEncoder, 158, 263);
109+
result = result && checkNext(bitStreamEncoder, 158, 553);
110+
result = result && checkNext(bitStreamEncoder, 158, 553);
111+
result = result && checkNext(bitStreamEncoder, 158, 553);
112+
return result;
113+
}
114+
115+
void testMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) {
116+
Serial.print(" testMessage407 ");
117+
bitStreamEncoder.reset(407, false);
118+
bool result = true;
119+
result = result && check(bitStreamEncoder, 158, 1026);
120+
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
121+
result = result && checkNext(bitStreamEncoder, 158, 1026);
122+
result = result && !bitStreamEncoder.next();
123+
logTestResult(result);
124+
}
125+
126+
void testMessage407Repeated(LegoPfBitStreamEncoder& bitStreamEncoder) {
127+
Serial.print(" testMessage407Repeated ");
128+
bitStreamEncoder.reset(407, true);
129+
bool result = true;
130+
result = result && check(bitStreamEncoder, 158, 1026);
131+
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
132+
result = result && checkNext(bitStreamEncoder, 158, 1026 + 5 * 16000 - 10844);
133+
result = result && checkNext(bitStreamEncoder, 158, 1026);
134+
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
135+
result = result && checkNext(bitStreamEncoder, 158, 1026 + 5 * 16000 - 10844);
136+
result = result && checkNext(bitStreamEncoder, 158, 1026);
137+
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
138+
result = result && checkNext(bitStreamEncoder, 158, 1026 + 8 * 16000 - 10844);
139+
result = result && checkNext(bitStreamEncoder, 158, 1026);
140+
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
141+
result = result && checkNext(bitStreamEncoder, 158, 1026 + 8 * 16000 - 10844);
142+
result = result && checkNext(bitStreamEncoder, 158, 1026);
143+
result = result && checkDataBitsOfMessage407(bitStreamEncoder);
144+
result = result && checkNext(bitStreamEncoder, 158, 1026);
145+
result = result && !bitStreamEncoder.next();
146+
logTestResult(result);
147+
}
148+
149+
void testMessageBitCountRepeat(LegoPfBitStreamEncoder& bitStreamEncoder) {
150+
Serial.print(" testMessageBitCountRepeat ");
151+
bitStreamEncoder.reset(0xFFFF, true);
152+
int bitCount = 1;
153+
while (bitStreamEncoder.next()) {
154+
bitCount++;
155+
}
156+
logTestResult(bitCount == 5*18);
157+
}
158+
159+
void testGetChannelId1(LegoPfBitStreamEncoder& bitStreamEncoder) {
160+
Serial.print(" testGetChannelId1 ");
161+
bitStreamEncoder.reset(407, false);
162+
logTestResult(bitStreamEncoder.getChannelId() == 1);
163+
}
164+
165+
void testGetChannelId2(LegoPfBitStreamEncoder& bitStreamEncoder) {
166+
Serial.print(" testGetChannelId2 ");
167+
bitStreamEncoder.reset(4502, false);
168+
logTestResult(bitStreamEncoder.getChannelId() == 2);
169+
}
170+
171+
void testGetChannelId3(LegoPfBitStreamEncoder& bitStreamEncoder) {
172+
Serial.print(" testGetChannelId3 ");
173+
bitStreamEncoder.reset(8597, false);
174+
logTestResult(bitStreamEncoder.getChannelId() == 3);
175+
}
176+
177+
void testGetChannelId4(LegoPfBitStreamEncoder& bitStreamEncoder) {
178+
Serial.print(" testGetChannelId4 ");
179+
bitStreamEncoder.reset(12692, false);
180+
logTestResult(bitStreamEncoder.getChannelId() == 4);
181+
}
182+
183+
void testGetMessageLengthAllHigh(LegoPfBitStreamEncoder& bitStreamEncoder) {
184+
Serial.print(" testGetMessageLengthAllHigh ");
185+
bitStreamEncoder.reset(0xFFFF, false);
186+
logTestResult(bitStreamEncoder.getMessageLength() == 13744);
187+
}
188+
189+
void testGetMessageLengthAllLow(LegoPfBitStreamEncoder& bitStreamEncoder) {
190+
Serial.print(" testGetMessageLengthAllLow ");
191+
bitStreamEncoder.reset(0x0, false);
192+
logTestResult(bitStreamEncoder.getMessageLength() == 9104);
193+
}
194+
195+
196+
197+

ir_Lego_PF.cpp

+18-105
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "IRremote.h"
22
#include "IRremoteInt.h"
3+
#include "ir_Lego_PF_BitStreamEncoder.h"
34

45
//==============================================================================
56
// L EEEEEE EEEE OOOO
@@ -16,118 +17,30 @@
1617
//
1718
#if SEND_LEGO_PF
1819

19-
class BitStreamEncoder {
20-
private:
21-
uint16_t data;
22-
bool repeatMessage;
23-
int messageBitIdx;
24-
int repeatCount;
25-
int messageLength;
26-
27-
// HIGH data bit = IR mark + high pause
28-
// LOW data bit = IR mark + low pause
29-
static const int LOW_BIT_DURATION = 421;
30-
static const int HIGH_BIT_DURATION = 711;
31-
static const int START_BIT_DURATION = 1184;
32-
static const int STOP_BIT_DURATION = 1184;
33-
static const int IR_MARK_DURATION = 158;
34-
static const int HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION;
35-
static const int LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION;
36-
static const int START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION;
37-
static const int STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION;
38-
static const int MESSAGE_BITS = 18;
39-
static const int MAX_MESSAGE_LENGTH = 16000;
40-
41-
public:
42-
void reset(uint16_t data, bool repeatMessage) {
43-
this->data = data;
44-
this->repeatMessage = repeatMessage;
45-
messageBitIdx = 0;
46-
repeatCount = 0;
47-
messageLength = getMessageLength();
48-
}
49-
50-
int getChannelId() const { return 1 + ((data >> 12) & 0x3); }
51-
52-
int getMessageLength() const {
53-
// Sum up all marks
54-
int length = MESSAGE_BITS * IR_MARK_DURATION;
55-
56-
// Sum up all pauses
57-
length += START_PAUSE_DURATION;
58-
for (unsigned long mask = 1UL << 15; mask; mask >>= 1) {
59-
if (data & mask) {
60-
length += HIGH_PAUSE_DURATION;
61-
} else {
62-
length += LOW_PAUSE_DURATION;
63-
}
64-
}
65-
length += STOP_PAUSE_DURATION;
66-
return length;
67-
}
68-
69-
boolean next() {
70-
messageBitIdx++;
71-
if (messageBitIdx >= MESSAGE_BITS) {
72-
repeatCount++;
73-
messageBitIdx = 0;
74-
}
75-
if (repeatCount >= 1 && !repeatMessage) {
76-
return false;
77-
} else if (repeatCount >= 5) {
78-
return false;
79-
} else {
80-
return true;
81-
}
82-
}
83-
84-
int getMarkDuration() const { return IR_MARK_DURATION; }
85-
86-
int getPauseDuration() const {
87-
if (messageBitIdx == 0)
88-
return START_PAUSE_DURATION;
89-
else if (messageBitIdx < MESSAGE_BITS - 1) {
90-
return getDataBitPause();
91-
} else {
92-
return getStopPause();
93-
}
94-
}
95-
96-
private:
97-
int getDataBitPause() const {
98-
const int pos = MESSAGE_BITS - 2 - messageBitIdx;
99-
const bool isHigh = data & (1 << pos);
100-
return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION;
101-
}
102-
103-
int getStopPause() const {
104-
if (repeatMessage) {
105-
return getRepeatStopPause();
106-
} else {
107-
return STOP_PAUSE_DURATION;
108-
}
109-
}
110-
111-
int getRepeatStopPause() const {
112-
if (repeatCount == 0 || repeatCount == 1) {
113-
return STOP_PAUSE_DURATION + 5 * MAX_MESSAGE_LENGTH - messageLength;
114-
} else if (repeatCount == 2 || repeatCount == 3) {
115-
return STOP_PAUSE_DURATION
116-
+ (6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength;
117-
} else {
118-
return STOP_PAUSE_DURATION;
119-
}
120-
}
121-
};
20+
#if DEBUG
21+
namespace {
22+
void logFunctionParameters(uint16_t data, bool repeat) {
23+
DBG_PRINT("sendLegoPowerFunctions(data=");
24+
DBG_PRINT(data);
25+
DBG_PRINT(", repeat=");
26+
DBG_PRINTLN(repeat?"true)" : "false)");
27+
}
28+
} // anonymous namespace
29+
#endif // DEBUG
12230

12331
void IRsend::sendLegoPowerFunctions(uint16_t data, bool repeat)
12432
{
33+
#if DEBUG
34+
::logFunctionParameters(data, repeat);
35+
#endif // DEBUG
36+
12537
enableIROut(38);
126-
static BitStreamEncoder bitStreamEncoder;
38+
static LegoPfBitStreamEncoder bitStreamEncoder;
12739
bitStreamEncoder.reset(data, repeat);
12840
do {
12941
mark(bitStreamEncoder.getMarkDuration());
13042
space(bitStreamEncoder.getPauseDuration());
13143
} while (bitStreamEncoder.next());
13244
}
133-
#endif
45+
46+
#endif // SEND_LEGO_PF

0 commit comments

Comments
 (0)