A simple example to drive an APA-102 LED strip.

Dependencies:   mbed APA102b Ping SLCD

main.cpp

Committer:
rosienej
Date:
2015-04-14
Revision:
6:27f43abd16e2
Parent:
4:50ce957663ee

File content as of revision 6:27f43abd16e2:

#include "mbed.h"
#include "Ping.h"
#include "SLCD.h"

#include "APA102a.h"

SLCD slcd;
DigitalIn Button(PTC12);
Ping ping(PTA13); 

APA102a LEDs(PTA16, PTA17, PTA15,1000000); // mosi, miso, sclk, rate

// This function was downloaded from:
// http://blog.saikoled.com/post/43693602826/why-every-led-light-should-be-using-hsi 
// Blog Post attributed to Brian Neltner

// Function example takes H, S, I, and a pointer to the 
// returned RGB colorspace converted vector. It should
// be initialized with:
//
// int rgb[3];
//
// in the calling function. After calling hsi2rgb
// the vector rgb will contain red, green, and blue
// calculated values.
// 

void hsi2rgb(float H, float S, float I, int* rgb) {

  int r, g, b;
  H = fmod(H,360); // cycle H around to 0-360 degrees
  H = 3.14159*H/(float)180; // Convert to radians.
  S = S>0?(S<1?S:1):0; // clamp S and I to interval [0,1]
  I = I>0?(I<1?I:1):0;
    
  // Math! Thanks in part to Kyle Miller.
  if(H < 2.09439) {
    r = 255*I/3*(1+S*cos(H)/cos(1.047196667-H));
    g = 255*I/3*(1+S*(1-cos(H)/cos(1.047196667-H)));
    b = 255*I/3*(1-S);
  } else if(H < 4.188787) {
    H = H - 2.09439;
    g = 255*I/3*(1+S*cos(H)/cos(1.047196667-H));
    b = 255*I/3*(1+S*(1-cos(H)/cos(1.047196667-H)));
    r = 255*I/3*(1-S);
  } else {
    H = H - 4.188787;
    b = 255*I/3*(1+S*cos(H)/cos(1.047196667-H));
    r = 255*I/3*(1+S*(1-cos(H)/cos(1.047196667-H)));
    g = 255*I/3*(1-S);
  }
  rgb[0]=r;
  rgb[1]=g;
  rgb[2]=b;
}
/// pseudo random number
unsigned int m_z=12434,m_w=33254;

unsigned int rnd() {
    m_z = 36969 * (m_z & 65535) + (m_z >>16);
    m_w = 18000 * (m_w & 65535) + (m_w >>16);
    return ((m_z <<16) + m_w);
}

