How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
borissid
 
Posts: 14
Joined: Fri Oct 07, 2022 12:41 pm

How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by borissid »

Hi,

I have successfully followed the Adafruit tutorials on how to upload .bmp images to my 2.9" flexible epaper display using the Arduino IDE, however now would like to have several images circulating between each other every couple (probably more than just a couple) of seconds. I used the Adafruit ImageReaderLibrary > ThinkinkDisplays example code, however as I am still very new to coding, I don't know how to manipulate the code to be able to achieve this goal. Does someone know how I would go about approaching this? Perhaps someone already has come across this task and has already created a code for this?

Thank you very much in advance for any help or suggestions!

borissid

User avatar
mikeysklar
 
Posts: 13945
Joined: Mon Aug 01, 2016 8:10 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by mikeysklar »

Is this the model of the 2.9” flexible are you using?

https://www.adafruit.com/product/4262

Are you using a Breakout Friend or Feather Friend?

You had mentioned in another thread that you are a Feather M0. Is that correct?

User avatar
borissid
 
Posts: 14
Joined: Fri Oct 07, 2022 12:41 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by borissid »

Exactly, I am using the Adafruit E-ink Friend w/sram memory buffer (https://www.adafruit.com/product/4224) connected to the Adafruit Itsy Bitsy Express m0 (https://www.adafruit.com/product/3727). The 2.9" flexible display connected to the E-ink Friend is from Waveshare, but works seemlessly with the Adafruit devices.

User avatar
mikeysklar
 
Posts: 13945
Joined: Mon Aug 01, 2016 8:10 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by mikeysklar »

This is the eInk ImageReader example code for your breakout board. Is that what you have been running?

https://github.com/adafruit/Adafruit_Im ... akouts.ino

The setup() code has a lot of diagnostic information. The elegant thing to do would breakout the code specific to loading blinka.bmp into a seperate function called load_bmp().This function should take an argument of the filename to load. That way your main loop() code can call:

Code: Select all

load_bmp(“image1.bmp”);
load_bmp(“image2.bmp”);
load_bmp(“image3.bmp”);
Not the easiest thing for a newbie to code up, but give it a shot and see what you can do.

User avatar
borissid
 
Posts: 14
Joined: Fri Oct 07, 2022 12:41 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by borissid »

Everything seems to be the same except the parts where you have to uncomment the type of screen you have. I think the code you chose is the Adafruit ImageReader Library > Eink Breakouts whereas the one I used is the Adafruit ImageReader Library > ThinkInkDisplays. But from what I can see, the actual code is identical.

I will give it a try!

User avatar
mikeysklar
 
Posts: 13945
Joined: Mon Aug 01, 2016 8:10 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by mikeysklar »

You are using an eInk Breakout Friend. The example I linked in is what you will want to use over the ThinkInk examples which could have subtle differences in initialization.

User avatar
borissid
 
Posts: 14
Joined: Fri Oct 07, 2022 12:41 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by borissid »

Tried using the EinkBreakout code, and can't get it to work. Works up until "Drawing canvas to EPD..." and then stops and nothing happens. I think it might be the fact that I have a different screen because in the EinkBreakout code it specifically names the adafruit 2.9" display

Code: Select all

Adafruit_IL0373 display(296, 128, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY)
whereas the ThinkinkDisplay code just shows the size and type of display

Code: Select all

ThinkInk_290_Mono_M06 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY)
Is there a way to apply the load_bmp function to the ThinkinkDisplay code?

User avatar
mikeysklar
 
Posts: 13945
Joined: Mon Aug 01, 2016 8:10 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by mikeysklar »

Did you uncomment both of these lines in the EInkBreakouts.ino example code?

Code: Select all

