problem with octows2811 and (probably not) MIDI

Status
Not open for further replies.

artag

Active member
I have the code below to regularly send out some MIDI values. I'm also maintaining 4 strings of 360 WS2813 LEDs using the octows2811 library on a teensy 3.5.

Building this on arduino 1.8.2 works as expected. But if I build the same thing on arduino 1.8.4 (with the appropriate teensyduino), the LEDs flicker madly. I can disable the MIDI output by failing to call midiloop() and all is well.

However, if I change the bytes in the structure below to ints, it also works on 1.8.4.

I suspect this is nothing to do with MIDI, but is related to the 3-byte structure size. Perhaps on 1.8.4, the structure is improperly aligned and is generating bus faults that screw with the DMA.

I realise the fragment below isn't enough to duplicate the problem, but if this isn't a known problem (I see there is now an arduino 1.8.5 to use) I'll try to make a minimal example that will show the problem up.


Code:
static struct MIDI_CHANNEL {
  byte m_channel;
  byte m_control;
  byte m_value;
} midi_channels[MIDI_CHANNELS] =
  {
    {1, CONTROL_VOL, 0},
    {2, CONTROL_VOL, 0},
    {3, CONTROL_VOL, 0},
    {4, CONTROL_VOL, 0},
    {5, CONTROL_VOL, 0},
    {6, CONTROL_VOL, 0},
    {7, CONTROL_VOL, 0},
    {8, CONTROL_VOL, 0},
    {9, CONTROL_VOL, 0},
    {10, CONTROL_VOL, 0},
  };

void midisetup()
{
  MIDI.begin(3);
}

// send the next midi command if time to send the previous one is exceeded 

void midiloop( void)
{
  static int chix = 0;
  static uint32_t last_midi = 0;

  if ((millis() - last_midi) > 0) {

    //Serial.printf("chix %d ch %d cn %d val %d\n", chix, midi_channels[chix].m_channel, midi_channels[chix].m_control, midi_channels[chix].m_value);
    
    MIDI.sendControlChange(midi_channels[chix].m_control, midi_channels[chix].m_value, midi_channels[chix].m_channel);
  
    chix = (chix+1) % MIDI_CHANNELS;
    last_midi = millis();
  }
}
 
Last edited:
I'm pleased to find I can give a very simple example - BasicTest from the OctoWS2811 library also has a problem with 1.8.4 but not 1.8.2. I'm using that unmodified on my setup (so not all the leds light)

It's very strange though : red, green, blue and yellow phases are fine. pink and orange flicker. white is OK. All on 1.8.4. But all are stable on 1.8.2 with no hardware changes.

Update : arduino 1.8.5 with Teensyduino 1.40 has the same problem.
 
Last edited:
if ((millis() - last_midi) > 0)...
Doesn't this fire every time?
Looks like it could pump out midi at an alarming rate....

Likely not the only issue but it might explain why not calling the midi function limits the problem.
 
The idea is that it doesn't do more than 1 transmission per millisecond, though I agree it's a bit dodgy. The message it sends lasts about 800us.

But while not calling that code stops the problem, merely commenting out the midi transmission doesn't stop it. It's the access to the midi_channels that does it (not incrementing chix so that only the first entry is ever examined also stops the flickering).
 
Last edited:
Where did you buy these WS2813 LEDs?

I have lots of WS2812B (both the older 6 pin version and the newer 4 pin types), but so far no WS2813. Maybe I'll get some for testing...
 
Where did you buy these WS2813 LEDs?

I have lots of WS2812B (both the older 6 pin version and the newer 4 pin types), but so far no WS2813. Maybe I'll get some for testing...

I think the 6 pin are actually 2812 and the 4 pin the 2812B.

I got them from Ray Wu - I bought 60m in the unpackaged form (just 0.5m strips). He seems to have a good reputation amongst DIY buyers. But they're widely available on ebay too.

https://www.aliexpress.com/store/701799?spm=2114.12010608.0.0.31bfab140E6TuN

