Open Lighting Architecture: C++ DMX Client API Tutorial

| Open Lighting Architecture 0.10.9

Loading...
Searching...
No Matches
C++ DMX Client API Tutorial

Send and Receive DMX512 data using the C++ API.

# Overview

This page introduces the OLA Client API, and provides sample programs to send and receive DMX512 data from olad. For information on how to use more advanced features of the API, see Advanced C++ Client API.

OLA comes with two C++ clients. The ola::client::StreamingClient is a simplified client that is limited to sending DMX512 data. ola::client::OlaClient is a full featured client that can both send and receive data, as well as control all aspects of OLA, like patching ports, configuring devices etc.

# Building

Once OLA is installed on your system, the examples can be built with:

    g++ example.cpp $(pkg-config --cflags --libs libola)

# Streaming Client DMX512 Transmit

The quickest way to get started is by using ola::client::StreamingClient The program below sends 100 frames of DMX data to the olad server on universe number 1. The frames are sent 25ms apart which gives a frame rate of 40 fps.

Each frame consists of 512 DMX data slots. The first slot is incremented by one each frame, the other slots are always 0. This produces the following sequence of DMX frames:

Time (ms) DMX Data
0 0,0,0,0,.....
25 1,0,0,0,.....
50 2,0,0,0,.....
75 3,0,0,0,.....
....
2475 100,0,0,0,.....
#include <stdlib.h>
#include <unistd.h>
#include <ola/DmxBuffer.h>
#include <ola/Logging.h>
#include <ola/client/StreamingClient.h>
#include <iostream>
using std::cout;
using std::endl;
int main(int, char *[]) {
unsigned int universe = 1; // universe to use for sending data
// turn on OLA logging
ola::InitLogging(ola::OLA_LOG_WARN, ola::OLA_LOG_STDERR);
ola::DmxBuffer buffer; // A DmxBuffer to hold the data.
buffer.Blackout(); // Set all channels to 0
// Create a new client.
ola::client::StreamingClient ola_client(
(ola::client::StreamingClient::Options()));
// Setup the client, this connects to the server
if (!ola_client.Setup()) {
std::cerr << "Setup failed" << endl;
exit(1);
}
// Send 100 frames to the server. Increment slot (channel) 0 each time a
// frame is sent.
for (unsigned int i = 0; i < 100; i++) {
buffer.SetChannel(0, i);
if (!ola_client.SendDmx(universe, buffer)) {
cout << "Send DMX failed" << endl;
exit(1);
}
usleep(25000); // sleep for 25ms between frames.
}
return 0;
}

# OLA Client DMX512 Transmit

While ola::client::StreamingClient is easy to use, it has the drawback that it can only send DMX512 data. It's not possible to receive DMX512, use RDM or control the behavior of olad with the StreamingClient. To do that we need to use ola::client::OlaClient.

ola::client::OlaClient provides a much richer interface for interacting with the server and uses a Event Driven programming model. This makes it more complicated to use. For more examples showing the non-DMX512 aspects of OlaClient, see the Advanced C++ Client API.

The following code uses ola::client::OlaClient and behaves the same as the Streaming Client DMX512 Transmit example above.

#include <ola/DmxBuffer.h>
#include <ola/io/SelectServer.h>
#include <ola/Logging.h>
#include <ola/client/ClientWrapper.h>
#include <ola/Callback.h>
using std::cout;
using std::endl;
bool SendData(ola::client::OlaClientWrapper *wrapper) {
static unsigned int universe = 1;
static unsigned int i = 0;
ola::DmxBuffer buffer;
buffer.Blackout();
buffer.SetChannel(0, i);
wrapper->GetClient()->SendDMX(universe, buffer, ola::client::SendDMXArgs());
if (++i == 100) {
wrapper->GetSelectServer()->Terminate();
}
return true;
}
int main(int, char *[]) {
ola::InitLogging(ola::OLA_LOG_WARN, ola::OLA_LOG_STDERR);
ola::client::OlaClientWrapper wrapper;
if (!wrapper.Setup()) {
std::cerr << "Setup failed" << endl;
exit(1);
}
// Create a timeout and register it with the SelectServer
ola::io::SelectServer *ss = wrapper.GetSelectServer();
ss->RegisterRepeatingTimeout(25, ola::NewCallback(&SendData, &wrapper));
// Start the main loop
ss->Run();
}

# DMX512 Receive

Receiving DMX involves setting up a callback handler and then instructing the OlaClient to call the handler when new DMX512 data is received. The example below will print a line for each DMX512 frame received on universe 1.

#include <ola/DmxBuffer.h>
#include <ola/Logging.h>
#include <ola/client/ClientWrapper.h>
#include <string>
static const unsigned int UNIVERSE = 1;
// Called when universe registration completes.
void RegisterComplete(const ola::client::Result& result) {
if (!result.Success()) {
OLA_WARN << "Failed to register universe: " << result.Error();
}
}
// Called when new DMX data arrives.
void NewDmx(const ola::client::DMXMetadata &metadata,
const ola::DmxBuffer &data) {
std::cout << "Received " << data.Size()
<< " channels for universe " << metadata.universe
<< ", priority " << static_cast<int>(metadata.priority)
<< std::endl;
}
int main() {
ola::InitLogging(ola::OLA_LOG_INFO, ola::OLA_LOG_STDERR);
ola::client::OlaClientWrapper wrapper;
if (!wrapper.Setup())
exit(1);
ola::client::OlaClient *client = wrapper.GetClient();
// Set the callback and register our interest in this universe
client->SetDMXCallback(ola::NewCallback(&NewDmx));
client->RegisterUniverse(
UNIVERSE, ola::client::REGISTER,
ola::NewSingleCallback(&RegisterComplete));
wrapper.GetSelectServer()->Run();
}