Quantcast
Channel: ArduPilot Discourse - Latest topics
Viewing all articles
Browse latest Browse all 46943

Different colors on WS2812 leds on same channel

$
0
0

Hi.

For general drone orientation while flying, I like to have a red led on the left, a green red on the right, white leds on the back and yellow leds on the front, but as far as I could see, all WS2812 leds on a channel share color. I don’t know if there have been variations on this fixed scheme.

On a Cinewhoop I placed 32 leds on its FC single channel:

  • 1-8: front right (will be green);
  • 9-16: front left (will be red)
  • 17-24: back right (will flash white)
  • 25-32: back left (will flash white

Not knowing much about C++ and ArduCopter code, I did the following modifications on v4.5.7:

libraries/AP_Notify/RGBLed.cpp:

uint32_t RGBLed::get_colour_sequence_traffic_light(void) const
{
    if (AP_Notify::flags.initialising) {
        return DEFINE_COLOUR_SEQUENCE(RED,GREEN,BLUE,RED,GREEN,BLUE,RED,GREEN,BLUE,BLACK);
    }

    if (AP_Notify::flags.armed) {
//        return DEFINE_COLOUR_SEQUENCE_SLOW(RED);
          return DEFINE_COLOUR_SEQUENCE_SLOW(WHITE);
    }
...

(when armed, instead of flashing red, flashing white (leds 17-32))

libraries/AP_Notify/SerialLED.cpp:

bool SerialLED::hw_set_rgb(uint8_t red, uint8_t green, uint8_t blue)
{
    if (enable_mask == 0) {
        // nothing is enabled, no pins set as LED output
        return true;
    }

    AP_SerialLED *led = AP_SerialLED::get_singleton();
    if (led == nullptr) {
        return false;
    }

    for (uint16_t chan = 0; chan < 16; chan++) {
        if ((1U << chan) & enable_mask) {
            const uint8_t num_leds = 32;

            for (uint16_t i = 0; i < num_leds; i++) {
                uint8_t r = red;
                uint8_t g = green;
                uint8_t b = blue;

                if (i < num_leds / 4) {
                    // Verde
                    r = 0;
                    g = 255;
                    b = 0;
                } else if (i < num_leds / 2) {
                    // Rojo
                    r = 255;
                    g = 0;
                    b = 0;
                }

                led->set_RGB(chan + 1, i, r, g, b);
            }
        }
    }

    for (uint16_t chan = 0; chan < 16; chan++) {
        if ((1U << chan) & enable_mask) {
            led->send(chan + 1);
        }
    }

    return true;
}

(Direct modification on leds 1-16. Note that class AP_SerialLED does not expose the number of leds on a channel, so this ugly code is valid for my particular case (which has a single channel, so code could be simplified)).

The result is what I wanted (shown armed):

Front right red leds and front right green leds don’t flash, but it is enough for me.

Is already there or will be a more elegant solution, avoiding the ugly code above?

2 posts - 2 participants

Read full topic


Viewing all articles
Browse latest Browse all 46943

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>