# Cannot get PROGMEM to work

**URL:** <https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256>\
**Category:** Programming\
**Created:** [August 5, 2023, 11:10am UTC](https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256 "2023-08-05T11:10:04Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![mikedb](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mikedb/32/1098613_2.png) [@mikedb](https://forum.arduino.cc/u/mikedb)\
**Post date:** [August 5, 2023, 11:10am UTC](https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256/1 "2023-08-05T11:10:04Z")

</div>

Hi Everyone.  
I created 4 characters in a array and I can print each one on a Oled screen , using 28% memory.

Since I still need to add the rest of the characters and I will run out of memory.  
I tried some samples of PROGMEM but the code still uses 28% memory and the characters now just print random pixels.

Some of the samples I tried.

```arduino
/*const PROGMEM uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234};
  const dataType variableName[] PROGMEM = {}; // use this form
  const PROGMEM dataType variableName[] = {}; // or this one
  const dataType PROGMEM variableName[] = {}; // not this one
*/

const PROGMEM byte data[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 
 0xF8, //48 bytes
                             0xFF, 0x1F, 0x1C, 0x00, 0x38, 0x0E, 0x00, 0x70, 0x07, 0x00,
                             0xE0, 0x07, 0x00, 0xE0, 0x07, 0x00, 0xE0, 0x07, 0x00, 0xE0,
                             0x0E, 0x00, 0x70, 0x1C, 0x00, 0x38, 0xF8, 0xFF, 0x1F, 0xF0,
                             0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

```

My full code

```arduino

//##################
// DIGISPARK
//##################
/*
   print 0 or 1 or 2 or 3 on Oled
*/

#include <Wire.h>

#define OLED_I2c_ADDRESS 0x3d// 0x3C
// registers Addresses
#define COMMAND_REG 0x80 // B1000 0000
#define DATA_REG 0x40 // B0100 0000
// commands
#define ON_CMD 0xAF
#define NORMAL_DISPLAY_CMD 0xA6// INVERT B/W = 0xA7
#define PAGE_ADDRESSING_MODE 0x03 // 

int dataPos = 144;//start of progmem first page

int xPos = 0;
int yPos = 0;

//=====BIG FONTS==24H X 16W==========
//===== 0,1,2,3 ====

/*const PROGMEM uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234};
  const dataType variableName[] PROGMEM = {}; // use this form
  const PROGMEM dataType variableName[] = {}; // or this one
  const dataType PROGMEM variableName[] = {}; // not this one
*/

const PROGMEM byte data[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF8, //48 bytes
                             0xFF, 0x1F, 0x1C, 0x00, 0x38, 0x0E, 0x00, 0x70, 0x07, 0x00,
                             0xE0, 0x07, 0x00, 0xE0, 0x07, 0x00, 0xE0, 0x07, 0x00, 0xE0,
                             0x0E, 0x00, 0x70, 0x1C, 0x00, 0x38, 0xF8, 0xFF, 0x1F, 0xF0,
                             0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             //===== 1 = 48 ===
                             0x00, 0x00, 0x00, 0x30, 0x00, 0xC0, 0x38, 0x00, 0xE0, 0x3C,
                             0x00, 0xE0, 0x1E, 0x00, 0xE0, 0x0F, 0x00, 0xE0, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00,
                             0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             //==== 2 = 96
                             0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x3C, 0x00, 0xFC, 0x3E,
                             0x00, 0xFE, 0x0E, 0x00, 0xFF, 0x07, 0x00, 0xEF, 0x07, 0x80,
                             0xE7, 0x07, 0xC0, 0xE3, 0x07, 0xE0, 0xE1, 0x07, 0xF0, 0xE0,
                             0x1E, 0x78, 0xE0, 0xFE, 0x3F, 0xE0, 0xFC, 0x1F, 0xE0, 0xF0,
                             0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             //==== 3 = 144
                             0x00, 0x00, 0x00, 0x38, 0x00, 0x1C, 0x3C, 0x00, 0x3C, 0x1E,
                             0x00, 0x78, 0x07, 0x00, 0xE0, 0x03, 0x00, 0xC0, 0x03, 0x38,
                             0xC0, 0x03, 0x38, 0xC0, 0x03, 0x38, 0xC0, 0x07, 0x7E, 0xE0,
                             0x0E, 0xFE, 0x60, 0x1E, 0xE7, 0x79, 0xFC, 0xC3, 0x3F, 0xF8,
                             0x81, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            };
void setup()
{
  oled_begin();
  setCursor(50, yPos); //x,y
}

void loop()
{
  //======== THIS WORKS FONT CREATOR =============

  //char 0 dataPos 0

  //char 1 dataPos 48

  //char 2 dataPos 96

  //char 3 dataPos 144

  for (int i = 0; i < 16; i++)
  {
    writeData(data[dataPos]);
    dataPos = dataPos + 3;//Select every 3 rd byte
  }
  yPos = yPos + 1;
  dataPos = 144;// char start pos in array
  dataPos = dataPos + yPos;//jump to next array adress from 0
  setCursor(50, yPos ); //x,y

  if (yPos > 2)//page number
  {
    while (1)
    {}
  }

}

//===================================

void oled_begin()
{
  Wire.begin(); // join i2c bus (address optional for master)
  turnON();
  NormalDisplayMode();
  //setPageMode();
  writeCommand(0x8d); //Charge Pump
  writeCommand(0x14);
  clearFullDisplay();
}

void writeCommand(byte command) {
  Wire.beginTransmission(OLED_I2c_ADDRESS); // begin transmitting (OLED_I2c_ADDRESS=0x3C)
  Wire.write(COMMAND_REG); // Command Reg Address (COMMAND_REG =0x80 )
  Wire.write(command); // Command to be excuted
  Wire.endTransmission(); // stop transmitting
}

void writeData(byte data) {
  Wire.beginTransmission(OLED_I2c_ADDRESS); // begin transmitting (OLED_I2c_ADDRESS=0x3C)
  Wire.write(DATA_REG); //Data Reg Address (DATA_REG =0x40)
  Wire.write(data); //Write data
  Wire.endTransmission(); // stop transmitting
}

void turnON() {
  writeCommand(ON_CMD);
}
void NormalDisplayMode()
{
  writeCommand(NORMAL_DISPLAY_CMD);
}
void setPageMode()
{
  byte addressingMode = PAGE_ADDRESSING_MODE;
  writeCommand(0x20); //set addressing mode
  writeCommand(PAGE_ADDRESSING_MODE); //set page addressing mode
}

void clearFullDisplay()
{
  for (byte page = 0; page < 8; page++)
  {
    setCursor(0, page);
    for (byte column = 0; column < 130; column++)
    { //clear all columns..was128 pixels left far right
      writeData(0x00);
    }
  }

}

void setCursor(byte Y, byte X)
{
  writeCommand(0x00 + (Y & 0x0F)); //set column lower address
  writeCommand(0x10 + ((Y >> 4) & 0x0F)); //set column higher address
  writeCommand(0xB0 + X); //set page address
}

```

---

<div class="post-metadata">

**Author:** ![anon56112670](https://avatars.discourse-cdn.com/v4/letter/a/c5a1d2/32.png) [@anon56112670](https://forum.arduino.cc/u/anon56112670)\
**Post date:** [August 5, 2023, 11:25am UTC](https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256/2 "2023-08-05T11:25:36Z")

</div>

Reading from PROGMEM requires special instructions.  
Check the [reference](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/) page.

---

<div class="post-metadata">

**Author:** ![mikedb](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mikedb/32/1098613_2.png) [@mikedb](https://forum.arduino.cc/u/mikedb)\
**Post date:** [August 5, 2023, 11:32am UTC](https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256/3 "2023-08-05T11:32:31Z")

</div>

> [@anon56112670](#):
>
> Check the [reference](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/) page.

I did see that page but still missing something ,This is from the reference page that I tried.

> [@mikedb](#):
>
> ```arduino
> const dataType variableName[] PROGMEM = {}; // use this form
> const PROGMEM dataType variableName[] = {}; // or this one
> const dataType PROGMEM variableName[] = {}; // not this one
> 
> ```

---

<div class="post-metadata">

**Author:** ![UKHeliBob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ukhelibob/32/215663_2.png) [@UKHeliBob](https://forum.arduino.cc/u/UKHeliBob)\
**Post date:** [August 5, 2023, 11:35am UTC](https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256/4 "2023-08-05T11:35:47Z")

</div>

You need to use special instructions to read data from PROGMEM

See [Why use PROGMEM in Arduino? - LogiqBit](https://www.logiqbit.com/progmem-in-arduino#:~:text=Reading%20data%20back%20from%20PROGMEM&text=You%20need%20to%20use%20two,of%20memory%20at%20an%20address).

---

<div class="post-metadata">

**Author:** ![mikedb](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mikedb/32/1098613_2.png) [@mikedb](https://forum.arduino.cc/u/mikedb)\
**Post date:** [August 5, 2023, 1:11pm UTC](https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256/5 "2023-08-05T13:11:39Z")

</div>

Thanks for the pointers.  
Program storage went down from 28% to 21%  
I manage to read from PROGMEM with this changed line.

```arduino
 {data = (pgm_read_byte(&myArray[dataPos]));
    writeData(data);
    dataPos = dataPos + 3;//Select every 3 rd byte
  }

```

Byte 0,3,6,9 ....... print the top part of the character  
Byte 1,4,7,10 ..... print the middel part  
Byte 2,5,8,11..... print the bottom

![image](https://europe1.discourse-cdn.com/arduino/original/4X/4/6/5/465ed4ef27ad63ef7c6dc7e909307db60982cd34.jpeg)

---

<div class="post-metadata">

**Author:** ![david\_2018](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/david_2018/32/1013044_2.png) [@david\_2018](https://forum.arduino.cc/u/david_2018)\
**Post date:** [August 5, 2023, 1:48pm UTC](https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256/6 "2023-08-05T13:48:52Z")

</div>

> [@mikedb](#):
>
> Program storage went down from 28% to 21%

Using PROGMEM really should not affect program storage that much, the main effect is to save dynamic memory (ram), and often program memory usage will increase by a few bytes because of the extra instructions needed to fetch the data from PROGMEM. If your program memory use dropped that much you must have changed something else in the code.

---

<div class="post-metadata">

**Author:** ![mikedb](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mikedb/32/1098613_2.png) [@mikedb](https://forum.arduino.cc/u/mikedb)\
**Post date:** [August 6, 2023, 8:41am UTC](https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256/7 "2023-08-06T08:41:33Z")

</div>

> [@david\_2018](#):
>
> Using PROGMEM really should not affect program storage that much

Correct .. I have no idea what I am doing.

When I save the Array like this , prog memory is 26% used.

```arduino
const PROGMEM byte myArray[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF8, //48 bytes
                                0xFF, 0x1F, 0x1C, 0x00, 0x38, 0x0E, 0x00, 0x70, 0x07, 0x00,
                                0xE0, 0x07, 0x00, 0xE0, 0x07, 0x00, 0xE0, 0x07, 0x00, 0xE0,
                                0x0E, 0x00, 0x70, 0x1C, 0x00, 0x38, 0xF8, 0xFF, 0x1F, 0xF0,
                                0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

```

When I use this , also 26% prog memory used.

```arduino
byte myArray[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF8, //48 bytes
               0xFF, 0x1F, 0x1C, 0x00, 0x38, 0x0E, 0x00, 0x70, 0x07, 0x00,
               0xE0, 0x07, 0x00, 0xE0, 0x07, 0x00, 0xE0, 0x07, 0x00, 0xE0,
               0x0E, 0x00, 0x70, 0x1C, 0x00, 0x38, 0xF8, 0xFF, 0x1F, 0xF0,
               0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

```

---

<div class="post-metadata">

**Author:** ![anon56112670](https://avatars.discourse-cdn.com/v4/letter/a/c5a1d2/32.png) [@anon56112670](https://forum.arduino.cc/u/anon56112670)\
**Post date:** [August 6, 2023, 8:48am UTC](https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256/8 "2023-08-06T08:48:07Z")

</div>

The values for an initialised array have to be stored in flash memory, even if the array exists as const, but resides in RAM.  
PROGMEM simply ensures it remains in flash, and doesn't get copied to RAM

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [February 2, 2024, 8:48am UTC](https://forum.arduino.cc/t/cannot-get-progmem-to-work/1155256/9 "2024-02-02T08:48:27Z")

</div>

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.
