Personalized font on adafruit mini thermal printer

Hi all, I'm working with a mini thermal printer Adafruit connected to an arduino nano rp2040 connect. I'd like to set a personalized font for my prints and not only use font A and font B (which are provided by default). Any idea?

I think those font are in ROM in the printer

you possibly could build your own bitmaps and send that out ?

see the guide at Overview | Mini Thermal Receipt Printers | Adafruit Learning System for details

yup, I was able to build my own bitmap (.h file), I've included it in my code but i don't know what to write here: printer.setFont('B'); instead of "B". I'm sure it's super easy but
I'm a beginner :slight_smile:

The .h file I've created is this:

const uint8_t Chiswick_Grotesque_Semibold7pt7bBitmaps[] PROGMEM = {
  0x00, 0xFF, 0xFC, 0x30, 0xFB, 0xB0, 0x32, 0x36, 0x24, 0xFF, 0x24, 0x24,
  0xFF, 0x6C, 0x4C, 0x48, 0x10, 0x21, 0xE6, 0xED, 0x5E, 0x1F, 0x1F, 0x17,
  0xAF, 0xF1, 0xC1, 0x00, 0x71, 0x1B, 0x23, 0x68, 0x6D, 0x07, 0x40, 0x17,
  0x83, 0x98, 0xB3, 0x16, 0x64, 0x78, 0x1C, 0x06, 0xC0, 0xD8, 0x1E, 0xE7,
  0xB0, 0xF4, 0x33, 0x86, 0x70, 0xCF, 0x4E, 0x78, 0xE8, 0x36, 0x6C, 0xCC,
  0xCC, 0xC6, 0x63, 0xC6, 0x63, 0x33, 0x33, 0x36, 0x6C, 0x77, 0xDC, 0x40,
  0x21, 0x3E, 0x42, 0x00, 0xD8, 0xC0, 0xC0, 0x00, 0x46, 0x21, 0x18, 0x84,
  0x62, 0x11, 0x80, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
  0x66, 0x3C, 0xFD, 0xB6, 0xDB, 0x6C, 0x3D, 0xCF, 0x18, 0x30, 0x61, 0x83,
  0x1C, 0x71, 0xFC, 0x7E, 0x06, 0x0C, 0x18, 0x3E, 0x03, 0x03, 0x03, 0xC6,
  0x7C, 0x0C, 0x0C, 0x1C, 0x2C, 0x6C, 0xCC, 0xFF, 0x0C, 0x0C, 0x0C, 0x1F,
  0x10, 0x30, 0x30, 0x2E, 0x33, 0x03, 0x03, 0x47, 0x3C, 0x3C, 0xC5, 0x07,
  0xEE, 0xF8, 0xF1, 0xE3, 0x6C, 0x70, 0xFE, 0x0C, 0x30, 0x61, 0x83, 0x0C,
  0x18, 0x61, 0xC0, 0x7D, 0x8F, 0x1F, 0x77, 0x8F, 0xF3, 0xE3, 0xC6, 0xF8,
  0x79, 0x8B, 0x1E, 0x3C, 0x6F, 0xC1, 0x86, 0x8C, 0xF0, 0xC0, 0x30, 0xC0,
  0x36, 0x1B, 0x30, 0xF0, 0x80, 0xF8, 0x01, 0xF0, 0xC1, 0xC7, 0xE8, 0x00,
  0x7B, 0x30, 0xC6, 0x30, 0x83, 0x00, 0x00, 0xC0, 0x07, 0xC1, 0x82, 0x20,
  0x14, 0x7D, 0xD9, 0x99, 0x99, 0xB3, 0x2B, 0x32, 0xBF, 0xC4, 0x00, 0x60,
  0xE1, 0xF8, 0x0C, 0x0E, 0x07, 0x06, 0xC3, 0x61, 0xB9, 0xFC, 0xC6, 0x41,
  0xE0, 0xC0, 0xFD, 0x8F, 0x1E, 0x3F, 0x98, 0xF1, 0xE3, 0xC7, 0xF8, 0x1E,
  0x31, 0x98, 0x78, 0x0C, 0x06, 0x03, 0x02, 0xC3, 0x61, 0x0F, 0x00, 0xFC,
  0xC6, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC6, 0xFC, 0xFF, 0x0C, 0x30,
  0xFB, 0x0C, 0x30, 0xC3, 0xF0, 0xFF, 0x83, 0x06, 0x0F, 0x98, 0x30, 0x60,
  0xC1, 0x80, 0x1E, 0x31, 0x98, 0x78, 0x0C, 0x06, 0x03, 0x06, 0x83, 0x61,
  0x8F, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
  0xFF, 0xFF, 0xF0, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x4D, 0xE0, 0xC6,
  0xCC, 0xD8, 0xD0, 0xF8, 0xFC, 0xCC, 0xC6, 0xC6, 0xC7, 0xC1, 0x83, 0x06,
  0x0C, 0x18, 0x30, 0x60, 0xC1, 0xFC, 0xE1, 0xFC, 0x7F, 0x3F, 0xCF, 0xDA,
  0xF6, 0xBD, 0xEF, 0x73, 0xCC, 0xF3, 0x30, 0xE3, 0xE3, 0xF3, 0xF3, 0xDB,
  0xDF, 0xCF, 0xC7, 0xC7, 0xC3, 0x1E, 0x1C, 0x66, 0x1B, 0x03, 0xC0, 0xF0,
  0x3C, 0x0D, 0x86, 0x71, 0x87, 0x80, 0xFD, 0x8F, 0x1E, 0x3C, 0x7F, 0xB0,
  0x60, 0xC1, 0x80, 0x1E, 0x0C, 0x31, 0x86, 0x60, 0x6C, 0x0D, 0x81, 0xB7,
  0x33, 0xBE, 0x73, 0x83, 0xE4, 0x0C, 0x80, 0xE0, 0xFC, 0xC6, 0xC6, 0xC6,
  0xF8, 0xCC, 0xC6, 0xC6, 0xC6, 0xC7, 0x79, 0x8B, 0x1F, 0x0F, 0xCF, 0xC3,
  0xC3, 0xC6, 0xF0, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
  0x18, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, 0xC1,
  0xB0, 0x98, 0xCC, 0x63, 0x21, 0xB0, 0xD8, 0x38, 0x1C, 0x0E, 0x00, 0xE3,
  0x0D, 0x8E, 0x36, 0x39, 0x99, 0xE6, 0x36, 0xD8, 0xD3, 0x43, 0xCF, 0x0F,
  0x1C, 0x18, 0x60, 0x61, 0x80, 0x61, 0xB9, 0x8D, 0x83, 0xC1, 0xC0, 0xE0,
  0xD8, 0x6C, 0x63, 0x31, 0xC0, 0xC3, 0x62, 0x66, 0x34, 0x3C, 0x18, 0x18,
  0x18, 0x18, 0x18, 0x7F, 0x07, 0x06, 0x0C, 0x1C, 0x18, 0x38, 0x70, 0xE0,
  0xFF, 0xFC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0x06, 0x10, 0x86, 0x10, 0x86,
  0x10, 0x86, 0x10, 0x00, 0xF3, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x10, 0x70,
  0xA3, 0x64, 0x40, 0xFE, 0x47, 0x78, 0x18, 0x33, 0xEC, 0xD9, 0x9F, 0x80,
  0xC1, 0x83, 0x07, 0xEC, 0x78, 0xF1, 0xE3, 0xCF, 0x78, 0x38, 0xCB, 0x06,
  0x0C, 0x6C, 0x9E, 0x00, 0x06, 0x0C, 0x1B, 0xFE, 0x78, 0xF1, 0xE3, 0xEE,
  0xFC, 0x38, 0xDB, 0x17, 0xEC, 0x08, 0x9F, 0x00, 0x3B, 0x19, 0xE6, 0x31,
  0x8C, 0x63, 0x00, 0x06, 0x78, 0xCC, 0xCC, 0x78, 0x20, 0x3C, 0x3E, 0xC6,
  0xC6, 0x7C, 0xC3, 0x0C, 0x3F, 0xCF, 0x3C, 0xF3, 0xCF, 0x30, 0xC3, 0xFF,
  0xF0, 0x18, 0x00, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x3F, 0x00, 0xC1, 0x83,
  0x06, 0x4D, 0x9E, 0x3E, 0x66, 0xCD, 0x98, 0xFF, 0xFF, 0xF0, 0xFF, 0xF3,
  0x3C, 0xCF, 0x33, 0xCC, 0xF3, 0x3C, 0xCC, 0xFF, 0x3C, 0xF3, 0xCF, 0x3C,
  0xC0, 0x38, 0xDB, 0x1E, 0x3C, 0x6D, 0x8E, 0x00, 0xFD, 0x9F, 0x1E, 0x3C,
  0x79, 0xFF, 0x60, 0xC1, 0x80, 0x7F, 0xCF, 0x1E, 0x3C, 0x7C, 0xDF, 0x83,
  0x06, 0x0C, 0xFE, 0xF1, 0x8C, 0x63, 0x00, 0x76, 0xF9, 0xF3, 0xCD, 0xC0,
  0x66, 0xF6, 0x66, 0x66, 0x70, 0xCF, 0x3C, 0xF3, 0xCF, 0x3F, 0xC0, 0xC6,
  0xC9, 0xB3, 0x63, 0x87, 0x0C, 0x00, 0xCC, 0x53, 0xB6, 0xED, 0xAA, 0x7A,
  0x8C, 0xE3, 0x38, 0x66, 0xD8, 0xE1, 0xC3, 0x8D, 0xB1, 0x80, 0x63, 0x33,
  0x32, 0x36, 0x1E, 0x1C, 0x0C, 0x08, 0x18, 0xF0, 0xF8, 0xCC, 0xC6, 0x63,
  0xE0, 0x07, 0x66, 0x66, 0x86, 0x66, 0x67, 0x10, 0xFF, 0xFF, 0xFF, 0x0E,
  0x66, 0x66, 0x16, 0x66, 0x6E, 0x80, 0x6D, 0x60 };

