Quantcast
Channel: MSP430 Technical Forums
Viewing all articles
Browse latest Browse all 2077

Struct, classes and a strange error.

$
0
0

Hi,

 

I am using a MSP430 and Energia to drive two neopixel sticks with eight LEDS on each. I am running into a weird error. I am a creating a class for each stick which will provide different animations. I am using a struct to hold the colour values. I am unable to get the two neopixel sticks to display different animations. What is weird is that if I remove the rainbow portion of the code, along with the structs it uses, I can get two different animations to display. When I add code back in line by line, I lose the multiple animations when adding the rainbow struct back in. I have a feeling that I am possibly not using structs the correctly, could there be a memory overflow that I am not aware of somehow? I have posted the code below, in the hopes that someone with more knowledge could shed some light on this.

 

Edit. I am able to get different animations on each neopixel stick, but only on four leds per stick. Am I running out of memory?

 

Thanks

  Jason

#include <WS2811Driver.h>

// Pattern types supported:
enum  pattern { NONE, BREATHE, RAINBOW };
enum  direction { UP, DOWN };

boolean FadeDone = false;

typedef struct Colours
{
   uint8_t  red;
   uint8_t  green;
   uint8_t  blue;
   uint16_t  hue;  // 0-360
   uint8_t sat; // 0 is pure white light
   uint8_t val; // Brightness
} ;

class animateStrip : public WS2811Driver
{
  //************************************************************************* 
  //    Class Initialisation
  //*************************************************************************     
  public:
  pattern CurrentPattern;  // Which pattern is running
  direction Direction;
  unsigned long Interval;  // Delay time
  unsigned long LastUpdate;  // Time of last update
 
  Colours RGB;
  Colours rainbowStart_RGB;
  Colours rainbowCurr_RGB;
  Colours rainbowEnd_RGB; 
    
  uint8_t TotalSteps;  // Steps in the animation
  uint8_t Index;
  
  void (*OnComplete)();
  animateStrip(uint8_t pixels, uint8_t pin, uint8_t type, void (*callback)()):WS2811Driver(pixels, pin, type)
  {
    OnComplete = callback;
  }

//************************************************************************* 
//    Update and state tracking functions    
//*************************************************************************    
  
  void Update()
  {
    if((millis() - LastUpdate) > Interval) // time to update
    {
      LastUpdate = millis();
      switch(CurrentPattern)
      {
         case BREATHE:
            BreatheUpdate();
            break;
         case RAINBOW:
            RainbowUpdate();
            break;
       }
     }
  }
 
  void Increment()
  {
  if (Direction == UP)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        FadeDone = true;  
          if (OnComplete != NULL)
          {
            OnComplete(); // call the comlpetion callback
          }
      }
    }
    else // Direction == DOWN
    {
       --Index;
       if (Index <= 0)
       {
         Index = TotalSteps-1;
          FadeDone = true;
         if (OnComplete != NULL)
         {
           OnComplete(); // call the comlpetion callback
         }
       }
    }
  }
    // Reverse pattern direction
   void Reverse()
   {
     if (Direction == UP)
     {
       Direction = DOWN;
       Index = TotalSteps-1;
     }
     else
     {
       Direction = UP;
       Index = 0;
     }
   }
