mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Merge branch 'master' into add_v4l
Former-commit-id: 47ecb30270511ff7ce5acec48c4042dc1b13850c
This commit is contained in:
commit
1981f6e307
@ -348,10 +348,12 @@
|
||||
],
|
||||
|
||||
/// The black border configuration, contains the following items:
|
||||
/// * enable : true if the detector should be activated
|
||||
/// * enable : true if the detector should be activated
|
||||
/// * threshold : Value below which a pixel is regarded as black (value between 0.0 and 1.0)
|
||||
"blackborderdetector" :
|
||||
{
|
||||
"enable" : true
|
||||
"enable" : true,
|
||||
"threshold" : 0.01
|
||||
},
|
||||
|
||||
/// The configuration of the effect engine, contains the following items:
|
||||
|
@ -13,9 +13,9 @@
|
||||
"device" :
|
||||
{
|
||||
"name" : "MyPi",
|
||||
"type" : "test",
|
||||
"output" : "~/hyperion.test.out",
|
||||
"rate" : 250000,
|
||||
"type" : "adalight",
|
||||
"output" : "/dev/ttyUSB0",
|
||||
"rate" : 115200,
|
||||
"colorOrder" : "rgb"
|
||||
},
|
||||
|
||||
@ -348,10 +348,12 @@
|
||||
],
|
||||
|
||||
/// The black border configuration, contains the following items:
|
||||
/// * enable : true if the detector should be activated
|
||||
/// * enable : true if the detector should be activated
|
||||
/// * threshold : Value below which a pixel is regarded as black (value between 0.0 and 1.0)
|
||||
"blackborderdetector" :
|
||||
{
|
||||
"enable" : true
|
||||
"enable" : true,
|
||||
"threshold" : 0.01
|
||||
},
|
||||
|
||||
/// The configuration of the effect engine, contains the following items:
|
||||
@ -371,6 +373,38 @@
|
||||
"duration_ms" : 3000
|
||||
},
|
||||
|
||||
/// The configuration for the frame-grabber, contains the following items:
|
||||
/// * width : The width of the grabbed frames [pixels]
|
||||
/// * height : The height of the grabbed frames [pixels]
|
||||
/// * frequency_Hz : The frequency of the frame grab [Hz]
|
||||
// "framegrabber" :
|
||||
// {
|
||||
// "width" : 64,
|
||||
// "height" : 64,
|
||||
// "frequency_Hz" : 10.0
|
||||
// },
|
||||
|
||||
/// The configuration of the XBMC connection used to enable and disable the frame-grabber. Contains the following fields:
|
||||
/// * xbmcAddress : The IP address of the XBMC-host
|
||||
/// * xbmcTcpPort : The TCP-port of the XBMC-server
|
||||
/// * grabVideo : Flag indicating that the frame-grabber is on(true) during video playback
|
||||
/// * grabPictures : Flag indicating that the frame-grabber is on(true) during picture show
|
||||
/// * grabAudio : Flag indicating that the frame-grabber is on(true) during audio playback
|
||||
/// * grabMenu : Flag indicating that the frame-grabber is on(true) in the XBMC menu
|
||||
/// * grabScreensaver : Flag indicating that the frame-grabber is on(true) when XBMC is on screensaver
|
||||
/// * enable3DDetection : Flag indicating that the frame-grabber should switch to a 3D compatible modus if a 3D video is playing
|
||||
// "xbmcVideoChecker" :
|
||||
// {
|
||||
// "xbmcAddress" : "127.0.0.1",
|
||||
// "xbmcTcpPort" : 9090,
|
||||
// "grabVideo" : true,
|
||||
// "grabPictures" : true,
|
||||
// "grabAudio" : true,
|
||||
// "grabMenu" : false,
|
||||
// "grabScreensaver" : true,
|
||||
// "enable3DDetection" : true
|
||||
// },
|
||||
|
||||
/// The configuration of the Json server which enables the json remote interface
|
||||
/// * port : Port at which the json server is started
|
||||
"jsonServer" :
|
||||
|
@ -1 +1 @@
|
||||
4d50c38a61c9f32a15b29ef3b3953c2835fa9cac
|
||||
5e8ca7ba33eb38d828b50971ec94b045025caa78
|
@ -1 +1 @@
|
||||
69287788649383ba7926e315debc69b7f4bd82a0
|
||||
2ad39031528c40c14e352cbc84784f48564cc59b
|
@ -48,8 +48,9 @@ namespace hyperion
|
||||
public:
|
||||
///
|
||||
/// Constructs a black-border detector
|
||||
/// @param[in] blackborderThreshold The threshold which the blackborder detector should use
|
||||
///
|
||||
BlackBorderDetector();
|
||||
BlackBorderDetector(uint8_t blackborderThreshold);
|
||||
|
||||
///
|
||||
/// Performs the actual black-border detection on the given image
|
||||
@ -125,7 +126,11 @@ namespace hyperion
|
||||
inline bool isBlack(const Pixel_T & color)
|
||||
{
|
||||
// Return the simple compare of the color against black
|
||||
return color.red < 3 && color.green < 3 && color.green < 3;
|
||||
return color.red < _blackborderThreshold && color.green < _blackborderThreshold && color.green < _blackborderThreshold;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Threshold for the blackborder detector [0 .. 255]
|
||||
const uint8_t _blackborderThreshold;
|
||||
};
|
||||
} // end namespace hyperion
|
||||
|
@ -21,11 +21,13 @@ namespace hyperion
|
||||
/// horizontal border becomes the current border
|
||||
/// @param blurRemoveCnt The size to add to a horizontal or vertical border (because the
|
||||
/// outer pixels is blurred (black and color combined due to image scaling))
|
||||
/// @param[in] blackborderThreshold The threshold which the blackborder detector should use
|
||||
///
|
||||
BlackBorderProcessor(
|
||||
const unsigned unknownFrameCnt,
|
||||
const unsigned borderFrameCnt,
|
||||
const unsigned blurRemoveCnt);
|
||||
const unsigned blurRemoveCnt,
|
||||
uint8_t blackborderThreshold);
|
||||
|
||||
///
|
||||
/// Return the current (detected) border
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
verifyBorder(image);
|
||||
|
||||
// Create a result vector and call the 'in place' functionl
|
||||
std::vector<ColorRgb> colors = mImageToLeds->getMeanLedColor(image);
|
||||
std::vector<ColorRgb> colors = _imageToLeds->getMeanLedColor(image);
|
||||
|
||||
// return the computed colors
|
||||
return colors;
|
||||
@ -75,7 +75,7 @@ public:
|
||||
verifyBorder(image);
|
||||
|
||||
// Determine the mean-colors of each led (using the existing mapping)
|
||||
mImageToLeds->getMeanLedColor(image, ledColors);
|
||||
_imageToLeds->getMeanLedColor(image, ledColors);
|
||||
}
|
||||
|
||||
///
|
||||
@ -98,8 +98,10 @@ private:
|
||||
/// given led-string specification
|
||||
///
|
||||
/// @param[in] ledString The led-string specification
|
||||
/// @param[in] enableBlackBorderDetector Flag indicating if the blacborder detector should be enabled
|
||||
/// @param[in] blackborderThreshold The threshold which the blackborder detector should use
|
||||
///
|
||||
ImageProcessor(const LedString &ledString, bool enableBlackBorderDetector);
|
||||
ImageProcessor(const LedString &ledString, bool enableBlackBorderDetector, uint8_t blackborderThreshold);
|
||||
|
||||
///
|
||||
/// Performs black-border detection (if enabled) on the given image
|
||||
@ -116,17 +118,17 @@ private:
|
||||
const hyperion::BlackBorder border = _borderProcessor->getCurrentBorder();
|
||||
|
||||
// Clean up the old mapping
|
||||
delete mImageToLeds;
|
||||
delete _imageToLeds;
|
||||
|
||||
if (border.unknown)
|
||||
{
|
||||
// Construct a new buffer and mapping
|
||||
mImageToLeds = new hyperion::ImageToLedsMap(image.width(), image.height(), 0, 0, mLedString.leds());
|
||||
_imageToLeds = new hyperion::ImageToLedsMap(image.width(), image.height(), 0, 0, _ledString.leds());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Construct a new buffer and mapping
|
||||
mImageToLeds = new hyperion::ImageToLedsMap(image.width(), image.height(), border.horizontalSize, border.verticalSize, mLedString.leds());
|
||||
_imageToLeds = new hyperion::ImageToLedsMap(image.width(), image.height(), border.horizontalSize, border.verticalSize, _ledString.leds());
|
||||
}
|
||||
|
||||
std::cout << "CURRENT BORDER TYPE: unknown=" << border.unknown << " hor.size=" << border.horizontalSize << " vert.size=" << border.verticalSize << std::endl;
|
||||
@ -135,14 +137,14 @@ private:
|
||||
|
||||
private:
|
||||
/// The Led-string specification
|
||||
const LedString mLedString;
|
||||
const LedString _ledString;
|
||||
|
||||
/// Flag the enables(true)/disabled(false) blackborder detector
|
||||
bool _enableBlackBorderRemoval;
|
||||
const bool _enableBlackBorderRemoval;
|
||||
|
||||
/// The processor for black border detection
|
||||
hyperion::BlackBorderProcessor * _borderProcessor;
|
||||
|
||||
/// The mapping of image-pixels to leds
|
||||
hyperion::ImageToLedsMap* mImageToLeds;
|
||||
hyperion::ImageToLedsMap* _imageToLeds;
|
||||
};
|
||||
|
@ -30,8 +30,10 @@ public:
|
||||
/// Initialises this factory with the given led-configuration
|
||||
///
|
||||
/// @param[in] ledString The led configuration
|
||||
/// @param[in] enableBlackBorderDetector Flag indicating if the blacborder detector should be enabled
|
||||
/// @param[in] blackborderThreshold The threshold which the blackborder detector should use
|
||||
///
|
||||
void init(const LedString& ledString, bool enableBlackBorderDetector);
|
||||
void init(const LedString& ledString, bool enableBlackBorderDetector, double blackborderThreshold);
|
||||
|
||||
///
|
||||
/// Creates a new ImageProcessor. The onwership of the processor is transferred to the caller.
|
||||
@ -46,4 +48,7 @@ private:
|
||||
|
||||
/// Flag indicating if the black border detector should be used
|
||||
bool _enableBlackBorderDetector;
|
||||
|
||||
/// Threshold for the blackborder detector [0 .. 255]
|
||||
uint8_t _blackborderThreshold;
|
||||
};
|
||||
|
@ -4,7 +4,8 @@
|
||||
|
||||
using namespace hyperion;
|
||||
|
||||
BlackBorderDetector::BlackBorderDetector()
|
||||
BlackBorderDetector::BlackBorderDetector(uint8_t blackborderThreshold) :
|
||||
_blackborderThreshold(blackborderThreshold)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
using namespace hyperion;
|
||||
|
||||
BlackBorderProcessor::BlackBorderProcessor(
|
||||
const unsigned unknownFrameCnt,
|
||||
BlackBorderProcessor::BlackBorderProcessor(const unsigned unknownFrameCnt,
|
||||
const unsigned borderFrameCnt,
|
||||
const unsigned blurRemoveCnt) :
|
||||
const unsigned blurRemoveCnt,
|
||||
uint8_t blackborderThreshold) :
|
||||
_unknownSwitchCnt(unknownFrameCnt),
|
||||
_borderSwitchCnt(borderFrameCnt),
|
||||
_blurRemoveCnt(blurRemoveCnt),
|
||||
_detector(),
|
||||
_detector(blackborderThreshold),
|
||||
_currentBorder({true, -1, -1}),
|
||||
_previousDetectedBorder({true, -1, -1}),
|
||||
_consistentCnt(0)
|
||||
|
@ -270,7 +270,10 @@ Hyperion::Hyperion(const Json::Value &jsonConfig) :
|
||||
throw std::runtime_error("Color transformation incorrectly set");
|
||||
}
|
||||
// initialize the image processor factory
|
||||
ImageProcessorFactory::getInstance().init(_ledString, jsonConfig["blackborderdetector"].get("enable", true).asBool());
|
||||
ImageProcessorFactory::getInstance().init(
|
||||
_ledString,
|
||||
jsonConfig["blackborderdetector"].get("enable", true).asBool(),
|
||||
jsonConfig["blackborderdetector"].get("threshold", 0.01).asDouble());
|
||||
|
||||
// initialize the color smoothing filter
|
||||
_device = createColorSmoothing(jsonConfig["color"]["smoothing"], _device);
|
||||
|
@ -6,46 +6,46 @@
|
||||
|
||||
using namespace hyperion;
|
||||
|
||||
ImageProcessor::ImageProcessor(const LedString& ledString, bool enableBlackBorderDetector) :
|
||||
mLedString(ledString),
|
||||
ImageProcessor::ImageProcessor(const LedString& ledString, bool enableBlackBorderDetector, uint8_t blackborderThreshold) :
|
||||
_ledString(ledString),
|
||||
_enableBlackBorderRemoval(enableBlackBorderDetector),
|
||||
_borderProcessor(new BlackBorderProcessor(600, 50, 1)),
|
||||
mImageToLeds(nullptr)
|
||||
_borderProcessor(new BlackBorderProcessor(600, 50, 1, blackborderThreshold)),
|
||||
_imageToLeds(nullptr)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
ImageProcessor::~ImageProcessor()
|
||||
{
|
||||
delete mImageToLeds;
|
||||
delete _imageToLeds;
|
||||
delete _borderProcessor;
|
||||
}
|
||||
|
||||
unsigned ImageProcessor::getLedCount() const
|
||||
{
|
||||
return mLedString.leds().size();
|
||||
return _ledString.leds().size();
|
||||
}
|
||||
|
||||
void ImageProcessor::setSize(const unsigned width, const unsigned height)
|
||||
{
|
||||
// Check if the existing buffer-image is already the correct dimensions
|
||||
if (mImageToLeds && mImageToLeds->width() == width && mImageToLeds->height() == height)
|
||||
if (_imageToLeds && _imageToLeds->width() == width && _imageToLeds->height() == height)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean up the old buffer and mapping
|
||||
delete mImageToLeds;
|
||||
delete _imageToLeds;
|
||||
|
||||
// Construct a new buffer and mapping
|
||||
mImageToLeds = new ImageToLedsMap(width, height, 0, 0, mLedString.leds());
|
||||
_imageToLeds = new ImageToLedsMap(width, height, 0, 0, _ledString.leds());
|
||||
}
|
||||
|
||||
bool ImageProcessor::getScanParameters(size_t led, double &hscanBegin, double &hscanEnd, double &vscanBegin, double &vscanEnd) const
|
||||
{
|
||||
if (led < mLedString.leds().size())
|
||||
if (led < _ledString.leds().size())
|
||||
{
|
||||
const Led & l = mLedString.leds()[led];
|
||||
const Led & l = _ledString.leds()[led];
|
||||
hscanBegin = l.minX_frac;
|
||||
hscanEnd = l.maxX_frac;
|
||||
vscanBegin = l.minY_frac;
|
||||
|
@ -10,13 +10,25 @@ ImageProcessorFactory& ImageProcessorFactory::getInstance()
|
||||
return instance;
|
||||
}
|
||||
|
||||
void ImageProcessorFactory::init(const LedString& ledString, bool enableBlackBorderDetector)
|
||||
void ImageProcessorFactory::init(const LedString& ledString, bool enableBlackBorderDetector, double blackborderThreshold)
|
||||
{
|
||||
_ledString = ledString;
|
||||
_enableBlackBorderDetector = enableBlackBorderDetector;
|
||||
|
||||
int threshold = int(std::ceil(blackborderThreshold * 255));
|
||||
if (threshold < 0)
|
||||
threshold = 0;
|
||||
else if (threshold > 255)
|
||||
threshold = 255;
|
||||
_blackborderThreshold = uint8_t(threshold);
|
||||
|
||||
if (_enableBlackBorderDetector)
|
||||
{
|
||||
std::cout << "Black border threshold set to " << blackborderThreshold << " (" << int(_blackborderThreshold) << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
ImageProcessor* ImageProcessorFactory::newImageProcessor() const
|
||||
{
|
||||
return new ImageProcessor(_ledString, _enableBlackBorderDetector);
|
||||
return new ImageProcessor(_ledString, _enableBlackBorderDetector, _blackborderThreshold);
|
||||
}
|
||||
|
@ -223,6 +223,12 @@
|
||||
"enable" : {
|
||||
"type" : "boolean",
|
||||
"required" : true
|
||||
},
|
||||
"threshold" : {
|
||||
"type" : "number",
|
||||
"required" : false,
|
||||
"minimum" : 0.0,
|
||||
"maximum" : 1.0
|
||||
}
|
||||
},
|
||||
"additionalProperties" : false
|
||||
|
@ -54,6 +54,7 @@ if(ENABLE_SPIDEV)
|
||||
${CURRENT_SOURCE_DIR}/LedSpiDevice.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceP9813.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
|
||||
)
|
||||
SET(Leddevice_SOURCES
|
||||
@ -61,6 +62,7 @@ if(ENABLE_SPIDEV)
|
||||
${CURRENT_SOURCE_DIR}/LedSpiDevice.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceP9813.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
|
||||
)
|
||||
endif(ENABLE_SPIDEV)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifdef ENABLE_SPIDEV
|
||||
#include "LedDeviceLpd6803.h"
|
||||
#include "LedDeviceLpd8806.h"
|
||||
#include "LedDeviceP9813.h"
|
||||
#include "LedDeviceWs2801.h"
|
||||
#endif
|
||||
|
||||
@ -62,6 +63,16 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
|
||||
|
||||
device = deviceLpd8806;
|
||||
}
|
||||
else if (type == "p9813")
|
||||
{
|
||||
const std::string output = deviceConfig["output"].asString();
|
||||
const unsigned rate = deviceConfig["rate"].asInt();
|
||||
|
||||
LedDeviceP9813* deviceP9813 = new LedDeviceP9813(output, rate);
|
||||
deviceP9813->open();
|
||||
|
||||
device = deviceP9813;
|
||||
}
|
||||
else if (type == "ws2801" || type == "lightberry")
|
||||
{
|
||||
const std::string output = deviceConfig["output"].asString();
|
||||
|
56
libsrc/leddevice/LedDeviceP9813.cpp
Normal file
56
libsrc/leddevice/LedDeviceP9813.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
// STL includes
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
// Linux includes
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
// hyperion local includes
|
||||
#include "LedDeviceP9813.h"
|
||||
|
||||
LedDeviceP9813::LedDeviceP9813(const std::string& outputDevice, const unsigned baudrate) :
|
||||
LedSpiDevice(outputDevice, baudrate, 0),
|
||||
_ledCount(0)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
int LedDeviceP9813::write(const std::vector<ColorRgb> &ledValues)
|
||||
{
|
||||
if (_ledCount != ledValues.size())
|
||||
{
|
||||
_ledBuf.resize(ledValues.size() * 4 + 8, 0x00);
|
||||
_ledCount = ledValues.size();
|
||||
}
|
||||
|
||||
uint8_t * dataPtr = _ledBuf.data();
|
||||
for (const ColorRgb & color : ledValues)
|
||||
{
|
||||
*dataPtr++ = calculateChecksum(color);
|
||||
*dataPtr++ = color.blue;
|
||||
*dataPtr++ = color.green;
|
||||
*dataPtr++ = color.red;
|
||||
}
|
||||
|
||||
return writeBytes(_ledBuf.size(), _ledBuf.data());
|
||||
}
|
||||
|
||||
int LedDeviceP9813::switchOff()
|
||||
{
|
||||
return write(std::vector<ColorRgb>(_ledCount, ColorRgb{0,0,0}));
|
||||
}
|
||||
|
||||
uint8_t LedDeviceP9813::calculateChecksum(const ColorRgb & color) const
|
||||
{
|
||||
uint8_t res = 0;
|
||||
|
||||
res |= (uint8_t)0x03 << 6;
|
||||
res |= (uint8_t)(~(color.blue >> 6) & 0x03) << 4;
|
||||
res |= (uint8_t)(~(color.green >> 6) & 0x03) << 2;
|
||||
res |= (uint8_t)(~(color.red >> 6) & 0x03);
|
||||
|
||||
return res;
|
||||
}
|
50
libsrc/leddevice/LedDeviceP9813.h
Normal file
50
libsrc/leddevice/LedDeviceP9813.h
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
// STL includes
|
||||
#include <string>
|
||||
|
||||
// hyperion include
|
||||
#include "LedSpiDevice.h"
|
||||
|
||||
///
|
||||
/// Implementation of the LedDevice interface for writing to P9813 led device.
|
||||
///
|
||||
class LedDeviceP9813 : public LedSpiDevice
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs the LedDevice for a string containing leds of the type P9813
|
||||
///
|
||||
/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
|
||||
/// @param baudrate The used baudrate for writing to the output device
|
||||
///
|
||||
LedDeviceP9813(const std::string& outputDevice,
|
||||
const unsigned baudrate);
|
||||
|
||||
///
|
||||
/// Writes the led color values to the led-device
|
||||
///
|
||||
/// @param ledValues The color-value per led
|
||||
/// @return Zero on succes else negative
|
||||
///
|
||||
virtual int write(const std::vector<ColorRgb> &ledValues);
|
||||
|
||||
/// Switch the leds off
|
||||
virtual int switchOff();
|
||||
|
||||
private:
|
||||
|
||||
/// the number of leds
|
||||
size_t _ledCount;
|
||||
|
||||
/// Buffer for writing/written led data
|
||||
std::vector<uint8_t> _ledBuf;
|
||||
|
||||
///
|
||||
/// Calculates the required checksum for one led
|
||||
///
|
||||
/// @param color The color of the led
|
||||
/// @return The checksum for the led
|
||||
///
|
||||
uint8_t calculateChecksum(const ColorRgb & color) const;
|
||||
};
|
@ -70,5 +70,6 @@ if(NOT APPLE AND UNIX)
|
||||
include_directories(/usr/include)
|
||||
add_executable(test_uartHighSpeed TestUartHighSpeed.cpp)
|
||||
|
||||
add_executable(test_nonInvWs2812b TestNonInvWs2812b.cpp)
|
||||
add_executable(test_nonUniformWs2812b TestNonUniformWs2812b.cpp)
|
||||
add_executable(test_nonInvWs2812b TestNonInvWs2812b.cpp)
|
||||
endif()
|
||||
|
@ -41,7 +41,7 @@ int TC_NO_BORDER()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
BlackBorderDetector detector;
|
||||
BlackBorderDetector detector(3);
|
||||
|
||||
{
|
||||
Image<ColorRgb> image = createImage(64, 64, 0, 0);
|
||||
@ -60,7 +60,7 @@ int TC_TOP_BORDER()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
BlackBorderDetector detector;
|
||||
BlackBorderDetector detector(3);
|
||||
|
||||
{
|
||||
Image<ColorRgb> image = createImage(64, 64, 12, 0);
|
||||
@ -79,7 +79,7 @@ int TC_LEFT_BORDER()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
BlackBorderDetector detector;
|
||||
BlackBorderDetector detector(3);
|
||||
|
||||
{
|
||||
Image<ColorRgb> image = createImage(64, 64, 0, 12);
|
||||
@ -98,7 +98,7 @@ int TC_DUAL_BORDER()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
BlackBorderDetector detector;
|
||||
BlackBorderDetector detector(3);
|
||||
|
||||
{
|
||||
Image<ColorRgb> image = createImage(64, 64, 12, 12);
|
||||
@ -116,7 +116,7 @@ int TC_UNKNOWN_BORDER()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
BlackBorderDetector detector;
|
||||
BlackBorderDetector detector(3);
|
||||
|
||||
{
|
||||
Image<ColorRgb> image = createImage(64, 64, 30, 30);
|
||||
|
@ -48,7 +48,7 @@ int main()
|
||||
unsigned borderCnt = 50;
|
||||
unsigned blurCnt = 0;
|
||||
|
||||
BlackBorderProcessor processor(unknownCnt, borderCnt, blurCnt);
|
||||
BlackBorderProcessor processor(unknownCnt, borderCnt, blurCnt, 3);
|
||||
|
||||
// Start with 'no border' detection
|
||||
Image<ColorRgb> noBorderImage = createImage(64, 64, 0, 0);
|
||||
|
@ -4,6 +4,11 @@
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include <unistd.h> //Used for UART
|
||||
#include <fcntl.h> //Used for UART
|
||||
#include <termios.h> //Used for UART
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
std::vector<uint8_t> encode(const std::vector<uint8_t> & data);
|
||||
void split(const uint8_t byte, uint8_t & out1, uint8_t & out2);
|
||||
uint8_t encode(const bool bit1, const bool bit2, const bool bit3);
|
||||
@ -23,10 +28,41 @@ void print(uint8_t byte)
|
||||
}
|
||||
}
|
||||
|
||||
void printClockSignal(const std::vector<uint8_t> & signal)
|
||||
{
|
||||
bool prevBit = true;
|
||||
bool nextBit = true;
|
||||
|
||||
for (uint8_t byte : signal)
|
||||
{
|
||||
|
||||
for (int i=-1; i<9; ++i)
|
||||
{
|
||||
if (i == -1) // Start bit
|
||||
nextBit = false;
|
||||
else if (i == 8) // Stop bit
|
||||
nextBit = true;
|
||||
else
|
||||
nextBit = byte & (1 << i);
|
||||
|
||||
if (!prevBit && nextBit)
|
||||
{
|
||||
std::cout << ' ';
|
||||
}
|
||||
|
||||
if (nextBit)
|
||||
std::cout << '1';
|
||||
else
|
||||
std::cout << '0';
|
||||
|
||||
prevBit = nextBit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<uint8_t> data(3, 0x55);
|
||||
|
||||
const std::vector<uint8_t> data(9, 0xff);
|
||||
std::vector<uint8_t> encData = encode(data);
|
||||
|
||||
for (uint8_t encByte : encData)
|
||||
@ -36,7 +72,45 @@ int main()
|
||||
std::cout << " 1";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
printClockSignal(encData);
|
||||
std::cout << std::endl;
|
||||
|
||||
//OPEN THE UART
|
||||
// int uart0_filestream = open("/dev/ttyAMA0", O_WRONLY | O_NOCTTY | O_NDELAY);
|
||||
int uart0_filestream = open("/dev/ttyUSB0", O_WRONLY | O_NOCTTY | O_NDELAY);
|
||||
if (uart0_filestream == -1)
|
||||
{
|
||||
//ERROR - CAN'T OPEN SERIAL PORT
|
||||
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Configure the port
|
||||
struct termios options;
|
||||
tcgetattr(uart0_filestream, &options);
|
||||
options.c_cflag = B4000000 | CS8 | CLOCAL;
|
||||
options.c_iflag = IGNPAR;
|
||||
options.c_oflag = 0;
|
||||
options.c_lflag = 0;
|
||||
|
||||
tcflush(uart0_filestream, TCIFLUSH);
|
||||
tcsetattr(uart0_filestream, TCSANOW, &options);
|
||||
|
||||
char c = getchar();
|
||||
|
||||
const int breakLength_ms = 1;
|
||||
|
||||
encData = std::vector<uint8_t>(128, 0x10);
|
||||
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
|
||||
tcsendbreak(uart0_filestream, breakLength_ms);
|
||||
|
||||
//tcdrain(uart0_filestream);
|
||||
// res = write(uart0_filestream, encData.data(), encData.size());
|
||||
// (void)res;
|
||||
|
||||
close(uart0_filestream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -96,19 +170,16 @@ std::vector<uint8_t> encode(const std::vector<uint8_t> & data)
|
||||
previousByte = nextByte;
|
||||
}
|
||||
|
||||
result.push_back(previousByte);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void split(const uint8_t byte, uint8_t & out1, uint8_t & out2)
|
||||
{
|
||||
print(byte); std::cout << " => ";
|
||||
print(out2); std::cout << " => ";
|
||||
out1 &= ~0x0F;
|
||||
out1 |= (byte & 0x0F) << 4;
|
||||
// out2 &= ~0xF0;
|
||||
print(out2); std::cout << " => ";
|
||||
out2 = (byte & 0xF0) >> 4;
|
||||
print(out2); std::cout << std::endl;
|
||||
}
|
||||
|
||||
uint8_t encode(const bool bit1, const bool bit2, const bool bit3)
|
||||
|
186
test/TestNonUniformWs2812b.cpp
Normal file
186
test/TestNonUniformWs2812b.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
|
||||
// STL includes
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include <unistd.h> //Used for UART
|
||||
#include <fcntl.h> //Used for UART
|
||||
#include <termios.h> //Used for UART
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
std::vector<uint8_t> encode(const std::vector<uint8_t> & data);
|
||||
uint8_t encode(const bool bit1, const bool bit2, const bool bit3);
|
||||
|
||||
void printClockSignal(const std::vector<uint8_t> & signal)
|
||||
{
|
||||
bool prevBit = true;
|
||||
bool nextBit = true;
|
||||
|
||||
for (uint8_t byte : signal)
|
||||
{
|
||||
|
||||
for (int i=-1; i<9; ++i)
|
||||
{
|
||||
if (i == -1) // Start bit
|
||||
nextBit = true;
|
||||
else if (i == 8) // Stop bit
|
||||
nextBit = false;
|
||||
else
|
||||
nextBit = ~byte & (1 << i);
|
||||
|
||||
if (!prevBit && nextBit)
|
||||
{
|
||||
std::cout << ' ';
|
||||
}
|
||||
|
||||
if (nextBit)
|
||||
std::cout << '1';
|
||||
else
|
||||
std::cout << '0';
|
||||
|
||||
prevBit = nextBit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
const std::vector<uint8_t> white{0xff, 0xff, 0xff};
|
||||
const std::vector<uint8_t> green{0xff, 0x00, 0x00};
|
||||
const std::vector<uint8_t> red {0x00, 0xff, 0x00};
|
||||
const std::vector<uint8_t> blue {0x00, 0x00, 0xff};
|
||||
const std::vector<uint8_t> cyan {0xff, 0x00, 0xff};
|
||||
const std::vector<uint8_t> mix {0x55, 0x55, 0x55};
|
||||
const std::vector<uint8_t> black{0x00, 0x00, 0x00};
|
||||
const std::vector<uint8_t> gray{0x01, 0x01, 0x01};
|
||||
|
||||
// printClockSignal(encode(mix));std::cout << std::endl;
|
||||
|
||||
//OPEN THE UART
|
||||
// int uart0_filestream = open("/dev/ttyAMA0", O_WRONLY | O_NOCTTY | O_NDELAY);
|
||||
int uart0_filestream = open("/dev/ttyUSB0", O_WRONLY | O_NOCTTY | O_NDELAY);
|
||||
if (uart0_filestream == -1)
|
||||
{
|
||||
//ERROR - CAN'T OPEN SERIAL PORT
|
||||
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Configure the port
|
||||
struct termios options;
|
||||
tcgetattr(uart0_filestream, &options);
|
||||
options.c_cflag = B2500000 | CS8 | CLOCAL;
|
||||
options.c_iflag = IGNPAR;
|
||||
options.c_oflag = 0;
|
||||
options.c_lflag = 0;
|
||||
|
||||
tcflush(uart0_filestream, TCIFLUSH);
|
||||
tcsetattr(uart0_filestream, TCSANOW, &options);
|
||||
|
||||
{
|
||||
getchar();
|
||||
const std::vector<uint8_t> encGreenData = encode(green);
|
||||
const std::vector<uint8_t> encBlueData = encode(blue);
|
||||
const std::vector<uint8_t> encRedData = encode(red);
|
||||
const std::vector<uint8_t> encGrayData = encode(gray);
|
||||
const std::vector<uint8_t> encBlackData = encode(black);
|
||||
|
||||
//std::cout << "Writing GREEN ("; printClockSignal(encode(green)); std::cout << ")" << std::endl;
|
||||
const std::vector<uint8_t> garbage {0x0f};
|
||||
write(uart0_filestream, garbage.data(), garbage.size());
|
||||
write(uart0_filestream, encGreenData.data(), encGreenData.size());
|
||||
write(uart0_filestream, encRedData.data(), encRedData.size());
|
||||
write(uart0_filestream, encBlueData.data(), encBlueData.size());
|
||||
write(uart0_filestream, encGrayData.data(), encGrayData.size());
|
||||
write(uart0_filestream, encBlackData.data(), encBlackData.size());
|
||||
}
|
||||
{
|
||||
getchar();
|
||||
const std::vector<uint8_t> encData = encode(white);
|
||||
std::cout << "Writing WHITE ("; printClockSignal(encode(white)); std::cout << ")" << std::endl;
|
||||
const std::vector<uint8_t> garbage {0x0f};
|
||||
write(uart0_filestream, garbage.data(), garbage.size());
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
}
|
||||
{
|
||||
getchar();
|
||||
const std::vector<uint8_t> encData = encode(green);
|
||||
std::cout << "Writing GREEN ("; printClockSignal(encode(green)); std::cout << ")" << std::endl;
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
}
|
||||
{
|
||||
getchar();
|
||||
const std::vector<uint8_t> encData = encode(red);
|
||||
std::cout << "Writing RED ("; printClockSignal(encode(red)); std::cout << ")" << std::endl;
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
}
|
||||
{
|
||||
getchar();
|
||||
const std::vector<uint8_t> encData = encode(blue);
|
||||
std::cout << "Writing BLUE ("; printClockSignal(encode(blue)); std::cout << ")" << std::endl;
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
}
|
||||
{
|
||||
getchar();
|
||||
const std::vector<uint8_t> encData = encode(cyan);
|
||||
std::cout << "Writing CYAN? ("; printClockSignal(encode(cyan)); std::cout << ")" << std::endl;
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
}
|
||||
{
|
||||
getchar();
|
||||
const std::vector<uint8_t> encData = encode(mix);
|
||||
std::cout << "Writing MIX ("; printClockSignal(encode(mix)); std::cout << ")" << std::endl;
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
}
|
||||
{
|
||||
getchar();
|
||||
const std::vector<uint8_t> encData = encode(black);
|
||||
std::cout << "Writing BLACK ("; printClockSignal(encode(black)); std::cout << ")" << std::endl;
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
write(uart0_filestream, encData.data(), encData.size());
|
||||
}
|
||||
|
||||
close(uart0_filestream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> encode(const std::vector<uint8_t> & data)
|
||||
{
|
||||
std::vector<uint8_t> result;
|
||||
for (size_t iByte=0; iByte<data.size(); iByte+=3)
|
||||
{
|
||||
const uint8_t byte1 = data[iByte];
|
||||
const uint8_t byte2 = data[iByte+1];
|
||||
const uint8_t byte3 = data[iByte+2];
|
||||
|
||||
result.push_back(encode(byte1 & 0x80, byte1 & 0x40, byte1 & 0x20));
|
||||
result.push_back(encode(byte1 & 0x10, byte1 & 0x08, byte1 & 0x04));
|
||||
result.push_back(encode(byte1 & 0x02, byte1 & 0x01, byte2 & 0x80));
|
||||
result.push_back(encode(byte2 & 0x40, byte2 & 0x20, byte2 & 0x10));
|
||||
result.push_back(encode(byte2 & 0x08, byte2 & 0x04, byte2 & 0x02));
|
||||
result.push_back(encode(byte2 & 0x01, byte3 & 0x80, byte3 & 0x40));
|
||||
result.push_back(encode(byte3 & 0x20, byte3 & 0x10, byte3 & 0x08));
|
||||
result.push_back(encode(byte3 & 0x04, byte3 & 0x02, byte3 & 0x01));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t encode(const bool bit1, const bool bit2, const bool bit3)
|
||||
{
|
||||
uint8_t result = 0x44; // 0100 0100
|
||||
|
||||
if (bit1)
|
||||
result |= 0x01; // 0000 0001
|
||||
|
||||
if (bit2)
|
||||
result |= 0x18; // 0001 1000
|
||||
|
||||
if (bit3)
|
||||
result |= 0x80; // 1000 0000
|
||||
|
||||
return ~result;
|
||||
}
|
@ -261,7 +261,8 @@ uint8_t bit3Encode(const bool bit_1, const bool bit_2, const bool bit_3);
|
||||
void test3bitsEncoding()
|
||||
{
|
||||
//OPEN THE UART
|
||||
int uart0_filestream = open("/dev/ttyAMA0", O_WRONLY | O_NOCTTY | O_NDELAY);
|
||||
// int uart0_filestream = open("/dev/ttyAMA0", O_WRONLY | O_NOCTTY | O_NDELAY);
|
||||
int uart0_filestream = open("/dev/ttyUSB0", O_WRONLY | O_NOCTTY | O_NDELAY);
|
||||
if (uart0_filestream == -1)
|
||||
{
|
||||
//ERROR - CAN'T OPEN SERIAL PORT
|
||||
|
Loading…
Reference in New Issue
Block a user