Using SimplePWMPin outside ProffieOS

Hey Folks,

I’m trying to set up an Arduino sketch that can drive a neopixel blade with a single, solid color outside of ProffieOS. The goal is to get power reading of how much power a blade uses at various levels of battery charge, in various colors. I was seeing some odd power behavior inside ProffieOS, so I’m trying again outside ProffieOS.

In terms of pure Arduino sketches, I’ve already figured out how to make the sample arduino sketches Blink and Fading work on ProffieBoard, but 500Hz isn’t enough to drive NeoPixels, so clearly I need to go a level deeper so I can get a faster PWM frequency.

Looking at the source of analogWrite(), I found some functions I could google. That led me to ProffieOS/blades/pwm_pin.h at 2e87f62ba9b77ff4f30d98b27ad8228ef319893c · profezzorn/ProffieOS · GitHub , which looks like a very convenient wrapper around machine-specific code.

The problem is I don’t actually know how to instantiate this class, nor do I know what words to google. Here’s my first guess: dpaste/EekBM (Arduino) . Most of that code is copy/paste from ProffieOS, the relevant bit is the setup() code at the bottom. Am I setting up the SimplePWMPin correctly? Or do I need to change that code?

(Yes, I’ll need to change various constants in the copied code. I’ll dig through the datasheets after I’ve verified that the amalgamated code can generate any sort of PWM signal.)

Neopixels do not use PWM!

Either, you have a simple RGB LED strip, which requires three powerful FETs and PWM to drive, or you have a neopixel strip, which has +, - and data inputs, and the data is an 800kHz serial-like protocol which lets you control each individual pixel on the strip.

You don’t use PWM to drive NeoPixels though.
If you h ave regular RGB leds, then 500Hz is enough.
If you have NeoPixels, then you don’t use PWM.

Also, are you running this on a Proffieboard, or some other kind of Arduino board?

No, but you can use carefully-chosen PWM bytes/ints to send one bit at a time. Just gotta make sure you have a new byte/int every 1.25us. If your sketch is doing nothing except driving a single neopixel strand, that should be feasible on an 80MHz processor. Here’s a sample timing diagram that shows you can use an approximation of the right timing and still be within the error bounds for a ws2812b:

All times should be well within 150ns of the times quoted in the spec sheet.

That 0.25us interval is 4 MHz, but I suspect there’s probably a way to achieve the right timings with 800KHz PWM if you can get new data loaded fast enough .

If the FastLED library worked, I would have used that, but it only supports STM32F , not STM32L, and the port didn’t quite look trivial.

What would you suggest if not PWM?

This is an actual ProffieBoard 3, bought from Tritium. Which is why I’m not just using FastLED.

Ok, so yes, generating Neopixel data is often done by setting up a PWM timer and then feeding it a new value every time the timer wraps around. This is in fact what ProffieOS does, and you’d be much better off copying that code than trying to do it with SimplePWMPin.

(For reference, that code is here: ProffieOS/blades/stm32l4_ws2811.h at 0f3120a58ed3157c7eabb6913eedbb1191fde0db · profezzorn/ProffieOS · GitHub)

This code is long and complicated though, it uses DMA to transfer data from a small buffer, that buffer is replenished by an interrupt which:

  1. takes linear Color16 values as input
  2. dithers the colors in time and space
  3. converts the Color16 into 3 or 4 bytes based on the byte order
  4. converts each bit into one byte that contains a high or low value for the timer.

If your goal is to verify that this code actually works as intended, then I would suggest two ways that might be simpler:

a. use a teensy + fastled or teensy + octows2811 (or any other arduino that works with fastled)
b. use a logic analyzer to read the output from the Proffieboard and verify that it has the correct values.

1 Like