Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Gauthier Legrand <[email protected]>
Romuald Conty <[email protected]>
Michiel Brink <[email protected]>


152 changes: 152 additions & 0 deletions Core/artdmx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/* dmxmain.c forkt from https://github.com/ohm2013loc/art/blob/master/dmxmain.c */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>
#include <artdmx.h>

#define OpOutput 0x5000

#define VERSION_HI 0
#define VERSION_LO 14

#define ARTNET_PORT "6454"


struct pkt_ArtOutput {
char ID[8];
unsigned short OpCode;
unsigned char ProtVerHi;
unsigned char ProtVerLo;
unsigned char Sequence;
unsigned char Physical;
unsigned char SubUni;
unsigned char Net;
unsigned char LengthHi;
unsigned char Length;
unsigned char Data[512];
} __attribute__((packed));

#define DMXPKTLEN(channels) (channels+18)

int art_socket;

struct addrinfo *dmx_dest;

void setup_socket(char *universe_address)
{
struct addrinfo hints, *res;
struct sockaddr_in myaddr;
struct timeval timeout;
int rv;

timeout.tv_sec = 3;
timeout.tv_usec = 0;

int yes = 1;

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;

getaddrinfo("255.255.255.255", ARTNET_PORT, &hints, &res);

art_socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (art_socket == -1) {
perror("socket");
exit(1);
}

#if 0
if (bind(art_socket, res->ai_addr, res->ai_addrlen) == -1) {
perror("bind");
exit(1);
}
#endif

if (setsockopt(art_socket,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))
== -1) {
perror("setsockopt");
exit(1);
}

if (setsockopt(art_socket,SOL_SOCKET,SO_BROADCAST,&yes,sizeof(int))
== -1) {
perror("setsockopt");
exit(1);
}

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;

if ((rv = getaddrinfo(universe_address, ARTNET_PORT, &hints, &dmx_dest))
!= 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
exit(1);
}

}

void send_dmx(struct addrinfo *dest, char *data, int length)
{
struct pkt_ArtOutput pkt;
int i;
int numbytes;
static unsigned char dmx_sequence;

strcpy(pkt.ID, "Art-Net");
pkt.OpCode = OpOutput;
pkt.ProtVerHi = VERSION_HI;
pkt.ProtVerLo = VERSION_LO;
pkt.Sequence = dmx_sequence++;
if (dmx_sequence == 0)
dmx_sequence++;
pkt.Physical = 0;
pkt.SubUni = 0;
pkt.Net = 0;
pkt.LengthHi = (length >> 8);
pkt.Length = length & 0xff;
memcpy(pkt.Data, data, length);

if ((numbytes = sendto(art_socket, &pkt, DMXPKTLEN(length), 0,
dest->ai_addr, dest->ai_addrlen)) == -1) {
perror("sendto");
exit(1);
}
}

struct timeval delay_time;

void delay_setup(void)
{
gettimeofday(&delay_time, NULL);
}

void frame_delay(unsigned int microseconds)
{
struct timeval interval;
struct timeval now;
struct timespec int_ts;

interval.tv_sec = microseconds / 1000000;
interval.tv_usec = microseconds % 1000000;

timeradd(&delay_time, &interval, &delay_time);

gettimeofday(&now, NULL);

do {
timersub(&delay_time, &now, &interval);

int_ts.tv_sec = interval.tv_sec;
int_ts.tv_nsec = interval.tv_usec * 1000;

nanosleep(&int_ts, NULL);

gettimeofday(&now, NULL);
} while (timercmp(&delay_time, &now, >));
}
21 changes: 21 additions & 0 deletions Core/artdmx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
dmxmain.h forkt from https://github.com/ohm2013loc/art/blob/master/dmxmain.c
*/

#ifndef dmxmain_H
#define dmxmain_H

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

extern struct addrinfo *dmx_dest;

void setup_socket(char *universe_address);
void send_dmx(struct addrinfo *dest, char *data, int length);
void delay_setup(void);
void frame_delay(unsigned int microseconds);


