Skip to content
This repository was archived by the owner on May 6, 2021. It is now read-only.

Commit 2a7eb3c

Browse files
committed
Modification and additions to test working of ws2812b
1 parent 4314edf commit 2a7eb3c

File tree

5 files changed

+130
-76
lines changed

5 files changed

+130
-76
lines changed

libsrc/leddevice/LedDeviceWs2812b.cpp

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11

2+
// Linux includes
3+
#include <unistd.h>
4+
25
// Local Hyperion-Leddevice includes
36
#include "LedDeviceWs2812b.h"
47

@@ -17,15 +20,19 @@ int LedDeviceWs2812b::write(const std::vector<ColorRgb> & ledValues)
1720
}
1821

1922
// Translate the channel of each color to a signal
20-
auto bufIt = _ledBuffer.begin();
21-
for (const ColorRgb& color : ledValues)
23+
for (unsigned iLed=0; iLed<ledValues.size(); ++iLed)
2224
{
23-
*bufIt++ = _byte2signalTable[color.red];
24-
*bufIt++ = _byte2signalTable[color.green];
25-
*bufIt++ = _byte2signalTable[color.blue];
25+
const ColorRgb & color = ledValues[iLed];
26+
27+
_ledBuffer[3*iLed] = _byte2signalTable[color.red];
28+
_ledBuffer[3*iLed + 1] = _byte2signalTable[color.green];
29+
_ledBuffer[3*iLed + 2] = _byte2signalTable[color.blue];
2630
}
2731

28-
return writeBytes(_ledBuffer.size()*sizeof(ByteSignal), reinterpret_cast<uint8_t *>(_ledBuffer.data()));
32+
const int result = writeBytes(_ledBuffer.size()*sizeof(ByteSignal), reinterpret_cast<uint8_t *>(_ledBuffer.data()));
33+
// Official latch time is 50us (lets give it 50us more)
34+
usleep(100);
35+
return result;
2936
}
3037

3138
int LedDeviceWs2812b::switchOff()
@@ -63,25 +70,42 @@ uint8_t LedDeviceWs2812b::bits2Signal(const bool bit1, const bool bit2) const
6370
{
6471
// See https://github.com/tvdzwan/hyperion/wiki/Ws2812b for the explanation of the given
6572
// translations
73+
74+
// Encoding scheme 1
75+
// 00 1 1000 1100 0 1 0111 0011 0 1 1100 1110 0 0xCE
76+
// 01 1 1000 1110 0 1 0111 0001 0 1 1000 1110 0 0x8E
77+
// 10 1 1100 1100 0 1 0011 0011 0 1 1100 1100 0 0xCC
78+
// 11 1 1100 1110 0 1 0011 0001 0 1 1000 1100 0 0x8C
79+
80+
// Encoding schem 2
81+
// 00 - 1 0000 1000 0 - 1 1111 0111 0 - 1 1110 1111 0 - 0xEF
82+
// 01 - 1 0000 1111 0 - 1 1111 0000 0 - 1 0000 1111 0 - 0x0F
83+
// 10 - 1 1110 1000 0 - 1 0001 0111 0 - 1 1110 1000 0 - 0xE8
84+
// 11 - 1 1110 1111 0 - 1 0001 0000 0 - 1 0000 1000 0 - 0x08
85+
6686
if (bit1)
6787
{
6888
if (bit2)
6989
{
90+
// return 0x08;
7091
return 0x8C;
7192
}
7293
else
7394
{
95+
// return 0xE8;
7496
return 0xCC;
7597
}
7698
}
7799
else
78100
{
79101
if (bit2)
80102
{
103+
// return 0x0F;
81104
return 0x8E;
82105
}
83106
else
84107
{
108+
// return 0xEF;
85109
return 0xCE;
86110
}
87111
}

libsrc/leddevice/LedRs232Device.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ int LedRs232Device::writeBytes(const unsigned size, const uint8_t * data)
5757

5858
try
5959
{
60+
_rs232Port.flushOutput();
6061
_rs232Port.write(data, size);
6162
_rs232Port.flush();
6263
}

test/DetermineWs2811Timing.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ int main()
4949
requiredTiming(400, 850, 150, 5); // Zero
5050
requiredTiming(800, 450, 150, 5); // One
5151

52+
requiredTiming(650, 600, 150, 5); // One
53+
5254
// 4bits
5355
requiredTiming(400, 850, 150, 4); // Zero
5456
requiredTiming(800, 450, 150, 4); // One

test/TestRs232HighSpeed.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ int testSerialPortLib()
6262
continue;
6363
}
6464

65+
rs232Port.flushOutput();
6566
rs232Port.write(data);
67+
rs232Port.flush();
6668