const GFXglyph Chiswick_Grotesque_Semibold7pt7bGlyphs[] PROGMEM = {
  {     0,   1,   1,   3,    0,    0 },   // 0x20 ' '
  {     1,   2,  10,   4,    1,   -9 },   // 0x21 '!'
  {     4,   4,   3,   6,    1,   -9 },   // 0x22 '"'
  {     6,   8,  10,  10,    1,   -9 },   // 0x23 '#'
  {    16,   7,  13,   9,    1,  -11 },   // 0x24 '$'
  {    28,  11,  10,  13,    1,   -9 },   // 0x25 '%'
  {    42,  11,  10,  12,    1,   -9 },   // 0x26 '&'
  {    56,   2,   3,   3,    1,   -9 },   // 0x27 '''
  {    57,   4,  12,   5,    1,   -9 },   // 0x28 '('
  {    63,   4,  12,   5,    0,   -9 },   // 0x29 ')'
  {    69,   5,   4,   5,    0,   -9 },   // 0x2A '*'
  {    72,   5,   5,   7,    1,   -6 },   // 0x2B '+'
  {    76,   2,   3,   4,    1,    0 },   // 0x2C ','
  {    77,   2,   1,   4,    1,   -3 },   // 0x2D '-'
  {    78,   2,   1,   4,    1,    0 },   // 0x2E '.'
  {    79,   5,  13,   5,    0,  -10 },   // 0x2F '/'
  {    88,   8,  10,  10,    1,   -9 },   // 0x30 '0'
  {    98,   3,  10,   4,    0,   -9 },   // 0x31 '1'
  {   102,   7,  10,   9,    1,   -9 },   // 0x32 '2'
  {   111,   8,  10,   9,    0,   -9 },   // 0x33 '3'
  {   121,   8,  10,  10,    1,   -9 },   // 0x34 '4'
  {   131,   8,  10,   9,    0,   -9 },   // 0x35 '5'
  {   141,   7,  10,   9,    1,   -9 },   // 0x36 '6'
  {   150,   7,  10,   9,    1,   -9 },   // 0x37 '7'
  {   159,   7,  10,   9,    1,   -9 },   // 0x38 '8'
  {   168,   7,  10,   9,    1,   -9 },   // 0x39 '9'
  {   177,   2,   6,   4,    1,   -5 },   // 0x3A ':'
  {   179,   2,   8,   4,    1,   -5 },   // 0x3B ';'
  {   181,   5,   5,   7,    1,   -6 },   // 0x3C '<'
  {   185,   5,   4,   7,    1,   -6 },   // 0x3D '='
  {   188,   5,   5,   7,    1,   -6 },   // 0x3E '>'
  {   192,   6,  10,   7,    0,   -9 },   // 0x3F '?'
  {   200,  12,  12,  14,    1,   -9 },   // 0x40 '@'
  {   218,   9,  10,   9,    0,   -9 },   // 0x41 'A'
  {   230,   7,  10,   9,    1,   -9 },   // 0x42 'B'
  {   239,   9,  10,  11,    1,   -9 },   // 0x43 'C'
  {   251,   8,  10,  10,    1,   -9 },   // 0x44 'D'
  {   261,   6,  10,   8,    1,   -9 },   // 0x45 'E'
  {   269,   7,  10,   8,    1,   -9 },   // 0x46 'F'
  {   278,   9,  10,  11,    1,   -9 },   // 0x47 'G'
  {   290,   8,  10,  10,    1,   -9 },   // 0x48 'H'
  {   300,   2,  10,   4,    1,   -9 },   // 0x49 'I'
  {   303,   6,  10,   7,    0,   -9 },   // 0x4A 'J'
  {   311,   8,  10,   9,    1,   -9 },   // 0x4B 'K'
  {   321,   7,  10,   8,    1,   -9 },   // 0x4C 'L'
  {   330,  10,  10,  12,    1,   -9 },   // 0x4D 'M'
  {   343,   8,  10,  10,    1,   -9 },   // 0x4E 'N'
  {   353,  10,  10,  12,    1,   -9 },   // 0x4F 'O'
  {   366,   7,  10,   9,    1,   -9 },   // 0x50 'P'
  {   375,  11,  12,  12,    1,   -9 },   // 0x51 'Q'
  {   392,   8,  10,   9,    1,   -9 },   // 0x52 'R'
  {   402,   7,  10,   9,    1,   -9 },   // 0x53 'S'
  {   411,   8,  10,  10,    1,   -9 },   // 0x54 'T'
  {   421,   8,  10,  10,    1,   -9 },   // 0x55 'U'
  {   431,   9,  10,   9,    0,   -9 },   // 0x56 'V'
  {   443,  14,  10,  14,    0,   -9 },   // 0x57 'W'
  {   461,   9,  10,   9,    0,   -9 },   // 0x58 'X'
  {   473,   8,  10,   8,    0,   -9 },   // 0x59 'Y'
  {   483,   8,  10,  10,    1,   -9 },   // 0x5A 'Z'
  {   493,   4,  12,   5,    1,   -9 },   // 0x5B '['
  {   499,   5,  13,   5,    0,  -10 },   // 0x5C '\'
  {   508,   4,  12,   5,    0,   -9 },   // 0x5D ']'
  {   514,   7,   5,   7,    0,  -10 },   // 0x5E '^'
  {   519,   7,   1,   7,    0,    3 },   // 0x5F '_'
  {   520,   4,   2,   6,    1,   -9 },   // 0x60 '`'
  {   521,   7,   7,   8,    1,   -6 },   // 0x61 'a'
  {   528,   7,  10,   9,    1,   -9 },   // 0x62 'b'
  {   537,   7,   7,   8,    1,   -6 },   // 0x63 'c'
  {   544,   7,  10,   9,    1,   -9 },   // 0x64 'd'
  {   553,   7,   7,   8,    1,   -6 },   // 0x65 'e'
  {   560,   5,  10,   6,    1,   -9 },   // 0x66 'f'
  {   567,   8,  11,   8,    1,   -7 },   // 0x67 'g'
  {   578,   6,  10,   8,    1,   -9 },   // 0x68 'h'
  {   586,   2,  10,   4,    1,   -9 },   // 0x69 'i'
  {   589,   5,  13,   4,   -2,   -9 },   // 0x6A 'j'
  {   598,   7,  10,   7,    1,   -9 },   // 0x6B 'k'
  {   607,   2,  10,   4,    1,   -9 },   // 0x6C 'l'
  {   610,  10,   7,  12,    1,   -6 },   // 0x6D 'm'
  {   619,   6,   7,   8,    1,   -6 },   // 0x6E 'n'
  {   625,   7,   7,   9,    1,   -6 },   // 0x6F 'o'
  {   632,   7,  10,   9,    1,   -6 },   // 0x70 'p'
  {   641,   7,  10,   9,    1,   -6 },   // 0x71 'q'
  {   650,   5,   7,   6,    1,   -6 },   // 0x72 'r'
  {   655,   5,   7,   7,    1,   -6 },   // 0x73 's'
  {   660,   4,   9,   6,    1,   -8 },   // 0x74 't'
  {   665,   6,   7,   8,    1,   -6 },   // 0x75 'u'
  {   671,   7,   7,   7,    0,   -6 },   // 0x76 'v'
  {   678,  10,   7,  10,    0,   -6 },   // 0x77 'w'
  {   687,   7,   7,   7,    0,   -6 },   // 0x78 'x'
  {   694,   8,  10,   7,   -1,   -6 },   // 0x79 'y'
  {   704,   5,   7,   7,    1,   -6 },   // 0x7A 'z'
  {   709,   4,  13,   5,    1,  -10 },   // 0x7B '{'
  {   716,   2,  12,   4,    1,   -9 },   // 0x7C '|'
  {   719,   4,  13,   5,    0,  -10 },   // 0x7D '}'
  {   726,   6,   2,   6,    0,   -5 } }; // 0x7E '~'

