Errors accessing struct + union

Hello,
Trying to manage led wall and drawing digits on it.
Created some structs to manage pixel fonts.

// Fonts definition
typedef struct DigitRow {
unsigned row : 5;
unsigned : 0;
};

typedef struct DigitColumn {
unsigned column : 7;
unsigned : 0;
};

typedef struct {
byte height;
byte width;
union {
DigitRow row[7]; //Digit by row
DigitColumn column[5]; //Digit by column
};
}
Digit;

Digit pixelFont[] = {
{7, 5, B01110, B10001, B10001, B10001, B10001, B10001, B01110}, // Font[Ø] = '0'
...
{7, 1, B0, B0, B1, B0, B1, B0, B0}, // Font[10] = ':'
...
{7, 5, B01110, B10001, B10001, B11111, B10001, B10001, B10001}, // Font[17] = 'A'
...
{7, 3, B111, B010, B010, B010, B010, B010, B111} // Font[25] = 'I'
};

Got a lot of warnings ...

  • ... 'typedef' was ignored in this declaration
  • ... missing braces around initializer for 'Digit::'
  • ... missing braces around initializer for 'DigitRow [7]'
  • ... missing braces around initializer for 'DigitRow'

To draw a digit on the led wall, I try something like that ...

void drawChar (char digit, int x, int y, uint32_t aColor) {
for (byte i = 0; i < pixelFont[digit].width; i++) {
for (byte j = 0; j < pixelFont[digit].height; j++) {
strip.setPixelColor(width - i, height - j, (bitRead(pixelFont[0].row[j], i) == 1 ? aColor : black);
}
}
}

... and got an error :
error: no match for 'operator>>' in 'pixelFont[(((int)digit) + -0x000000030)].Digit::.Digit::::row[((int)j)] >> i'

whouuups ...!!!

How can/should I access to a bit in a row of a digit in pixelFont ?

Thanks for your help !!!

  • JLD -

Your last struct needs a name. As does your union inside it, thus

// Fonts definition
typedef struct DigitRow {
  unsigned row : 5;
  unsigned : 0;
};

typedef struct DigitColumn {
  unsigned column : 7;
  unsigned : 0;
};


typedef struct pixelThing{
  byte height;
  byte width;
  union {
    DigitRow row[7]; //Digit by row
    DigitColumn column[5]; //Digit by column
  }placementThing;
};

Thanks a lot for your help.

Modified the struct this way ...

typedef struct digitStruct{
byte height;
byte width;
union {
DigitRow row[7]; //Digit by row
DigitColumn column[5]; //Digit by column
} pixelMatrix;
} Digit;

Digit pixelFont[] = {
{7, 5, B01110, B10001, B10001, B10001, B10001, B10001, B01110}, // Font[Ø] = '0'
...
{7, 1, B0, B0, B1, B0, B1, B0, B0}, // Font[10] = ':'
...
{7, 5, B01110, B10001, B10001, B11111, B10001, B10001, B10001}, // Font[17] = 'A'
...
{7, 3, B111, B010, B010, B010, B010, B010, B111} // Font[25] = 'I'
};

How can I access for example to the first bit of the first line of '0' ?

Sorry for such a stupid question, but the remains of my past developer experience are ... quite far in the past ... :wink:

Best regards,

  • JLD -

pixelFont[0].pixelMatrix.row[0];

I don't think it's going to work the way you expect.

I agree, it doesn't work ...

Trying :
int b = bitRead(pixelFont[0].pixelMatrix.row[0], 1);

and get :

error: no match for 'operator>>' in 'pixelFont[0].digitStruct::pixelMatrix.digitStruct::pixelUnion::row[0] >> 1'

Any idea of a direction that I should work in to meet my requirements ?

Thanks !

  • JLD -
#include <stdio.h>


// Fonts definition
typedef struct  {
  unsigned row : 5;
  unsigned : 0;
}DigitRow;

typedef struct {
  unsigned column : 7;
  unsigned : 0;
} DigitColumn;


typedef struct digitStruct{
  char height;
  char width;
  union {
    DigitRow row[7]; //Digit by row
    DigitColumn column[5]; //Digit by column
  } pixelMatrix;
} Digit;

Digit pixelFont[] = {
  {7, 5, 01110, 10001, 10001, 10001, 10001, 10001, 01110}, 
  {7, 1, 0, 0, 1, 0, 1, 0, 0}, 
  {7, 5, 01110, 10001, 10001, 11111, 10001, 10001, 10001}, 
  {7, 3, 111, 010, 010, 010, 010, 010, 111} 
};

int main()
{
    printf("%u\n",pixelFont[0].pixelMatrix.row[0]);
    printf("%u\n",pixelFont[0].height);
    printf("Hello, World!\n");

    return 0;
}

I run this code on compileonline and got output 8 and 7.
PS: i currently i dont't have arduino board.

Thanks for your help.

The problem seems in accessing the bit field ...

typedef struct digitStruct{
byte height;
byte width;
union {
DigitRow row[7]; //Digit by row
DigitColumn column[5]; //Digit by column
} pixelMatrix;
} Digit;

Digit pixelFont[] = {
{7, 5, B01110, B10001, B10001, B10001, B10001, B10001, B01110}, // Font[Ø] = '0'
...
{7, 1, B0, B0, B1, B0, B1, B0, B0}, // Font[10] = ':'
...
{7, 5, B01110, B10001, B10001, B11111, B10001, B10001, B10001}, // Font[17] = 'A'
...
{7, 3, B111, B010, B010, B010, B010, B010, B111} // Font[25] = 'I'
};

...

... bitRead(pixelFont[0].pixelMatrix.row[0], 1) ...

This line doesn't work ...

error: no match for 'operator>>' in 'pixelFont[0].digitStruct::pixelMatrix.digitStruct::pixelUnion::row[0] >> 1'

Don't understand why and the way to turn around and draw pixel mapped digits !

Any idea ?

Best regards,

  • JLD -

That isn't going to work as you think it will. A struct or union can't be of a size which is not a multiple of 8bits.

Think of this:

struct {
   unsigned char bits:7;
} SomeType;

What is the size of SomeType? You might say 7 bits as that is all that is in it, but actually it will be 8bits (you can check by doing sizeof(SomeType) - you will get 1, i.e. 1 byte - you won't get 7/8ths).

Why does it do this? Well, think of if you have a pointer in memory to a SomeType. If it was seven bits in size, how would you express that?

SomeType array[4];

Say the first element is stored at address 0x000. Where is the second element stored? A pointer is described as number of bytes, so what would be the address of the second element if the data type was only 7 bits in size? You couldn't have an address of 0.875, that would make no sense.

What this means is your union won't be anything like you think. In fact it will be a union of size 7 bytes, where the first 5 bytes are common between your array of DigitColumn and DigitRow types.