#endif // dmxmain_H

61 changes: 40 additions & 21 deletions Core/ledmatrix.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright 2012, 2013 Gauthier Legrand
* Copyright 2012, 2013 Romuald Conty
* Copyright 2015, 2017 Michiel Brink
*
* This file is part of Minotor.
*
Expand Down Expand Up @@ -29,7 +30,8 @@ LedMatrix::LedMatrix(const QSize size, const QSize panelSize, const QSize matrix
_panelSize(panelSize),
_matrixSize(matrixSize),
_port(NULL),
_connected(false)
_connected_tty(false),
_connected_art(false)
{
_port = new QextSerialPort();

Expand All @@ -39,7 +41,7 @@ LedMatrix::LedMatrix(const QSize size, const QSize panelSize, const QSize matrix

LedMatrix::~LedMatrix()
{
if (_connected) _port->close();
if (_connected_tty) _port->close();
delete _port;
}

Expand All @@ -49,27 +51,36 @@ bool LedMatrix::openPortByName(const QString& portName)
_port->setBaudRate(BAUD1000000);
if (_port->open(QIODevice::WriteOnly)){
qDebug() << "Led matrix connected to:" << this->portName();
_connected = true;
_connected_tty = true;
emit(connected());
} else {
qDebug() << "Led matrix failed to connect to:" << portName;
}
return _connected;
return _connected_tty;
}

bool LedMatrix::openArtByIp(const QString& artIp)
{
qDebug() << "ip address:" << artIp;
setup_socket((char*)artIp.toStdString().c_str());
delay_setup();
_connected_art = true;
return _connected_art;
}

void LedMatrix::closePort()
{
if (_port) {
_port->close();
qDebug() << "Led matrix disconnected.";
_connected = false;
_connected_tty = false;
emit(connected(false));
}
}

bool LedMatrix::isConnected()
{
return _connected;
return _connected_tty;
}

QString LedMatrix::portName() const
Expand Down Expand Up @@ -120,20 +131,21 @@ void LedMatrix::computeLookUpTable()

for (unsigned int y=0;y<matrix_height_in_pixels;y++)
{
for (unsigned int x=0;x<matrix_width_in_pixels;x++) {
const unsigned int x_panel_id = (y%2)
?((matrix_panel_width_in_pixels-1)-(x%matrix_panel_width_in_pixels))
:(x%matrix_panel_width_in_pixels);
const unsigned int y_panel_id = (y%matrix_panel_height_in_pixels);
const unsigned int panel_id = ((y/matrix_panel_height_in_pixels)%2)
?((matrix_width_in_panel-1)-(x/matrix_panel_width_in_pixels)) + ((y/matrix_panel_height_in_pixels) * matrix_width_in_panel)
:(x/matrix_panel_width_in_pixels) + ((y/matrix_panel_height_in_pixels) * matrix_width_in_panel);

const unsigned int id = x_panel_id + (y_panel_id*matrix_panel_width_in_pixels) + (panel_id*matrix_panel_width_in_pixels*matrix_panel_height_in_pixels);
const unsigned int i = x+(y*matrix_width_in_pixels);
Q_ASSERT(i<(unsigned int)_pixelsLUT.size());
_pixelsLUT.data()[i] = id;
}
for (unsigned int x=0;x<matrix_width_in_pixels;x++)
{
const unsigned int x_panel_id = (y%2)
?((matrix_panel_width_in_pixels-1)-(x%matrix_panel_width_in_pixels))
:(x%matrix_panel_width_in_pixels);
const unsigned int y_panel_id = (y%matrix_panel_height_in_pixels);
const unsigned int panel_id = ((y/matrix_panel_height_in_pixels)%2)
?((matrix_width_in_panel-1)-(x/matrix_panel_width_in_pixels)) + ((y/matrix_panel_height_in_pixels) * matrix_width_in_panel)
:(x/matrix_panel_width_in_pixels) + ((y/matrix_panel_height_in_pixels) * matrix_width_in_panel);

const unsigned int id = x_panel_id + (y_panel_id*matrix_panel_width_in_pixels) + (panel_id*matrix_panel_width_in_pixels*matrix_panel_height_in_pixels);
const unsigned int i = x+(y*matrix_width_in_pixels);
Q_ASSERT(i<(unsigned int)_pixelsLUT.size());
_pixelsLUT.data()[i] = id;
}
}
}
}
Expand Down Expand Up @@ -164,12 +176,19 @@ void LedMatrix::show(const QImage *image)
framebuffer[b_id] = (qBlue(rgb)==0x01)?0:qBlue(rgb);
}
}
if(_connected)
if(_connected_tty)
{
_port->write(_framebuffer.constData(),_framebuffer.size());
char endFrame = 0x01;
_port->write(&endFrame,1);
}