const GFXfont Chiswick_Grotesque_Semibold7pt7b PROGMEM = {
  (uint8_t  *)Chiswick_Grotesque_Semibold7pt7bBitmaps,
  (GFXglyph *)Chiswick_Grotesque_Semibold7pt7bGlyphs,
  0x20, 0x7E, 16 };

Sorry to say that, but it is not easy at all, because the printer library seems not support an external fonts. The only way I see is to print every char as bitmap, which means that you will not be able to use standard print operators to output text and will be forced to write your own functions for this.

1 Like

that's a GFXfont bitmap.

Now you'll have to write code that takes a string you want to print, go through each character, find the associated bitmap and send the right commands to the printer.
Not sure the printer can go backwards so you might need to build a buffer for one full printer line before sending it out

1 Like

Which exact printer do you have? Looking through the manual for one of their discontinued receipt printers, there is an option for loading a custom character set of up to 64 characters.

A bit of a discussion here https://forums.adafruit.com/viewtopic.php?t=32217 on uploading a character, the printer appears to only support 12x24 bit characters.

Thanks for the answer! I thought that once I've created the bitmap file it would have been a much simpler and automatic process, like writing the font name in setfont. I have no clue how I could write such a function that takes the string I want to print, go through each character, find the associated bitmap and send the right commands to the printer. What I want for my project is that every time the user finishes to use a device the printer prints one of 100 different texts put in a random function and some of them are very very long. I don't know, maybe this process you are suggesting me is too complicated for my project

