Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: reading - writing two bitmap files to 3.5 teensy

  1. #1
    Member
    Join Date
    Jul 2018
    Location
    El Paso, TX
    Posts
    79

    reading - writing two bitmap files to 3.5 teensy

    Ran into trouble writing out two bitmap pictures. Morton Kopf was helping me and I made great progress with him.
    Morton had written some code for a Light Painting some years ago using 3.6 teensy. I am using 3.5 teensy. Everything works but can only display one bitmap picture. I need to show one bitmap and 30 seconds later display the other continuously. Best practice? This is a lighted painting but somewhat different.

    Code:
    //#define USE_OCTOWS2811
    #include <SD.h>
    #include <OctoWS2811.h>
    #include <SPI.h>
    //#include <FastLED.h>
    
    //----------set the three below------//
    const int ledsPerStrip = 432;
    #define imageHeight 48
    #define imageWidth 72
    
    DMAMEM int displayMemory[ledsPerStrip*6];
    int drawingMemory[ledsPerStrip*6];
    const int config = WS2811_GRB | WS2811_800kHz;
    OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);
    #define RED    0xFF0000
    const int chipSelect = BUILTIN_SDCARD;
    // File bmpFile;
    
    
    //buffer to hold pixel data. remains size of pixel number//
    const int ARRAY_SIZE = imageHeight*imageWidth;
    const int byteBuffSize = ARRAY_SIZE*3;
    byte pixelBUFFER[byteBuffSize];
    byte ArrayB[ARRAY_SIZE];
    byte ArrayG[ARRAY_SIZE];
    byte ArrayR[ARRAY_SIZE];
    
    /////////////////////
    void setup(void) {
      Serial.begin(9600);
      leds.begin();
      leds.show();
    
    // if you dont get all leds lighting then going off, check your wiring
    
    Serial.println("init");
    delay(500);
    Serial.print("Initializing SD cardů");
    
    if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    while(1);
    }
    Serial.println("SD OK!");
    }
    //////////////////////////////////
    
    void loop() {
    
    // paint to bitMap 72X48
    // bmpDraw("LEMON1.bmp");
    bmpDraw("THISWHT2.bmp");
      
        delay(1000);
      
    /*
    //do a colour wipe to set all leds to red
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, RED);
        leds.show();
        delay(5);
      } */
    }
    
    //////////////////////////////////////////////
    int32_t readNbytesInt(File *p_file, int position, byte nBytes)
    {
        if (nBytes > 4)
            return 0;
    
        p_file->seek(position);
    
        int32_t weight = 1;
        int32_t result = 0;
        for (; nBytes; nBytes--)
        {
            result += weight * p_file->read();
            weight <<= 8;
        }
        return result;
    }
    
    
    void bmpDraw( char* fileName)
    {
    // Open file
        File bmpImage = SD.open(fileName, FILE_READ);
        
        int32_t dataStartingOffset = readNbytesInt(&bmpImage, 0x0A, 4);
    
        // Change their types to int32_t (4byte)
        int32_t width = readNbytesInt(&bmpImage, 0x12, 4); //0x12 - dec18
        int32_t height = readNbytesInt(&bmpImage, 0x16, 4); //0x16 - dec22
        int32_t ImgSize = readNbytesInt(&bmpImage, 0x22,4); //-dec34
        
        Serial.println(width);
        Serial.println(height);
        Serial.println(ImgSize);
    
        int16_t pixelsize = readNbytesInt(&bmpImage, 0x1C, 2);
    
        if (pixelsize != 24)
        {
            Serial.println("Image is not 24 bpp");
            while (1);
        }
    
        bmpImage.seek(dataStartingOffset);//skip bitmap header
    
        byte B, G, R;
    
     for(int i=0;i<ARRAY_SIZE;i++){
                ArrayB[i] = bmpImage.read();
                ArrayG[i] = bmpImage.read();
                ArrayR[i] = bmpImage.read();
     }          
        bmpImage.close();
        Serial.println("done writing to Buffer");
        unsigned int Color (byte b, byte g, byte r);
      /*  
      int ledCount =0;
        for(int i=0; i<width*height;i++){
          leds.setPixel(ledCount,Color(ArrayR[i],ArrayG[i],ArrayB[i]));
            ledCount = ledCount+1;
        }   
        leds.show();
    } */
    uint32_t ledCount =0;
    uint32_t ledLocation = 0;
     for (int y = 0; y<imageHeight; y++){ //for each row
          for(int x =  0; x<imageWidth; x++){ //go through each coloumn
        
        //use the & bitwise method to see if an odd or even row, we start rows at zero, so if row is odd, we go backwards
            if( y & 0x01) {
              ledLocation =  (y*imageWidth) + ((imageWidth -1) -x);
    
             } else {
            // Even rows go forwards
                ledLocation = (y * imageWidth) + x;
                    }
          //set the pixel at ledLocation with the next colour in the colour array
          leds.setPixel(ledLocation,Color(ArrayR[ledCount],ArrayG[ledCount],ArrayB[ledCount]));
          
          //move on the colour array location by one.
          ledCount = ledCount+1;   
          }
       }
       leds.show();
    }
    
    //------- HELPER FUNCTION------//
    // Create a 24 bit color value from R,G,B ////these strips are BGR, but you might need to change this
    unsigned int Color(byte b, byte g, byte r)
    {
      //Take the lowest 8 bits of each value and append them end to end
    return( ((unsigned int)b & 0x1F )<<16 | ((unsigned int)g & 0x1F)<<8 | (unsigned int)r & 0x1F);
      }
    //end of helper function

  2. #2
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    880
    @johnwatterson, sorry, missed this, perhaps keep all questions to the same bitmap thread. Anyhow, you need to put in a timer function of some sort. the easiest way is to count milliseconds. We mark the time that a routine starts, count the number of milliseconds that it has been going for, and when it reaches the milliseconds we have set for it, move on. This can be done by including the counter inside the routine, or in the loop() section. Below is an example of it inside the routine, but I have not tested this our. let me know how you get on.

    Code:
    //#define USE_OCTOWS2811
    #include <SD.h>
    #include <OctoWS2811.h>
    #include <SPI.h>
    //#include <FastLED.h>
    
    //----------set the three below------//
    const int ledsPerStrip = 432;
    #define imageHeight 48
    #define imageWidth 72
    
    DMAMEM int displayMemory[ledsPerStrip*6];
    int drawingMemory[ledsPerStrip*6];
    const int config = WS2811_GRB | WS2811_800kHz;
    OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);
    #define RED    0xFF0000
    const int chipSelect = BUILTIN_SDCARD;
    // File bmpFile;
    
    
    //buffer to hold pixel data. remains size of pixel number//
    const int ARRAY_SIZE = imageHeight*imageWidth;
    const int byteBuffSize = ARRAY_SIZE*3;
    byte pixelBUFFER[byteBuffSize];
    byte ArrayB[ARRAY_SIZE];
    byte ArrayG[ARRAY_SIZE];
    byte ArrayR[ARRAY_SIZE];
    
    /////////////////////
    void setup(void) {
      Serial.begin(9600);
      leds.begin();
      leds.show();
    
    // if you dont get all leds lighting then going off, check your wiring
    
    Serial.println("init");
    delay(500);
    Serial.print("Initializing SD card…");
    
    if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    while(1);
    }
    Serial.println("SD OK!");
    }
    //////////////////////////////////
    
    void loop() {
    
    // paint to bitMap 72X48
    // bmpDraw("LEMON1.bmp");
    
    
    bmpDraw(3000,"THISWHT2.bmp"); //display for 3000 millis, then move on to something else
      
    //    delay(1000);
      
    
    //do a colour wipe to set all leds to red
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, RED);
        leds.show();
        delay(50);
      } 
    }
    
    //////////////////////////////////////////////
    int32_t readNbytesInt(File *p_file, int position, byte nBytes)
    {
        if (nBytes > 4)
            return 0;
    
        p_file->seek(position);
    
        int32_t weight = 1;
        int32_t result = 0;
        for (; nBytes; nBytes--)
        {
            result += weight * p_file->read();
            weight <<= 8;
        }
        return result;
    }
    
    
    void bmpDraw(unsigned long time, char* fileName)
    {
    unsigned long currentTime = millis();
     while (millis()< currentTime + (time)) {
      
    // Open file
        File bmpImage = SD.open(fileName, FILE_READ);
        
        int32_t dataStartingOffset = readNbytesInt(&bmpImage, 0x0A, 4);
    
        // Change their types to int32_t (4byte)
        int32_t width = readNbytesInt(&bmpImage, 0x12, 4); //0x12 - dec18
        int32_t height = readNbytesInt(&bmpImage, 0x16, 4); //0x16 - dec22
        int32_t ImgSize = readNbytesInt(&bmpImage, 0x22,4); //-dec34
        
        Serial.println(width);
        Serial.println(height);
        Serial.println(ImgSize);
    
        int16_t pixelsize = readNbytesInt(&bmpImage, 0x1C, 2);
    
        if (pixelsize != 24)
        {
            Serial.println("Image is not 24 bpp");
            while (1);
        }
    
        bmpImage.seek(dataStartingOffset);//skip bitmap header
    
        byte B, G, R;
    
     for(int i=0;i<ARRAY_SIZE;i++){
                ArrayB[i] = bmpImage.read();
                ArrayG[i] = bmpImage.read();
                ArrayR[i] = bmpImage.read();
     }          
        bmpImage.close();
        Serial.println("done writing to Buffer");
        unsigned int Color (byte b, byte g, byte r);
      /*  
      int ledCount =0;
        for(int i=0; i<width*height;i++){
          leds.setPixel(ledCount,Color(ArrayR[i],ArrayG[i],ArrayB[i]));
            ledCount = ledCount+1;
        }   
        leds.show();
    } */
    uint32_t ledCount =0;
    uint32_t ledLocation = 0;
     for (int y = 0; y<imageHeight; y++){ //for each row
          for(int x =  0; x<imageWidth; x++){ //go through each coloumn
        
        //use the & bitwise method to see if an odd or even row, we start rows at zero, so if row is odd, we go backwards
            if( y & 0x01) {
              ledLocation =  (y*imageWidth) + ((imageWidth -1) -x);
    
             } else {
            // Even rows go forwards
                ledLocation = (y * imageWidth) + x;
                    }
          //set the pixel at ledLocation with the next colour in the colour array
          leds.setPixel(ledLocation,Color(ArrayR[ledCount],ArrayG[ledCount],ArrayB[ledCount]));
          
          //move on the colour array location by one.
          ledCount = ledCount+1;   
          }
       }
       leds.show();
     }
    }
    
    //------- HELPER FUNCTION------//
    // Create a 24 bit color value from R,G,B ////these strips are BGR, but you might need to change this
    unsigned int Color(byte b, byte g, byte r)
    {
      //Take the lowest 8 bits of each value and append them end to end
    return( ((unsigned int)b & 0x1F )<<16 | ((unsigned int)g & 0x1F)<<8 | (unsigned int)r & 0x1F);
      }
    //end of helper function

  3. #3
    Member
    Join Date
    Jul 2018
    Location
    El Paso, TX
    Posts
    79
    Great - thank you, I am very excited. Will try this when I get to the studio.

  4. #4
    Member
    Join Date
    Jul 2018
    Location
    El Paso, TX
    Posts
    79
    OK, That routine did work to show the bitmap then painted Leds in red.
    Here I would like to load and show the second bitmap but the second bitmap does not load and show.
    I will post the whole program again with Red leds commented out and bmp file added.


    Code:
    //#define USE_OCTOWS2811
    #include <SD.h>
    #include <OctoWS2811.h>
    #include <SPI.h>
    //#include <FastLED.h>
    
    //----------set the three below------//
    const int ledsPerStrip = 432;
    #define imageHeight 48
    #define imageWidth 72
    
    DMAMEM int displayMemory[ledsPerStrip*6];
    int drawingMemory[ledsPerStrip*6];
    const int config = WS2811_GRB | WS2811_800kHz;
    OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);
    #define RED    0xFF0000
    const int chipSelect = BUILTIN_SDCARD;
    // File bmpFile;
    
    
    //buffer to hold pixel data. remains size of pixel number//
    const int ARRAY_SIZE = imageHeight*imageWidth;
    const int byteBuffSize = ARRAY_SIZE*3;
    byte pixelBUFFER[byteBuffSize];
    byte ArrayB[ARRAY_SIZE];
    byte ArrayG[ARRAY_SIZE];
    byte ArrayR[ARRAY_SIZE];
    
    /////////////////////
    void setup(void) {
      Serial.begin(9600);
      leds.begin();
      leds.show();
    
    // if you dont get all leds lighting then going off, check your wiring
    
    Serial.println("init");
    delay(500);
    Serial.print("Initializing SD card…");
    
    if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    while(1);
    }
    Serial.println("SD OK!");
    }
    //////////////////////////////////
    
    void loop() {
    
    // paint to bitMap 72X48
    // bmpDraw("THISWHT2");
    // bmpDraw("LEMON1.bmp");
    
    
    bmpDraw(3000,"THISWHT2.bmp"); //display for 3000 millis, then move on to something else
    bmpDraw(10000,"LEMON1,bmp");  //probably 5-10 mins in the end
      
    
    /*
    //do a colour wipe to set all leds to red
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, RED);
        leds.show();
        delay(50);
      }
      */
       
    }
    
    //////////////////////////////////////////////
    int32_t readNbytesInt(File *p_file, int position, byte nBytes)
    {
        if (nBytes > 4)
            return 0;
    
        p_file->seek(position);
    
        int32_t weight = 1;
        int32_t result = 0;
        for (; nBytes; nBytes--)
        {
            result += weight * p_file->read();
            weight <<= 8;
        }
        return result;
    }
    
    
    void bmpDraw(unsigned long time, char* fileName)
    {
    unsigned long currentTime = millis();
     while (millis()< currentTime + (time)) {
      
    // Open file
        File bmpImage = SD.open(fileName, FILE_READ);
        
        int32_t dataStartingOffset = readNbytesInt(&bmpImage, 0x0A, 4);
    
        // Change their types to int32_t (4byte)
        int32_t width = readNbytesInt(&bmpImage, 0x12, 4); //0x12 - dec18
        int32_t height = readNbytesInt(&bmpImage, 0x16, 4); //0x16 - dec22
        int32_t ImgSize = readNbytesInt(&bmpImage, 0x22,4); //-dec34
        
        Serial.println(width);
        Serial.println(height);
        Serial.println(ImgSize);
    
        int16_t pixelsize = readNbytesInt(&bmpImage, 0x1C, 2);
    
        if (pixelsize != 24)
        {
            Serial.println("Image is not 24 bpp");
            while (1);
        }
    
        bmpImage.seek(dataStartingOffset);//skip bitmap header
    
        byte B, G, R;
    
     for(int i=0;i<ARRAY_SIZE;i++){
                ArrayB[i] = bmpImage.read();
                ArrayG[i] = bmpImage.read();
                ArrayR[i] = bmpImage.read();
     }          
        bmpImage.close();
        Serial.println("done writing to Buffer");
        unsigned int Color (byte b, byte g, byte r);
      /*  
      int ledCount =0;
        for(int i=0; i<width*height;i++){
          leds.setPixel(ledCount,Color(ArrayR[i],ArrayG[i],ArrayB[i]));
            ledCount = ledCount+1;
        }   
        leds.show();
    } */
    uint32_t ledCount =0;
    uint32_t ledLocation = 0;
     for (int y = 0; y<imageHeight; y++){ //for each row
          for(int x =  0; x<imageWidth; x++){ //go through each coloumn
        
        //use the & bitwise method to see if an odd or even row, we start rows at zero, so if row is odd, we go backwards
            if( y & 0x01) {
              ledLocation =  (y*imageWidth) + ((imageWidth -1) -x);
    
             } else {
            // Even rows go forwards
                ledLocation = (y * imageWidth) + x;
                    }
          //set the pixel at ledLocation with the next colour in the colour array
          leds.setPixel(ledLocation,Color(ArrayR[ledCount],ArrayG[ledCount],ArrayB[ledCount]));
          
          //move on the colour array location by one.
          ledCount = ledCount+1;   
          }
       }
       leds.show();
     }
    }
    
    //------- HELPER FUNCTION------//
    // Create a 24 bit color value from R,G,B ////these strips are BGR, but you might need to change this
    unsigned int Color(byte b, byte g, byte r)
    {
      //Take the lowest 8 bits of each value and append them end to end
    return( ((unsigned int)b & 0x1F )<<16 | ((unsigned int)g & 0x1F)<<8 | (unsigned int)r & 0x1F);
      }
    //end of helper function

  5. #5
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    880
    check the spelling of the BMP file in the code. At the moment you have a comma, not a point. That may or may not be the issue, but the code should work if you have the right file name, and the file exists on the card.
    Code:
    bmpDraw(10000,"LEMON1,bmp");  //probably 5-10 mins in the end

  6. #6
    Member
    Join Date
    Jul 2018
    Location
    El Paso, TX
    Posts
    79
    Silly mistake. Thanks.

  7. #7
    Member
    Join Date
    Jul 2018
    Location
    El Paso, TX
    Posts
    79
    OK, my friend that did fix it. Wonderful. I thought we needed a separate function like bmpDraw1 and bmpDraw2 but I love the simple way you got this running for me. Just great. Very happy. I will be glad to send you the gift I offered before (even though it may not be necessary). Send me your mailing address to my email at hotmail account and I will take care of it. Strictly up to you. Really I could not have finished this project without you. Will send a video later. Thanks to all you support guys.

  8. #8
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    880
    great that it's all going now, no need for anything other than the thanks you have already said.

Posting Permissions

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