if(_connected_art)
{
dmx_universe = (char*)_framebuffer.constData();
send_dmx(dmx_dest, dmx_universe, 512);
frame_delay(20000);
}
emit(updated());
}
}
12 changes: 11 additions & 1 deletion Core/ledmatrix.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright 2012, 2013 Gauthier Legrand
* Copyright 2012, 2013 Romuald Conty
* Copyright 2015, 2017 Michiel Brink
*
* This file is part of Minotor.
*
Expand Down Expand Up @@ -28,6 +29,8 @@

#include <QVarLengthArray>

#include "artdmx.h"

#include "qextserialport.h"

class LedMatrix : public QObject
Expand All @@ -38,6 +41,7 @@ class LedMatrix : public QObject
~LedMatrix();

bool openPortByName(const QString &portName);
bool openArtByIp(const QString &artIp);
void closePort();
QString portName() const;

Expand All @@ -61,7 +65,13 @@ class LedMatrix : public QObject

// Connection
QextSerialPort *_port;
bool _connected;
bool _connected_tty;
bool _connected_art;

//artnet
char* dmx_universe;
std::vector<int> dmx_universe_temp;
char* _ipAdress;

// Returns true if LedMatrix is fully configured (ie. does have all requiered sizes sets)
bool isConfigured() const;
Expand Down
1 change: 1 addition & 0 deletions Core/minotor.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright 2012, 2013 Gauthier Legrand
* Copyright 2012, 2013 Romuald Conty
* Copyright 2015, 2017 Michiel Brink
*
* This file is part of Minotor.
*
Expand Down
1 change: 1 addition & 0 deletions Core/minotor.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright 2012, 2013 Gauthier Legrand
* Copyright 2012, 2013 Romuald Conty
* Copyright 2015, 2017 Michiel Brink
*
* This file is part of Minotor.
*
Expand Down
12 changes: 7 additions & 5 deletions Minotor.pro
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ SOURCES += \
Animation/minatext.cpp \
Animation/minavibration.cpp \
Animation/minawaveform.cpp \
Core/artdmx.cpp \
Core/Midi/midi.cpp \
Core/Midi/midicontrol.cpp \
Core/Midi/midicontrollablelist.cpp \
Expand Down Expand Up @@ -105,6 +106,7 @@ HEADERS += \
Animation/minatext.h \
Animation/minavibration.h \
Animation/minawaveform.h \
Core/artdmx.h \
Core/Midi/midi.h \
Core/Midi/midicontrol.h \
Core/Midi/midicontrollablelist.h \
Expand Down Expand Up @@ -211,11 +213,11 @@ clang.commands = scan-build make clean all
clang.depends = qmake_clang

cppcheck.commands = \
cppcheck --quiet --enable=all \
--force --inconclusive \
-i libraries \
-I libraries/qextserialport/src \
./
cppcheck --quiet --enable=all \
--force --inconclusive \
-i libraries \
-I libraries/qextserialport/src \
./

QMAKE_EXTRA_TARGETS += clang qmake_clang cppcheck dmg

Expand Down
Loading