Neopixel RGB with Navigator Board

Hello!

I wanted to confirm/perhaps receive an example for using Neopixels with the Navigator board. I am generally unfamiliar with Neopixels and have not used them, but am including /want to include them in an AUV mast design.

NeoPixel Jewel - 7 x 5050 RGBW LED w/ Integrated Drivers [Natural White - ~4500K] : ID 2859 : Adafruit Industries, Unique & fun DIY electronics and kits

If I purchased this Neopixel array, am currently assuming that in terms of using the Neopixel Library, that since this array contains seven elements, that when I use the Navigator Library in C++, I will need to populate my RGB array with 24 values for an RGB value of each indexable RGB in the array - including the Neopixel which is on board (three elements for defining the Neopixels RGB values), and then 21 more, for the sevel subsequent Neopixel’s RGB triplet?

navigator-lib/examples/cpp/rainbow.cpp at master · bluerobotics/navigator-lib · GitHub

I don’t have the hardware and am unable to test yet, but it is on the way.

Best,
Ray

1 Like

Hi Ray!

The board itself has a RGB LED, not sure if this will interfere with the RGBW strip, it should be connected in parallel so it may work.
We are updating the libraries to support it, we don’t have the strip to test, so please report if it works. I’ll update there once we do the releases for C++ / Python, Rust should be released in the next hour.

Hey Raymond @rturrisi ,

We have made a newer version with “set_neopixel_rgbw(const uint8_t (*rgb_array)[4], uintptr_t length)” method.

Further details:

Please let me know if you had success setting up the Neopixel RGB"W" there.

All the best,

Raul

Hey @RaulTrombin & @patrickelectric -

The RGBW function works fine for the onboard LED, however I’m looking to use an RGB/RGBW strip. Inside the Rust Library I see that you have a fixed strip size, which prevents the set_neopixel_rgb/set_neopixel_rgbw function from iterating over a complete strip.

navigator-rs/src/lib.rs at c4176116ede22449a9e5e37424f307a810375063 · bluerobotics/navigator-rs · GitHub

When I have a Neopixel array connected to the pins, the first in the array has the same value as the Neopixel that is on the board, however I cannot assign values to the rest of the pixels in the array, and the program crashes since the function tries to assign a value to an element outside the length of the array.

Is there a way for us to change this on our end, or do we need to wait for a patch which lets us set the strip size?

Also, I have been using 0.0.3 so it hasn’t been an issue, but the bindings.h file that gets generated upon updating, needs to include a preprocessor directive such as “#pragma once” or “#ifnotdef NAV
, #def NAV
”. I have applications which use features on the board which are not mutually exclusive and can be ran in separate moos apps/ros nodes, where there is a clash during compilation. For example, I have an application for managing the IMU/Mags, and another app which manages PWM outputs and ADC readings. I have common libraries, references, and utilities, where bindings.h is included and referenced between the two apps.

Would you be able to post an update so I can test a complete strip?

Hi Ray,

In rust we have the with_rgb_led_strip_size method: NavigatorBuilder in navigator_rs - Rust

At the moment we don’t have the option to custom LED strip sizes from C++ and Python, we’ll let you know once we have it.

Do you have an estimated release date for the 1) strips of LEDs functionality, and 2) access to the second onboard magnetometer?

Hi Ray,

We can do a release of the strip size access via python and C++ next week (It’s already available in Rust).
The second navigator may be tricker, but I’ll try to add it in the same release as well.

Hey Patrick,

That would be greatly appreciated! Thanks. We have some presentations coming up soon and I wanted to include a vehicle demonstration (not the critical part, but the LEDs are a nice touch).

For the magnetometer, I was looking through BR’s repos and crates and I couldn’t see any supporting libraries. Have you been able to successfully interface with the second magnetometer?

The one that is onboard is pretty good - the following photos are from the calibration routine I have in C++/Python. When tested outside, it only needed offset constants, and the scaling matrix was almost identity.

First image is simply the raw data, where the blue sphere is the target, and the point cloud is where we sampled in time series.

The top of this second image is after including the offsets and the scaling matrix.

The coefficients were only
b = [-6.802798693134499,-12.810034812439271,3.8460008279144398]’

A = [1.0573555731245843,0.0017889995888048583,0.002088227906481734; 0.0017889995888048583,1.0516530952316332,-0.0017990317696794096; 0.0020882127768074685,-0.0017990317696794096,1.0372066316037334]

While the main one we have access to is good, the orientation filters I was using was somewhat unstable when I included the magnetometer (i.e. a change in roll over 5 degrees induced a change in yaw, in controlled conditions). This was using Madgwick’s library from his thesis/some of his papers - I am aiming to include the second Magnetometer soon and include the measurements in a more cohesive sensor fusion stack.

Best,
Ray

Hey @patrickelectric - just saw the latest commit / version. Tested it and things worked fine.

#include "bindings.h"
#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>

void color_from_sine(float percentage, uint8_t (&ledValues)[4]) {
  float pi = M_PI;
  float red = std::sin(percentage * 2.0 * pi) * 0.5 + 0.5;
  float green = std::sin((percentage + 0.33) * 2.0 * pi) * 0.5 + 0.5;
  float blue = std::sin((percentage + 0.67) * 2.0 * pi) * 0.5 + 0.5;
  ledValues[0] = static_cast<uint8_t>(red * 255.0);
  ledValues[1] = static_cast<uint8_t>(green * 255.0);
  ledValues[2] = static_cast<uint8_t>(blue * 255.0);
  ledValues[3] = 0;
}

int main() {
  std::cout << "Creating rainbow effect!" << std::endl;
  set_rgb_led_strip_size(7);
  init();
  uint8_t rgb_array[7][4];
  uint8_t element[4];
  while (true) {
    int steps = 1000;
    for (int i = 0; i <= steps; i++) {
      float ratio = static_cast<float>(i) / static_cast<float>(steps);
      color_from_sine(ratio, element);
      for (int j = 0; j < 7; j++) {
        rgb_array[j][0] = element[0];
        rgb_array[j][1] = element[1];
        rgb_array[j][2] = element[2];
        rgb_array[j][3] = element[3];
      }
      set_neopixel_rgbw(rgb_array, 7);
      std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
  }
  return 0;
}

Hi,

I’m glad that the neo rgbw support an generic led array strips are working for you.
About the second magnetometer, it’ll take longer than expected. But we expect to add it this quarter.