How to get character from charset by ascii int

Hi,

I'm trying to display a custom character to a custom created led panel i created from a string of ws2812 addressable leds.

I've got a set of characters:

byte ch48[24] = {0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0}; // 0
byte ch49[24] = {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0}; // 1
byte ch50[24] = {1,0,0,1,1,1,1,0,1,0,1,0,0,0,0,1,1,1,0,0,0,0,0,1}; // 2
byte ch51[24] = {0,1,1,1,1,1,1,1,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,1}; // 3
byte ch52[24] = {1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,1}; // 4
byte ch53[24] = {0,1,1,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,1,1,1,1,1,1}; // 5
byte ch54[24] = {0,1,1,0,0,0,0,1,1,0,1,0,0,0,0,1,1,1,1,1,1,1,1,0}; // 6
byte ch55[24] = {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1}; // 7
byte ch56[24] = {0,1,1,1,1,1,1,1,1,0,1,0,0,0,0,1,1,1,1,1,1,1,1,0}; // 8
byte ch57[24] = {1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,1,0,0,1,1,1,1,1,0}; // 9
etc....

it's the ascii code with a ch prefix to create a valid variable name.

I'm able to create an array with the ascii codes from a string

But i'm stuck at getting the correct byte array with the corresponding character.

So how do I convert a char int e.g. "48" to "ch48" as a variable name.

Thanks in advance

Peter

Are you only interested in numerals '0' - '9' or do you want the whole ASCII character set?

No, it's a "complete" char set for now it has about 84 characters
including "%", "&", "*" etc.

Use a two dimensional array, then use an offset - 48 to get a character (for example char 48 will be index 0 of the array)

Also you could save 6 times the memory if you stored your values in uint32_t variables (because they are only 1 or 0, like bits)

uint32_t chars[] =
{
  0b011111111000000111111110, // 0
  ...

Then use bitRead to get each bits

With a 2D array for the numerals. Note this is a minimalist’s implementation with no array bounds checking. The rest of the character set is left as an exercise to the student. Be sure to handle discontinuities in your set relative to ASCII codes.

As @guix noted, there’s likely a more efficient way to store your data.

void displayCharacter(const uint8_t ledPattern[24]);

const uint8_t numerals[][24] {
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0}, // 0
  {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0}, // 1
  {1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1}, // 2
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1}, // 3
  {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}, // 4
  {0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1}, // 5
  {0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0}, // 6
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1}, // 7
  {0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0}, // 8
  {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0}  // 9
};

void setup() {
  char num = '4';
  displayCharacter(numerals[num - '0']);
}

void loop() {
}

void displayCharacter(const uint8_t ledPattern[24]) {
  // display the pattern
}

Why not reduce your use of precious RAM by a factor of eight, by packing the data?

Or eliminate RAM use by the character generator, by using only PROGMEM

Thanks so far but how would I declare eg.

ch33[24] = {0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0}; // !
ch37[24] = {1,0,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,1}; // %
ch39[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0}; // ’
ch41[24] = {0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1}; // )
ch43[24] = {0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0}; // +
ch45[24] = {0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0}; // -

How can i create such an array with missing indices?

You need to give up on your original notation that you can use a value to construct a variable name. It can't work. Variable names are lost once the code is compiled.

I understand that let me rephrase the question

how can i do something like:

uint32_t chars[48][1] = { 0b011111111000000111111110 };
uint32_t chars[49][1] = { 0b000000001111111100000010 };

so I can call e.g. chars[49]

that i don't understand

uint32_t characters[] {
  // Led pattern for index 0 goes here
  // Led pattern for index 1 goes here
  // Led pattern for index 2 goes here
  // .
  // .
  // .
  // .
  // Led pattern for index 47 goes here
  0b011111111000000111111110,   // 48
  0b000000001111111100000010,   // 49
  // Led pattern for index 50 goes here
  // Led pattern for index 51 goes here
  // .
  // .
  // .
  // .
};

You may need to offset your array index, to exclude the non-printable ASCII characters, with a simple subtraction

When there are missing indices, you can add padding in the array (useless 0's), it will waste some memory but it's the easiest way to do it

For example between 33 and 37

    0b000000001011111100000000, // !
    0, // 34 unused
    0, // 35 unused
    0, // 36 unused
    0b100001110001100011100001, // %

Your lists are 3 bytes long.
You could use

byte chars[] = { // array of 84 3-byte characters
0x7f,0x81,0xfe , //0b011111111000000111111110 48 at 0,1,2
0x00,0xff,0x02, //0b000000001111111100000010 49 at 3,4,5
etc
};

then

unsigned long character[x] = (chars[x*3]<<16) | (chars[(x*3)+1]<<8] | chars[(x*3)+2]; // x is the index into array, 0 to 84

(chars[x*3]<<16)Needs more casting

guix:
When there are missing indices, you can add padding in the array (useless 0's), it will waste some memory but it's the easiest way to do it

For example between 33 and 37

    0b000000001011111100000000, // !

0, // 34 unused
   0, // 35 unused
   0, // 36 unused
   0b100001110001100011100001, // %

Ok thanks a lot I will try that

"Needs more casting", but the general idea is there.

peterv3210:
Thanks so far but how would I declare eg.

ch33[24] = {0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0}; // !
ch37[24] = {1,0,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,1}; // %
ch39[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0}; // '
ch41[24] = {0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1}; // )
ch43[24] = {0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0}; // +
ch45[24] = {0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0}; // -

How can i create such an array with missing indices?

byte *Characters[] =
{
0,0,0,0,0,0,0,0,0,0,  // 0-9
0,0,0,0,0,0,0,0,0,0, // 10-19
0,0,0,0,0,0,0,0,0,0, // 20-29
0, // 30
0, // 31
0, // 32
ch33,
0, // 34
0, // 35
0, // 36
ch37, // %
0, // 38
ch39, // '
0, // 40
ch41, // )
0, // 42
ch43, // +
0, // 44
ch45, // -

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