mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Merge remote-tracking branch 'upstream/master' into proto_json_forwarder
Former-commit-id: 6eb800d3ed5badd831bd79fc8cfb66115df8ec28
This commit is contained in:
commit
e667be5e0b
@ -6,8 +6,8 @@ SET(CMAKE_SYSTEM_VERSION 1)
|
||||
# specify the cross compiler
|
||||
SET(CMAKE_C_COMPILER ${CUBIXCROSS_DIR}/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/arm-linux-gnueabihf-gcc)
|
||||
SET(CMAKE_CXX_COMPILER ${CUBIXCROSS_DIR}/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/arm-linux-gnueabihf-g++)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard")
|
||||
|
||||
# where is the target environment
|
||||
SET(CMAKE_FIND_ROOT_PATH ${CUBIXCROSS_DIR}/rootfs)
|
||||
|
@ -28,6 +28,7 @@ tar --create --verbose --gzip --absolute-names --show-transformed-names --ignore
|
||||
"$builddir/bin/hyperiond" \
|
||||
"$builddir/bin/hyperion-remote" \
|
||||
"$builddir/bin/hyperion-v4l2" \
|
||||
"$builddir/bin/gpio2spi" \
|
||||
"$builddir/bin/dispmanx2png" \
|
||||
"$repodir/effects/"* \
|
||||
"$repodir/bin/hyperion.init.sh" \
|
||||
|
@ -40,7 +40,7 @@ if [ $IS_OPENELEC -eq 1 ]; then
|
||||
if [ $IS_IMX6 -eq 1 ]; then
|
||||
curl -L --get https://raw.githubusercontent.com/tvdzwan/hyperion/master/deploy/hyperion_imx6.tar.gz | tar -C /storage -xz
|
||||
else
|
||||
curl -L --get https://raw.githubusercontent.com/tvdzwan/hyperion/master/deploy/hyperion.tar.gz | tar -C /storage -xz
|
||||
curl -L --get https://raw.githubusercontent.com/tvdzwan/hyperion/master/deploy/hyperion_rpi.tar.gz | tar -C /storage -xz
|
||||
fi
|
||||
curl -L --get https://raw.githubusercontent.com/tvdzwan/hyperion/master/deploy/hyperion.deps.openelec-rpi.tar.gz | tar -C /storage/hyperion/bin -xz
|
||||
# modify the default config to have a correct effect path
|
||||
@ -49,7 +49,7 @@ else
|
||||
if [ $IS_IMX6 -eq 1 ]; then
|
||||
wget https://raw.githubusercontent.com/tvdzwan/hyperion/master/deploy/hyperion_imx6.tar.gz -O - | tar -C /opt -xz
|
||||
else
|
||||
wget https://raw.githubusercontent.com/tvdzwan/hyperion/master/deploy/hyperion.tar.gz -O - | tar -C /opt -xz
|
||||
wget https://raw.githubusercontent.com/tvdzwan/hyperion/master/deploy/hyperion_rpi.tar.gz -O - | tar -C /opt -xz
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -1 +1 @@
|
||||
471d676fb66aa53e3b10d887a1d9e6d3b4afea90
|
||||
44d552b5adb3dc5af38edd5e6fb208a0dc75d63d
|
@ -1 +0,0 @@
|
||||
d6c2a97271d37ffb04fa2e1e9ce7812d5b132811
|
@ -1 +1 @@
|
||||
d2bf44cca4e7753b53acc2ebbdb933ba8f74f93f
|
||||
7f0d60e7e0c7075cae5cef69ec5408f3087c00df
|
@ -1 +1 @@
|
||||
7936b39302bec31b18f11a321ba6904c12b5c3ec
|
||||
511ab205cce688c5d7151087d8659905402e5015
|
@ -1 +1 @@
|
||||
774c67bd8e4e46d2ebf9c223a38fdfd93cae1100
|
||||
e26ac1a0bf52bcd54ab00c37ff25d01a457eec9d
|
57
doc/UDP_led_driver.txt
Normal file
57
doc/UDP_led_driver.txt
Normal file
@ -0,0 +1,57 @@
|
||||
BACKGROUND
|
||||
---------------------------------------------------------
|
||||
The UDP led device type can be used to send LED data over UDP packets.
|
||||
It was originally designed to support an ESP8266 Wifi module based WS2812
|
||||
LED strip controller.
|
||||
|
||||
I've used this to support :
|
||||
- A string of 600 LEDs as xmas decorations
|
||||
The effects development kit is great for these scenarios
|
||||
|
||||
- a 61 LED collection of concentric circles
|
||||
This has been used as a "night light" and a super lo-res
|
||||
TV
|
||||
|
||||
In each of these cases, the hyperion-remote iOS app is a great way to
|
||||
control the effects.
|
||||
|
||||
|
||||
CONFIG
|
||||
---------------------------------------------------------
|
||||
Simple example for devices that support a raw binary protocol.
|
||||
"device" :
|
||||
{
|
||||
"name" : "MyPi",
|
||||
"type" : "udp",
|
||||
"output" : "esp201-0.home:2391", "protocol" : 0,
|
||||
"rate" : 1000000,
|
||||
"colorOrder" : "grb"
|
||||
},
|
||||
|
||||
|
||||
|
||||
If you are using an ESP8266/Arduino device with a long LED strip, you chould use this alternate protocol.
|
||||
The ESP8266/Arduino doesnt support datagram re-assembly so will never see any udp packets greater than 1450.
|
||||
"device" :
|
||||
{
|
||||
"name" : "MyPi",
|
||||
"type" : "udp",
|
||||
// "output" : "esp201-0.home:2392", "protocol" : 2, "maxpacket" : 1450,
|
||||
"rate" : 1000000,
|
||||
"colorOrder" : "rgb"
|
||||
},
|
||||
|
||||
PROTOCOL
|
||||
---------------------------------------------------------
|
||||
Simple UDP packets are sent.
|
||||
|
||||
Packet Format protocol 0:
|
||||
3 bytes per LED as R, G, B
|
||||
|
||||
Packet Format protocol 2:
|
||||
0: update number & 0xf;
|
||||
1: fragment of this update
|
||||
2: 1st led# of this update - high byte
|
||||
3: 1st led# of this update - low byte
|
||||
4..n 3 bytes per LED as R, G, B
|
||||
|
8
effects/udp.json
Normal file
8
effects/udp.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"name" : "UDP listener",
|
||||
"script" : "udp.py",
|
||||
"args" :
|
||||
{
|
||||
"udpPort" : 2391
|
||||
}
|
||||
}
|
47
effects/udp.py
Normal file
47
effects/udp.py
Normal file
@ -0,0 +1,47 @@
|
||||
import hyperion
|
||||
import time
|
||||
import colorsys
|
||||
import socket
|
||||
import errno
|
||||
|
||||
# Get the parameters
|
||||
udpPort = int(hyperion.args.get('udpPort', 2812))
|
||||
|
||||
UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
UDPSock.setblocking(False)
|
||||
|
||||
listen_addr = ("",udpPort)
|
||||
print "udp.py: bind socket port:",udpPort
|
||||
UDPSock.bind(listen_addr)
|
||||
|
||||
hyperion.setColor(hyperion.ledCount * bytearray((int(0), int(0), int(0))) )
|
||||
|
||||
# Start the write data loop
|
||||
while not hyperion.abort():
|
||||
try:
|
||||
data,addr = UDPSock.recvfrom(4500)
|
||||
# print data.strip(),len(data),addr
|
||||
if (len(data)%3 == 0):
|
||||
# print "numleds ",len(data)/3
|
||||
ledData = bytearray()
|
||||
for i in range(hyperion.ledCount):
|
||||
if (i<(len(data)/3)):
|
||||
ledData += data[i*3+0]
|
||||
ledData += data[i*3+1]
|
||||
ledData += data[i*3+2]
|
||||
else:
|
||||
ledData += bytearray((int(0), int(0), int(0)))
|
||||
|
||||
hyperion.setColor(ledData)
|
||||
|
||||
else:
|
||||
print "not div 3"
|
||||
except IOError as e:
|
||||
if e.errno == errno.EWOULDBLOCK:
|
||||
pass
|
||||
else:
|
||||
print "errno:", e.errno
|
||||
|
||||
print "udp.py: closing socket"
|
||||
UDPSock.close()
|
||||
|
@ -1,3 +1,4 @@
|
||||
//#include <iostream>
|
||||
#pragma once
|
||||
|
||||
// Utils includes
|
||||
@ -82,10 +83,13 @@ namespace hyperion
|
||||
int firstNonBlackXPixelIndex = -1;
|
||||
int firstNonBlackYPixelIndex = -1;
|
||||
|
||||
width--; // remove 1 pixel to get end pixel index
|
||||
height--;
|
||||
|
||||
// find first X pixel of the image
|
||||
for (int x = 0; x < width33percent; ++x)
|
||||
{
|
||||
const Pixel_T & color1 = image( (width - 1 - x), yCenter); // right side center line check
|
||||
const Pixel_T & color1 = image( (width - x), yCenter); // right side center line check
|
||||
const Pixel_T & color2 = image(x, height33percent);
|
||||
const Pixel_T & color3 = image(x, height66percent);
|
||||
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
|
||||
@ -98,7 +102,7 @@ namespace hyperion
|
||||
// find first Y pixel of the image
|
||||
for (int y = 0; y < height33percent; ++y)
|
||||
{
|
||||
const Pixel_T & color1 = image(xCenter, (height - 1 - y)); // bottom center line check
|
||||
const Pixel_T & color1 = image(xCenter, (height - y)); // bottom center line check
|
||||
const Pixel_T & color2 = image(width33percent, y );
|
||||
const Pixel_T & color3 = image(width66percent, y);
|
||||
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
|
||||
@ -174,7 +178,8 @@ namespace hyperion
|
||||
}
|
||||
|
||||
|
||||
// osd detection mode (find x then y at detected x to avoid changes by osd overlays)
|
||||
///
|
||||
/// osd detection mode (find x then y at detected x to avoid changes by osd overlays)
|
||||
template <typename Pixel_T>
|
||||
BlackBorder process_osd(const Image<Pixel_T> & image)
|
||||
{
|
||||
@ -184,20 +189,21 @@ namespace hyperion
|
||||
int height = image.height();
|
||||
int width33percent = width / 3;
|
||||
int height33percent = height / 3;
|
||||
// int width66percent = width33percent * 2;
|
||||
int height66percent = height33percent * 2;
|
||||
// int xCenter = width / 2;
|
||||
int yCenter = height / 2;
|
||||
|
||||
|
||||
int firstNonBlackXPixelIndex = -1;
|
||||
int firstNonBlackYPixelIndex = -1;
|
||||
|
||||
width--; // remove 1 pixel to get end pixel index
|
||||
height--;
|
||||
|
||||
// find first X pixel of the image
|
||||
int x;
|
||||
for (x = 0; x < width33percent; ++x)
|
||||
{
|
||||
const Pixel_T & color1 = image( (width - 1 - x), yCenter); // right side center line check
|
||||
const Pixel_T & color1 = image( (width - x), yCenter); // right side center line check
|
||||
const Pixel_T & color2 = image(x, height33percent);
|
||||
const Pixel_T & color3 = image(x, height66percent);
|
||||
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
|
||||
@ -210,11 +216,13 @@ namespace hyperion
|
||||
// find first Y pixel of the image
|
||||
for (int y = 0; y < height33percent; ++y)
|
||||
{
|
||||
const Pixel_T & color1 = image(x, (height - 1 - y)); // left side bottom check
|
||||
const Pixel_T & color2 = image(x, y );// left side top check
|
||||
const Pixel_T & color3 = image( (width - 1 - x), y); // right side top check
|
||||
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
|
||||
const Pixel_T & color1 = image(x, y );// left side top check
|
||||
const Pixel_T & color2 = image(x, (height - y)); // left side bottom check
|
||||
const Pixel_T & color3 = image( (width - x), y); // right side top check
|
||||
const Pixel_T & color4 = image( (width - x), (height - y)); // right side bottom check
|
||||
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3) || !isBlack(color4))
|
||||
{
|
||||
// std::cout << "y " << y << " lt " << int(isBlack(color1)) << " lb " << int(isBlack(color2)) << " rt " << int(isBlack(color3)) << " rb " << int(isBlack(color4)) << std::endl;
|
||||
firstNonBlackYPixelIndex = y;
|
||||
break;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <iostream>
|
||||
// BlackBorders includes
|
||||
#include <blackborder/BlackBorderDetector.h>
|
||||
#include <cmath>
|
||||
|
||||
using namespace hyperion;
|
||||
|
||||
|
@ -1,12 +1,9 @@
|
||||
//*
|
||||
#include <iostream>
|
||||
/*
|
||||
#include <iomanip>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::setw;
|
||||
using std::left;
|
||||
//*/
|
||||
|
||||
// Blackborder includes
|
||||
#include <blackborder/BlackBorderProcessor.h>
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
|
||||
// STL includes
|
||||
#include <cmath>
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
|
@ -33,8 +33,9 @@ SET(Leddevice_HEADERS
|
||||
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.h
|
||||
${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceSedu.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceTest.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceTest.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceUdp.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceTpm2.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceAtmo.h
|
||||
@ -55,8 +56,9 @@ SET(Leddevice_SOURCES
|
||||
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceSedu.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceUdp.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceTpm2.cpp
|
||||
|
@ -1,7 +1,9 @@
|
||||
|
||||
// STL includes
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
// Linux includes
|
||||
#include <fcntl.h>
|
||||
@ -17,46 +19,27 @@ LedDeviceAPA102::LedDeviceAPA102(const std::string& outputDevice, const unsigned
|
||||
// empty
|
||||
}
|
||||
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
#define APA102_START_FRAME_BYTES 4
|
||||
#define APA102_LED_BYTES 4
|
||||
#define APA102_END_FRAME_BITS_MIN 32
|
||||
#define APA102_END_FRAME_BITS(leds) MAX((((leds-1)/2)+1),APA102_END_FRAME_BITS_MIN)
|
||||
#define APA102_END_FRAME_BYTES(leds) (((APA102_END_FRAME_BITS(leds)-1)/8)+1)
|
||||
#define APA102_LED_HEADER 0xe0
|
||||
#define APA102_LED_MAX_INTENSITY 0x1f
|
||||
|
||||
int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
|
||||
{
|
||||
const unsigned int startFrameSize = APA102_START_FRAME_BYTES;
|
||||
const unsigned int ledsCount = ledValues.size() ;
|
||||
const unsigned int ledsSize = ledsCount * APA102_LED_BYTES ;
|
||||
const unsigned int endFrameBits = APA102_END_FRAME_BITS(ledsCount) ;
|
||||
const unsigned int endFrameSize = APA102_END_FRAME_BYTES(ledsCount) ;
|
||||
const unsigned int transferSize = startFrameSize + ledsSize + endFrameSize ;
|
||||
|
||||
if(_ledBuffer.size() != transferSize){
|
||||
_ledBuffer.resize(transferSize, 0x00);
|
||||
const unsigned int startFrameSize = 4;
|
||||
const unsigned int endFrameSize = std::max<unsigned int>(((ledValues.size() + 15) / 16), 4);
|
||||
const unsigned int mLedCount = (ledValues.size() * 4) + startFrameSize + endFrameSize;
|
||||
if(_ledBuffer.size() != mLedCount){
|
||||
_ledBuffer.resize(mLedCount, 0xFF);
|
||||
_ledBuffer[0] = 0x00;
|
||||
_ledBuffer[1] = 0x00;
|
||||
_ledBuffer[2] = 0x00;
|
||||
_ledBuffer[3] = 0x00;
|
||||
}
|
||||
|
||||
unsigned idx = 0, i;
|
||||
for (i=0; i<APA102_START_FRAME_BYTES; i++) {
|
||||
_ledBuffer[idx++] = 0x00 ;
|
||||
|
||||
for (unsigned iLed=1; iLed<=ledValues.size(); ++iLed) {
|
||||
const ColorRgb& rgb = ledValues[iLed-1];
|
||||
_ledBuffer[iLed*4] = 0xFF;
|
||||
_ledBuffer[iLed*4+1] = rgb.red;
|
||||
_ledBuffer[iLed*4+2] = rgb.green;
|
||||
_ledBuffer[iLed*4+3] = rgb.blue;
|
||||
}
|
||||
|
||||
for (i=0; i<ledsCount; i++) {
|
||||
const ColorRgb& rgb = ledValues[i];
|
||||
|
||||
_ledBuffer[idx++] = APA102_LED_HEADER + APA102_LED_MAX_INTENSITY;
|
||||
_ledBuffer[idx++] = rgb.red;
|
||||
_ledBuffer[idx++] = rgb.green;
|
||||
_ledBuffer[idx++] = rgb.blue;
|
||||
}
|
||||
for(i=0; i<endFrameSize; i++)
|
||||
_ledBuffer[idx++] = 0x00 ;
|
||||
|
||||
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "LedDeviceSedu.h"
|
||||
#include "LedDeviceTest.h"
|
||||
#include "LedDeviceFadeCandy.h"
|
||||
#include "LedDeviceUdp.h"
|
||||
#include "LedDeviceHyperionUsbasp.h"
|
||||
#include "LedDevicePhilipsHue.h"
|
||||
#include "LedDeviceTpm2.h"
|
||||
@ -251,6 +252,14 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
|
||||
const uint16_t channel = deviceConfig.get("channel", 0).asInt();
|
||||
device = new LedDeviceFadeCandy(host, port, channel);
|
||||
}
|
||||
else if (type == "udp")
|
||||
{
|
||||
const std::string output = deviceConfig["output"].asString();
|
||||
const unsigned rate = deviceConfig["rate"].asInt();
|
||||
const unsigned protocol = deviceConfig["protocol"].asInt();
|
||||
const unsigned maxPacket = deviceConfig["maxpacket"].asInt();
|
||||
device = new LedDeviceUdp(output, rate, protocol, maxPacket);
|
||||
}
|
||||
else if (type == "tpm2")
|
||||
{
|
||||
const std::string output = deviceConfig["output"].asString();
|
||||
|
165
libsrc/leddevice/LedDeviceUdp.cpp
Normal file
165
libsrc/leddevice/LedDeviceUdp.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
|
||||
// Local-Hyperion includes
|
||||
#include "LedDeviceUdp.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <assert.h>
|
||||
|
||||
struct addrinfo hints, *servinfo, *p;
|
||||
//char udpbuffer[1024];
|
||||
int sockfd;
|
||||
int ledprotocol;
|
||||
int leds_per_pkt;
|
||||
int update_number;
|
||||
int fragment_number;
|
||||
|
||||
LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, const unsigned protocol, const unsigned maxPacket)
|
||||
//LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate) :
|
||||
// _ofs(output.empty()?"/home/pi/LedDevice.out":output.c_str())
|
||||
{
|
||||
|
||||
std::string hostname;
|
||||
std::string port;
|
||||
ledprotocol = protocol;
|
||||
leds_per_pkt = ((maxPacket-4)/3);
|
||||
if (leds_per_pkt <= 0) {
|
||||
leds_per_pkt = 200;
|
||||
}
|
||||
|
||||
//printf ("leds_per_pkt is %d\n", leds_per_pkt);
|
||||
int got_colon=0;
|
||||
for (unsigned int i=0; i<output.length(); i++) {
|
||||
if (output[i] == ':') {
|
||||
got_colon++;
|
||||
} else if (got_colon == 0) {
|
||||
hostname+=output[i];
|
||||
} else {
|
||||
port+=output[i];
|
||||
}
|
||||
}
|
||||
//std::cout << "output " << output << " hostname " << hostname << " port " << port <<std::endl;
|
||||
assert(got_colon==1);
|
||||
|
||||
int rv;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
||||
if ((rv = getaddrinfo(hostname.c_str() , port.c_str(), &hints, &servinfo)) != 0) {
|
||||
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
|
||||
assert(rv==0);
|
||||
}
|
||||
|
||||
// loop through all the results and make a socket
|
||||
for(p = servinfo; p != NULL; p = p->ai_next) {
|
||||
if ((sockfd = socket(p->ai_family, p->ai_socktype,
|
||||
p->ai_protocol)) == -1) {
|
||||
perror("talker: socket");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
fprintf(stderr, "talker: failed to create socket\n");
|
||||
assert(p!=NULL);
|
||||
}
|
||||
}
|
||||
|
||||
LedDeviceUdp::~LedDeviceUdp()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
int LedDeviceUdp::write(const std::vector<ColorRgb> & ledValues)
|
||||
{
|
||||
|
||||
char udpbuffer[4096];
|
||||
int udpPtr=0;
|
||||
|
||||
update_number++;
|
||||
update_number &= 0xf;
|
||||
|
||||
if (ledprotocol == 0) {
|
||||
int i=0;
|
||||
for (const ColorRgb& color : ledValues)
|
||||
{
|
||||
if (i<4090) {
|
||||
udpbuffer[i++] = color.red;
|
||||
udpbuffer[i++] = color.green;
|
||||
udpbuffer[i++] = color.blue;
|
||||
}
|
||||
//printf ("c.red %d sz c.red %d\n", color.red, sizeof(color.red));
|
||||
}
|
||||
sendto(sockfd, udpbuffer, i, 0, p->ai_addr, p->ai_addrlen);
|
||||
}
|
||||
if (ledprotocol == 1) {
|
||||
#define MAXLEDperFRAG 450
|
||||
int mLedCount = ledValues.size();
|
||||
|
||||
for (int frag=0; frag<4; frag++) {
|
||||
udpPtr=0;
|
||||
udpbuffer[udpPtr++] = 0;
|
||||
udpbuffer[udpPtr++] = 0;
|
||||
udpbuffer[udpPtr++] = (frag*MAXLEDperFRAG)/256; // high byte
|
||||
udpbuffer[udpPtr++] = (frag*MAXLEDperFRAG)%256; // low byte
|
||||
int ct=0;
|
||||
for (int this_led = frag*300; ((this_led<mLedCount) && (ct++<MAXLEDperFRAG)); this_led++) {
|
||||
const ColorRgb& color = ledValues[this_led];
|
||||
if (udpPtr<4090) {
|
||||
udpbuffer[udpPtr++] = color.red;
|
||||
udpbuffer[udpPtr++] = color.green;
|
||||
udpbuffer[udpPtr++] = color.blue;
|
||||
}
|
||||
}
|
||||
if (udpPtr > 7)
|
||||
sendto(sockfd, udpbuffer, udpPtr, 0, p->ai_addr, p->ai_addrlen);
|
||||
}
|
||||
}
|
||||
if (ledprotocol == 2) {
|
||||
udpPtr = 0;
|
||||
unsigned int ledCtr = 0;
|
||||
fragment_number = 0;
|
||||
udpbuffer[udpPtr++] = update_number & 0xf;
|
||||
udpbuffer[udpPtr++] = fragment_number++;
|
||||
udpbuffer[udpPtr++] = ledCtr/256; // high byte
|
||||
udpbuffer[udpPtr++] = ledCtr%256; // low byte
|
||||
|
||||
for (const ColorRgb& color : ledValues)
|
||||
{
|
||||
if (udpPtr<4090) {
|
||||
udpbuffer[udpPtr++] = color.red;
|
||||
udpbuffer[udpPtr++] = color.green;
|
||||
udpbuffer[udpPtr++] = color.blue;
|
||||
}
|
||||
ledCtr++;
|
||||
if ( (ledCtr % leds_per_pkt == 0) || (ledCtr == ledValues.size()) ) {
|
||||
sendto(sockfd, udpbuffer, udpPtr, 0, p->ai_addr, p->ai_addrlen);
|
||||
memset(udpbuffer, 0, sizeof udpbuffer);
|
||||
udpPtr = 0;
|
||||
udpbuffer[udpPtr++] = update_number & 0xf;
|
||||
udpbuffer[udpPtr++] = fragment_number++;
|
||||
udpbuffer[udpPtr++] = ledCtr/256; // high byte
|
||||
udpbuffer[udpPtr++] = ledCtr%256; // low byte
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LedDeviceUdp::switchOff()
|
||||
{
|
||||
// return write(std::vector<ColorRgb>(mLedCount, ColorRgb{0,0,0}));
|
||||
return 0;
|
||||
}
|
44
libsrc/leddevice/LedDeviceUdp.h
Normal file
44
libsrc/leddevice/LedDeviceUdp.h
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
// STL includes0
|
||||
#include <fstream>
|
||||
|
||||
// Leddevice includes
|
||||
#include <leddevice/LedDevice.h>
|
||||
|
||||
///
|
||||
/// Implementation of the LedDevice that write the led-colors to an
|
||||
/// ASCII-textfile('/home/pi/LedDevice.out')
|
||||
///
|
||||
class LedDeviceUdp : public LedDevice
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs the test-device, which opens an output stream to the file
|
||||
///
|
||||
LedDeviceUdp(const std::string& output, const unsigned baudrate, const unsigned protocol, const unsigned maxPacket);
|
||||
|
||||
///
|
||||
/// Destructor of this test-device
|
||||
///
|
||||
virtual ~LedDeviceUdp();
|
||||
|
||||
///
|
||||
/// Writes the given led-color values to the output stream
|
||||
///
|
||||
/// @param ledValues The color-value per led
|
||||
///
|
||||
/// @return Zero on success else negative
|
||||
///
|
||||
virtual int write(const std::vector<ColorRgb> & ledValues);
|
||||
|
||||
/// Switch the leds off
|
||||
virtual int switchOff();
|
||||
|
||||
private:
|
||||
/// The outputstream
|
||||
// std::ofstream _ofs;
|
||||
|
||||
/// the number of leds (needed when switching off)
|
||||
size_t mLedCount;
|
||||
};
|
Loading…
Reference in New Issue
Block a user