Adafruit_IL0373 display(296, 128, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
#define FLEXIBLE_290

User avatar
borissid
 
Posts: 14
Joined: Fri Oct 07, 2022 12:41 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by borissid »

Yes, I uncommented both lines. Tried also uncommenting either, also changing the pin out numbers to -1 (all except EPD CS and EPD DC). Nothing seems to work.

User avatar
mikeysklar
 
Posts: 13945
Joined: Mon Aug 01, 2016 8:10 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by mikeysklar »

Since theThinkInk example works you could craft your own load_bmp() function that takes and argument so you can rotate through multiple BMPs in the main loop.

However, my recommendation would be to consider using the CircuitPython slide code. This would allow for an easier experience. Take a look at this guide which shows an example of using the adafruit_slideshow library. I also linked to the github repo below that has more code examples.

https://learn.adafruit.com/magtag-slide ... how-viewer

https://github.com/adafruit/Adafruit_Ci ... n/examples

User avatar
borissid
 
Posts: 14
Joined: Fri Oct 07, 2022 12:41 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by borissid »

Thank you for the suggestions but still having a lot of trouble though.

for the ThinkInk example, I don't know how I would construct this function and how/where I would implement it in the code. Do you have any suggestions on how/where I can learn this? Or maybe show an example of how you would do it? I am starting to understand the code more and more (the comments help of course), but when it comes to restructuring it I am lost.

I think the ThinkInk option would also be better for me as for my project I am most probably going to work with several sizes of e-paper displays, and so this code (if done so that it can loop between images) could be applied to different sizes quite easily.

User avatar
borissid
 
Posts: 14
Joined: Fri Oct 07, 2022 12:41 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by borissid »

With the CircuitPython Slide code I get the error:

code.py output:
Traceback (most recent call last):
File "code.py", line 14, in <module>
File "adafruit_magtag/magtag.py", line 33, in <module>
File "adafruit_portalbase/__init__.py", line 27, in <module>
MemoryError: memory allocation failed, allocating 286 bytes

which I guess makes sense since I am using the library compatible for the Magtag rather than the flexible 2.9" display that I have. If I can't get the ThinkInk code to work, how would I have to alter the CircuitPython slide code so that the library for the adafruit_slideshow gets applied to the library of the flexible 2.9" display rather than the Magtag one? Hopefully that makes sense?

User avatar
borissid
 
Posts: 14
Joined: Fri Oct 07, 2022 12:41 pm

Re: How to Circulate between .bmp Images on Epaper Display using Arduino IDE?

Post by borissid »

Asked an acquaintance for help and he was able to solve the problem!
Here the code for anyone who is looking for the same solution:

Code: Select all

// Adafruit_ImageReader test for Adafruit E-Ink Breakouts.
// Demonstrates loading images from SD card or flash memory to the screen,
// to RAM, and how to query image file dimensions.
// Requires BMP file in root directory of QSPI Flash:
// blinka.bmp.

#include <Adafruit_GFX.h>         // Core graphics library
#include "Adafruit_ThinkInk.h"
#include <SdFat.h>                // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h>    // SPI / QSPI flash library
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions


// Comment out the next line to load from SPI/QSPI flash instead of SD card:
//#define USE_SD_CARD

#define EPD_DC      12 // can be any pin, but required!
#define EPD_CS      13  // can be any pin, but required!
#define SRAM_CS     11  // can set to -1 to not use a pin (uses a lot of RAM!)
#define EPD_BUSY    9  // can set to -1 to not use a pin (will wait a fixed delay)
#define EPD_RESET   10  // can set to -1 and share with chip Reset (can't deep sleep)
#define SD_CS       -1  // SD card chip select

// Mono Displays
//ThinkInk_154_Mono_D67 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_154_Mono_D27 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Mono_B72 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Mono_B73 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Mono_BN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
ThinkInk_290_Mono_M06 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_420_Mono_BN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);

// Tri-Color Displays
//ThinkInk_154_Tricolor_Z17 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_154_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Tricolor_Z16 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_270_Tricolor_C44 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_290_Tricolor_Z10 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_420_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);

// Grayscale Displays
//ThinkInk_154_Grayscale4_T8 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_290_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);


#if defined(USE_SD_CARD)
  SdFat                    SD;         // SD card filesystem
  Adafruit_ImageReader_EPD reader(SD); // Image-reader object, pass in SD filesys
#else

// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
  #if defined(__SAMD51__) || defined(NRF52840_XXAA)
    Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS,
      PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
  #else
    #if (SPI_INTERFACES_COUNT == 1 || defined(ADAFRUIT_CIRCUITPLAYGROUND_M0))
      Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
    #else
      Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
    #endif
  #endif
  Adafruit_SPIFlash         flash(&flashTransport);
  FatVolume             filesys;
  Adafruit_ImageReader_EPD  reader(filesys); // Image-reader, pass in flash filesys
#endif

Adafruit_Image_EPD   img;        // An image loaded into RAM

