Profi Led Lua Script

Hi,

Beginner at programming
Cant figure out which one of the given examples is using Profi LED

Is there some documentation on how to use Profi LED with lua script
Till now I have managed to set Profi LED as notification LED’s

Thanks,
MindProbe

All the examples can use both,

You just need to comment in the correct setup function.

Just load the script and change your notify output to Scripting1

Thanks a lot @iampete

for others who come looking for this in the future

serialLED:set_num_profiled(10, 8)

function update_LEDs()
	serialLED:set_RGB(10, 0, 255, 0, 0)
	serialLED:set_RGB(10, 1, 255, 0, 0)
	serialLED:set_RGB(10, 2, 255, 0, 0)
	serialLED:set_RGB(10, 3, 255, 0, 0)
	serialLED:set_RGB(10, 4, 0, 255, 0)
	serialLED:set_RGB(10, 5, 0, 255, 0)
	serialLED:set_RGB(10, 6, 0, 255, 0)
	serialLED:set_RGB(10, 7, 0, 255, 0)
	serialLED:send(10)
	return update_LEDs, 2000
end
return update_LEDs, 2000

This is for the new Hexsoon EDU 450 quadcopter with 4 Leds connected to Hexsoon 40A PDB
Each LED has 2 individual profiLeds inside and can be controlled seperately

The signal port on the pdb has two outputs :
Brown is Data
Black is Clock
And the white wire in both connector is ground

Connect connector with black wire in AUX1 and brown in AUX2
Set these parameters

SERVO9_FUNCTION     132
SERVO10_FUNCTION     94
SCR_ENABLE     1

and upload the above script

This makes the front two Red and the rear two green (depends on which led is connected to which port on the PDB)

A few notes to improve your script:

  • You aren’t making use of the SERVO10_FUNCTION parameter.
  • You have a lot of “magic numbers” rather than named variables.
  • You have a bit of repeated code.
  • If you are only setting the color values once, there is no need to repeat it every 2 seconds.
    • And if you just need solid color LEDs, you could install those at less cost and zero code complexity :slight_smile:
  • Slightly off topic from coding, if you are intending to have these mimic aircraft position lights, the left should be red, and the right should be green (rather than fore/aft).

Here’s a revised version that’s admittedly a little longer and includes a minor amount of complexity for example’s sake, but it’s hopefully easier to read and modify:

-- configuration "constants"
local SERVO_FN          = 94
local NUM_LEDS          =  8
local MAV_SEVERITY_INFO =  6

-- color "constants"
local R = 0
local G = 1
local B = 2

local RED = {
    [R] = 255,
    [G] =   0,
    [B] =   0
}

local GREEN = {
    [R] =   0,
    [G] = 255,
    [B] =   0
}

-- helper function to set sequential LEDs to a certain color
local function set_led_colors(channel, index_first, index_last, color)
    for i = index_first, index_last do
        serialLED:set_RGB(channel, i, color[R], color[G], color[B])
    end
end

-- find servo channel for LEDs
local CHAN = SRV_Channels:find_channel(SERVO_FN)

-- exit gracefully if parameter not set
if not CHAN then
    gcs:send_text(MAV_SEVERITY_INFO, string.format('LEDs: Channel (%d) not set', SERVO_FN))
    return
end

-- according to comment from LED_roll.lua example - possibly unnecessary with more recent versions?
-- slightly breaks my usual convention of all caps for "immutable" pseudo-constants, but this is the last time we will change its value, so I prefer this capitalization style here
CHAN = CHAN + 1

-- configure LED driver
serialLED:set_num_profiled(CHAN, NUM_LEDS)

-- set first half to RED
set_led_colors(CHAN, 0, math.floor(NUM_LEDS / 2), RED)

-- set second half to GREEN
set_led_colors(CHAN, math.ceil(NUM_LEDS / 2), NUM_LEDS - 1, GREEN)

-- commit color changes
serialLED:send(CHAN)

gcs:send_text(MAV_SEVERITY_INFO, string.format('LEDs (%d): Colors set', NUM_LEDS))

-- no need to call an update function - this runs once

Fair warning - I did not test the revision, so I apologize for any typos or errors.

Barring silly mistakes on my part, if it doesn’t work, perhaps the Lua scripting engine is loaded before the LED driver is ready. In that case, it’s pretty easy to encapsulate the bulk of the script inside a function that could be called after a couple of seconds.

Thanks a lot @Yuri_Rage ,

