(Feat): Implement DMX Engine
This commit is contained in:
parent
3e73cd63bb
commit
0f5c1da12f
11
src/DmxWriter.cpp
Normal file
11
src/DmxWriter.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// Created by illyum on 8/16/2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DmxWriter.h"
|
||||||
|
|
||||||
|
DmxWriter::DmxWriter(DMXEngine& engine) : dmxEngine(engine) {}
|
||||||
|
|
||||||
|
void DmxWriter::setChannel(int channel, unsigned char value) {
|
||||||
|
dmxEngine.setChannelValue(channel, value);
|
||||||
|
}
|
19
src/DmxWriter.h
Normal file
19
src/DmxWriter.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Created by illyum on 8/16/2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef DMXWRITER_H
|
||||||
|
#define DMXWRITER_H
|
||||||
|
|
||||||
|
#include "dmx.h"
|
||||||
|
|
||||||
|
class DmxWriter {
|
||||||
|
public:
|
||||||
|
DmxWriter(DMXEngine& engine);
|
||||||
|
void setChannel(int channel, unsigned char value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DMXEngine& dmxEngine;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DMXWRITER_H
|
114
src/dmx.cpp
114
src/dmx.cpp
@ -1,3 +1,117 @@
|
|||||||
//
|
//
|
||||||
// Created by illyum on 8/15/2024.
|
// Created by illyum on 8/15/2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "dmx.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
#include "windows.h"
|
||||||
|
|
||||||
|
DMXEngine::DMXEngine(const char* portName, int baudRate, int dataSize)
|
||||||
|
: running(false), buffer(dataSize, 0) {
|
||||||
|
hSerial = CreateFileA(portName, GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
|
if (hSerial == INVALID_HANDLE_VALUE) {
|
||||||
|
std::cerr << "Error opening " << portName << " port" << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
configurePort();
|
||||||
|
}
|
||||||
|
|
||||||
|
DMXEngine::~DMXEngine() {
|
||||||
|
if (running) {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
CloseHandle(hSerial);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMXEngine::configurePort() {
|
||||||
|
DCB dcbSerialParams = { 0 };
|
||||||
|
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
|
||||||
|
if (!GetCommState(hSerial, &dcbSerialParams)) {
|
||||||
|
std::cerr << "Error getting COM port state" << std::endl;
|
||||||
|
CloseHandle(hSerial);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
dcbSerialParams.BaudRate = 250000;
|
||||||
|
dcbSerialParams.ByteSize = 8;
|
||||||
|
dcbSerialParams.StopBits = TWOSTOPBITS;
|
||||||
|
dcbSerialParams.Parity = NOPARITY;
|
||||||
|
|
||||||
|
if (!SetCommState(hSerial, &dcbSerialParams)) {
|
||||||
|
std::cerr << "Error setting COM port state" << std::endl;
|
||||||
|
CloseHandle(hSerial);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMTIMEOUTS timeouts = { 0 };
|
||||||
|
timeouts.ReadIntervalTimeout = 50;
|
||||||
|
timeouts.ReadTotalTimeoutConstant = 50;
|
||||||
|
timeouts.ReadTotalTimeoutMultiplier = 10;
|
||||||
|
timeouts.WriteTotalTimeoutConstant = 50;
|
||||||
|
timeouts.WriteTotalTimeoutMultiplier = 10;
|
||||||
|
|
||||||
|
if (!SetCommTimeouts(hSerial, &timeouts)) {
|
||||||
|
std::cerr << "Error setting COM port timeouts" << std::endl;
|
||||||
|
CloseHandle(hSerial);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMXEngine::start() {
|
||||||
|
running = true;
|
||||||
|
dmxThread = std::thread(dmxThreadFunc, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMXEngine::stop() {
|
||||||
|
running = false;
|
||||||
|
if (dmxThread.joinable()) {
|
||||||
|
dmxThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
DMXEngine::dumpZeros();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DMXEngine::setChannelValue(int channel, unsigned char value) {
|
||||||
|
if (channel >= 0 && channel < buffer.size()) {
|
||||||
|
buffer[channel] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMXEngine::sendDMXData() {
|
||||||
|
while (running) {
|
||||||
|
// Break condition
|
||||||
|
EscapeCommFunction(hSerial, SETBREAK);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
EscapeCommFunction(hSerial, CLRBREAK);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // MAB
|
||||||
|
|
||||||
|
DWORD bytesWritten;
|
||||||
|
unsigned char startCode = 0;
|
||||||
|
WriteFile(hSerial, &startCode, 1, &bytesWritten, NULL);
|
||||||
|
WriteFile(hSerial, buffer.data(), buffer.size(), &bytesWritten, NULL);
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(25));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMXEngine::dumpZeros() {
|
||||||
|
std::fill(buffer.begin(), buffer.end(), 0);
|
||||||
|
|
||||||
|
EscapeCommFunction(hSerial, SETBREAK);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
EscapeCommFunction(hSerial, CLRBREAK);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // MAB
|
||||||
|
|
||||||
|
DWORD bytesWritten;
|
||||||
|
unsigned char startCode = 0;
|
||||||
|
WriteFile(hSerial, &startCode, 1, &bytesWritten, NULL);
|
||||||
|
WriteFile(hSerial, buffer.data(), buffer.size(), &bytesWritten, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMXEngine::dmxThreadFunc(DMXEngine* engine) {
|
||||||
|
engine->sendDMXData();
|
||||||
|
}
|
||||||
|
37
src/dmx.h
37
src/dmx.h
@ -2,7 +2,38 @@
|
|||||||
// Created by illyum on 8/15/2024.
|
// Created by illyum on 8/15/2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef RAYLIBDMX_DMX_H
|
#ifndef DMX_H
|
||||||
#define RAYLIBDMX_DMX_H
|
#define DMX_H
|
||||||
|
|
||||||
#endif //RAYLIBDMX_DMX_H
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
#include <atomic>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
struct DMXFixture {
|
||||||
|
unsigned char r, g, b;
|
||||||
|
int channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DMXEngine {
|
||||||
|
public:
|
||||||
|
explicit DMXEngine(const char* portName, int baudRate = 250000, int dataSize = 512);
|
||||||
|
~DMXEngine();
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
void setChannelValue(int channel, unsigned char value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void sendDMXData();
|
||||||
|
void dumpZeros();
|
||||||
|
void configurePort();
|
||||||
|
static void dmxThreadFunc(DMXEngine* engine);
|
||||||
|
|
||||||
|
void* hSerial;
|
||||||
|
std::atomic<bool> running;
|
||||||
|
std::vector<unsigned char> buffer;
|
||||||
|
std::thread dmxThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DMX_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user