void setup(void) {
  Serial.begin(9600);
  //while(!Serial);           // Wait for Serial Monitor before continuing

  Serial.println(F("before display.begin()"));

  display.begin();

#if defined(FLEXIBLE_213) || defined(FLEXIBLE_290)
  // The flexible displays have different buffers and invert settings!
  display.setBlackBuffer(1, false);
  display.setColorBuffer(1, false);
#endif

  // The Adafruit_ImageReader constructor call (above, before setup())
  // accepts an uninitialized SdFat or FatVolume object. This MUST
  // BE INITIALIZED before using any of the image reader functions!
  Serial.print(F("Initializing filesystem..."));
  // SPI or QSPI flash requires two steps, one to access the bare flash
  // memory itself, then the second to access the filesystem within...
#if defined(USE_SD_CARD)
  // SD card is pretty straightforward, a single call...
  if(!SD.begin(SD_CS, SD_SCK_MHZ(10))) { // Breakouts require 10 MHz limit due to longer wires
    Serial.println(F("SD begin() failed"));
    for(;;); // Fatal error, do not continue
  }
#else
  // SPI or QSPI flash requires two steps, one to access the bare flash
  // memory itself, then the second to access the filesystem within...
  if(!flash.begin()) {
    Serial.println(F("flash begin() failed"));
    for(;;);
  }
  if(!filesys.begin(&flash)) {
    Serial.println(F("filesys begin() failed"));
    for(;;);
  }
#endif
  Serial.println(F("OK!"));
}

void loop() {
  // To add a new image - increase numImages and add an element to imagePaths inside the { }
  const int numImages = 4;
  char * imagePaths[numImages] = { (char *)"/2.bmp", (char *)"/moon.bmp", (char *)"/1.bmp", (char *)"/book.bmp" };
  for (int i = 0; i < numImages; i++)
    drawImage(imagePaths[i]);

  //drawImage((char *)"/1.bmp");
  //drawImage((char *)"/2.bmp");
  //drawImage((char *)"/moon.bmp");
  //drawImage((char *)"/book.bmp");
}

// Draw image with the given name and set a 30 sec delay.
// Print error if something went wrong
void drawImage(char * name) {
  ImageReturnCode stat; // Status from image-reading functions
  stat = reader.drawBMP(name, display, 0, 0);
  // Only print if something went wrong
  if(stat != IMAGE_SUCCESS)
    reader.printStatus(stat);
  display.display();
   // Pause 30 seconds before continuing because it's eInk
  delay(10 * 1000);
}

Only thing that needs to be altered/changed is adding the respective libraries

Code: Select all

#include <Adafruit_GFX.h>         // Core graphics library
#include "Adafruit_ThinkInk.h"
#include <SdFat.h>                // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h>    // SPI / QSPI flash library
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
un/commenting out if you have/don't have an sd card

Code: Select all

// Comment out the next line to load from SPI/QSPI flash instead of SD card:
//#define USE_SD_CARD
choosing the pinouts

Code: Select all

#define EPD_DC      12 // can be any pin, but required!
#define EPD_CS      13  // can be any pin, but required!
#define SRAM_CS     11  // can set to -1 to not use a pin (uses a lot of RAM!)
#define EPD_BUSY    9  // can set to -1 to not use a pin (will wait a fixed delay)
#define EPD_RESET   10  // can set to -1 and share with chip Reset (can't deep sleep)
#define SD_CS       -1  // SD card chip select
choosing the right display

Code: Select all

// Mono Displays
//ThinkInk_154_Mono_D67 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_154_Mono_D27 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Mono_B72 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Mono_B73 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Mono_BN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
ThinkInk_290_Mono_M06 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_420_Mono_BN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);

// Tri-Color Displays
//ThinkInk_154_Tricolor_Z17 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_154_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Tricolor_Z16 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_270_Tricolor_C44 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_290_Tricolor_Z10 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_420_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);

// Grayscale Displays
//ThinkInk_154_Grayscale4_T8 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_290_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
in void loop changing the amount of images

Code: Select all

const int numImages = 4;
writing the names of the .bmp files you want to display that are in the CIRCUITPY/sd/SPI flash of your microcontroller

Code: Select all

char * imagePaths[numImages] = { (char *)"/2.bmp", (char *)"/moon.bmp", (char *)"/1.bmp", (char *)"/book.bmp" };
optionally, changing the delay between images

Code: Select all

delay(10 * 1000);

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”