6769
data.clear();
6870
for (int i=0; i<9; ++i)

test/TestUartHighSpeed.cpp

Lines changed: 95 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,80 @@
1212
#include <csignal>
1313
#include <cstdint>
1414
#include <bitset>
15+
#include <vector>
16+
17+
#include <pthread.h>
18+
#include <sched.h>
19+
20+
void set_realtime_priority() {
21+
int ret;
22+
23+
// We'll operate on the currently running thread.
24+
pthread_t this_thread = pthread_self();
25+
// struct sched_param is used to store the scheduling priority
26+
struct sched_param params;
27+
// We'll set the priority to the maximum.
28+
params.sched_priority = sched_get_priority_max(SCHED_FIFO);
29+
std::cout << "Trying to set thread realtime prio = " << params.sched_priority << std::endl;
30+
31+
// Attempt to set thread real-time priority to the SCHED_FIFO policy
32+
ret = pthread_setschedparam(this_thread, SCHED_FIFO, &params);
33+
if (ret != 0) {
34+
// Print the error
35+
std::cout << "Unsuccessful in setting thread realtime prio (erno=" << ret << ")" << std::endl;
36+
return;
37+
}
38+
39+
// Now verify the change in thread priority
40+
int policy = 0;
41+
ret = pthread_getschedparam(this_thread, &policy, &params);
42+
if (ret != 0) {
43+
std::cout << "Couldn't retrieve real-time scheduling paramers" << std::endl;
44+
return;
45+
}
46+
47+
// Check the correct policy was applied
48+
if(policy != SCHED_FIFO) {
49+
std::cout << "Scheduling is NOT SCHED_FIFO!" << std::endl;
50+
} else {
51+
std::cout << "SCHED_FIFO OK" << std::endl;
52+
}
53+
54+
// Print thread scheduling priority
55+
std::cout << "Thread priority is " << params.sched_priority << std::endl;
56+
}
57+
1558

16-
#include <QElapsedTimer>
59+
struct ColorSignal
60+
{
61+
uint8_t green_1;
62+
uint8_t green_2;
63+
uint8_t green_3;
64+
uint8_t green_4;
65+
66+
uint8_t red_1;
67+
uint8_t red_2;
68+
uint8_t red_3;
69+
uint8_t red_4;
70+
71+
uint8_t blue_1;
72+
uint8_t blue_2;
73+
uint8_t blue_3;
74+
uint8_t blue_4;
75+
};
76+
77+
static ColorSignal RED_Signal = { 0xCE, 0xCE, 0xCE, 0xCE,
78+
0xCE, 0x8C, 0x8C, 0x8C,
79+
0xCE, 0xCE, 0xCE, 0xCE };
80+
static ColorSignal GREEN_Signal = { 0xCE, 0x8C, 0x8C, 0x8C,
81+
0xCE, 0xCE, 0xCE, 0xCE,
82+
0xCE, 0xCE, 0xCE, 0xCE };
83+
static ColorSignal BLUE_Signal = { 0xCE, 0xCE, 0xCE, 0xCE,
84+
0xCE, 0xCE, 0xCE, 0xCE,
85+
0xCE, 0x8C, 0x8C, 0x8C};
86+
static ColorSignal BLACK_Signal = { 0xCE, 0xCE, 0xCE, 0xCE,
87+
0xCE, 0xCE, 0xCE, 0xCE,
88+
0xCE, 0xCE, 0xCE, 0xCE};
1789

1890
static volatile bool _running;
1991

@@ -46,7 +118,7 @@ int main()
46118
// immediately with a failure status if the output can't be written immediately.
47119
//
48120
// O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
49-
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
121+
uart0_filestream = open("/dev/ttyAMA0", O_WRONLY | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
50122
if (uart0_filestream == -1)
51123
{
52124
//ERROR - CAN'T OPEN SERIAL PORT
@@ -67,17 +139,18 @@ int main()
67139
// PARODD - Odd parity (else even)
68140
struct termios options;
69141
tcgetattr(uart0_filestream, &options);
70-
options.c_cflag = B4000000 | CS8 | CLOCAL | CREAD; //<Set baud rate
142+
options.c_cflag = B4000000 | CS8 | CLOCAL; //<Set baud rate
71143
options.c_iflag = IGNPAR;
72144
options.c_oflag = 0;
73145
options.c_lflag = 0;
74-
tcflush(uart0_filestream, TCIFLUSH);
146+
cfmakeraw(&options);
75147

76148
std::cout << "options.c_cflag = " << options.c_cflag << std::endl;
77149
std::cout << "options.c_iflag = " << options.c_iflag << std::endl;
78150
std::cout << "options.c_oflag = " << options.c_oflag << std::endl;
79151
std::cout << "options.c_lflag = " << options.c_lflag << std::endl;
80152

153+
tcflush(uart0_filestream, TCIFLUSH);
81154
tcsetattr(uart0_filestream, TCSANOW, &options);
82155
// Let's verify configured options
83156
tcgetattr(uart0_filestream, &options);
@@ -128,47 +201,9 @@ int main()
128201
}
129202

130203
//----- TX BYTES -----
131-
uint8_t tx_buffer[3*3*8*4];
132-
uint8_t *p_tx_buffer;
133-
134-
// for (int i=0; i<3; ++i)
135-
// {
136-
// Writing 0xFF, 0x00, 0x00
137-
// *p_tx_buffer++ = 0x8C;
138-
// *p_tx_buffer++ = 0x8C;
139-
// *p_tx_buffer++ = 0x8C;
140-
// *p_tx_buffer++ = 0x8C;
141-
142-
std::default_random_engine generator;
143-
std::uniform_int_distribution<int> distribution(1,2);
144-
145-
p_tx_buffer = &tx_buffer[0];
146-
for (int i=0; i<9; ++i)
147-
{
148-
int coinFlip = distribution(generator);
149-
if (coinFlip == 1)
150-
{
151-
*p_tx_buffer++ = 0xCE;
152-
*p_tx_buffer++ = 0xCE;
153-
*p_tx_buffer++ = 0xCE;
154-
*p_tx_buffer++ = 0xCE;
155-
}
156-
else
157-
{
158-
*p_tx_buffer++ = 0x8C;
159-
*p_tx_buffer++ = 0x8C;
160-
*p_tx_buffer++ = 0x8C;
161-
*p_tx_buffer++ = 0x8C;
162-
}
163-
}
164-
165-
std::cout << "Binary stream: [";
166-
for (unsigned char* txIt=&(tx_buffer[0]); txIt!=p_tx_buffer; ++txIt)
167-
{
168-
std::cout << " 1 " << (std::bitset<8>) (*txIt) << " 0 ";
169-
}
170-
std::cout << "]" << std::endl;
204+
std::vector<ColorSignal> signalData(10, RED_Signal);
171205

206+
int loopCnt = 0;
172207
std::cout << "Type 'c' to continue, 'q' or 'x' to quit: ";
173208
while (_running)
174209
{
@@ -182,38 +217,28 @@ int main()
182217
continue;
183218
}
184219

185-
int count = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0])); //Filestream, bytes to write, number of bytes to write
186-
if (count < 0)
220+
set_realtime_priority();
221+
for (int iRun=0; iRun<10; ++iRun)
187222
{
188-
std::cerr << "UART TX error" << std::endl;
223+
// tcflush(uart0_filestream, TCOFLUSH);
224+
write(uart0_filestream, signalData.data(), signalData.size()*sizeof(ColorSignal));
225+
tcdrain(uart0_filestream);
189226

190-
//----- CLOSE THE UART -----
191-
close(uart0_filestream);
192-
return -1;
193-
}
194-
std::cout << "Writing " << count << " bytes to uart" << std::endl;
227+
usleep(100000);
228+
++loopCnt;
229+
230+
if (loopCnt%3 == 2)
231+
signalData = std::vector<ColorSignal>(10, GREEN_Signal);
232+
else if(loopCnt%3 == 1)
233+
signalData = std::vector<ColorSignal>(10, BLUE_Signal);
234+
else if(loopCnt%3 == 0)
235+
signalData = std::vector<ColorSignal>(10, RED_Signal);
195236

196-
p_tx_buffer = &tx_buffer[0];
197-
for (int i=0; i<9; ++i)
198-
{
199-
int coinFlip = distribution(generator);
200-
if (coinFlip == 1)
201-
{
202-
*p_tx_buffer++ = 0xCE;
203-
*p_tx_buffer++ = 0xCE;
204-
*p_tx_buffer++ = 0xCE;
205-
*p_tx_buffer++ = 0xCE;
206-
}
207-
else
208-
{
209-
*p_tx_buffer++ = 0x8C;
210-
*p_tx_buffer++ = 0x8C;
211-
*p_tx_buffer++ = 0x8C;
212-
*p_tx_buffer++ = 0x8C;
213-
}
214237
}
215238
}
216239

240+
signalData = std::vector<ColorSignal>(50, BLACK_Signal);
241+
write(uart0_filestream, signalData.data(), signalData.size()*sizeof(ColorSignal));
217242
//----- CLOSE THE UART -----
218243
close(uart0_filestream);
219244

0 commit comments

Comments
 (0)