local SERVO_FN          = 94
local NUM_LEDS          =  8
local MAV_SEVERITY_INFO =  6
local R = 0
local G = 1
local B = 2
local RED = {
    [R] = 255,
    [G] =   0,
    [B] =   0
}
local GREEN = {
    [R] =   0,
    [G] = 255,
    [B] =   0
}
local function set_led_colors(channel, index_first, index_last, color)
    for i = index_first, index_last do
        serialLED:set_RGB(channel, i, color[R], color[G], color[B])
    end
end
local CHAN = SRV_Channels:find_channel(SERVO_FN)
if not CHAN then
    gcs:send_text(MAV_SEVERITY_INFO, string.format('LEDs: Channel (%d) not set', SERVO_FN))
    return
end
CHAN = CHAN + 1
serialLED:set_num_profiled(CHAN, NUM_LEDS)
function updateloop()
	set_led_colors(CHAN, 0, math.floor(NUM_LEDS / 2), RED)
	set_led_colors(CHAN, math.ceil(NUM_LEDS / 2), NUM_LEDS - 1, GREEN)
	serialLED:send(CHAN)
	return updateloop, 2000
end
return updateloop, 2000

Your revision worked after adding those three lines inside an update loop. But it should’ve worked without it.

I didn’t get what you meant by this, could you explain a little bit more

It looks like this may be the reason you needed to use a recursion loop to get things to work. If the script runs before the LED driver is loaded/ready, any calls to it will be ineffective.

Instead of using a loop, let’s try this simple change. If it still doesn’t work (for reasons I can’t explain), your looped version isn’t necessarily bad, as there will be very little processing time used.

local SERVO_FN          =   94
local NUM_LEDS          =    8
local MAV_SEVERITY_INFO =    6
local BOOT_DELAY_MS     = 2000
local R = 0
local G = 1
local B = 2
local RED = {
    [R] = 255,
    [G] =   0,
    [B] =   0
}
local GREEN = {
    [R] =   0,
    [G] = 255,
    [B] =   0
}
local function set_led_colors(channel, index_first, index_last, color)
    for i = index_first, index_last do
        serialLED:set_RGB(channel, i, color[R], color[G], color[B])
    end
end
local CHAN = SRV_Channels:find_channel(SERVO_FN)
if not CHAN then
    gcs:send_text(MAV_SEVERITY_INFO, string.format('LEDs: Channel (%d) not set', SERVO_FN))
    return
end
CHAN = CHAN + 1
serialLED:set_num_profiled(CHAN, NUM_LEDS)
function run_once()
	set_led_colors(CHAN, 0, math.floor(NUM_LEDS / 2), RED)
	set_led_colors(CHAN, math.ceil(NUM_LEDS / 2), NUM_LEDS - 1, GREEN)
	serialLED:send(CHAN)
end
return run_once, BOOT_DELAY_MS

Works like a charm when BOOT_DELAY_MS set to 3000

Thanks for all of it @Yuri_Rage

Also I made a simple program that blinks led when disarmed and makes them solid when armed. Thanks a lot, @iampete for helping me on discord

Although its not as readable and user friendly as yuri’s but could help someone looking for something similar

local chan = SRV_Channels:find_channel(94)
local num_leds = 8

chan = chan + 1

function led_always_ON()
	for led = 0, num_leds-5 do
		serialLED:set_RGB(chan, led, 255, 0, 0)
	end
	for led = 4, num_leds-1 do
		serialLED:set_RGB(chan, led, 0, 255, 0)
	end
	serialLED:send(chan)
	if not arming:is_armed() then
		gcs:send_text(6, "Disarmed")
		return led_OFF,10
	end
	return led_always_ON,100
end

function led_ON()
	for led = 0, num_leds-5 do
		serialLED:set_RGB(chan, led, 255, 0, 0)
	end
	for led = 4, num_leds-1 do
		serialLED:set_RGB(chan, led, 0, 255, 0)
	end
	serialLED:send(chan)
	if arming:is_armed() then
		gcs:send_text(6, "Armed")
		return led_always_ON,10
	end
	return led_OFF,500
	
end

function led_OFF()
	for led = 0, num_leds-5 do
		serialLED:set_RGB(chan, led, 0, 0, 0)
	end
	
	for led = 4, num_leds-1 do
		serialLED:set_RGB(chan, led, 0, 0, 0)
	end
	serialLED:send(chan)
	if arming:is_armed() then
		gcs:send_text(6, "Armed")
		return led_always_ON,10
	end
	return led_ON,500
end
serialLED:set_num_profiled(chan, num_leds)
return led_always_ON,1500

1 Like