diff --git a/plugins/uartdmx/README.md b/plugins/uartdmx/README.md new file mode 100644 index 0000000000..8957e95701 --- /dev/null +++ b/plugins/uartdmx/README.md @@ -0,0 +1,34 @@ +Native UART DMX Plugin +====================== + +This plugin drives a supported POSIX UART (plus extensions) to produce a +direct DMX output stream. The host needs to create the DMX stream itself as +there is no external microcontroller. + +This is tested with the on-board UART of the Raspberry Pi. See here for a +possible schematic: +http://eastertrail.blogspot.co.uk/2014/04/command-and-control-ii.html + + +## Config file: `ola-uartdmx.conf` + +`enabled = true` +Enable this plugin (DISABLED by default). + +`device = /dev/ttyAMA0` +The device to use for DMX output (optional). Multiple devices are supported +if the hardware exists. On later software it may also be /dev/serial0. +Using USB-serial adapters is not supported (try the +*ftdidmx* plugin instead). + + +### Per Device Settings (using above device name) + +`-break = 100` +The DMX break time in microseconds for this device (optional). + +`-malf = 100` +The Mark After Last Frame time in microseconds for this device (optional). + +`-padding = 0` Minimal slots count in DMX frame (optional). +Default is 0, which allows empty frame. Using minimal timing, frame period reaches 140 microseconds, while standard requires minimum 1204us. Using BREAK=88us and MAB=8us, frame has to include 25 slots, that gives frame period 1240us. diff --git a/plugins/uartdmx/UartDmxDevice.cpp b/plugins/uartdmx/UartDmxDevice.cpp index 83a15348b2..54841274c5 100644 --- a/plugins/uartdmx/UartDmxDevice.cpp +++ b/plugins/uartdmx/UartDmxDevice.cpp @@ -34,8 +34,10 @@ using std::string; const char UartDmxDevice::K_MALF[] = "-malf"; const char UartDmxDevice::K_BREAK[] = "-break"; +const char UartDmxDevice::K_PADDING[] = "-padding"; const unsigned int UartDmxDevice::DEFAULT_BREAK = 100; const unsigned int UartDmxDevice::DEFAULT_MALF = 100; +const unsigned int UartDmxDevice::DEFAULT_PADDING = 0; UartDmxDevice::UartDmxDevice(AbstractPlugin *owner, @@ -57,7 +59,10 @@ UartDmxDevice::UartDmxDevice(AbstractPlugin *owner, if (!StringToInt(m_preferences->GetValue(DeviceMalfKey()), &m_malft)) { m_malft = DEFAULT_MALF; } - m_widget.reset(new UartWidget(path)); + if (!StringToInt(m_preferences->GetValue(DevicePaddingKey()), &m_paddingt)) { + m_paddingt = DEFAULT_PADDING; + } + m_widget.reset(new UartWidget(path, m_paddingt)); } UartDmxDevice::~UartDmxDevice() { @@ -77,6 +82,9 @@ string UartDmxDevice::DeviceMalfKey() const { string UartDmxDevice::DeviceBreakKey() const { return m_path + K_BREAK; } +string UartDmxDevice::DevicePaddingKey() const { + return m_path + K_PADDING; +} /** * Set the default preferences for this one Device @@ -94,6 +102,9 @@ void UartDmxDevice::SetDefaults() { save |= m_preferences->SetDefaultValue(DeviceMalfKey(), UIntValidator(8, 1000000), DEFAULT_MALF); + save |= m_preferences->SetDefaultValue(DevicePaddingKey(), + UIntValidator(0, 512), + DEFAULT_PADDING); if (save) { m_preferences->Save(); } diff --git a/plugins/uartdmx/UartDmxDevice.h b/plugins/uartdmx/UartDmxDevice.h index b4efbb388e..492e49783b 100644 --- a/plugins/uartdmx/UartDmxDevice.h +++ b/plugins/uartdmx/UartDmxDevice.h @@ -52,6 +52,7 @@ class UartDmxDevice : public Device { // Per device options std::string DeviceBreakKey() const; std::string DeviceMalfKey() const; + std::string DevicePaddingKey() const; void SetDefaults(); std::auto_ptr m_widget; @@ -60,11 +61,14 @@ class UartDmxDevice : public Device { const std::string m_path; unsigned int m_breakt; unsigned int m_malft; + unsigned int m_paddingt; static const unsigned int DEFAULT_MALF; static const char K_MALF[]; static const unsigned int DEFAULT_BREAK; static const char K_BREAK[]; + static const unsigned int DEFAULT_PADDING; + static const char K_PADDING[]; DISALLOW_COPY_AND_ASSIGN(UartDmxDevice); }; diff --git a/plugins/uartdmx/UartWidget.cpp b/plugins/uartdmx/UartWidget.cpp index d0fc3a709c..bedf57f519 100644 --- a/plugins/uartdmx/UartWidget.cpp +++ b/plugins/uartdmx/UartWidget.cpp @@ -46,6 +46,7 @@ #include "ola/io/IOUtils.h" #include "ola/Logging.h" #include "plugins/uartdmx/UartWidget.h" +#include "plugins/uartdmx/UartDmxDevice.h" namespace ola { namespace plugin { @@ -54,8 +55,9 @@ namespace uartdmx { using std::string; using std::vector; -UartWidget::UartWidget(const string& path) +UartWidget::UartWidget(const std::string &path, unsigned int padding) : m_path(path), + m_padding(padding), m_fd(NOT_OPEN) { } @@ -122,6 +124,10 @@ bool UartWidget::Write(const ola::DmxBuffer& data) { buffer[0] = DMX512_START_CODE; data.Get(buffer + 1, &length); + if (length < m_padding) { + memset((buffer + 1 + length), 0x00, (m_padding - length) ); + length = m_padding; + } if (write(m_fd, buffer, length + 1) <= 0) { // TODO(richardash1981): handle errors better as per the test code, diff --git a/plugins/uartdmx/UartWidget.h b/plugins/uartdmx/UartWidget.h index 81faf15fe7..34e13e59d9 100644 --- a/plugins/uartdmx/UartWidget.h +++ b/plugins/uartdmx/UartWidget.h @@ -48,9 +48,9 @@ class UartWidget { /** * Construct a new UartWidget instance for one widget. * @param path The device file path of the serial port + * @param padding Minimum DMX frame slots count, padded with NULLs */ - explicit UartWidget(const std::string &path); - + explicit UartWidget(const std::string &path, unsigned int padding); /** Destructor */ virtual ~UartWidget(); @@ -81,6 +81,7 @@ class UartWidget { private: const std::string m_path; + unsigned int m_padding; /** * variable to hold the Unix file descriptor used to open and manipulate