From 48ba63ba1180671fd4bd87cbd5d9313cdb4a012a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 30 Oct 2019 21:14:35 +1100 Subject: [PATCH] AP_Scripting: added example script for LEDs show LED values based on roll --- libraries/AP_Scripting/examples/LED_roll.lua | 85 ++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 libraries/AP_Scripting/examples/LED_roll.lua diff --git a/libraries/AP_Scripting/examples/LED_roll.lua b/libraries/AP_Scripting/examples/LED_roll.lua new file mode 100644 index 0000000000..a997c2b5a3 --- /dev/null +++ b/libraries/AP_Scripting/examples/LED_roll.lua @@ -0,0 +1,85 @@ +--[[ +Script to control LED strips based on the roll of the aircraft. This is an example to demonstrate +the LED interface for WS2812 LEDs +--]] + +--[[ +for this demo we will use a single strip with 30 LEDs +--]] +local num_leds = 30 + +--[[ + use SERVOn_FUNCTION 94 for LED. We can control up to 16 separate strips of LEDs + by putting them on different channels +--]] +local chan = SRV_Channels:find_channel(94) + +if not chan then + gcs:send_text(6, string.format("LEDs: channel not set")) + return +end + +-- find_channel returns 0 to 15, convert to 1 to 16 +chan = chan + 1 + +gcs:send_text(6, string.format("LEDs: chan=" .. tostring(chan))) + +-- initialisation code +serialLED:set_num_LEDs(chan, num_leds) + +-- constrain a value between limits +function constrain(v, vmin, vmax) + if v < vmin then + v = vmin + end + if v > vmax then + v = vmax + end + return v +end + +--[[ +Table of colors on a rainbow, red first +--]] +local rainbow = { + { 255, 0, 0 }, + { 255, 127, 0 }, + { 255, 255, 0 }, + { 0, 255, 0 }, + { 0, 0, 255 }, + { 75, 0, 130 }, + { 143, 0, 255 }, +} + +--[[ +Function to set a LED to a color on a classic rainbow spectrum, with v=0 giving red +--]] +function set_Rainbow(chan, led, v) + local num_rows = #rainbow + local row = math.floor(constrain(v * (num_rows-1)+1, 1, num_rows-1)) + local v0 = (row-1) / (num_rows-1) + local v1 = row / (num_rows-1) + local p = (v - v0) / (v1 - v0) + r = math.floor(rainbow[row][1] + p * (rainbow[row+1][1] - rainbow[row][1])) + g = math.floor(rainbow[row][2] + p * (rainbow[row+1][2] - rainbow[row][2])) + b = math.floor(rainbow[row][3] + p * (rainbow[row+1][3] - rainbow[row][3])) + serialLED:set_RGB(chan, uint32_t(1 << led), r, g, b) +end + +--[[ +We will set the colour of the LEDs based on roll of the aircraft +--]] +function update_LEDs() + local roll = constrain(ahrs:get_roll(), math.rad(-60), math.rad(60)) + + for led = 0, num_leds-1 do + local v = constrain(0.5 + 0.5 * math.sin(roll * (led - num_leds/2) / (num_leds/2)), 0, 1) + set_Rainbow(chan, led, v) + end + serialLED:send() + + return update_LEDs, 20 -- run at 50Hz +end + +return update_LEDs, 1000 +