//************************************************************************* 
//    Animation functions    
//*************************************************************************         
    
  void Breathe(uint16_t delayTime, uint8_t Colour) // Initialise for a fade in
  {
    CurrentPattern = BREATHE;
    Interval = delayTime;
    TotalSteps = 255;
    Index = 0;
    RGB.hue = 0;
    RGB.sat = 255;
    RGB.val = 255; 
  }
  // Do the actual fade in
  void BreatheUpdate()
  {
   if (Index == 0) { RGB.hue = random(0,360); } // Add a random colour
     setBrightness(Index);
     RGB = HSVtoRGB2(RGB);
     ColorSet(RGB);
     Increment();
     if (Index == 254) { Reverse(); }
  }
 
  void Rainbow(uint16_t steps, uint16_t delayTime) 
  {
    CurrentPattern = RAINBOW;
    Interval = delayTime;
    TotalSteps = steps;
    Index = 0;
        
    rainbowStart_RGB.hue = random(0, 360);
    rainbowStart_RGB.val = 255;
    rainbowStart_RGB.sat = 255;
    
    rainbowEnd_RGB.hue = 0;//random(0,360);
    rainbowEnd_RGB.sat = 255;
    rainbowEnd_RGB.val = 255;
    rainbowStart_RGB = HSVtoRGB2(rainbowStart_RGB);
    rainbowEnd_RGB = HSVtoRGB2(rainbowEnd_RGB);
    
}

  void RainbowUpdate()
  {
    
    rainbowCurr_RGB.red =   ((rainbowStart_RGB.red   * (TotalSteps - Index)) + (rainbowEnd_RGB.red * Index)) 
                              / TotalSteps;
    rainbowCurr_RGB.green = ((rainbowStart_RGB.green * (TotalSteps - Index)) + (rainbowEnd_RGB.green * Index)) 
                              / TotalSteps;
    rainbowCurr_RGB.blue =  ((rainbowStart_RGB.blue  * (TotalSteps - Index)) + (rainbowEnd_RGB.blue * Index)) 
                              / TotalSteps;
    rainbowCurr_RGB.sat = 255;
    rainbowCurr_RGB.val = 255;
    ColorSet(rainbowCurr_RGB);
    show();
    Increment();
  
    if (FadeDone) 
    { 
      rainbowStart_RGB = rainbowCurr_RGB;
      rainbowEnd_RGB.hue = random(0,360);
      rainbowEnd_RGB = HSVtoRGB2(rainbowEnd_RGB);
      FadeDone = false;
    }
  }
  
  
    
//************************************************************************* 
//    Helper functions    
//*************************************************************************     
    
  void ColorSet(Colours thisRGB)
  // Sets all pixels to the same colour
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, thisRGB.red, thisRGB.green, thisRGB.blue);
    }
    show();
  }
    
  Colours HSVtoRGB2(Colours rgb) 
  {
    // hue: 0-359, sat: 0-255, val (lightness): 0-255
    int r, g, b, base;
  
    base = ((255 - rgb.sat) * rgb.val)>>8;
    switch(rgb.hue/60) {
    case 0:
      r = rgb.val;
      g = (((rgb.val-base)*rgb.hue)/60)+base;
      b = base;
      break;
    case 1:
      r = (((rgb.val-base)*(60-(rgb.hue%60)))/60)+base;
      g = rgb.val;
      b = base;
      break;
    case 2:
      r = base;
      g = rgb.val;
      b = (((rgb.val-base)*(rgb.hue%60))/60)+base;
      break;
    case 3:
      r = base;
      g = (((rgb.val-base)*(60-(rgb.hue%60)))/60)+base;
      b = rgb.val;
      break;
    case 4:
      r = (((rgb.val-base)*(rgb.hue%60))/60)+base;
      g = base;
      b = rgb.val;
      break;
    case 5:
      r = rgb.val;
      g = base;
      b = (((rgb.val-base)*(60-(rgb.hue%60)))/60)+base;
      break;
    }
    rgb.red=r;
    rgb.green=g;
    rgb.blue=b;
    return rgb;
  }
  
// End of class 
};

//************************************************************************* 
//    Setup and main functions    
//*************************************************************************  
animateStrip stick1(8, P1_4, NEO_GRB, &StickCompleteNOP);
animateStrip stick2(8, P2_4, NEO_GRB, &StickCompleteNOP);

void setup() {
   
  stick1.begin();
  stick2.begin();
  
  stick1.Rainbow(20, 20);
  stick2.Breathe(10, 10);
 
  //Serial.begin(9600);
  //Serial.println("Setup OK");
}

void loop() {
   //Serial.println("Loop");
   stick1.Update();
   stick2.Update();
  
   
}

//************************************************************************* 
//    Completion functions    
//*************************************************************************  

void StickCompleteNOP()
{
  return;  
}

Viewing all articles
Browse latest Browse all 2077

Trending Articles