شاید برای شما هم پیش اومده باشه که وقتی از متغیر ها یاجدول های بزرگی مثل فونت ها استفاده میکنید در صورتی که این متغیر حتی اگر به صورت const هم تعریف شده باشه رم رو مشغول میکنه و در واقع اگر شما نیاز به یک بایت اون داشته باشید کل متغیر در حافظه رم قرار خواهد گرفت
برای رفع این مشکل باید متغیر رو از نوع فلش PROGMEM تعریف کرد و مقدار اون رو در صورت نیاز از ادرسی که در اختیار قرار میگیره خوند در این صورت همه متغیر ی رشته در رم قرار نمیگیره بلکه فقط مقداری از اون که نیاز هست و خونده شده
برای این منظور بایدابتدا فایل pgmspace.h رو وارد برنامه کنیم
حالا یه رشته از نوع PROGMEM تعریف میکنیم برای مثال اینجا قراره یه فونت 8x8 تعریف کنیم
همونطوری که مشاهده میکنید رشته ما از نوع PROGMEM تعریف شده
برای خوندن از این رشته هم باید از ماکرو pgm_read_byte استفاده کنیم یعنی نمیشه به صورت معمولی از این رشته استفاده کرد لذا به این صورت عمل میکنیم

همونطوری که در تصویر فوق مشاهده میکنید در صورتی که متغیر از نوع PROGMEM نباشه 98.4 درصد از رم اشغال میشه اما وقتی از نوع PROGMEM باشه حتی یک بایت از رم هم اشغال نخواهد شد