int main()
{
    // Quick example to drive an APA-102 LED Strip from a FRDM-KL46z
    
    // http://www.insomnialighting.com/catalog/index.php?main_page=product_info&products_id=61
    // Wire the unit up to SPI, common ground and give it 5 volt power.
    
    // Shift through the spectrum, slowly rotate.
    
    // Setup the spi for 8 bit data, high steady state clock,
    // second edge capture, with a 1MHz clock rate

    int rgb[3]; 
    unsigned char r,g,b;
    const int N=66;  // Number of APA-102 Elements 
   // const int N=144;
    int range;
    unsigned int Pixel;
    unsigned int Pixels[N];
    
    float hue,sat,ints;
    float hue_adjust =0;
    
    const int NumberOfRays = 19;
    
    
    float RayHues[19] =   // hues are 0 to 360, http://en.wikipedia.org/wiki/HSL_and_HSV
    {0.0,19.0,38.0,57.0,76.0,95.0,114.0,
    133.0,152.0,171.0,190.0,209.0,228.0,
    247.0,266.0,285.0,304.0,323.0,342.0};
    
    float RaySats[19] =   // hues are 0 to 360, http://en.wikipedia.org/wiki/HSL_and_HSV
    {0.8,0.8,0.8,0.8,0.8,0.8,0.8,
     0.8,0.8,0.8,0.8,0.8,0.8,0.8,
     0.8,0.8,0.8,0.8,0.8};
    
     float RayInts[19] =   // hues are 0 to 360, http://en.wikipedia.org/wiki/HSL_and_HSV
    {0.8,0.8,0.8,0.8,0.8,0.8,0.8,
     0.8,0.8,0.8,0.8,0.8,0.8,0.8,
     0.8,0.8,0.8,0.8,0.8};
    
    int RayLengths[19] = {3, 4, 5, 4, 2, 5, 4, 2,   4,5,3,4,3,2,2,3,2,4,5};
    
    int Rays[19][5] = {
        {1 ,20,39, 0, 0},  //3 
        {2 ,21,40,53, 0},  //4
        {3 ,22,41,54,64},  //5
        {4 ,23,42,55, 0},  //4
        {5 ,24, 0, 0, 0},  //2
        {6 ,25,43,56,65},  //5
        {7 ,26,44,57, 0},  //4
        {8 ,27, 0, 0, 0},  //2
        {9 ,28,45,58, 0},  //4
        {10,29,46,59,66},  //5
        {11,30,47, 0, 0},  //3
        {12,31,48,60, 0},  //4
        {13,32,49, 0, 0},  //3
        {14,33, 0, 0, 0},  //2
        {15,34, 0, 0, 0},  //2
        {16,35,50, 0, 0},  //3
        {17,36, 0, 0, 0},  //2
        {18,37,51,61,0},   //4
        {19,38,52,62,63}}; //5
        
    
    int colors=0x000000;
    
    int Mode=0;
    const int NModes = 8;
    
    LEDs.SetBuffer(Pixels,1,N, N,0, false,false); 
        slcd.Home();                                   
        slcd.printf("%d",Mode);   
    
    
       
    while (true) {
        ping.Send();    
        wait_ms(50);  // update rate.
        range = ping.Read_cm();
        colors+=range/10;
        
        if (!Button ){ 
            Mode++;
            Mode = (Mode %NModes);
            slcd.Home();                                   
            slcd.printf("%d",Mode);   
            
            }
        
        for(int i = 0;i<19;i++) RaySats[i] = 0.8;
        for(int i = 0;i<19;i++) RayInts[i] = 0.8;
        
        
        switch(Mode){
            case 0: hue_adjust =0;
                    break; // just display the last "static" image
            case 1: hue_adjust = range; // rotate the hue by the range
                    break;
            case 2: hue_adjust = colors; // change the spin rate by the range
                    break;
            case 3: hue_adjust++; // spin at a fixed rate
                    break;
            case 4: for(int i = 0;i<19;i++) RaySats[i] = 1.0/(1.0*(rnd()%16+1));
                    break;
            case 5: for(int i = 0;i<19;i++) RayInts[i] = 1.0/(1.0*(rnd()%16+1));
                    break;
            case 6: for(int i = 0;i<19;i++) RayInts[i] = 1.0/(1.0*(rnd()%16+1));
                    for(int i = 0;i<19;i++) RaySats[i] = 1.0/(1.0*(rnd()%16+1));
                    break;
            case 7: hue_adjust = rnd()%16;
                    break;
                    
            }
        
        
        for(int i=0;i<NumberOfRays;i++)
        {   
          for(int j=0;j<RayLengths[i];j++)
          {
        
                hue  = RayHues[i]+ hue_adjust;
                sat  = RaySats[i];
                ints = RayInts[i];
                hsi2rgb(hue, sat, ints,rgb);
                r = rgb[0];
                g = rgb[1];
                b = rgb[2];
                
                Pixel=LEDs.IRGB(7,r,g,b);
                Pixels[Rays[i][j]-1]=Pixel;  // arrays in C++ start at zero.  Need to subtract 1.
            
            } 
         }
   /*     
        for(int i=0;i<N;i++)
        {
           hue = (1.0*i)/(1.0*N) * 360 + hue_adjust;
           sat = 0.8;
           ints = 0.7;
           hsi2rgb(hue, sat, ints,rgb);
                r = rgb[0];
                g = rgb[1];
                b = rgb[2];
                
                Pixel=LEDs.IRGB(7,r,g,b);
                Pixels[i]=Pixel;  
            } 
            */
        LEDs.Repaint();
        
    }
}