OctoWS2811 leds.show() and IntervalTimer issue.

Status
Not open for further replies.

HopWorks

Active member
I have three interval timers going. One for serial communications, one that flashes the on-board LED, and one that is for led strip effects. All is good except I added OctoWS2811 support for my WS2812 LEDs and now it hangs. I wanted to flash one LED on the strip when I handle the on-board LED as a test. When I add leds.show() to my LED flashing function, the 3.1 appears to hang. Could it be an interrupt conflict of some kind? Can I use interval timers with the OctoWS2811 library? If so, what special considerations should I include?

I ran the basic test and the LED strip lights up and changes colors as expected.

The code is pretty busy but it works just fine. I didn't strip out all the other stuff yet. I want to control the LED strip with my Teensy 3.1 using serial commands from my Teensy 3.0. The blue tooth module works fine too and I haven't decided which teensy to attach it to yet. It establishes a link with my Motorola Droid.

Code:
//LED Strip Setup
#include <OctoWS2811.h>

const int ledsPerStrip = 60;

DMAMEM int displayMemory[ledsPerStrip*6];
int drawingMemory[ledsPerStrip*6];

const int config = WS2811_GRB | WS2811_800kHz;

OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);

IntervalTimer myTimer;
IntervalTimer ledfx;
IntervalTimer comm;
volatile unsigned int oc=0;      //LED cycle counter
volatile unsigned int ocL=0;     //LED cycle limit (alternates between ocL1 and ocL2) 
volatile unsigned int ocL1=100;  //LED on duration (cycles)
volatile unsigned int ocL2=2000; //LED off duration (cycles)
volatile unsigned int ledstate=0;//Initial LED state (toggles)
volatile unsigned int a1=0;      //a1-a5 are for debugging
volatile unsigned int a2=0;
volatile unsigned int a3=0;
volatile unsigned int a4=0;
volatile unsigned int a5=0;
volatile boolean term=LOW;
volatile unsigned char serial_rx[64];
volatile unsigned char serial_tx[64];
volatile unsigned int s_rx_in=0;
volatile unsigned int s_tx_in=0;
volatile unsigned char com[256];
volatile unsigned int com_in=0;
volatile unsigned int com_out=0;
volatile unsigned char led_com[512];
volatile unsigned int led_com_idx=0;
volatile unsigned char led_fx[512];
volatile unsigned int led_fx_idx=0;
volatile boolean command=LOW;
volatile boolean response=LOW;

char a = 0;
const int led = LED_BUILTIN;
String cmd=""; 

void setup()
{
  leds.begin();
  leds.show();

  Serial2.begin(9600); // USB is always 12 Mbit/sec
  Serial1.begin(9600); // Start up Bluetooth Module
  pinMode(led, OUTPUT);
  myTimer.begin(toggle_led_isr,1000);
  ledfx.begin(led_fx_isr,50);
  comm.begin(communications_isr,10);
  digitalWrite(led, HIGH);
  digitalWrite(led, LOW);
  
  Serial2.print("HopWorks / Droid 4 Bluetooth Link Test #1\n");
  Serial2.print("NODE - TEENSY 3.1\n");
  Serial1.print("HopWorks / Droid 4 Bluetooth Link Test #1\n");
  Serial1.print("NODE - BLUE TOOTH MODULE\n");
}
#define RED    0xFF0000
#define GREEN  0x00FF00
#define BLUE   0x0000FF
#define YELLOW 0xFFFF00
#define PINK   0xFF1088
#define ORANGE 0xE05800
#define WHITE  0xFFFFFF

void loop()
{
  boolean cc;
  noInterrupts();
  cc=command;
  interrupts();

  if(cc==HIGH){
    String mycom=pop_command();
    char charbuf[50];
    mycom.toCharArray(charbuf,50);
    Serial1.print(mycom.length());
    Serial1.print(' ');
    Serial1.print(a1);
    Serial1.print(' ');
    Serial1.print(a2);
    Serial1.print(' ');
    Serial1.print(a3);
    Serial1.print(' ');
    Serial1.print(a4);
    Serial1.print(' ');
    Serial1.print(a5);
    Serial1.print('\n');

    Serial1.print("  0  2  3  4  5  6  7  8  9 10 11 12 13 14 15\n");
    for(int i=0;i<15;i++){
      Serial1.print("|");
      Serial1.print(hex(charbuf[i]));
    }
    Serial1.print("|\n");
    Serial1.println(mycom);
  }

}

String hex(int a){
  String temp=String(a,HEX);
  if(temp.length()==1){
    temp="0"+temp;
  }
  return temp;
}


void toggle_led_isr(void)
{
  oc++;
  if(oc>ocL){
    if(ledstate==LOW){
      //leds.setPixel(1, 255);//uncommenting prevents on-board LED flash. hang?
      //leds.show();
      ledstate=HIGH;
      ocL=ocL1;
    }else{
      //leds.setPixel(1, 0);//uncommenting prevents on-board LED flash. hang?
      //leds.show();
      ledstate=LOW;
      ocL=ocL2;
    }
    oc=0;
    digitalWrite(led, ledstate);
  }
}

void led_fx_isr(void)
{
}
void communications_isr(void)
{
    if (Serial2.available()){
      char a=(char)Serial2.read();
      if(a=='~'){
        term=HIGH;
      }
      if(a==13){
        push_command();
      }else{
	serial_rx[s_rx_in]=a;
	s_rx_in++;
      }
      Serial2.write(a);
    }
    if (Serial1.available()){
      char a=(char)Serial1.read();
      s_tx_in++;
      serial_tx[s_tx_in]=a;
      if(a==13){
        response=HIGH;
      }
      Serial2.write(a);
      Serial1.write(a);
    }
}
void push_command(void){
  a1=s_rx_in;
  
  for(unsigned int i=0;i<s_rx_in;i++){
    com[com_in]=serial_rx[i];
    com_in++;
  }
  a2=com_in;
  com[com_in]=0;
  com_in++;

  s_rx_in=0;
  command=HIGH;
}
String pop_command(void){
  noInterrupts();
  char mycmd[64]="";
  int i=0;
  while(com[i]!=0){
    mycmd[i]= com[i];
    i++;
  }
  mycmd[i]=0;
  i++;
  for(int i2=0;i2<(256-i);i2++){
    com[i2]=com[i+i2];
  }
  a3=i;
  a4=com_in;
  com_in-=i;
  if(com_in==0) command=LOW;
  a5=com_in;
  String str(mycmd);
  interrupts();
  return mycmd;
}
 
Well, I confirmed that calling leds.show() from an IntervalTimer function doesn't work, but doing it outside the function works just fine. After reading more about IntervalTimers, and the Metro library, I decided to give a non-interrupt solution a try. I want the LED effects to be precise, not stuttering when serial communications are happening, but perhaps all-interrupt timing is overkill.
 
Status
Not open for further replies.
Back
Top