توجه داشته باشید
دلیل اینکه هیچ رمی اشغال نمیشه اینه که کامپایلر فقط از ادرس و اشاره گر استفاده میکنه
در واقع وقتی متغیری از نوع PROGMEM تعریف میکنیم اشاره گری به ادرس خاصی از حافظه فلش که مقدار دهی شده تعریف کردیم
برای رفع این مشکل باید متغیر رو از نوع فلش PROGMEM تعریف کرد و مقدار اون رو در صورت نیاز از ادرسی که در اختیار قرار میگیره خوند در این صورت همه متغیر ی رشته در رم قرار نمیگیره بلکه فقط مقداری از اون که نیاز هست و خونده شده
برای این منظور بایدابتدا فایل pgmspace.h رو وارد برنامه کنیم
کد:
#include "pgmspace.h"
حالا یه رشته از نوع PROGMEM تعریف میکنیم برای مثال اینجا قراره یه فونت 8x8 تعریف کنیم
کد:
const char f8x8b[] PROGMEM = {
0x08,0x08,0x00,0x80,0x00,0x00,0x00,0x00 ,
0x7E,0x81,0x95,0xB1,0xB1,0x95,0x81,0x7E ,
0x7E,0xFF,0xEB,0xCF,0xCF,0xEB,0xFF,0x7E ,
0x0E,0x1F,0x3F,0x7E,0x3F,0x1F,0x0E,0x00 ,
0x08,0x1C,0x3E,0x7F,0x3E,0x1C,0x08,0x00 ,
0x38,0x38,0x9F,0xFF,0x9F,0x38,0x38,0x00 ,
0x10,0x38,0xBC,0xFF,0xBC,0x38,0x10,0x00 ,
0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00 ,
0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF ,
0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00 ,
0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF ,
0x70,0x88,0x88,0x88,0x89,0x7D,0x03,0x0F ,
0x00,0x4E,0x51,0xF1,0xF1,0x51,0x4E,0x00 ,
0xC0,0xE0,0x7F,0x05,0x05,0x05,0x05,0x07 ,
0xC0,0xE0,0x7F,0x05,0x05,0x65,0x75,0x3F ,
0x5A,0x5A,0x3C,0xE7,0xE7,0x3C,0x5A,0x5A ,
0x7F,0x3E,0x3E,0x1C,0x1C,0x08,0x08,0x00 ,
0x08,0x08,0x1C,0x1C,0x3E,0x3E,0x7F,0x00 ,
0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00 ,
0x00,0x00,0x5F,0x00,0x00,0x5F,0x00,0x00 ,
0x06,0x09,0x09,0x7F,0x01,0x01,0x7F,0x01 ,
0x40,0xDA,0xA7,0xA5,0xE5,0x59,0x03,0x02 ,
0x00,0x70,0x70,0x70,0x70,0x70,0x70,0x00 ,
0x80,0x94,0xB6,0xFF,0xFF,0xB6,0x94,0x80 ,
0x00,0x0C,0x06,0x7F,0x06,0x0C,0x00,0x00 ,
0x00,0x18,0x30,0x7F,0x30,0x18,0x00,0x00 ,
0x08,0x08,0x08,0x2A,0x3E,0x1C,0x08,0x00 ,
0x08,0x1C,0x3E,0x2A,0x08,0x08,0x08,0x00 ,
0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x00 ,
0x08,0x1C,0x3E,0x08,0x08,0x3E,0x1C,0x08 ,
0x30,0x38,0x3C,0x3E,0x3C,0x38,0x30,0x00 ,
0x06,0x0E,0x1E,0x3E,0x1E,0x0E,0x06,0x00 ,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,
0x00,0x00,0x00,0x5F,0x00,0x00,0x00,0x00 ,
0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00 ,
0x00,0x14,0x7F,0x14,0x14,0x7F,0x14,0x00 ,
0x00,0x24,0x2A,0x6B,0x6B,0x2A,0x12,0x00 ,
0x00,0x46,0x26,0x10,0x08,0x64,0x62,0x00 ,
0x30,0x4A,0x45,0x4D,0x32,0x48,0x48,0x00 ,
0x00,0x00,0x04,0x03,0x00,0x00,0x00,0x00 ,
0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00 ,
0x00,0x00,0x41,0x22,0x1C,0x00,0x00,0x00 ,
0x08,0x2A,0x1C,0x1C,0x1C,0x2A,0x08,0x00 ,
0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00 ,
0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00 ,
0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00 ,
0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00 ,
0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x00 ,
0x00,0x3E,0x61,0x51,0x49,0x45,0x3E,0x00 ,
0x00,0x44,0x42,0x7F,0x40,0x40,0x00,0x00 ,
0x00,0x62,0x51,0x51,0x49,0x49,0x66,0x00 ,
0x00,0x22,0x41,0x49,0x49,0x49,0x36,0x00 ,
0x10,0x18,0x14,0x52,0x7F,0x50,0x10,0x00 ,
0x00,0x27,0x45,0x45,0x45,0x45,0x39,0x00 ,
0x00,0x3C,0x4A,0x49,0x49,0x49,0x30,0x00 ,
0x00,0x03,0x01,0x71,0x09,0x05,0x03,0x00 ,
0x00,0x36,0x49,0x49,0x49,0x49,0x36,0x00 ,
0x00,0x06,0x49,0x49,0x49,0x29,0x1E,0x00 ,
0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x00 ,
0x00,0x00,0x80,0x66,0x00,0x00,0x00,0x00 ,
0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00 ,
0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x00 ,
0x00,0x00,0x00,0x41,0x22,0x14,0x08,0x00 ,
0x00,0x02,0x01,0x01,0x51,0x09,0x06,0x00 ,
0x00,0x3E,0x41,0x5D,0x55,0x55,0x1E,0x00 ,
0x00,0x7C,0x12,0x11,0x11,0x12,0x7C,0x00 ,
0x00,0x41,0x7F,0x49,0x49,0x49,0x36,0x00 ,
0x00,0x1C,0x22,0x41,0x41,0x41,0x22,0x00 ,
0x00,0x41,0x7F,0x41,0x41,0x22,0x1C,0x00 ,
0x00,0x41,0x7F,0x49,0x5D,0x41,0x63,0x00 ,
0x00,0x41,0x7F,0x49,0x1D,0x01,0x03,0x00 ,
0x00,0x1C,0x22,0x41,0x51,0x51,0x72,0x00 ,
0x00,0x7F,0x08,0x08,0x08,0x08,0x7F,0x00 ,
0x00,0x00,0x41,0x7F,0x41,0x00,0x00,0x00 ,
0x00,0x30,0x40,0x40,0x41,0x3F,0x01,0x00 ,
0x00,0x41,0x7F,0x08,0x14,0x22,0x41,0x40 ,
0x00,0x41,0x7F,0x41,0x40,0x40,0x60,0x00 ,
0x00,0x7F,0x01,0x02,0x04,0x02,0x01,0x7F ,
0x00,0x7F,0x01,0x02,0x04,0x08,0x7F,0x00 ,
0x00,0x3E,0x41,0x41,0x41,0x41,0x3E,0x00 ,
0x00,0x41,0x7F,0x49,0x09,0x09,0x06,0x00 ,
0x00,0x1E,0x21,0x21,0x31,0x21,0x5E,0x40 ,
0x00,0x41,0x7F,0x49,0x19,0x29,0x46,0x00 ,
0x00,0x26,0x49,0x49,0x49,0x49,0x32,0x00 ,
0x00,0x03,0x01,0x41,0x7F,0x41,0x01,0x03 ,
0x00,0x3F,0x40,0x40,0x40,0x40,0x3F,0x00 ,
0x00,0x0F,0x10,0x20,0x40,0x20,0x10,0x0F ,
0x00,0x3F,0x40,0x40,0x38,0x40,0x40,0x3F ,
0x00,0x41,0x22,0x14,0x08,0x14,0x22,0x41 ,
0x00,0x01,0x02,0x44,0x78,0x44,0x02,0x01 ,
0x00,0x43,0x61,0x51,0x49,0x45,0x43,0x61 ,
0x00,0x7F,0x41,0x41,0x41,0x00,0x00,0x00 ,
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x00 ,
0x00,0x41,0x41,0x41,0x7F,0x00,0x00,0x00 ,
0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00 ,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 ,
0x00,0x00,0x00,0x03,0x04,0x00,0x00,0x00 ,
0x00,0x20,0x54,0x54,0x54,0x54,0x78,0x40 ,
0x00,0x01,0x7F,0x30,0x48,0x48,0x48,0x30 ,
0x00,0x38,0x44,0x44,0x44,0x44,0x28,0x00 ,
0x00,0x30,0x48,0x48,0x48,0x31,0x7F,0x40 ,
0x00,0x38,0x54,0x54,0x54,0x54,0x18,0x00 ,
0x00,0x00,0x48,0x7E,0x49,0x01,0x02,0x00 ,
0x00,0x98,0xA4,0xA4,0xA4,0xA4,0x78,0x04 ,
0x00,0x41,0x7F,0x08,0x04,0x04,0x78,0x00 ,
0x00,0x00,0x44,0x7D,0x40,0x00,0x00,0x00 ,
0x00,0x60,0x80,0x80,0x80,0x84,0x7D,0x00 ,
0x00,0x01,0x7F,0x10,0x28,0x44,0x40,0x00 ,
0x00,0x00,0x41,0x7F,0x40,0x00,0x00,0x00 ,
0x00,0x7C,0x04,0x04,0x78,0x04,0x04,0x78 ,
0x00,0x7C,0x08,0x04,0x04,0x04,0x78,0x00 ,
0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00 ,
0x00,0x84,0xFC,0x98,0x24,0x24,0x18,0x00 ,
0x00,0x18,0x24,0x24,0x98,0xFC,0x84,0x00 ,
0x00,0x44,0x7C,0x48,0x04,0x04,0x18,0x00 ,
0x00,0x48,0x54,0x54,0x54,0x54,0x24,0x00 ,
0x00,0x04,0x04,0x3F,0x44,0x44,0x20,0x00 ,
0x00,0x3C,0x40,0x40,0x40,0x20,0x7C,0x00 ,
0x00,0x0C,0x10,0x20,0x40,0x20,0x10,0x0C ,
0x00,0x3C,0x40,0x40,0x38,0x40,0x40,0x3C ,
0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00 ,
0x00,0x9C,0xA0,0xA0,0xA0,0xA0,0x7C,0x00 ,
0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00 ,
0x00,0x08,0x08,0x36,0x41,0x41,0x00,0x00 ,
0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x00 ,
0x00,0x00,0x41,0x41,0x36,0x08,0x08,0x00 ,
0x00,0x02,0x01,0x01,0x02,0x02,0x01,0x00
};
همونطوری که مشاهده میکنید رشته ما از نوع PROGMEM تعریف شده
برای خوندن از این رشته هم باید از ماکرو pgm_read_byte استفاده کنیم یعنی نمیشه به صورت معمولی از این رشته استفاده کرد لذا به این صورت عمل میکنیم
کد:
for(uint8_t i=0; i<8; i++)str[i] = pgm_read_byte(&f8x8b[(' ' - 'A') * 8 + i]);

همونطوری که در تصویر فوق مشاهده میکنید در صورتی که متغیر از نوع PROGMEM نباشه 98.4 درصد از رم اشغال میشه اما وقتی از نوع PROGMEM باشه حتی یک بایت از رم هم اشغال نخواهد شد

توجه داشته باشید
دلیل اینکه هیچ رمی اشغال نمیشه اینه که کامپایلر فقط از ادرس و اشاره گر استفاده میکنه
در واقع وقتی متغیری از نوع PROGMEM تعریف میکنیم اشاره گری به ادرس خاصی از حافظه فلش که مقدار دهی شده تعریف کردیم