Skip to content
This repository was archived by the owner on May 6, 2021. It is now read-only.

Commit 8dbd3d9

Browse files
committed
add support for tinkerforge
1 parent 919c677 commit 8dbd3d9

File tree

6 files changed

+288
-7
lines changed

6 files changed

+288
-7
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ message(STATUS "ENABLE_SPIDEV = " ${ENABLE_SPIDEV})
1616
option(ENABLE_V4L2 "Enable the V4L2 grabber" ON)
1717
message(STATUS "ENABLE_V4L2 = " ${ENABLE_V4L2})
1818

19+
option(ENABLE_TINKERFORGE "Enable the TINKERFORGE device" OFF)
20+
message(STATUS "ENABLE_TINKERFORGE = " ${ENABLE_TINKERFORGE})
21+
1922
# Createt the configuration file
2023
# configure a header file to pass some of the CMake settings
2124
# to the source code
@@ -62,6 +65,10 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES_OLD)
6265
find_package(libusb-1.0 REQUIRED)
6366
find_package(Threads REQUIRED)
6467

68+
if (ENABLE_TINKERFORGE)
69+
find_package(libtinkerforge-1.0 REQUIRED)
70+
endif (ENABLE_TINKERFORGE)
71+
6572
include(${QT_USE_FILE})
6673
add_definitions(${QT_DEFINITIONS})
6774
# TODO[TvdZ]: This linking directory should only be added if we are cross compiling

HyperionConfig.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@
88

99
// Define to enable the spi-device
1010
#cmakedefine ENABLE_SPIDEV
11+
12+
// Define to enable the spi-device
13+
#cmakedefine ENABLE_TINKERFORGE

libsrc/leddevice/CMakeLists.txt

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,20 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/leddevice)
66
#add libusb and pthreads (required for the Lighpack usb device)
77
find_package(libusb-1.0 REQUIRED)
88
find_package(Threads REQUIRED)
9+
if(ENABLE_TINKERFORGE)
10+
find_package(libtinkerforge-1.0 REQUIRED)
11+
endif(ENABLE_TINKERFORGE)
12+
913

1014
include_directories(
11-
../../include/hidapi
12-
${LIBUSB_1_INCLUDE_DIRS}) # for Lightpack device
15+
../../include/hidapi
16+
${LIBUSB_1_INCLUDE_DIRS}) # for Lightpack device
17+
18+
19+
if(ENABLE_TINKERFORGE)
20+
include_directories(
21+
${LIBTINKERFORGE_1_INCLUDE_DIRS}) # for Tinkerforge device
22+
endif(ENABLE_TINKERFORGE)
1323

1424
# Group the headers that go through the MOC compiler
1525
SET(Leddevice_QT_HEADERS
@@ -67,6 +77,17 @@ if(ENABLE_SPIDEV)
6777
)
6878
endif(ENABLE_SPIDEV)
6979

80+
if(ENABLE_TINKERFORGE)
81+
SET(Leddevice_HEADERS
82+
${Leddevice_HEADERS}
83+
${CURRENT_SOURCE_DIR}/LedDeviceTinkerforge.h
84+
)
85+
SET(Leddevice_SOURCES
86+
${Leddevice_SOURCES}
87+
${CURRENT_SOURCE_DIR}/LedDeviceTinkerforge.cpp
88+
)
89+
endif(ENABLE_TINKERFORGE)
90+
7091

7192
QT4_WRAP_CPP(Leddevice_HEADERS_MOC ${Leddevice_QT_HEADERS})
7293

@@ -78,12 +99,19 @@ add_library(leddevice
7899
)
79100

