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

Commit 86d827f

Browse files
committed
Merge remote-tracking branch 'upstream/master' into support_for_philips_hue
2 parents dc69a21 + 2a77b55 commit 86d827f

File tree

11 files changed

+189
-23
lines changed

11 files changed

+189
-23
lines changed

config/hyperion.config.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
/// Device configuration contains the following fields:
66
/// * 'name' : The user friendly name of the device (only used for display purposes)
77
/// * 'type' : The type of the device or leds (known types for now are 'ws2801', 'ldp8806',
8-
/// 'lpd6803', 'sedu', 'adalight', 'lightpack', 'test' and 'none')
8+
/// 'lpd6803', 'sedu', 'adalight', 'lightpack', 'philipshue', 'test' and 'none')
99
/// * 'output' : The output specification depends on selected device. This can for example be the
1010
/// device specifier, device serial number, or the output file name
1111
/// * 'rate' : The baudrate of the output to the device
1212
/// * 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.).
13+
/// Specific of Philips Hue:
14+
/// * 'username' : The name of user registred on the Philips Hue Bridge
15+
/// * 'switchOffOnBlack' : Define if Hue light switch off when black is detected
16+
/// * 'transitiontime' : Set the time of transition between color of Hue light
1317
"device" :
1418
{
1519
"name" : "MyPi",

include/hyperion/Hyperion.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,6 @@ class Hyperion : public QObject
5252
SATURATION_GAIN, VALUE_GAIN, THRESHOLD, GAMMA, BLACKLEVEL, WHITELEVEL
5353
};
5454

55-
/// Enumeration containing the possible orders of device color byte data
56-
enum ColorOrder
57-
{
58-
ORDER_RGB, ORDER_RBG, ORDER_GRB, ORDER_BRG, ORDER_GBR, ORDER_BGR
59-
};
60-
6155
///
6256
/// Constructs the Hyperion instance based on the given Json configuration
6357
///
@@ -159,7 +153,14 @@ public slots:
159153

160154
public:
161155
static ColorOrder createColorOrder(const Json::Value & deviceConfig);
162-
static LedString createLedString(const Json::Value & ledsConfig);
156+
/**
157+
* Construct the 'led-string' with the integration area definition per led and the color
158+
* ordering of the RGB channels
159+
* @param ledsConfig The configuration of the led areas
160+
* @param deviceOrder The default RGB channel ordering
161+
* @return The constructed ledstring
162+
*/
163+
static LedString createLedString(const Json::Value & ledsConfig, const ColorOrder deviceOrder);
163164

164165
static MultiColorTransform * createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorTransformConfig);
165166
static ColorTransform * createColorTransform(const Json::Value & transformConfig);
@@ -194,9 +195,6 @@ private slots:
194195
/// The transformation from raw colors to led colors
195196
MultiColorTransform * _raw2ledTransform;
196197

197-
/// Value with the desired color byte order
198-
ColorOrder _colorOrder;
199-
200198
/// The actual LedDevice
201199
LedDevice * _device;
202200

include/hyperion/LedString.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,63 @@
1212
// Forward class declarations
1313
namespace Json { class Value; }
1414

