mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Merge branch 'master' into macos_compile
Conflicts: libsrc/leddevice/CMakeLists.txt libsrc/leddevice/LedDeviceFactory.cpp test/TestRs232HighSpeed.cpp Former-commit-id: 5583f2f881afd1a9b0c8ec3a52d7d3b54fe1dff7
This commit is contained in:
@@ -24,6 +24,8 @@ SET(Leddevice_HEADERS
|
||||
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceTest.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceSedu.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2812b.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2811.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceLightpack.h
|
||||
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.h
|
||||
@@ -37,6 +39,9 @@ SET(Leddevice_SOURCES
|
||||
${CURRENT_SOURCE_DIR}/LedRs232Device.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceSedu.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2811.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2812b.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceAdalight.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceLightpack.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.cpp
|
||||
|
@@ -7,11 +7,12 @@
|
||||
#include "LedDeviceLpd6803.h"
|
||||
#include "LedDeviceLpd8806.h"
|
||||
#include "LedDeviceWs2801.h"
|
||||
#include "LedDeviceWs2811.h"
|
||||
#endif
|
||||
|
||||
#include "LedDeviceSedu.h"
|
||||
#include "LedDeviceTest.h"
|
||||
#include "LedDeviceWs2811.h"
|
||||
#include "LedDeviceWs2812b.h"
|
||||
#include "LedDeviceAdalight.h"
|
||||
#include "LedDevicePaintpack.h"
|
||||
#include "LedDeviceLightpack.h"
|
||||
@@ -37,23 +38,6 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
|
||||
|
||||
device = deviceWs2801;
|
||||
}
|
||||
// else if (type == "ws2811")
|
||||
// {
|
||||
// const std::string output = deviceConfig["output"].asString();
|
||||
// const std::string outputSpeed = deviceConfig["output"].asString();
|
||||
// const std::string timingOption = deviceConfig["timingOption"].asString();
|
||||
|
||||
// ws2811::SpeedMode speedMode = (outputSpeed == "high")? ws2811::highspeed : ws2811::lowspeed;
|
||||
// if (outputSpeed != "high" && outputSpeed != "low")
|
||||
// {
|
||||
// std::cerr << "Incorrect speed-mode selected for WS2811: " << outputSpeed << " != {'high', 'low'}" << std::endl;
|
||||
// }
|
||||
|
||||
// LedDeviceWs2811 * deviceWs2811 = new LedDeviceWs2811(output, ws2811::fromString(timingOption, ws2811::option_2855), speedMode);
|
||||
// deviceWs2811->open();
|
||||
|
||||
// device = deviceWs2811;
|
||||
// }
|
||||
else if (type == "lpd6803" || type == "ldp6803")
|
||||
{
|
||||
const std::string output = deviceConfig["output"].asString();
|
||||
@@ -75,6 +59,30 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
|
||||
device = deviceLpd8806;
|
||||
}
|
||||
#endif
|
||||
// else if (type == "ws2811")
|
||||
// {
|
||||
// const std::string output = deviceConfig["output"].asString();
|
||||
// const std::string outputSpeed = deviceConfig["output"].asString();
|
||||
// const std::string timingOption = deviceConfig["timingOption"].asString();
|
||||
|
||||
// ws2811::SpeedMode speedMode = (outputSpeed == "high")? ws2811::highspeed : ws2811::lowspeed;
|
||||
// if (outputSpeed != "high" && outputSpeed != "low")
|
||||
// {
|
||||
// std::cerr << "Incorrect speed-mode selected for WS2811: " << outputSpeed << " != {'high', 'low'}" << std::endl;
|
||||
// }
|
||||
|
||||
// LedDeviceWs2811 * deviceWs2811 = new LedDeviceWs2811(output, ws2811::fromString(timingOption, ws2811::option_2855), speedMode);
|
||||
// deviceWs2811->open();
|
||||
|
||||
// device = deviceWs2811;
|
||||
// }
|
||||
else if (type == "ws2812b")
|
||||
{
|
||||
LedDeviceWs2812b * deviceWs2812b = new LedDeviceWs2812b();
|
||||
deviceWs2812b->open();
|
||||
|
||||
device = deviceWs2812b;
|
||||
}
|
||||
else if (type == "adalight")
|
||||
{
|
||||
const std::string output = deviceConfig["output"].asString();
|
||||
|
114
libsrc/leddevice/LedDeviceWs2812b.cpp
Normal file
114
libsrc/leddevice/LedDeviceWs2812b.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
|
||||
// Linux includes
|
||||
#include <unistd.h>
|
||||
|
||||
// Local Hyperion-Leddevice includes
|
||||
#include "LedDeviceWs2812b.h"
|
||||
|
||||
LedDeviceWs2812b::LedDeviceWs2812b() :
|
||||
LedRs232Device("/dev/ttyAMA0", 4000000)
|
||||
{
|
||||
fillTable();
|
||||
}
|
||||
|
||||
int LedDeviceWs2812b::write(const std::vector<ColorRgb> & ledValues)
|
||||
{
|
||||
// Ensure the size of the led-buffer
|
||||
if (_ledBuffer.size() != ledValues.size()*3)
|
||||
{
|
||||
_ledBuffer.resize(ledValues.size()*3);
|
||||
}
|
||||
|
||||
// Translate the channel of each color to a signal
|
||||
for (unsigned iLed=0; iLed<ledValues.size(); ++iLed)
|
||||
{
|
||||
const ColorRgb & color = ledValues[iLed];
|
||||
|
||||
_ledBuffer[3*iLed] = _byte2signalTable[color.red];
|
||||
_ledBuffer[3*iLed + 1] = _byte2signalTable[color.green];
|
||||
_ledBuffer[3*iLed + 2] = _byte2signalTable[color.blue];
|
||||
}
|
||||
|
||||
const int result = writeBytes(_ledBuffer.size()*sizeof(ByteSignal), reinterpret_cast<uint8_t *>(_ledBuffer.data()));
|
||||
// Official latch time is 50us (lets give it 50us more)
|
||||
usleep(100);
|
||||
return result;
|
||||
}
|
||||
|
||||
int LedDeviceWs2812b::switchOff()
|
||||
{
|
||||
// Set all bytes in the signal buffer to zero
|
||||
for (ByteSignal & signal : _ledBuffer)
|
||||
{
|
||||
signal = _byte2signalTable[0];
|
||||
}
|
||||
|
||||
return writeBytes(_ledBuffer.size()*sizeof(ByteSignal), reinterpret_cast<uint8_t *>(_ledBuffer.data()));
|
||||
}
|
||||
|
||||
void LedDeviceWs2812b::fillTable()
|
||||
{
|
||||
_byte2signalTable.clear();
|
||||
for (int byte=0; byte<256; ++byte)
|
||||
{
|
||||
const ByteSignal signal = byte2Signal(uint8_t(byte));
|
||||
_byte2signalTable.push_back(signal);
|
||||
}
|
||||
}
|
||||
|
||||
LedDeviceWs2812b::ByteSignal LedDeviceWs2812b::byte2Signal(const uint8_t byte) const
|
||||
{
|
||||
ByteSignal result;
|
||||
result.bit_12 = bits2Signal(byte & 0x80, byte & 0x40);
|
||||
result.bit_34 = bits2Signal(byte & 0x20, byte & 0x10);
|
||||
result.bit_56 = bits2Signal(byte & 0x08, byte & 0x04);
|
||||
result.bit_78 = bits2Signal(byte & 0x02, byte & 0x01);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t LedDeviceWs2812b::bits2Signal(const bool bit1, const bool bit2) const
|
||||
{
|
||||
// See https://github.com/tvdzwan/hyperion/wiki/Ws2812b for the explanation of the given
|
||||
// translations
|
||||
|
||||
// Encoding scheme 1
|
||||
// 00 1 1000 1100 0 1 0111 0011 0 1 1100 1110 0 0xCE
|
||||
// 01 1 1000 1110 0 1 0111 0001 0 1 1000 1110 0 0x8E
|
||||
// 10 1 1100 1100 0 1 0011 0011 0 1 1100 1100 0 0xCC
|
||||
// 11 1 1100 1110 0 1 0011 0001 0 1 1000 1100 0 0x8C
|
||||
|
||||
// Encoding schem 2
|
||||
// 00 - 1 0000 1000 0 - 1 1111 0111 0 - 1 1110 1111 0 - 0xEF
|
||||
// 01 - 1 0000 1111 0 - 1 1111 0000 0 - 1 0000 1111 0 - 0x0F
|
||||
// 10 - 1 1110 1000 0 - 1 0001 0111 0 - 1 1110 1000 0 - 0xE8
|
||||
// 11 - 1 1110 1111 0 - 1 0001 0000 0 - 1 0000 1000 0 - 0x08
|
||||
|
||||
if (bit1)
|
||||
{
|
||||
if (bit2)
|
||||
{
|
||||
// return 0x08;
|
||||
return 0x8C;
|
||||
}
|
||||
else
|
||||
{
|
||||
// return 0xE8;
|
||||
return 0xCC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bit2)
|
||||
{
|
||||
// return 0x0F;
|
||||
return 0x8E;
|
||||
}
|
||||
else
|
||||
{
|
||||
// return 0xEF;
|
||||
return 0xCE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
76
libsrc/leddevice/LedDeviceWs2812b.h
Normal file
76
libsrc/leddevice/LedDeviceWs2812b.h
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// Hyperion leddevice includes
|
||||
#include "LedRs232Device.h"
|
||||
|
||||
///
|
||||
/// The LedDevice for controlling a string of WS2812B leds. These are controlled over the mini-UART
|
||||
/// of the RPi (/dev/ttyAMA0).
|
||||
///
|
||||
class LedDeviceWs2812b : public LedRs232Device
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs the device (all required parameters are hardcoded)
|
||||
///
|
||||
LedDeviceWs2812b();
|
||||
|
||||
///
|
||||
/// Write the color data the the WS2812B led string
|
||||
///
|
||||
/// @param ledValues The color data
|
||||
/// @return Zero on succes else negative
|
||||
///
|
||||
virtual int write(const std::vector<ColorRgb> & ledValues);
|
||||
|
||||
///
|
||||
/// Write zero to all leds(that have been written by a previous write operation)
|
||||
///
|
||||
/// @return Zero on succes else negative
|
||||
///
|
||||
virtual int switchOff();
|
||||
|
||||
private:
|
||||
|
||||
///
|
||||
/// Structure holding the four output-bytes corresponding to a single input byte
|
||||
///
|
||||
struct ByteSignal
|
||||
{
|
||||
uint8_t bit_12;
|
||||
uint8_t bit_34;
|
||||
uint8_t bit_56;
|
||||
uint8_t bit_78;
|
||||
};
|
||||
/// Translation table from single input-byte to output-bytes
|
||||
std::vector<ByteSignal> _byte2signalTable;
|
||||
|
||||
///
|
||||
/// Fills the translation table (_byte2signalTable)
|
||||
///
|
||||
void fillTable();
|
||||
|
||||
///
|
||||
/// Computes the output bytes that belong to a given input-byte (no table lookup)
|
||||
///
|
||||
/// @param byte The input byte
|
||||
/// @return The four bytes (ByteSignal) for the output signal
|
||||
///
|
||||
ByteSignal byte2Signal(const uint8_t byte) const;
|
||||
|
||||
///
|
||||
/// Translates two bits to a single byte
|
||||
///
|
||||
/// @param bit1 The value of the first bit (1=true, zero=false)
|
||||
/// @param bit1 The value of the ssecond bit (1=true, zero=false)
|
||||
///
|
||||
/// @return The output-byte for the given two bit
|
||||
///
|
||||
uint8_t bits2Signal(const bool bit1, const bool bit2) const;
|
||||
|
||||
///
|
||||
/// The output buffer for writing bytes to the output
|
||||
///
|
||||
std::vector<ByteSignal> _ledBuffer;
|
||||
};
|
@@ -57,7 +57,9 @@ int LedRs232Device::writeBytes(const unsigned size, const uint8_t * data)
|
||||
|
||||
try
|
||||
{
|
||||
_rs232Port.flushOutput();
|
||||
_rs232Port.write(data, size);
|
||||
_rs232Port.flush();
|
||||
}
|
||||
catch (const serial::SerialException & serialExc)
|
||||
{
|
||||
@@ -77,6 +79,7 @@ int LedRs232Device::writeBytes(const unsigned size, const uint8_t * data)
|
||||
{
|
||||
_rs232Port.open();
|
||||
_rs232Port.write(data, size);
|
||||
_rs232Port.flush();
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
|
Reference in New Issue
Block a user