Loading animations 70x70 pixels from a SD card

There is a file with arrays of small images, and since I need a lot of them, they don’t fit into memory. I want to load them from the flash drive that is on the screen. How can this be done in a simple way? I'll attach the sketch that I cut off, leaving something without which it does not work. In the sketch, the picture is read from an array that is loaded into the controller's memory. I need to read not from memory, but from flash drives and store these micro pictures on a flash drive. Help me please.

Link to the archive with the sketch and the file to be read.

Of the devices, this is an arduino mega and a touchscreen with a built-in card reader.

I suspect you are much more likely to receive help if you post the code on the forum instead of forcing people to download a random file, decompress the contents, then finally be able to see the code.

Please use code tags.

1 Like
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

#if ARDUINO < 165
#define USE_GFX_KBV
#include "ADA_GFX_kbv.h"
#else
#include "Adafruit_GFX.h"
#endif
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
//#include <Adafruit_TFTLCD.h>
//Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

uint16_t g_identifier;

void setup() {

    static uint16_t identifier;
    tft.reset();                 //we can't read ID on 9341 until begin()
    g_identifier = tft.readID(); //

    if (g_identifier == 0x00D3) g_identifier = 0x9481; // write-only shield
    if (g_identifier == 0xFFFF) g_identifier = 0x9341; // serial
    //    g_identifier = 0x7789;                             // force ID
    tft.begin(g_identifier);

    
            extern const uint8_t biohazard1_L[];  
            tft.setAddrWindow(0, 0, 63, 64);
            tft.pushColors(biohazard1_L, 4096, 1);

            
            analogWrite(44, 255); 
}






void loop() {
   
}

Here is the code, but it doesn't seem to help. For tests, I used arduino mega and I forgot that this board has more memory than arduino nano. In a real project, I wanted to use exactly arduino nano. This sketch stores large arrays of graphic icons in memory. From these icons, I thought to make animations by loading frame by frame. As a result, the memory ran out and I ran into a dead end. I chose this method because the icons loaded quickly enough. Please tell me if you know, maybe there is a way to implement the idea of ​​displaying animations of 70x70 pixels icons.
When using an arduino nano, I will be severely limited in memory and I will need to read the icons from the sd card, but how can I make the drawing go quickly?

1 Like

Hello @vik2 :slight_smile:

Did you try to add flash drive support to your code yourself? Please show us your efforts.

please clarify in quantitative terms - milliseconds or fps, how quickly you want to draw your icons?

The official language of the forum is English, please use it.

I see that you changed the question about using SD to a question about flash drive. Corrected my answer too
You didn't answer the question of how fast you need to load images. It's pointless to discuss anything without it.

Let's pretend I don't know you. I want the images to load as quickly as possible. Get the lowest possible delay. I checked reading from the sd card on a test sketch and it did not suit me. I was satisfied with the example that I just laid out, but the working memory is clogged in it and this is on the arduino mega, but it makes no sense to think about the nano. There is a whole other question here. Is it possible at all what I think or is it better to change the board? In short, is it possible to load 70x70 icons at a speed of about 50 milliseconds?

What color depth do you use for the images? Or what is the size of the 70x70 image in bytes?

this may make sense, Arduino Mega has very little memory, there are many boards where there is more memory .

But by the way - are you use PROGMEM for storing your images?

I take an icon and convert it with this tool. I think the tool is from the library developer. I just take a full color 70x70 png and convert it to an array. one such picture on a computer takes 6 kilobytes
http://www.rinkydinkelectronics.com/t_imageconverter565.php

Yes, that's right, because this method gives an increase in speed even in a test sketch.

no, here you are mistaken, it does not increase the speed. But the memory size for your pictures in Mega will be 32 times larger with the PROGMEM directive than without it.
Perhaps you not need a SD card - PROGMEM gives you 256k on Mega