15+
/// Enumeration containing the possible orders of device color byte data
16+
enum ColorOrder
17+
{
18+
ORDER_RGB, ORDER_RBG, ORDER_GRB, ORDER_BRG, ORDER_GBR, ORDER_BGR
19+
};
20+
21+
inline std::string colorOrderToString(const ColorOrder colorOrder)
22+
{
23+
switch (colorOrder)
24+
{
25+
case ORDER_RGB:
26+
return "rgb";
27+
case ORDER_RBG:
28+
return "rbg";
29+
case ORDER_GRB:
30+
return "grb";
31+
case ORDER_BRG:
32+
return "brg";
33+
case ORDER_GBR:
34+
return "gbr";
35+
case ORDER_BGR:
36+
return "bgr";
37+
default:
38+
return "not-a-colororder";
39+
}
40+
}
41+
inline ColorOrder stringToColorOrder(const std::string & order)
42+
{
43+
if (order == "rgb")
44+
{
45+
return ORDER_RGB;
46+
}
47+
else if (order == "bgr")
48+
{
49+
return ORDER_BGR;
50+
}
51+
else if (order == "rbg")
52+
{
53+
return ORDER_RBG;
54+
}
55+
else if (order == "brg")
56+
{
57+
return ORDER_BRG;
58+
}
59+
else if (order == "gbr")
60+
{
61+
return ORDER_GBR;
62+
}
63+
else if (order == "grb")
64+
{
65+
return ORDER_GRB;
66+
}
67+
68+
std::cout << "Unknown color order defined (" << order << "). Using RGB." << std::endl;
69+
return ORDER_RGB;
70+
}
71+
1572
///
1673
/// The Led structure contains the definition of the image portion used to determine a single led's
1774
/// color.
@@ -40,6 +97,8 @@ struct Led
4097
double minY_frac;
4198
/// The maximum horizontal scan line included for this leds color
4299
double maxY_frac;
100+
/// the color order
101+
ColorOrder colorOrder;
43102
};
44103

45104
///

libsrc/hyperion/Hyperion.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include <effectengine/EffectEngine.h>
2828

2929

30-
Hyperion::ColorOrder Hyperion::createColorOrder(const Json::Value &deviceConfig)
30+
ColorOrder Hyperion::createColorOrder(const Json::Value &deviceConfig)
3131
{
3232
// deprecated: force BGR when the deprecated flag is present and set to true
3333
if (deviceConfig.get("bgr-output", false).asBool())
@@ -187,14 +187,16 @@ RgbChannelTransform* Hyperion::createRgbChannelTransform(const Json::Value& colo
187187
return transform;
188188
}
189189

190-
LedString Hyperion::createLedString(const Json::Value& ledsConfig)
190+
LedString Hyperion::createLedString(const Json::Value& ledsConfig, const ColorOrder deviceOrder)
191191
{
192192
LedString ledString;
193193

194+
const std::string deviceOrderStr = colorOrderToString(deviceOrder);
194195
for (const Json::Value& ledConfig : ledsConfig)
195196
{
196197
Led led;
197198
led.index = ledConfig["index"].asInt();
199+
198200
const Json::Value& hscanConfig = ledConfig["hscan"];
199201
const Json::Value& vscanConfig = ledConfig["vscan"];
200202
led.minX_frac = std::max(0.0, std::min(1.0, hscanConfig["minimum"].asDouble()));
@@ -212,6 +214,10 @@ LedString Hyperion::createLedString(const Json::Value& ledsConfig)
212214
std::swap(led.minY_frac, led.maxY_frac);
213215
}
214216

217+
// Get the order of the rgb channels for this led (default is device order)
218+
const std::string ledOrderStr = ledConfig.get("colorOrder", deviceOrderStr).asString();
219+
led.colorOrder = stringToColorOrder(ledOrderStr);
220+
215221
ledString.leds().push_back(led);
216222
}
217223

@@ -262,10 +268,9 @@ LedDevice * Hyperion::createColorSmoothing(const Json::Value & smoothingConfig,
262268

263269

264270
Hyperion::Hyperion(const Json::Value &jsonConfig) :
265-
_ledString(createLedString(jsonConfig["leds"])),
271+
_ledString(createLedString(jsonConfig["leds"], createColorOrder(jsonConfig["device"]))),
266272
_muxer(_ledString.leds().size()),
267273
_raw2ledTransform(createLedColorsTransform(_ledString.leds().size(), jsonConfig["color"])),
268-
_colorOrder(createColorOrder(jsonConfig["device"])),
269274
_device(LedDeviceFactory::construct(jsonConfig["device"])),
270275
_effectEngine(nullptr),
271276
_timer()
@@ -429,10 +434,13 @@ void Hyperion::update()
429434

430435
// Apply the transform to each led and color-channel
431436
std::vector<ColorRgb> ledColors = _raw2ledTransform->applyTransform(priorityInfo.ledColors);
437+
const std::vector<Led>& leds = _ledString.leds();
438+
int i = 0;
432439
for (ColorRgb& color : ledColors)
433440
{
441+
const ColorOrder ledColorOrder = leds.at(i).colorOrder;
434442
// correct the color byte order
435-
switch (_colorOrder)
443+
switch (ledColorOrder)
436444
{
437445
case ORDER_RGB:
438446
// leave as it is
@@ -463,6 +471,7 @@ void Hyperion::update()
463471
break;
464472
}
465473
}
474+
i++;
466475
}
467476

468477
// Write the data to the device

libsrc/hyperion/hyperion.schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@
195195
}
196196
},
197197
"additionalProperties" : false
198+
},
199+
"colorOrder" : {
200+
"type" : "string",
201+
"required" : false
198202
}
199203
},
200204
"additionalProperties" : false