I don't really think the 2813 is the issue, though I guess it could have fussier timing requirements than the 2812s. I do have some of the others available so will check whether it shows up on those too.
 
I've just noticed that the OctoWS2812 library uses pin 12 for frame sync.
I'm using pin 12 for MISO0, but I'm not doing multi-teensy video syncing.

I can see that pin 12 is manipulated in the video output driver example, but is it also used internally ?
If I'm not using it specifically in my code, is it OK to use it for SPI0 or does that need to be remapped to pin39 ?
 
Where did you buy these WS2813 LEDs?

I have lots of WS2812B (both the older 6 pin version and the newer 4 pin types), but so far no WS2813. Maybe I'll get some for testing...

I got a cheap WS2813 ring, and it seems to skip first LED. Or perhaps it is stricter about timing, but the 2nd-nth LEDs smoothed out the signal. I've decided I don't need the hassle, so it has gone to the junk drawer.
 
Here's some screenshots of 'Basic test' built with arduino 1.8.2 and 1.8.5. I only changed

const int config = WS2811_GRB | WS2811_800kHz;

to
const int config = WS2811_GRB | WS2813_800kHz;

(but I don't think it matters in this example.

Here's a shot of the 1.8.2-compiled version

image353.png

And here's the 1.8.5 version

image751.png

Here's the 1.8.5 version zoomed in

image31295.png

It seems that the last bit of the data in each frame gets left on the wire, violating the frame reset spec.

I've tried replacing the 1.8.5 library code (V4) with the 1.8.2 library code (V3) and it does then behave like 1.8.2 with the data line resting at zero. I haven't yet tested with LEDs attached.
 
Last edited:
Before we go any further, could you please check which version of Teensyduino you are using. Click Help > About in Arduino.

Also, add any error to your code and click Verify. If there is more than one copy of OctoWS2811, Arduino will show a message about the duplicates when it gives the error. Please use this to make sure you really have only 1 copy of the library installed. Often times we get reports like this, and the problem turns out to be an old copy lingering in Documents/Arduino/libraries.
 
Help->about says teensyduino 1.40

I've checked in libraries (actually ~/Arduino/libraries since I'm on linux) but there's no OctoWS2811.