80101
target_link_libraries(leddevice
81-
hyperion-utils
82-
serialport
83-
${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev
84-
${CMAKE_THREAD_LIBS_INIT}
85-
${QT_LIBRARIES}
102+
hyperion-utils
103+
serialport
104+
${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev
105+
${CMAKE_THREAD_LIBS_INIT}
106+
${QT_LIBRARIES}
86107
)
108+
109+
if(ENABLE_TINKERFORGE)
110+
target_link_libraries(leddevice
111+
${LIBTINKERFORGE_1_LIBRARIES}
112+
)
113+
endif()
114+
87115
if(APPLE)
88116
target_link_libraries(leddevice hidapi-mac)
89117
else()

libsrc/leddevice/LedDeviceFactory.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
#include "LedDeviceWs2801.h"
1717
#endif
1818

19+
#ifdef ENABLE_TINKERFORGE
20+
#include "LedDeviceTinkerforge.h"
21+
#endif
22+
1923
#include "LedDeviceAdalight.h"
2024
#include "LedDeviceLightpack.h"
2125
#include "LedDeviceMultiLightpack.h"
@@ -87,6 +91,22 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
8791
device = deviceWs2801;
8892
}
8993
#endif
94+
95+
#ifdef ENABLE_TINKERFORGE
96+
else if (type=="tinkerforge")
97+
{
98+
const std::string host = deviceConfig.get("output", "127.0.0.1").asString();
99+
const uint16_t port = deviceConfig.get("port", 4223).asInt();
100+
const std::string uid = deviceConfig["uid"].asString();
101+
const unsigned rate = deviceConfig["rate"].asInt();
102+
103+
LedDeviceTinkerforge* deviceTinkerforge = new LedDeviceTinkerforge(host, port, uid, rate);
104+
deviceTinkerforge->open();
105+
106+
device = deviceTinkerforge;
107+
}
108+
#endif
109+
90110
// else if (type == "ws2811")
91111
// {
92112
// const std::string output = deviceConfig["output"].asString();
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
2+
// STL includes
3+
#include <cerrno>
4+
#include <cstring>
5+
6+
// Local LedDevice includes
7+
#include "LedDeviceTinkerforge.h"
8+
9+
static const unsigned MAX_NUM_LEDS = 320;
10+
static const unsigned MAX_NUM_LEDS_SETTABLE = 16;
11+
12+
LedDeviceTinkerforge::LedDeviceTinkerforge(const std::string &host, uint16_t port, const std::string &uid, const unsigned interval) :
13+
LedDevice(),
14+
_host(host),
15+
_port(port),
16+
_uid(uid),
17+
_interval(interval),
18+
_ipConnection(nullptr),
19+
_ledStrip(nullptr),
20+
_colorChannelSize(0)
21+
{
22+
// empty
23+
}
24+
25+
LedDeviceTinkerforge::~LedDeviceTinkerforge()
26+
{
27+
// Close the device (if it is opened)
28+
if (_ipConnection != nullptr && _ledStrip != nullptr)
29+
{
30+
switchOff();
31+
}
32+
if (_ipConnection != nullptr)
33+
delete _ipConnection;
34+
if (_ledStrip != nullptr)
35+
delete _ledStrip;
36+
}
37+
38+
int LedDeviceTinkerforge::open()
39+
{
40+
_ipConnection = new IPConnection;
41+
ipcon_create(_ipConnection);
42+
43+
int connectionStatus = ipcon_connect(_ipConnection, _host.c_str(), _port);
44+
if (connectionStatus < 0)
45+
{
46+
std::cerr << "Attempt to connect to master brick (" << _host << ":" << _port << ") failed with status " << connectionStatus << std::endl;
47+
return -1;
48+
}
49+
50+
_ledStrip = new LEDStrip;
51+
led_strip_create(_ledStrip, _uid.c_str(), _ipConnection);
52+
53+
int frameStatus = led_strip_set_frame_duration(_ledStrip, _interval);
54+
if (frameStatus < 0)
55+
{
56+
std::cerr << "Attempt to connect to led strip bricklet (led_strip_set_frame_duration()) failed with status " << frameStatus << std::endl;
57+
return -1;
58+
}
59+
60+
return 0;
61+
}
62+
63+
int LedDeviceTinkerforge::write(const std::vector<ColorRgb> &ledValues)
64+
{
65+
std::cerr << "Write" << std::endl;
66+
67+
unsigned nrLedValues = ledValues.size();
68+
69+
if (nrLedValues > MAX_NUM_LEDS)
70+
{
71+
std::cerr << "Invalid attempt to write led values. Not more than " << MAX_NUM_LEDS << " leds are allowed." << std::endl;
72+
return -1;
73+
}
74+
75+
if (_colorChannelSize < nrLedValues)
76+
{
77+
_redChannel.resize(nrLedValues, uint8_t(0));
78+
_greenChannel.resize(nrLedValues, uint8_t(0));
79+
_blueChannel.resize(nrLedValues, uint8_t(0));
80+
}
81+
_colorChannelSize = nrLedValues;
82+
83+
auto redIt = _redChannel.begin();
84+
auto greenIt = _greenChannel.begin();
85+
auto blueIt = _blueChannel.begin();
86+
87+
for (const ColorRgb &ledValue : ledValues)
88+
{
89+
*redIt = ledValue.red;
90+
redIt++;
91+
*greenIt = ledValue.green;
92+
greenIt++;
93+
*blueIt = ledValue.blue;
94+
blueIt++;
95+
}
96+
97+
return transferLedData(_ledStrip, 0, _colorChannelSize, &_redChannel[0], &_greenChannel[0], &_blueChannel[0]);
98+
}
99+
100+
int LedDeviceTinkerforge::switchOff()
101+
{
102+
std::cerr << "Switchoff" << std::endl;
103+
std::fill(_redChannel.begin(), _redChannel.end(), 0);
104+
std::fill(_greenChannel.begin(), _greenChannel.end(), 0);
105+
std::fill(_blueChannel.begin(), _blueChannel.end(), 0);
106+
107+
return transferLedData(_ledStrip, 0, _colorChannelSize, &_redChannel[0], &_greenChannel[0], &_blueChannel[0]);
108+
}
109+
110+
int LedDeviceTinkerforge::transferLedData(LEDStrip *ledStrip, unsigned index, unsigned length, uint8_t *redChannel, uint8_t *greenChannel, uint8_t *blueChannel)
111+
{
112+
// we need that array size no matter how many leds will really be set
113+
uint8_t _reds[MAX_NUM_LEDS_SETTABLE];
114+
uint8_t _greens[MAX_NUM_LEDS_SETTABLE];
115+
uint8_t _blues[MAX_NUM_LEDS_SETTABLE];
116+
117+
int status = E_INVALID_PARAMETER;
118+
unsigned i;
119+
unsigned int copyLength;
120+
121+
if (index >= 0 && length > 0 && index < length && length <= MAX_NUM_LEDS)
122+
{
123+
for (i = index; i < length; i += MAX_NUM_LEDS_SETTABLE)
124+
{
125+
copyLength = (i + MAX_NUM_LEDS_SETTABLE > length) ? length - i : MAX_NUM_LEDS_SETTABLE;
126+
127+
memcpy(_reds, redChannel + i, copyLength * sizeof(uint8_t));
128+
memcpy(_greens, greenChannel + i, copyLength * sizeof(uint8_t));
129+
memcpy(_blues, blueChannel + i, copyLength * sizeof(uint8_t));
130+
131+
status = led_strip_set_rgb_values(ledStrip, i, copyLength, _reds, _greens, _blues);
132+
133+
if (status != E_OK)
134+
{
135+
std::cerr << "Setting led values failed with status " << status << std::endl;
136+
break;
137+
}
138+
}
139+
}
140+
return status;
141+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
2+
#pragma once
3+
4+
// STL includes
5+
#include <cstdio>
6+
7+
// Hyperion-Leddevice includes
8+
#include <leddevice/LedDevice.h>
9+
10+
11+
extern "C" {
12+
#include <tinkerforge/ip_connection.h>
13+
#include <tinkerforge/bricklet_led_strip.h>
14+
}
15+
16+
class LedDeviceTinkerforge : public LedDevice
17+
{
18+
public:
19+
20+
LedDeviceTinkerforge(const std::string &host, uint16_t port, const std::string &uid, const unsigned interval);
21+
22+
virtual ~LedDeviceTinkerforge();
23+
24+
///
25+
/// Attempts to open a connection to the master bricklet and the led strip bricklet.
26+
///
27+
/// @return Zero on succes else negative
28+
///
29+
int open();
30+
31+
///
32+
/// Writes the colors to the led strip bricklet
33+
///
34+
/// @param ledValues The color value for each led
35+
///
36+
/// @return Zero on success else negative
37+
///
38+
virtual int write(const std::vector<ColorRgb> &ledValues);
39+
40+
///
41+
/// Switches off the leds
42+
///
43+
/// @return Zero on success else negative
44+
///
45+
virtual int switchOff();
46+
47+
private:
48+
///
49+
/// Writes the data to the led strip blicklet
50+
int transferLedData(LEDStrip *ledstrip, unsigned int index, unsigned int length, uint8_t *redChannel, uint8_t *greenChannel, uint8_t *blueChannel);
51+
52+
/// The host of the master brick
53+
const std::string _host;
54+
55+
/// The port of the master brick
56+
const uint16_t _port;
57+
58+
/// The uid of the led strip bricklet
59+
const std::string _uid;
60+
61+
/// The interval/rate
62+
const unsigned _interval;
63+
64+
/// ip connection handle
65+
IPConnection *_ipConnection;
66+
67+
/// led strip handle
68+
LEDStrip *_ledStrip;
69+
70+
/// buffer for red channel led data
71+
std::vector<uint8_t> _redChannel;
72+
73+
/// buffer for red channel led data
74+
std::vector<uint8_t> _greenChannel;
75+
76+
/// buffer for red channel led data
77+
std::vector<uint8_t> _blueChannel;
78+
79+
/// buffer size of the color channels
80+
unsigned int _colorChannelSize;
81+
82+
};

0 commit comments

Comments
 (0)