Forum Rule: Always post complete source code & details to reproduce any issue!
Page 3 of 3 FirstFirst 1 2 3
Results 51 to 56 of 56

Thread: OctoWS2811 POV reading BMP from SD card

  1. #51
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Ayer Massachussetts
    Quote Originally Posted by mortonkopf View Post

    if you already have this code, try putting this line just below your includes:

    unsigned int Color(byte b, byte g, byte r)
    That line is missing the ending semicolon. That line should be:

    unsigned int Color(byte b, byte g, byte r);

  2. #52
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    London, uk
    Good Catch MM

  3. #53
    can OctoWS2811 Lib run APA102 Leds or do we have to convert it, Id like to have the code running on those type of LEDs sofar. been using the Teensy 3.5 ant wanting to know what alteration to the code have to be done

  4. #54
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Ayer Massachussetts


    Quote Originally Posted by synersignart View Post
    can OctoWS2811 Lib run APA102 Leds or do we have to convert it, Id like to have the code running on those type of LEDs sofar. been using the Teensy 3.5 ant wanting to know what alteration to the code have to be done
    The OctoWS2811 library only handles WS2812 (aka what Adafruit calls neopixel) LEDs.

    If you wanted to use APA102 LEDs, you could use the Octows2811 board to provide the infrastructure, but you would need to use something else to drive the LEDs. I believe the FastLed library might be able to drive the APA102's in parallel, but I've never used it.

    You would need to use 4 parallel sets of APA102 LEDs since WS2812 LEDs only have one data pin and the clock is done at fixed intervals, APA102 LEDs have both a data and a clock pin, so you would need to use two wires for each strand, hence only 4 parallel rows instead of 8.

  5. #55
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    London, uk
    hi, have a read of Po Ting work using APA102 reading from SD Card for POV. its at the end of the thread here:

  6. #56
    Quote Originally Posted by niknak35 View Post
    I've been working on adapting this for APA102 strips. This code works but only displays 2 of the 3 RGB colors. Anyone have any luck getting this to work with APA102 strips?

    //#include <OctoWS2811.h>// ensure you are on PIN 2 + PINS 15 and 16 bridge 
    #include <SdFat.h>
    #include "FastLED.h"
    //OCtoWS2811 library from the good folk at PJRC
    //SDfat library from this brilliant person 
    // most of the code for the buffer workings come from (many thanks)
    //for SD card wiring
    //MOSI goes to pin 11
    //MISO goes to pin 12
    //SCLK goes to pin 13
    //SS goes to pin 10 
    #define NUM_LEDS 45
    #define DATA_PIN 4
    // Clock pin only needed for SPI based chipsets when not using hardware SPI
    #define CLOCK_PIN 3
    //fixed values for octoWS2811
    CRGB leds[NUM_LEDS];
    //for SD_Fat
    SdFile myFile;
    #define SD_CS SS // Set the chip select line to whatever you use (10 doesnt conflict with the library)
    SdFat sd; // set filesystem
    SdFile bmpFile; // set filesystem
    //for image processing
    #define BUF_SIZE 441//180//10240
    #define BUFFPIXEL 50//20//147
    int bmpLength = 45;//these two need filling in first
    int paintTime =40;//these two need filling in first
    int time = paintTime/bmpLength;
    // because the BMP is read from the bottom first, and we are displaying this using a POV wand,
    // the BMP needs to be saved on its side to display correctly when the POV is waved, that is
    // turned by 90 degrees, then saved as a 24bit bmp to the SD card
    // BMP needs to be NUM_LEDS high when saving a version to the BMP.
    // In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
    ArduinoOutStream cout(Serial);
    // store error strings in flash to save RAM
    #define error(s) sd.errorHalt_P(PSTR(s))
    void setup()
      FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(leds, NUM_LEDS);
    //  Serial.begin(9600); //for bug testing and speed checking using serial
    //  delay(100);
      progmemPrint(PSTR("Initializing SD card..."));
      if (!sd.begin(SD_CS, SPI_FULL_SPEED)) {
    void loop()
    //  upDown(5000); //this is a test pattern
    //Chaser(2000,1); //this is a test pattern
    //Blue_flower(5000,2); //this is a test pattern
    //  bmpDraw("diam.bmp",1000);
    //  bmpDraw("wing.bmp",1000);
     //   bmpDraw("ball.bmp",1000);//filename and time in ms to keep displaying
    //    for(int a=0;a<NUM_LEDS;a++){
    //    leds[a].setRGB(0,0,100);}//b,r,g - tested with single colour here
    //delay (10000);
    //some patterns
     void upDown(unsigned long time){
       unsigned long currentTime = millis();
     while (millis()< currentTime + (time)) {
       for (int i=0;i<NUM_LEDS;i++) { 
        for (int i=NUM_LEDS-1;i>0;i--) { 
    // ////////////////////////////////Chaser
    //void Chaser(long time, int frame){
    //unsigned long currentTime = millis();
    //unsigned int Colour2 = setRGB(255,0,0);//brg
    //unsigned int Colour =setRGB(0,0,0);
    //unsigned int Colour1 =setRGB(0,255,255);
    //int Led1 =0;
    //int Led2 =NUM_LEDS-1;
    //int increment =1;
    //int increment2=1;
    //while (millis()< currentTime + (time)) {
    //; delay(1);
    //for(int x = 0 ; x < NUM_LEDS ; x++) 
    //else if(Led1<0){increment=1;}
    //Led1 = Led1+increment;
    //else if(Led2>NUM_LEDS-1){increment2=-1;}
    //Led2 = Led2+increment2;
    //Led1 =0;
    //Led2 =NUM_LEDS-1;
    //increment =1;
     ///////////////////////////////////////////blue flower
     void Blue_flower(long time, int frame){
    unsigned long currentTime = millis();
    while (millis()< currentTime + (time)) {
     byte Counter;
     for(Counter=0;Counter < NUM_LEDS; Counter++)
    // Show a colour bar going down from 9 to 0
    byte Counter2;
    for(Counter2=NUM_LEDS;Counter2 > 0; Counter2--)
    void bmpDraw(char* filename){
    // unsigned long currentTime = millis();
     //so that the image continues to be displayed again for a set time
    //   while (millis()< currentTime + (time)) {
      SdFile   bmpFile;
      int      bmpWidth, bmpHeight;   // W+H in pixels
      uint8_t  bmpDepth;              // Bit depth (currently must be 24)
      uint32_t bmpImageoffset;        // Start of image data in file
      uint32_t rowSize;               // Not always = bmpWidth; may have padding
      uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel) 
      /*uint16_t*/uint32_t povbuffer[BUFFPIXEL];  // pixel out buffer (16-bit per pixel)//////mg/////this needs to be 24bit per pixel////////
      uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
      boolean  goodBmp = false;       // Set to true on valid header parse
      boolean  flip    = true;        // BMP is stored bottom-to-top
      int      w, h, row, col;
      /*uint8_t*/int  r, g, b;
      uint32_t pos = 0, startTime = millis();
      uint8_t  povidx = 0;
      boolean  first = true;
      // Open requested file on SD card, O_READ);
      // Parse BMP header
      if(read16(bmpFile) == 0x4D42) { // BMP signature
        progmemPrint(PSTR("File size: ")); 
        (void)read32(bmpFile); // Read & ignore creator bytes
        bmpImageoffset = read32(bmpFile); // Start of image data
        progmemPrint(PSTR("Image Offset: ")); 
        Serial.println(bmpImageoffset, DEC);
        // Read DIB header
        progmemPrint(PSTR("Header size: ")); 
        bmpWidth  = read32(bmpFile);
        bmpHeight = read32(bmpFile);
        if(read16(bmpFile) == 1) { // # planes -- must be '1'
          bmpDepth = read16(bmpFile); // bits per pixel
          progmemPrint(PSTR("Bit Depth: ")); //Serial.println(bmpDepth);
          if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
            goodBmp = true; // Supported BMP format -- proceed!
            // BMP rows are padded (if needed) to 4-byte boundary
           rowSize = (bmpWidth * 3 + 3) & ~3;
            // If bmpHeight is negative, image is in top-down order.
            // This is not canon but has been observed in the wild.
            if(bmpHeight < 0) {
              bmpHeight = -bmpHeight;
              flip      = false;
            w = bmpWidth;
            h = bmpHeight;
         for (row=0; row<h; row++) {       
             if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
                pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
              else     // Bitmap is stored top-to-bottom
                pos = bmpImageoffset + row * rowSize;
              if(bmpFile.curPosition() != pos) { // Need seek?
                buffidx = sizeof(sdbuffer); // Force buffer reload
              for (col=0; col<w; col++) { // For each column...
                // read more pixel data
               if (buffidx >= sizeof(sdbuffer)) { 
                 povidx = 0;         
        , sizeof(sdbuffer));
                  buffidx = 0; // Set index to beginning
                // set pixel
                r = sdbuffer[buffidx++];
                g = sdbuffer[buffidx++];
                b = sdbuffer[buffidx++];
    //we need to output BRG 24bit colour//
                povbuffer[povidx++] =((unsigned int)b & 0x1F <<16 | ((unsigned int)r & 0x1F)<<8 | ((unsigned int)g & 0x1F));
                //Color(b,r,g);//octo colour, but you might need to change this
            for(int i=0;i<NUM_LEDS;i++){
       leds[i]=povbuffer[i]; }
            delay(time);// change the delay time depending effect required
           //   delayMicroseconds(220);
        } // end scanline
    //        progmemPrint(PSTR("Loaded in ")); //for bug testing using serial output
    //        Serial.print(millis() - startTime);
    //        Serial.println(" ms");
          } // end goodBmp
    //  Serial.println(read16(bmpFile), HEX);
    //------- HELPER FUNCTION------//
    // Create a 24 bit color value from R,G,B ////these strips are BRG, but you might need to change this
    unsigned int Color(byte b/*r*/, byte g, byte /*b*/r)
      //Take the lowest 8 bits of each value and append them end to end
    return( ((unsigned int)g & 0x1F )<<16 | ((unsigned int)r & 0x1F)<<8 | (unsigned int)b & 0x1F);
    //end of helper function
    // These read 16- and 32-bit types from the SD card file.
    // BMP data is stored little-endian, Arduino is little-endian too.
    // May need to reverse subscript order if porting elsewhere.
    uint16_t read16(SdFile& f) {
      uint16_t result;
      ((uint8_t *)&result)[0] =; // LSB
      ((uint8_t *)&result)[1] =; // MSB
      return result;
    uint32_t read32(SdFile& f) {
      uint32_t result;
      ((uint8_t *)&result)[0] =; // LSB
      ((uint8_t *)&result)[1] =;
      ((uint8_t *)&result)[2] =;
      ((uint8_t *)&result)[3] =; // MSB
      return result;
    // Copy string from flash to serial port
    // Source string MUST be inside a PSTR() declaration!
    void progmemPrint(const char *str) {
      char c;
      while(c = pgm_read_byte(str++)) Serial.print(c);
    // Same as above, with trailing newline
    void progmemPrintln(const char *str) {
    Iím having the same problem. Got everything rolling but I cant seem to get the proper colors for the apa102ís displaying. Did you ever get this issue fixed?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts