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

Thread: OctoWS2811 POV reading BMP from SD card

  1. #26
    The BMP only displays once and the variable changes the speed at which it displays once. To clarify Thats what i got so far....

  2. #27
    Ok so I got the BMP issues resolved. I used a different work around for it but is working nicely now. Only thing is I cant display more then 85 leds. 86 or more make the stripe freeze. Lights come on most of the leds but just frozen not moving. I want to try some light painting!!! Any help would be great Im sure its just a setting I need to change.

  3. #28
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    916
    Well, could be power or code. How are you powering the LEDs and teensy? Also, are you using a bigger BMP with the longer length if LEDs? There may be a buffer issue. Also did you try the count loop approach instead for the repeating BMP as an alternative ?
    Last edited by mortonkopf; 05-21-2015 at 06:44 PM.

  4. #29
    USB 5v
    BMP is 150x600 pixels and code set to 150leds
    I just stacked the images in the BMP instead if messing with the code

  5. #30
    The patterns work fine on the 150 leds if that helps.

  6. #31
    If set to 150led and I put a BMP of 85pixels or smaller it will display BMP on 85pixels and patterns on all 150 leds.

  7. #32
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    916
    Yep, sounds more like a coding or buffer issue. What part of the code did you change as I have 147 LEDs working no problem in the original code

  8. #33
    Only changed
    const int ledsPerStrip = 150;//60;
    #define BUF_SIZE 10240//180//10240
    #define BUFFPIXEL 150//20//147
    and added BMP

  9. #34
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    916
    I think that buf_size needs to be put back to the three time led size value. For the original sketch it was 441 for three lots of 147 LEDs. So, set it to 450 or 512 and see if this resolves it. I am away at the moment, so can't test the issue.

  10. #35
    Still unable to display more than 85 pixels changed buffer size to 450. Did you have a chance to test settings?

  11. #36
    Did you use a 74HCT245 buffer chip?

  12. #37
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    916
    TekJunky, been away, hopefully I can get to revisit it this evening, but time is very limited right now.

  13. #38
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    916
    @TekJunky, in the drawBMP routine try changing povidx line to "uint16_t povidx = 0;" I think that it was a simple overrun of the uint8_t. You can set the BUFF_SIZE to 512. BUFFPIXEL should be set to the same size as your number of pixels (strip length).
    here is a picture of 147 led pixel staff I just took displaying two bmp from the sd card:
    Click image for larger version. 

Name:	lightstaff.jpg 
Views:	138 
Size:	131.7 KB 
ID:	4460
    Last edited by mortonkopf; 06-08-2015 at 07:03 PM.

  14. #39
    Junior Member
    Join Date
    May 2015
    Posts
    12
    Has anyone been able to get this to pick a file at random off the SD card? Ive been trying to modify the sketch todo so but it's failed horribly.

  15. #40
    Thanks mortonkopf ill check it in just a few and let you know.

  16. #41
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    916
    The following change is confirmed to work for using longer led strips for light painting or pov:
    was -- uint8_t buffidx = sizeof(sdbuffer);
    Changed to -- uint16_t buffidx = sizeof(sdbuffer);
    Fixed Display issues all 150 leds working properly now

  17. #42
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,743
    If you are storing the result of sizeof, the correct type to use is size_t. If you need a signed type instead of unsigned that is the same size use the type ssize_t. Those types are guaranteed to be big enough to hold the size of the maximum object in the system.

  18. #43
    Junior Member
    Join Date
    Aug 2015
    Posts
    1
    Hi all
    Hope im not bringing up an old post just got a couple of questions about the lightwand by mortonkopf has anyone had any luck with the APA102 led strip ? does the code work on teensy 3.1 ?
    Cheers

  19. #44
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    916
    @lumberg. I have not tried it with APA102. I have some ordered, and hope to get round to sorting out the two. Both the SD card and the APA102 will need to work together, and I have not tried this setup yet. I see from the latest FastLed (3), you can set the clock and data lines like so:
    Code:
      void setup() { 
          FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN>(leds, NUM_LEDS);
        }
    so it should be reasonably straight forward from a pin access point of view, but I have not tried the two together yet. The light wand was originally a test as the ws2811 leds were too slow for spinning poi POV.
    Last edited by mortonkopf; 08-30-2015 at 02:14 PM.

  20. #45
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    916
    trying to use SDFat with SPI leds will run into the same old problems two SPI 'devices'?

  21. #46
    I see this software based SPI solution for implementing an SD Card adaptor on the Teensy 3.1 platform for APA102 LEDs. Thoughts?
    Last edited by Intechgreater; 12-02-2015 at 04:30 AM.

  22. #47
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    916
    yes, I saw that softspi and I asked Zackees for some fuller usage examples but none were put in the repository. I did not follow the sd card route further as i was not convinced of the card read rate being high enough. It states 14m of 144leds at 30 updates a sec, this = 60,480 led point per sec, so for my 60led pov baton this lib will provide 1000 lines per sec. I spin at approx 2 rotations a sec (120bpm), so this method would only give me 500 line updates per full rotation, and that is not enough to give the dense detail that I want.

  23. #48
    Junior Member
    Join Date
    Jul 2016
    Posts
    1

    POV with APA102

    Hi
    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?
    Thanks
    Nick


    Code:
    //#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 http://forum.pjrc.com/forum.php
    //SDfat library from this brilliant person http://code.google.com/p/sdfatlib/ 
    // most of the code for the buffer workings come from ZTik.nl (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
    //while(!Serial){};
    //  delay(100);
      progmemPrint(PSTR("Initializing SD card..."));
      if (!sd.begin(SD_CS, SPI_FULL_SPEED)) {
        progmemPrintln(PSTR("failed!"));
        return;
      }
      progmemPrintln(PSTR("OK!"));
     
    
      delay(200);
    }
     
    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("red.bmp");
     bmpDraw("green.bmp");
     bmpDraw("blue.bmp");
     bmpDraw("rgbVertical.bmp");
     bmpDraw("rgbHori.bmp");
     bmpDraw("Bulge02b.bmp");
        
    
    
    //  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
    //    FastLED.show();
    //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++) { 
      leds[i].setRGB(255,0,0); 
      FastLED.show();    
       delay(1);
      leds[i].setRGB(0,0,0); 
         }
        for (int i=NUM_LEDS-1;i>0;i--) { 
      leds[i].setRGB(255,0,0); 
      FastLED.show();    
       delay(1);
       leds[i].setRGB(0,0,0); 
        }
     }
     }
    // ////////////////////////////////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)) {
    //leds[Led1]=leds[Colour1];
    //leds[Led2]=leds[Colour2];
    //FastLED.show(); delay(1);
    //for(int x = 0 ; x < NUM_LEDS ; x++) 
    //leds[x]=leds[Colour];
    //FastLED.show();
    //if(Led1>NUM_LEDS-1){increment=-1;}
    //else if(Led1<0){increment=1;}
    //Led1 = Led1+increment;
    //if(Led2<0){increment2=1;}
    //else if(Led2>NUM_LEDS-1){increment2=-1;}
    //Led2 = Led2+increment2;
    //}
    //Led1 =0;
    //Led2 =NUM_LEDS-1;
    //increment =1;
    //increment2=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++)
     {
       leds[Counter].setRGB(0,0,0);
       leds[Counter].setRGB(0,0,255);
    FastLED.show();
    //delayMicroseconds(100);
    delay(1);
    }  
    // Show a colour bar going down from 9 to 0
    byte Counter2;
    for(Counter2=NUM_LEDS;Counter2 > 0; Counter2--)
    {
    leds[Counter2-1].setRGB(255,0,0);
    if(Counter2>3){
    leds[Counter2-3].setRGB(0,255,0);}
    FastLED.show();
    //delayMicroseconds(100);
    delay(1);
    }  
    }}
     
    /////////////////////////////////////////////////////////////
    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
      bmpFile.open(filename, O_READ);
    //progmemPrint(PSTR(filename));
      // Parse BMP header
      if(read16(bmpFile) == 0x4D42) { // BMP signature
        progmemPrint(PSTR("File size: ")); 
        Serial.println(read32(bmpFile));
        (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: ")); 
        Serial.println(read32(bmpFile));
        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?
                bmpFile.seekSet(pos);
                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;         
                  bmpFile.read(sdbuffer, 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]; }
     
            FastLED.show();
            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);
       //}
      bmpFile.close();
    }
     
    //------- 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] = f.read(); // LSB
      ((uint8_t *)&result)[1] = f.read(); // MSB
      return result;
    }
     
    uint32_t read32(SdFile& f) {
      uint32_t result;
      ((uint8_t *)&result)[0] = f.read(); // LSB
      ((uint8_t *)&result)[1] = f.read();
      ((uint8_t *)&result)[2] = f.read();
      ((uint8_t *)&result)[3] = f.read(); // 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) {
      progmemPrint(str);
      Serial.println();
    }

  24. #49
    Junior Member
    Join Date
    Jan 2018
    Posts
    1
    Hello, im trying to make your design. Using a teensy 3.2. I have a problem with the code: 'Color' was not declared in this scope .
    I think it could be a problem with libraries meaby... But im too new on programming to know, could you help me, please?

    Thanks.

  25. #50
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    916
    the Colour function is a helper function. It should be declared in your sketch. Do you have the below code:
    Code:
    //------- 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
    if you already have this code, try putting this line just below your includes:

    Code:
    unsigned int Color(byte b, byte g, byte r)

Posting Permissions

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