libsrc/leddevice/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ SET(Leddevice_HEADERS
3131
${CURRENT_SOURCE_DIR}/LedDeviceTest.h
3232
${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.h
3333
${CURRENT_SOURCE_DIR}/LedDeviceTpm2.h
34+
${CURRENT_SOURCE_DIR}/LedDeviceAtmo.h
3435
)
3536

3637
SET(Leddevice_SOURCES
@@ -49,6 +50,7 @@ SET(Leddevice_SOURCES
4950
${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.cpp
5051
${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.cpp
5152
${CURRENT_SOURCE_DIR}/LedDeviceTpm2.cpp
53+
${CURRENT_SOURCE_DIR}/LedDeviceAtmo.cpp
5254
)
5355

5456
if(ENABLE_SPIDEV)

libsrc/leddevice/LedDeviceAtmo.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
// STL includes
3+
#include <cstring>
4+
#include <iostream>
5+
6+
// hyperion local includes
7+
#include "LedDeviceAtmo.h"
8+
9+
LedDeviceAtmo::LedDeviceAtmo(const std::string& outputDevice, const unsigned baudrate) :
10+
LedRs232Device(outputDevice, baudrate),
11+
_ledBuffer(4 + 5*3) // 4-byte header, 5 RGB values
12+
{
13+
_ledBuffer[0] = 0xFF; // Startbyte
14+
_ledBuffer[1] = 0x00; // StartChannel(Low)
15+
_ledBuffer[2] = 0x00; // StartChannel(High)
16+
_ledBuffer[3] = 0x0F; // Number of Databytes send (always! 15)
17+
}
18+
19+
int LedDeviceAtmo::write(const std::vector<ColorRgb> &ledValues)
20+
{
21+
// The protocol is shomehow limited. we always need to send exactly 5 channels + header
22+
// (19 bytes) for the hardware to recognize the data
23+
if (ledValues.size() != 5)
24+
{
25+
std::cerr << "AtmoLight: " << ledValues.size() << " channels configured. This should always be 5!" << std::endl;
26+
return 0;
27+
}
28+
29+
// write data
30+
memcpy(4 + _ledBuffer.data(), ledValues.data(), ledValues.size() * sizeof(ColorRgb));
31+
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
32+
}
33+
34+
int LedDeviceAtmo::switchOff()
35+
{
36+
memset(4 + _ledBuffer.data(), 0, _ledBuffer.size() - 4);
37+
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
38+
}

libsrc/leddevice/LedDeviceAtmo.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
// STL includes
4+
#include <string>
5+
6+
// hyperion incluse
7+
#include "LedRs232Device.h"
8+
9+
///
10+
/// Implementation of the LedDevice interface for writing to serial device using tpm2 protocol.
11+
///
12+
class LedDeviceAtmo : public LedRs232Device
13+
{
14+
public:
15+
///
16+
/// Constructs the LedDevice for attached serial device using supporting tpm2 protocol
17+
/// All LEDs in the stripe are handled as one frame
18+
///
19+
/// @param outputDevice The name of the output device (eg '/dev/ttyAMA0')
20+
/// @param baudrate The used baudrate for writing to the output device
21+
///
22+
LedDeviceAtmo(const std::string& outputDevice, const unsigned baudrate);
23+
24+
///
25+
/// Writes the led color values to the led-device
26+
///
27+
/// @param ledValues The color-value per led
28+
/// @return Zero on succes else negative
29+
///
30+
virtual int write(const std::vector<ColorRgb> &ledValues);
31+
32+
/// Switch the leds off
33+
virtual int switchOff();
34+
35+
private:
36+
/// The buffer containing the packed RGB values
37+
std::vector<uint8_t> _ledBuffer;
38+
};

libsrc/leddevice/LedDeviceFactory.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "LedDeviceHyperionUsbasp.h"
3333
#include "LedDevicePhilipsHue.h"
3434
#include "LedDeviceTpm2.h"
35+
#include "LedDeviceAtmo.h"
3536

3637
#ifdef ENABLE_WS2812BPWM
3738
#include "LedDeviceWS2812b.h"
@@ -211,6 +212,15 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
211212
deviceTpm2->open();
212213
device = deviceTpm2;
213214
}
215+
else if (type == "atmo")
216+
{
217+
const std::string output = deviceConfig["output"].asString();
218+
const unsigned rate = 38400;
219+
220+
LedDeviceAtmo * deviceAtmo = new LedDeviceAtmo(output, rate);
221+
deviceAtmo->open();
222+
device = deviceAtmo;
223+
}
214224
#ifdef ENABLE_WS2812BPWM
215225
else if (type == "ws2812b")
216226
{

libsrc/leddevice/LedDevicePiBlaster.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,13 @@ int LedDevicePiBlaster::write(const std::vector<ColorRgb> & ledValues)
8080
return -1;
8181
}
8282

83+
std::vector<int> iPins = {4, 17, 18, 27, 21, 22, 23, 24, 25};
84+
8385
unsigned colorIdx = 0;
84-
for (unsigned iChannel=0; iChannel<8; ++iChannel)
86+
for (std::vector<int>::iterator it = iPins.begin(); it != iPins.end(); ++it)
8587
{
8688
double pwmDutyCycle = 0.0;
87-
switch (_channelAssignment[iChannel])
89+
switch (_channelAssignment[*it])
8890
{
8991
case 'r':
9092
pwmDutyCycle = ledValues[colorIdx].red / 255.0;
@@ -102,7 +104,7 @@ int LedDevicePiBlaster::write(const std::vector<ColorRgb> & ledValues)
102104
continue;
103105
}
104106

105-
fprintf(_fid, "%i=%f\n", iChannel, pwmDutyCycle);
107+
// fprintf(_fid, "%i=%f\n", iChannel, pwmDutyCycle);
106108
fflush(_fid);
107109
}
108110

@@ -117,11 +119,13 @@ int LedDevicePiBlaster::switchOff()
117119
return -1;
118120
}
119121

120-
for (unsigned iChannel=0; iChannel<8; ++iChannel)
122+
std::vector<int> iPins = {4, 17, 18, 21, 22, 23, 24, 25};
123+
124+
for (std::vector<int>::iterator it = iPins.begin(); it != iPins.end(); ++it)
121125
{
122-
if (_channelAssignment[iChannel] != ' ')
126+
if (_channelAssignment[*it] != ' ')
123127
{
124-
fprintf(_fid, "%i=%f\n", iChannel, 0.0);
128+
fprintf(_fid, "%i=%f\n", *it, 0.0);
125129
fflush(_fid);
126130
}
127131
}

0 commit comments

Comments
 (0)