diff --git a/libsrc/leddevice/CMakeLists.txt b/libsrc/leddevice/CMakeLists.txt index a0b1c329..e1f3484c 100755 --- a/libsrc/leddevice/CMakeLists.txt +++ b/libsrc/leddevice/CMakeLists.txt @@ -33,9 +33,10 @@ SET(Leddevice_HEADERS ${CURRENT_SOURCE_DIR}/LedDevicePaintpack.h ${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.h ${CURRENT_SOURCE_DIR}/LedDeviceSedu.h + ${CURRENT_SOURCE_DIR}/LedDeviceDMX.h ${CURRENT_SOURCE_DIR}/LedDeviceFile.h ${CURRENT_SOURCE_DIR}/LedDeviceUdpRaw.h - ${CURRENT_SOURCE_DIR}/LedDeviceUdpH801.h + ${CURRENT_SOURCE_DIR}/LedDeviceUdpH801.h ${CURRENT_SOURCE_DIR}/LedDeviceUdpE131.h ${CURRENT_SOURCE_DIR}/ProviderUdp.h ${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.h @@ -60,10 +61,11 @@ SET(Leddevice_SOURCES ${CURRENT_SOURCE_DIR}/LedDevicePaintpack.cpp ${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.cpp ${CURRENT_SOURCE_DIR}/LedDeviceSedu.cpp + ${CURRENT_SOURCE_DIR}/LedDeviceDMX.cpp ${CURRENT_SOURCE_DIR}/LedDeviceFile.cpp ${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.cpp ${CURRENT_SOURCE_DIR}/LedDeviceUdpRaw.cpp - ${CURRENT_SOURCE_DIR}/LedDeviceUdpH801.cpp + ${CURRENT_SOURCE_DIR}/LedDeviceUdpH801.cpp ${CURRENT_SOURCE_DIR}/LedDeviceUdpE131.cpp ${CURRENT_SOURCE_DIR}/ProviderUdp.cpp ${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.cpp diff --git a/libsrc/leddevice/LedDeviceDMX.cpp b/libsrc/leddevice/LedDeviceDMX.cpp new file mode 100644 index 00000000..554fe38f --- /dev/null +++ b/libsrc/leddevice/LedDeviceDMX.cpp @@ -0,0 +1,84 @@ +#include "LedDeviceDMX.h" +#include +#include + +LedDeviceDMX::LedDeviceDMX(const Json::Value &deviceConfig) + : ProviderRs232(deviceConfig) +{ + std::string _dmxString = deviceConfig.get("dmxdevice", "invalid").asString(); + if (_dmxString == "raw") + { + _dmxDeviceType = 0; + _dmxStart = 1; + _dmxSlotsPerLed = 3; + } + else if (_dmxString == "McCrypt") + { + _dmxDeviceType = 1; + _dmxStart = 1; + _dmxSlotsPerLed = 4; + } + else + { + Error(_log, "unknown dmx device type %s", _dmxString.c_str()); + } + Debug(_log, "_dmxString \"%s\", _dmxDeviceType %d", _dmxString.c_str(), _dmxDeviceType ); + _rs232Port.setStopBits(QSerialPort::TwoStop); +} + +LedDevice* LedDeviceDMX::construct(const Json::Value &deviceConfig) +{ + return new LedDeviceDMX(deviceConfig); +} + +int LedDeviceDMX::write(const std::vector &ledValues) +{ + if ( (_ledBuffer.size() != _dmxChannelCount) || (_ledBuffer.size() == 0) ) + { + _dmxLedCount = std::min(_ledCount, 512/_dmxSlotsPerLed); + _dmxChannelCount = 1 + _dmxSlotsPerLed * _dmxLedCount; + + Debug(_log, "_dmxStart %d, _dmxSlotsPerLed %d", _dmxStart, _dmxSlotsPerLed); + Debug(_log, "_ledCount %d, _dmxLedCount %d, _dmxChannelCount %d", _ledCount, _dmxLedCount, _dmxChannelCount); + + _ledBuffer.resize(_dmxChannelCount, 0); + _ledBuffer[0] = 0x00; // NULL START code + } + + switch (_dmxDeviceType) { + case 0: + memcpy(_ledBuffer.data()+1, ledValues.data(), _dmxChannelCount-1); + break; + case 1: + int l =_dmxStart; + for (int d=0; d<_dmxLedCount; d++) + { + _ledBuffer[l++] = ledValues[d].red; + _ledBuffer[l++] = ledValues[d].green; + _ledBuffer[l++] = ledValues[d].blue; + _ledBuffer[l++] = 0xff; + } + break; + } + + _rs232Port.setBreakEnabled(true); + nanosleep((const struct timespec[]){{0, 176000L}}, NULL); // 176 uSec break time + _rs232Port.setBreakEnabled(false); + nanosleep((const struct timespec[]){{0, 12000L}}, NULL); // 176 uSec make after break time + +#undef uberdebug +#ifdef uberdebug + printf ("Writing %d bytes", _dmxChannelCount); + for (unsigned int i=0; i < _dmxChannelCount; i++) + { + if (i%32 == 0) { + printf ("\n%04x: ", i); + } + printf ("%02x ", _ledBuffer[i]); + } + printf ("\n"); +#endif + + return writeBytes(_dmxChannelCount, _ledBuffer.data()); +} + diff --git a/libsrc/leddevice/LedDeviceDMX.h b/libsrc/leddevice/LedDeviceDMX.h new file mode 100644 index 00000000..b5be8932 --- /dev/null +++ b/libsrc/leddevice/LedDeviceDMX.h @@ -0,0 +1,35 @@ +#pragma once + +// hyperion incluse +#include "ProviderRs232.h" + +/// +/// Implementation of the LedDevice interface for writing to DMX512 rs232 led device. +/// +class LedDeviceDMX : public ProviderRs232 +{ +public: + /// + /// Constructs specific LedDevice + /// + /// @param deviceConfig json device config + /// + LedDeviceDMX(const Json::Value &deviceConfig); + + /// constructs leddevice + static LedDevice* construct(const Json::Value &deviceConfig); + +private: + /// + /// Writes the led color values to the led-device + /// + /// @param ledValues The color-value per led + /// @return Zero on succes else negative + /// + virtual int write(const std::vector &ledValues); + int _dmxDeviceType = 0; + int _dmxStart = 1; + int _dmxSlotsPerLed = 3; + int _dmxLedCount = 0;; + unsigned int _dmxChannelCount = 0; +}; diff --git a/libsrc/leddevice/LedDeviceFactory.cpp b/libsrc/leddevice/LedDeviceFactory.cpp index 586c8b81..c0f112a4 100755 --- a/libsrc/leddevice/LedDeviceFactory.cpp +++ b/libsrc/leddevice/LedDeviceFactory.cpp @@ -35,6 +35,7 @@ #include "LedDevicePaintpack.h" #include "LedDevicePiBlaster.h" #include "LedDeviceSedu.h" +#include "LedDeviceDMX.h" #include "LedDeviceFile.h" #include "LedDeviceFadeCandy.h" #include "LedDeviceTpm2net.h" @@ -70,6 +71,7 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) LedDevice::addToDeviceMap("adalight" , LedDeviceAdalight::construct); LedDevice::addToDeviceMap("adalightapa102", LedDeviceAdalightApa102::construct); LedDevice::addToDeviceMap("sedu" , LedDeviceSedu::construct); + LedDevice::addToDeviceMap("dmx" , LedDeviceDMX::construct); LedDevice::addToDeviceMap("tpm2" , LedDeviceTpm2::construct); LedDevice::addToDeviceMap("atmo" , LedDeviceAtmo::construct); LedDevice::addToDeviceMap("fadecandy" , LedDeviceFadeCandy::construct); diff --git a/libsrc/leddevice/LedDeviceSchemas.qrc b/libsrc/leddevice/LedDeviceSchemas.qrc index ce04eb2d..e9699f6c 100644 --- a/libsrc/leddevice/LedDeviceSchemas.qrc +++ b/libsrc/leddevice/LedDeviceSchemas.qrc @@ -19,6 +19,7 @@ schemas/schema-piblaster.json schemas/schema-rawhid.json schemas/schema-sedu.json + schemas/schema-dmx.json schemas/schema-sk6812rgbw-spi.json schemas/schema-tinkerforge.json schemas/schema-tpm2net.json diff --git a/libsrc/leddevice/ProviderRs232.cpp b/libsrc/leddevice/ProviderRs232.cpp index 6bf2af64..281ae5e1 100644 --- a/libsrc/leddevice/ProviderRs232.cpp +++ b/libsrc/leddevice/ProviderRs232.cpp @@ -130,6 +130,7 @@ bool ProviderRs232::tryOpen(const int delayAfterConnect_ms) } return false; } + Debug(_log, "Setting baud rate to %d", _baudRate_Hz); _rs232Port.setBaudRate(_baudRate_Hz); _stateChanged = true; } diff --git a/libsrc/leddevice/ProviderRs232.h b/libsrc/leddevice/ProviderRs232.h index d285a179..829dd228 100644 --- a/libsrc/leddevice/ProviderRs232.h +++ b/libsrc/leddevice/ProviderRs232.h @@ -53,6 +53,9 @@ protected: void closeDevice(); + /// The RS232 serial-device + QSerialPort _rs232Port; + private slots: /// Unblock the device after a connection delay void unblockAfterDelay(); @@ -74,7 +77,7 @@ private: int _delayAfterConnect_ms; /// The RS232 serial-device - QSerialPort _rs232Port; +// QSerialPort _rs232Port; bool _blockedForDelay; diff --git a/libsrc/leddevice/schemas/schema-dmx.json b/libsrc/leddevice/schemas/schema-dmx.json new file mode 100644 index 00000000..4d2ab738 --- /dev/null +++ b/libsrc/leddevice/schemas/schema-dmx.json @@ -0,0 +1,29 @@ +{ + "type":"object", + "required":true, + "properties":{ + "output": { + "type": "string", + "title":"Output path", + "propertyOrder" : 1 + }, + "output": { + "type": "string", + "title":"DMX Device Type", + "propertyOrder" : 1 + }, + "rate": { + "type": "integer", + "title":"Baudrate", + "default": 250000, + "propertyOrder" : 2 + }, + "delayAfterConnect": { + "type": "integer", + "title":"Delay after connect", + "default": 250, + "propertyOrder" : 3 + } + }, + "additionalProperties": true +}