if the text is fixed then may be you could pre-generate the 100 images and keep them as bitmaps in Flash memory or on a SD card and then just use the functions to print bitmaps

I have an Adafruit mini thermal printer, this one Overview | Mini Thermal Receipt Printers | Adafruit Learning System

thanks for the link, now I read it

this was actually my plan B and it is definitely a better way to have control on the graphics for my prints. The thing is that I've already stored 60 images in the Flash memory of the arduino nano, that will be displayed on a ILI9341 Display LCD TFT SPI 2.8" while using the device I was talking about before. So another question related to that... do you know how can i check how much free space I still have in the flash memory of arduino nano? I know how much space is occupied by the images but I don't know which is the one occupied by my code.

Anyway, the solution could actually be using an SD card. Now I try to understand how can i actually use it if necessary.

:woozy_face: the Nano does not have much space. When you compile it will tell you the space occupied by your code and your progmem elements. You might need to add a side EEPROM / FRAM

Arduino IDE informs you about the code size after every successful compilation.

I apologize for the ignorance, the SD you were talking about should be connected to the arduino nano or printer and what component should I buy to read it? When I compile my code (this is not the one I'm working on) Arduino IDE tells me this:

"The sketch uses 1487551 bytes (8%) of the available program space. The maximum is 16777216 bytes.
Global variables use 44544 bytes (16%) of dynamic memory, leaving another 225792 bytes free for local variables. The maximum is 270336 bytes."

what information should I take into account to know how much more I can load? thanks for your patience!!

Is this an Arduino Nano?

I'm using an arduino nano rp2040 connect which has 264KB of SRAM

The number above is your available flash space for code and a constant data, like an images and fonts. It is a more than enough, I think, you don't need a SD card

1 Like

ah - my previous comment

was about the old Nano

1 Like

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