When I did the following error test, I still had the Octows2811.cpp and OctoWS2811.h copied from
arduino-1.8.2/hardware/teensy/avr/libraries/OctoWS2811 to arduino-1.8.5/hardware/teensy/avr/libraries/OctoWS2811
(since that had an effect, I'd assume it was the copy being found.)

I do have multiple copies of arduino and teensyduino installed. I switch between them by executing a specific copy, e.g. /usr/local/arduino/arduino-1.8.5/arduino. None of the copies are on my $path, I get a default (1.8.5 at the moment) via a soft link from /usr/local/bin/arduino.


Here's the result of adding an error, verbose enabled :

Arduino: 1.8.5 (Linux), TD: 1.40, Board: "Teensy 3.5, Serial, 120 MHz, Faster, US English"

/usr/local/arduino/arduino-1.8.5/arduino-builder -dump-prefs -logger=machine -hardware /usr/local/arduino/arduino-1.8.5/hardware -hardware /home/adrian/.arduino15/packages -tools /usr/local/arduino/arduino-1.8.5/tools-builder -tools /usr/local/arduino/arduino-1.8.5/hardware/tools/avr -tools /home/adrian/.arduino15/packages -built-in-libraries /usr/local/arduino/arduino-1.8.5/libraries -libraries /home/adrian/Arduino/libraries -fqbn=teensy:avr:teensy35:usb=serial,speed=120,opt=o2std,keys=en-us -vid-pid=0X16C0_0X0483 -ide-version=10805 -build-path /tmp/arduino_build_256290 -warnings=none -build-cache /tmp/arduino_cache_20019 -verbose /tmp/arduino_modified_sketch_731324/BasicTest.ino
/usr/local/arduino/arduino-1.8.5/arduino-builder -compile -logger=machine -hardware /usr/local/arduino/arduino-1.8.5/hardware -hardware /home/adrian/.arduino15/packages -tools /usr/local/arduino/arduino-1.8.5/tools-builder -tools /usr/local/arduino/arduino-1.8.5/hardware/tools/avr -tools /home/adrian/.arduino15/packages -built-in-libraries /usr/local/arduino/arduino-1.8.5/libraries -libraries /home/adrian/Arduino/libraries -fqbn=teensy:avr:teensy35:usb=serial,speed=120,opt=o2std,keys=en-us -vid-pid=0X16C0_0X0483 -ide-version=10805 -build-path /tmp/arduino_build_256290 -warnings=none -build-cache /tmp/arduino_cache_20019 -verbose /tmp/arduino_modified_sketch_731324/BasicTest.ino
Using board 'teensy35' from platform in folder: /usr/local/arduino/arduino-1.8.5/hardware/teensy/avr
Using core 'teensy3' from platform in folder: /usr/local/arduino/arduino-1.8.5/hardware/teensy/avr
Detecting libraries used...
"/usr/local/arduino/arduino-1.8.5/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -felide-constructors -std=gnu++14 -fno-rtti -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -D__MK64FX512__ -DTEENSYDUINO=140 -DARDUINO=10805 -DF_CPU=120000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-I/usr/local/arduino/arduino-1.8.5/hardware/teensy/avr/cores/teensy3" "/tmp/arduino_build_256290/sketch/BasicTest.ino.cpp" -o "/dev/null"
"/usr/local/arduino/arduino-1.8.5/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -felide-constructors -std=gnu++14 -fno-rtti -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -D__MK64FX512__ -DTEENSYDUINO=140 -DARDUINO=10805 -DF_CPU=120000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-I/usr/local/arduino/arduino-1.8.5/hardware/teensy/avr/cores/teensy3" "-I/usr/local/arduino/arduino-1.8.5/hardware/teensy/avr/libraries/OctoWS2811" "/tmp/arduino_build_256290/sketch/BasicTest.ino.cpp" -o "/dev/null"
Using cached library dependencies for file: /usr/local/arduino/arduino-1.8.5/hardware/teensy/avr/libraries/OctoWS2811/OctoWS2811.cpp
Generating function prototypes...
"/usr/local/arduino/arduino-1.8.5/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -felide-constructors -std=gnu++14 -fno-rtti -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -D__MK64FX512__ -DTEENSYDUINO=140 -DARDUINO=10805 -DF_CPU=120000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-I/usr/local/arduino/arduino-1.8.5/hardware/teensy/avr/cores/teensy3" "-I/usr/local/arduino/arduino-1.8.5/hardware/teensy/avr/libraries/OctoWS2811" "/tmp/arduino_build_256290/sketch/BasicTest.ino.cpp" -o "/tmp/arduino_build_256290/preproc/ctags_target_for_gcc_minus_e.cpp"
"/usr/local/arduino/arduino-1.8.5/tools-builder/ctags/5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "/tmp/arduino_build_256290/preproc/ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"/usr/local/arduino/arduino-1.8.5/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -felide-constructors -std=gnu++14 -fno-rtti -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -D__MK64FX512__ -DTEENSYDUINO=140 -DARDUINO=10805 -DF_CPU=120000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-I/usr/local/arduino/arduino-1.8.5/hardware/teensy/avr/cores/teensy3" "-I/usr/local/arduino/arduino-1.8.5/hardware/teensy/avr/libraries/OctoWS2811" "/tmp/arduino_build_256290/sketch/BasicTest.ino.cpp" -o "/tmp/arduino_build_256290/sketch/BasicTest.ino.cpp.o"
BasicTest:48: error: 'nothing' was not declared in this scope
const int config = WS2811_GRB | WS2813_800kHz | nothing;
^
Using library OctoWS2811 at version 1.4 in folder: /usr/local/arduino/arduino-1.8.5/hardware/teensy/avr/libraries/OctoWS2811
'nothing' was not declared in this scope


option enabled in File -> Preferences.
 
I'm running BasicTest on a Teensy 3.2, programmed with Arduino 1.8.5 and Teensyduino 1.40. I'm running this on Ubuntu 14.04, 64 bit.

I edited the config line to this:

Code:
const int config = WS2811_GRB | WS2813_800kHz;

Here's what I see on my oscilloscope when I look at the output on pin 2.

file.png
 
Any chance you could look at the file you have, in /usr/local/arduino/arduino-1.8.5/hardware/teensy/avr/libraries/OctoWS2811/OctoWS2811.cpp and compare it against the code on github?

The problem you're describing, where the output stays stuck at the last bit from the prior frame, sounds like an issue fixed on July 3. Many people experienced the problem manifest as the first LED not working properly. The best I can tell you is I recognize that waveform, and it was the issue added by a patch earlier this year to support Teensy 3.5 & 3.6, and was indeed fixed on July 3. I retested just now to make sure the latest still is fixed, as you can see above.

How you're getting this problem *with* the latest versions, but *not* with the older ones is a mystery to me. I know it sounds improbable, but is there any chance your installs have somehow become mixed up, that you're somehow using the old OctoWS2811.cpp with Arduino 1.8.5?
 
Your suggestion certainly sounds likely, and your screen capture shows both what I'd expect and what I'm getting in the 1.8.2 build. I was also sampling pin 2. And what makes the first led fail on a 2812 could certainly have a different effect with the 2813, since it tries to validate the previous LED's data. In fact, one fault I've seen in my fullsize code is alternate leds flashing. Perhaps I nominated the wrong arduino directory when I installed teensyduino ?

But the copy I have in 1.8.4 and 1.8.5 looks like the latest from github, notably in the changes committed on jun15th. The properties file in the directory also mentions 1.4 in the latest installation and 1.3 in the earlier one.

I see, though, that you tested with teensy 3.2 and I used a 3.5. If I understand the changes correctly they are different between 3.2 and 3.5, and 3.6 is different again but didn't change. Could you try again on a 3.5 please ?

I have removed the 1.8.5 arduino and re-installed with the a newly-downloaded teensyduino. I still have the output left alternately high and low as in my screenshot.

I tried with a teensy 3.6. Both builds idle the data line low, but the bursts look shorter. Haven't checked what's going on with that yet.
 
Last edited:
I'm testing now. Just to confirm, it is indeed broken on Teensy 3.5 (but works on LC, 3.0, 3.2, 3.6). I'm working on a fix for 3.5....

file.png
 



Excellent, thank you. Confirmed working. Not only on Basic Test, but also with my original problem.

Which is puzzling, really - Basic test isn't much like my code, and remember that initial question was about why it would change when I stopped indexing that array - e.g. by changing the a table from bytes to ints, or removing the line that increments 'chix' in some other code unrelated to the LED colour . I was just hoping that something that produced a similar fault, changed under the same conditions (1.8.2->1.8.5) and was easy to reproduce, was related.

Any idea what was happening ? Are there some circumstances (a race condition perhaps) that I was only getting with some code but was always happening in Basic Test ?
 
... that initial question was about why it would change when I stopped indexing that array - e.g. by changing the a table from bytes to ints, or removing the line that increments 'chix' in some other code unrelated to the LED colour

If there's still an unresolved issue, please start a new thread. It's perfectly fine to ask for help with your code, but please do post a complete program which can be copied into Arduino and run on a Teensy to reproduce the problem.
 
If there's still an unresolved issue, please start a new thread. It's perfectly fine to ask for help with your code, but please do post a complete program which can be copied into Arduino and run on a Teensy to reproduce the problem.

Not really unresolved - my code seems to work fine with your fix.

I'm just curious as the effect of that bug : what does that counter do ?
 
It's a subtle issue with clearing the state of not-so-well-documented DMA request/ack bits between the timers and DMA mux. Freescale was not very consistent in how they implement this. Each chip seems to require slightly different steps. Sorry, no time for a lengthy message. I'm going through a long list of reported issues, before I (mostly) disappear for a few days on a special project.
 
Status
Not open for further replies.
Back
Top