If one of the 70x70 picture has size 6K, so the MEGA memory size is enough for about 40 icons

            extern const uint8_t biohazard1_L[];  
            tft.setAddrWindow(0, 0, 63, 64);
            tft.pushColors(biohazard1_L, 4096, 1);

            extern const uint8_t biohazard2_L[];  
            tft.setAddrWindow(0, 0, 63, 64);
            tft.pushColors(biohazard2_L, 4096, 1);

            extern const uint8_t biohazard3_L[];  
            tft.setAddrWindow(0, 0, 63, 64);
            tft.pushColors(biohazard3_L, 4096, 1);

And so on.
My sketch freezes after I add 7 pictures. I think the RAM is clogged. That's why I thought about SD memory. I was thinking of reading an array from the SD card to RAM, then drawing to the screen.

this means nothing.
Can you show the definition of biohazard1_L[] array itself?
You may not include all values, but only the title and the first couple of lines of data

#include <Arduino.h>


const unsigned short biohazard1_L[4096] PROGMEM={
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0010 (16) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEF7D, 0xC638, 0x9492, 0x6B4D, 0x4228, 0x2945, 0x2124, 0x18C3, 0x1082,   // 0x0020 (32) pixels
0x1082, 0x10A2, 0x18C3, 0x2124, 0x2965, 0x4A49, 0x6B6D, 0x9CD3, 0xCE79, 0xF7BE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0030 (48) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0040 (64) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0050 (80) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xF7BE, 0xBDD7, 0x6B6D, 0x2965, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0060 (96) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0841, 0x31A6, 0x73AE, 0xC618, 0xFFDF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0070 (112) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0080 (128) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0090 (144) pixels

Where then can this data be stored?

In the MEGA program memory.
Please read something about PROGMEM directive.

What is the size of your program, what does the arduino IDE reports after the build?

The sketch uses 93772 bytes (36%) of device memory. A total of 253952 bytes are available.
Global variables use 513 bytes (6%) of dynamic memory, leaving 7679 bytes for local variables. Maximum: 8192 bytes.
I added the seventh icon to the rendering. As a result, everything hung the screen does not even respond to pressing.

yes
As I see, the problem is that all arduino progmem functions can only work with memory up to 64K. To use memory above 64K, you need to edit the library.

Returning to the first question - maybe you should separate your images into those that need to load quickly and those that can be loaded slowly. From the first 5-7 images put in the progmem, the rest - on the SD card.
Read this discussion, it might be helpful

I think I understand what it's about. Optimization and division into pieces of those that are moving and those that are static. I thought about it, but as planned, completely 70x70 pieces are updated. Here, either abandon the colored icons or change the design. Or alternatively try esp8266. Considering that I need a device smaller than an arduino mega, I will hit the limits even earlier. In any case, thank you very much for your tips.

yes it has up to 16 MB of memory on board, in which you can organize a ramdisk with file system support.
In fact, this is a controller with a flash drive already added to it with quick access.

It seemed to me or did you say at the beginning about the controller
RP2040?
I just went to watch it and the comment is already different :slight_smile:
With esp8266 there is a problem there are not enough pins to connect the screen. I searched the Internet but did not find a complete instruction on how to connect such a screen with so many pins. By the way, RP2040 can also work with it in arduino ide?


But if I searched badly and you know at least some instructions on how to connect to esp8266, I would be very grateful!

RP2040 microcontroller chip designed by Raspberry Pi in the United Kingdom

Dual-core Arm Cortex M0+ processor, flexible clock running up to 133 MHz

264KB of SRAM, and 2MB of on-board Flash memory

Pins that are needed for a memory card, I think they can be donated, but what about those that connect to analog pins? The esp8266 has only one analog pin.

yes, I mentioned it first, but than deleted my suggestions because the rp2040 is rather new board and you may have trouble finding code examples for it.
But overall it's a very interesting board, it may has 2, 4 or 16 Mb of on-board Flash memory

About your screen - as I see, it uses 8bit paralel connection. Perhaps would be better to use it with ESP32 instead of ESP8266, because esp32 has more pins and memory.
but sorry ... i'm not an expert in screens and can hardly give more advice.