mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Add sk6812rgbw support (#666)
* 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 * adding support for SK6812 - not working yet * Changed rpi_ws281x submodule to be penfold42's fork * Set White to zero for now * starting on the code to make the White led do stuff * Added some basic whie led calculation white = min(r,g,b) r-=w, g-=w, b-=w * cleaned up a couple of compiler warnings * updated strip type to use corrected RGBW strip type (the SK6812RGBW datasheet is wrong) * moved bitpair_to_byte initialiser to (hopefully) work with older GCC * compiler warning in udp driver removed some tabs in ws2812b.cpp * formatting - spaces to tabs * moved rpi_281x to tag sk6812-v1.0 * attempt #3 at migrating the rpi_281x submodule to my fork/branch * moving to my fork of rpi_281x * Started implementing multiple RGB to RGBW conversion options a quick hack has been implemented inside WS281x.cpp but ive started moving this to RgbToRgbw.cpp for reuse by other led device types * migrated RGB to RGBW conversion to RgbToRgbw.cpp Former-commit-id: ff8e9038c4bb8203b71b42d12bf23be4abcc0b3b
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -3,4 +3,5 @@ | ||||
| 	url = https://github.com/tvdzwan/protobuf.git | ||||
| [submodule "dependencies/external/rpi_ws281x"] | ||||
| 	path = dependencies/external/rpi_ws281x | ||||
| 	url = https://github.com/penfold42/rpi_ws281x | ||||
| 	url = https://github.com/penfold42/rpi_ws281x.git | ||||
| 	branch = sk6812 | ||||
|   | ||||
| @@ -5,6 +5,8 @@ | ||||
|  | ||||
| // Utility includes | ||||
| #include <utils/ColorRgb.h> | ||||
| #include <utils/ColorRgbw.h> | ||||
| #include <utils/RgbToRgbw.h> | ||||
|  | ||||
| /// | ||||
| /// Interface (pure virtual base class) for LedDevices. | ||||
|   | ||||
							
								
								
									
										65
									
								
								include/utils/ColorRgbw.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								include/utils/ColorRgbw.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| #pragma once | ||||
|  | ||||
| // STL includes | ||||
| #include <cstdint> | ||||
| #include <iostream> | ||||
|  | ||||
| struct ColorRgbw; | ||||
|  | ||||
| /// | ||||
| /// Plain-Old-Data structure containing the red-green-blue color specification. Size of the | ||||
| /// structure is exactly 3-bytes for easy writing to led-device | ||||
| /// | ||||
| struct ColorRgbw | ||||
| { | ||||
| 	/// The red color channel | ||||
| 	uint8_t red; | ||||
| 	/// The green color channel | ||||
| 	uint8_t green; | ||||
| 	/// The blue color channel | ||||
| 	uint8_t blue; | ||||
| 	/// The white color channel | ||||
| 	uint8_t white; | ||||
|  | ||||
| 	/// 'Black' RgbColor (0, 0, 0, 0) | ||||
| 	static ColorRgbw BLACK; | ||||
| 	/// 'Red' RgbColor (255, 0, 0, 0) | ||||
| 	static ColorRgbw RED; | ||||
| 	/// 'Green' RgbColor (0, 255, 0, 0) | ||||
| 	static ColorRgbw GREEN; | ||||
| 	/// 'Blue' RgbColor (0, 0, 255, 0) | ||||
| 	static ColorRgbw BLUE; | ||||
| 	/// 'Yellow' RgbColor (255, 255, 0, 0) | ||||
| 	static ColorRgbw YELLOW; | ||||
| 	/// 'White' RgbColor (0, 0, 0, 255) | ||||
| 	static ColorRgbw WHITE; | ||||
| }; | ||||
|  | ||||
| /// Assert to ensure that the size of the structure is 'only' 4 bytes | ||||
| static_assert(sizeof(ColorRgbw) == 4, "Incorrect size of ColorRgbw"); | ||||
|  | ||||
| /// | ||||
| /// Stream operator to write ColorRgb to an outputstream (format "'{'[red]','[green]','[blue]'}'") | ||||
| /// | ||||
| /// @param os The output stream | ||||
| /// @param color The color to write | ||||
| /// @return The output stream (with the color written to it) | ||||
| /// | ||||
| inline std::ostream& operator<<(std::ostream& os, const ColorRgbw& color) | ||||
| { | ||||
| 	os << "{" << unsigned(color.red) << "," << unsigned(color.green) << "," << unsigned(color.blue) << "," << unsigned(color.white) << "}"; | ||||
| 	return os; | ||||
| } | ||||
|  | ||||
|  | ||||
| /// Compare operator to check if a color is 'smaller' than another color | ||||
| inline bool operator<(const ColorRgbw & lhs, const ColorRgbw & rhs) | ||||
| { | ||||
| 	return (lhs.red < rhs.red) && (lhs.green < rhs.green) && (lhs.blue < rhs.blue) && (lhs.white < rhs.white); | ||||
| } | ||||
|  | ||||
| /// Compare operator to check if a color is 'smaller' than or 'equal' to another color | ||||
| inline bool operator<=(const ColorRgbw & lhs, const ColorRgbw & rhs) | ||||
| { | ||||
| 	return (lhs.red <= rhs.red) && (lhs.green <= rhs.green) && (lhs.blue <= rhs.blue) && (lhs.white < rhs.white); | ||||
| } | ||||
							
								
								
									
										4
									
								
								include/utils/RgbToRgbw.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								include/utils/RgbToRgbw.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| #include <utils/ColorRgb.h> | ||||
| #include <utils/ColorRgbw.h> | ||||
|  | ||||
| void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, std::string _whiteAlgorithm); | ||||
| @@ -363,8 +363,11 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) | ||||
| 		const int dmanum = deviceConfig.get("dmanum", 5).asInt(); | ||||
|                 const int pwmchannel = deviceConfig.get("pwmchannel", 0).asInt(); | ||||
| 		const int invert = deviceConfig.get("invert", 0).asInt(); | ||||
| 		const int rgbw = deviceConfig.get("rgbw", 0).asInt(); | ||||
| 		const std::string& whiteAlgorithm = deviceConfig.get("white_algorithm","").asString(); | ||||
|  | ||||
| 		LedDeviceWS281x * ledDeviceWS281x = new LedDeviceWS281x(gpio, leds, freq, dmanum, pwmchannel, invert); | ||||
| 		LedDeviceWS281x * ledDeviceWS281x = new LedDeviceWS281x(gpio, leds, freq, dmanum, pwmchannel, invert,  | ||||
| 			rgbw, whiteAlgorithm); | ||||
| 		device = ledDeviceWS281x; | ||||
| 	} | ||||
| #endif | ||||
|   | ||||
| @@ -3,8 +3,11 @@ | ||||
| #include "LedDeviceWS281x.h" | ||||
|  | ||||
| // Constructor | ||||
| LedDeviceWS281x::LedDeviceWS281x(const int gpio, const int leds, const uint32_t freq, const int dmanum, const int pwmchannel, const int invert) | ||||
| LedDeviceWS281x::LedDeviceWS281x(const int gpio, const int leds, const uint32_t freq, const int dmanum, const int pwmchannel, const int invert, const int rgbw, const std::string& whiteAlgorithm) | ||||
| { | ||||
| 	_whiteAlgorithm = whiteAlgorithm; | ||||
| std::cout << "whiteAlgorithm :" << whiteAlgorithm << ":\n"; | ||||
|  | ||||
| 	initialized = false; | ||||
| 	led_string.freq = freq; | ||||
| 	led_string.dmanum = dmanum; | ||||
| @@ -17,7 +20,11 @@ LedDeviceWS281x::LedDeviceWS281x(const int gpio, const int leds, const uint32_t | ||||
| 	led_string.channel[chan].invert = invert; | ||||
| 	led_string.channel[chan].count = leds; | ||||
| 	led_string.channel[chan].brightness = 255; | ||||
| 	if (rgbw == 1) { | ||||
| 		led_string.channel[chan].strip_type = SK6812_STRIP_GRBW; | ||||
| 	} else { | ||||
| 		led_string.channel[chan].strip_type = WS2811_STRIP_RGB; | ||||
| 	} | ||||
|  | ||||
| 	led_string.channel[!chan].gpionum = 0; | ||||
| 	led_string.channel[!chan].invert = invert; | ||||
| @@ -42,7 +49,19 @@ int LedDeviceWS281x::write(const std::vector<ColorRgb> &ledValues) | ||||
| 	{ | ||||
| 		if (idx >= led_string.channel[chan].count) | ||||
| 			break; | ||||
| 		led_string.channel[chan].leds[idx++] = ((uint32_t)color.red << 16) + ((uint32_t)color.green << 8) + color.blue; | ||||
|  | ||||
| 		_temp_rgbw.red = color.red; | ||||
| 		_temp_rgbw.green = color.green; | ||||
| 		_temp_rgbw.blue = color.blue; | ||||
| 		_temp_rgbw.white = 0; | ||||
|  | ||||
| 		if (led_string.channel[chan].strip_type == SK6812_STRIP_GRBW) { | ||||
| 			Rgb_to_Rgbw(color, &_temp_rgbw, _whiteAlgorithm); | ||||
| 		} | ||||
|  | ||||
| 		led_string.channel[chan].leds[idx++] =  | ||||
| 			((uint32_t)_temp_rgbw.white << 24) + ((uint32_t)_temp_rgbw.red << 16) + ((uint32_t)_temp_rgbw.green << 8) + _temp_rgbw.blue; | ||||
|  | ||||
| 	} | ||||
| 	while (idx < led_string.channel[chan].count) | ||||
| 		led_string.channel[chan].leds[idx++] = 0; | ||||
|   | ||||
| @@ -18,9 +18,11 @@ public: | ||||
| 	/// @param dmanum The DMA channel to use, default is 5 | ||||
| 	/// @param pwmchannel The pwm channel to use | ||||
| 	/// @param invert Invert the output line to support an inverting level shifter | ||||
| 	/// @param rgbw   Send 32 bit rgbw colour data for sk6812 | ||||
|  | ||||
| 	/// | ||||
| 	LedDeviceWS281x(const int gpio, const int leds, const uint32_t freq, int dmanum, int pwmchannel, int invert); | ||||
| 	LedDeviceWS281x(const int gpio, const int leds, const uint32_t freq, int dmanum, int pwmchannel, int invert,  | ||||
| 		int rgbw, const std::string& whiteAlgorithm); | ||||
|  | ||||
| 	/// | ||||
| 	/// Destructor of the LedDevice, waits for DMA to complete and then cleans up | ||||
| @@ -42,6 +44,8 @@ private: | ||||
| 	ws2811_t led_string; | ||||
| 	int chan; | ||||
| 	bool initialized; | ||||
|         std::string _whiteAlgorithm; | ||||
| 	ColorRgbw _temp_rgbw; | ||||
| }; | ||||
|  | ||||
| #endif /* LEDDEVICEWS281X_H_ */ | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
|  | ||||
| # Define the current source locations | ||||
| SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/utils) | ||||
| SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/utils) | ||||
| @@ -12,6 +11,8 @@ add_library(hyperion-utils | ||||
| 	${CURRENT_SOURCE_DIR}/ColorRgb.cpp | ||||
| 	${CURRENT_HEADER_DIR}/ColorRgba.h | ||||
| 	${CURRENT_SOURCE_DIR}/ColorRgba.cpp | ||||
| 	${CURRENT_HEADER_DIR}/ColorRgbw.h | ||||
| 	${CURRENT_SOURCE_DIR}/ColorRgbw.cpp | ||||
| 	${CURRENT_HEADER_DIR}/Image.h | ||||
| 	${CURRENT_HEADER_DIR}/Sleep.h | ||||
|  | ||||
| @@ -32,6 +33,9 @@ add_library(hyperion-utils | ||||
| 	${CURRENT_HEADER_DIR}/RgbChannelAdjustment.h | ||||
| 	${CURRENT_SOURCE_DIR}/RgbChannelAdjustment.cpp | ||||
|  | ||||
| 	${CURRENT_HEADER_DIR}/RgbToRgbw.h | ||||
| 	${CURRENT_SOURCE_DIR}/RgbToRgbw.cpp | ||||
|  | ||||
| 	${CURRENT_HEADER_DIR}/jsonschema/JsonFactory.h | ||||
| 	${CURRENT_HEADER_DIR}/jsonschema/JsonSchemaChecker.h | ||||
| 	${CURRENT_SOURCE_DIR}/jsonschema/JsonSchemaChecker.cpp | ||||
|   | ||||
							
								
								
									
										10
									
								
								libsrc/utils/ColorRgbw.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								libsrc/utils/ColorRgbw.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
|  | ||||
| // Local includes | ||||
| #include <utils/ColorRgbw.h> | ||||
|  | ||||
| ColorRgbw ColorRgbw::BLACK = {   0,   0,   0,   0 }; | ||||
| ColorRgbw ColorRgbw::RED   = { 255,   0,   0,   0 }; | ||||
| ColorRgbw ColorRgbw::GREEN = {   0, 255,   0,   0 }; | ||||
| ColorRgbw ColorRgbw::BLUE  = {   0,   0, 255,   0 }; | ||||
| ColorRgbw ColorRgbw::YELLOW= { 255, 255,   0,   0 }; | ||||
| ColorRgbw ColorRgbw::WHITE = {   0,   0,   0, 255 }; | ||||
							
								
								
									
										24
									
								
								libsrc/utils/RgbToRgbw.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								libsrc/utils/RgbToRgbw.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| #include <utils/ColorRgb.h> | ||||
| #include <utils/ColorRgbw.h> | ||||
|  | ||||
| void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, std::string _whiteAlgorithm) { | ||||
| 	if (_whiteAlgorithm == "subtract_minimum") { | ||||
| 		output->white = std::min(input.red, input.green); | ||||
| 		output->white = std::min(output->white, input.blue); | ||||
| 		output->red = input.red - output->white; | ||||
| 		output->green = input.green - output->white; | ||||
| 		output->blue = input.blue - output->white; | ||||
| 	} | ||||
| 	else if (_whiteAlgorithm == "sub_min_warm_adjust") { | ||||
| 	} | ||||
| 	else if ( (_whiteAlgorithm == "") || (_whiteAlgorithm == "white_off") ) { | ||||
| 		output->red = input.red; | ||||
| 		output->green = input.green; | ||||
| 		output->blue = input.blue; | ||||
| 		output->white = 0; | ||||
| 	} | ||||
| 	else { | ||||
| 		std::cout << "ERROR: unknown whiteAlgorithm " << _whiteAlgorithm << std::endl; | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user