From deed8066b058fa8071c48f2114f4e4bdaf2ad88b Mon Sep 17 00:00:00 2001 From: penfold42 Date: Sat, 30 Apr 2016 00:00:33 +1000 Subject: [PATCH] Piblaster fix (#614) * Removed -HUP so the default -TERM signal is sent instead. - hyperiond only listens for TERM and INT. HUP is often used to get an exe to reread its config Changed pgrep to add '-x' so it wont partial match on the exe name. - I have multiple instances with multiple hyperiond-instance1 names - this ensures the service script only kills the right process * reversing errant change to hyperion.systemd.sh * Experimental changes to piblaster code to work how i think it should It is now assumed that the PWM pins in groups of 3 correspond to RGB channels of the led. "assignment" : "rgbrgbrgb", Would result in: //Channel number GPIO number Led channel // 0 4 0 red // 1 17 0 green // 2 18 0 blue // 4 27 1 red // 5 21 1 green // 6 22 1 blue // 7 23 2 red // 8 24 2 green // 9 25 2 blue * Ammend pwm channel mapping comments to match the code * 1st cut of the new more flexible piblaster pin mapping support it works but is still rough * removed old "assignment" handling - prints an error messaage if found and terminates fixed the switchoff method * removing iPins hard coded list of valid GPIO pins * removed iPins array for switchOff function * code cleanups input validation * Handle catching (and ignoring) SIGPIPE. You can now kill and restart pi-blaster daemon and hyperiond will gracefully recover * added a binary for testing * Added sample config and my modified pi-blaster version to support more GPIOs * moved hyperiond * removed testing binaries move sample configuration to the configs directory * re enabled device config display * removed sample configuration Former-commit-id: 95e4d4ea2fb7cb5439e8cd597883a638da61a574 --- libsrc/leddevice/LedDeviceFactory.cpp | 16 +++- libsrc/leddevice/LedDevicePiBlaster.cpp | 119 ++++++++++++++++-------- libsrc/leddevice/LedDevicePiBlaster.h | 12 ++- 3 files changed, 99 insertions(+), 48 deletions(-) diff --git a/libsrc/leddevice/LedDeviceFactory.cpp b/libsrc/leddevice/LedDeviceFactory.cpp index 43e715a5..6d737ec9 100755 --- a/libsrc/leddevice/LedDeviceFactory.cpp +++ b/libsrc/leddevice/LedDeviceFactory.cpp @@ -206,11 +206,21 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) { const std::string output = deviceConfig.get("output", "").asString(); const std::string assignment = deviceConfig.get("assignment", "").asString(); + const Json::Value gpioMapping = deviceConfig.get("gpiomap", Json::nullValue); - LedDevicePiBlaster * devicePiBlaster = new LedDevicePiBlaster(output, assignment); - devicePiBlaster->open(); + if (assignment.length() > 0) { + std::cout << "ERROR: Sorry, the configuration syntax has changed in this version." << std::endl; + exit(EXIT_FAILURE); + } + if (! gpioMapping.isNull() ) { + LedDevicePiBlaster * devicePiBlaster = new LedDevicePiBlaster(output, gpioMapping); + devicePiBlaster->open(); - device = devicePiBlaster; + device = devicePiBlaster; + } else { + std::cout << "ERROR: no gpiomap defined." << std::endl; + exit(EXIT_FAILURE); + } } else if (type == "sedu") { diff --git a/libsrc/leddevice/LedDevicePiBlaster.cpp b/libsrc/leddevice/LedDevicePiBlaster.cpp index 9fe02a8b..dc09fe15 100644 --- a/libsrc/leddevice/LedDevicePiBlaster.cpp +++ b/libsrc/leddevice/LedDevicePiBlaster.cpp @@ -2,6 +2,11 @@ // STL includes #include #include +#include + + +// jsoncpp includes +#include // QT includes #include @@ -9,12 +14,40 @@ // Local LedDevice includes #include "LedDevicePiBlaster.h" -LedDevicePiBlaster::LedDevicePiBlaster(const std::string & deviceName, const std::string & channelAssignment) : +LedDevicePiBlaster::LedDevicePiBlaster(const std::string & deviceName, const Json::Value & gpioMapping) : _deviceName(deviceName), - _channelAssignment(channelAssignment), _fid(nullptr) { - // empty + + signal(SIGPIPE, SIG_IGN); + +// initialise the mapping tables +// -1 is invalid +// z is also meaningless +// { "gpio" : 4, "ledindex" : 0, "ledcolor" : "r" }, + #define TABLE_SZ sizeof(_gpio_to_led)/sizeof(_gpio_to_led[0]) + + for (int i=0; i < TABLE_SZ; i++ ) + { + _gpio_to_led[i] = -1; + _gpio_to_color[i] = 'z'; + } + +// walk through the json config and populate the mapping tables + for (const Json::Value& gpioMap : gpioMapping) + { + const int gpio = gpioMap.get("gpio",-1).asInt(); + const int ledindex = gpioMap.get("ledindex",-1).asInt(); + const std::string ledcolor = gpioMap.get("ledcolor","z").asString(); +// printf ("got gpio %d ledindex %d color %c\n", gpio,ledindex, ledcolor[0]); + // ignore missing/invalid settings + if ( (gpio >= 0) && (gpio < TABLE_SZ) && (ledindex >= 0) ){ + _gpio_to_led[gpio] = ledindex; + _gpio_to_color[gpio] = ledcolor[0]; // 1st char of string + } else { + printf ("IGNORING gpio %d ledindex %d color %c\n", gpio,ledindex, ledcolor[0]); + } + } } LedDevicePiBlaster::~LedDevicePiBlaster() @@ -63,15 +96,6 @@ int LedDevicePiBlaster::open(bool report) return 0; } -//Channel number GPIO number Pin in P1 header -// 0 4 P1-7 -// 1 17 P1-11 -// 2 18 P1-12 -// 3 21 P1-13 -// 4 22 P1-15 -// 5 23 P1-16 -// 6 24 P1-18 -// 7 25 P1-22 int LedDevicePiBlaster::write(const std::vector & ledValues) { // Attempt to open if not yet opened @@ -80,32 +104,47 @@ int LedDevicePiBlaster::write(const std::vector & ledValues) return -1; } - std::vector iPins = {4, 17, 18, 27, 21, 22, 23, 24, 25}; - - unsigned colorIdx = 0; - for (unsigned iPin=0; iPin= 0) && (valueIdx < (signed) ledValues.size()) ) { - case 'r': - pwmDutyCycle = ledValues[colorIdx].red / 255.0; - ++colorIdx; - break; - case 'g': - pwmDutyCycle = ledValues[colorIdx].green / 255.0; - ++colorIdx; - break; - case 'b': - pwmDutyCycle = ledValues[colorIdx].blue / 255.0; - ++colorIdx; - break; - default: - continue; - } + double pwmDutyCycle = 0.0; +// printf ("iPin %d valueIdx %d color %c\n", iPin, valueIdx, _gpio_to_color[ iPins[iPin] ] ) ; + switch (_gpio_to_color[ i ]) + { + case 'r': + pwmDutyCycle = ledValues[valueIdx].red / 255.0; + break; + case 'g': + pwmDutyCycle = ledValues[valueIdx].green / 255.0; + break; + case 'b': + pwmDutyCycle = ledValues[valueIdx].blue / 255.0; + break; + case 'w': + pwmDutyCycle = ledValues[valueIdx].red; + pwmDutyCycle += ledValues[valueIdx].green; + pwmDutyCycle += ledValues[valueIdx].blue; + pwmDutyCycle /= (3.0*255.0); + break; + default: + continue; + } - fprintf(_fid, "%i=%f\n", iPins[iPin], pwmDutyCycle); - fflush(_fid); +// fprintf(_fid, "%i=%f\n", iPins[iPin], pwmDutyCycle); + + if ( (fprintf(_fid, "%i=%f\n", i, pwmDutyCycle) < 0) + || (fflush(_fid) < 0)) { + if (_fid != nullptr) + { + fclose(_fid); + _fid = nullptr; + return -1; + } + } + } } return 0; @@ -119,13 +158,13 @@ int LedDevicePiBlaster::switchOff() return -1; } - std::vector iPins = {4, 17, 18, 21, 22, 23, 24, 25}; - - for (unsigned iPin=0; iPin= 0) { - fprintf(_fid, "%i=%f\n", iPins[iPin], 0.0); + fprintf(_fid, "%i=%f\n", i, 0.0); fflush(_fid); } } diff --git a/libsrc/leddevice/LedDevicePiBlaster.h b/libsrc/leddevice/LedDevicePiBlaster.h index 3e79856e..531372a6 100644 --- a/libsrc/leddevice/LedDevicePiBlaster.h +++ b/libsrc/leddevice/LedDevicePiBlaster.h @@ -4,6 +4,9 @@ // STL includes #include +// jsoncpp includes +#include + // Hyperion-Leddevice includes #include @@ -14,9 +17,9 @@ public: /// Constructs the PiBlaster device which writes to the indicated device and for the assigned /// channels /// @param deviceName The name of the output device - /// @param channelAssignment The RGB-Channel assignment (8 characters long) + /// @param gpioMapping The RGB-Channel assignment json object /// - LedDevicePiBlaster(const std::string & deviceName, const std::string & channelAssignment); + LedDevicePiBlaster(const std::string & deviceName, const Json::Value & gpioMapping); virtual ~LedDevicePiBlaster(); @@ -50,9 +53,8 @@ private: /// The name of the output device (very likely '/dev/pi-blaster') const std::string _deviceName; - /// String with eight characters with the rgb-channel assignment per pwm-channel - /// ('r' = red, 'g' = green, 'b' = blue, ' ' = empty) - const std::string _channelAssignment; + int _gpio_to_led[64]; + char _gpio_to_color[64]; /// File-Pointer to the PiBlaster device FILE * _fid;