Why does Hex not read out in an array for LED "clock"?

Hey everyone,
I was just wondering how hexadecimal is handled in arrays. It doesn’t seem to handle them like I would have thought and there doesn’t seem to be much on this topic. So I’ve got a simple 4 led row setup. In my array I have binary "data counting up. When I try to replace the binary with hex “data” i’ve already tried them as 0x00,0x01… and I can’t seem to figure it out. The code is below. I’d just much rather be using Hex to store in memory rather than binary because I’m working on just making my own POV.

int pins[] = {9,10,11,12};	// an array of pin numbers
int col_len = 4;		// column lenght

// customizable parameters
int timer1 = 1000;			// time between columns
int timer2 = 0;		// time between frames
int timer3 = 0;			// time between drawings
int frame_len = 4;		// frame length
int frame_num = 1;		// number of frames
// data corresponding to the image to be displayed
int data[] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF}; 

void setup()
{
	int i;
	for (i = 0; i < col_len; i++)
		pinMode(pins[i], OUTPUT);	// set each pin as an output
}

void loop()
{
	int a,b,c;
	
	// go through all data for all columns in each frame.
	for (a = 0; a < frame_num; a++)
	{
		for (b = 0; b < frame_len; b++)
		{
			for (c = 0; c < col_len; c++)
			{
				if (data[a*frame_len*col_len + b*col_len + c] == 0) {digitalWrite(pins[c], LOW);}
				else {digitalWrite(pins[c], HIGH);}
			}
			delay(timer1);
		}
		for (c = 0; c < col_len; c++)
		{digitalWrite(pins[c], LOW);}
		delay(timer2);
	}
	delay(timer3);
}

I don’t know why hex is not working for you but I don’t understand why you want to use it. When I was playing with POV I much preferred binary because it allowed me to visualise what I would output much better than hex would have done.

Incidentally this tests the values in the array and proves that they are correct

int data[] = {
  0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF}; 

void setup()
{
Serial.begin(9600);

  for (int i=0;i<=15;i++)
  {
    Serial.print(i);
    Serial.print("\t");
    Serial.print(data[i],DEC);
    Serial.print("\t");
    Serial.print(data[i],BIN);
    Serial.print("\t");
    Serial.println(data[i],HEX);
  }
}

void loop()
{
}

It doesn't seem to handle them like I would have thought

You need to tell us what your expectations were, and how what you observed differs from that.

In my array I have binary "data[](0,0,0,0....1,1,1,1) counting up

That data is in decimal, and doesn't really count up.

When I was playing with POV I much preferred binary because it allowed me to visualise what I would output much better than hex would have done.

And I would say exactly the opposite, it is easy to visualise a pattern when it is in hex, but difficult in binary because there is so many digits it is much harder to see the pattern.

OP

I have binary "data counting up

then you say

I try to replace the binary with hex "data"

These are not the same, to put that latter array into binary you need data[] = { B00000000, B00000001, B00000010, B00000011 ....

I suspect your mental model of number representations, arrays and their initialization values may be off.

Your best bet is to explains what you are trying to do and possible why you think it needs to be done some way you got in your head.

Alright, lets get some questions taken care of.

AWOL: You need to tell us what your expectations were, and how what you observed differs from that.

The lights (4 Leds) are by no means in order, I've written the binary down and it makes no sense. It appears random. The only solid thing I'm seeing is 0x8 every other clock cycle.

AWOL: In my array I have binary "data[](0,0,0,0....1,1,1,1) counting up

That data is in decimal, and doesn't really count up.

Grumpy_Mike:

I have binary "data counting up

then you say

I try to replace the binary with hex "data"

These are not the same, to put that latter array into binary you need data[] = { B00000000, B00000001, B00000010, B00000011 ....

I did not realize that if I was to place "B" it would represent a Byte. I was simply putting a single string of binary in and have it segmented by "col_len" so when I have

int data[] = {0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,1,0,0,0,1,0,1,0,1,1,0,0,1,1,1,1,0,0,0,1,0,0,1,1,0,1,0,1,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,1,1};

One of the if loops (last one using variable c in it) cuts up the array into 4 bit chunks. So if you look at it in 4 bit segments, you see the count up from 0000 to 1111.

Maybe I'm making the wrong assumption, but I like hex more and thought it'd be easier to code especially when long term this POV will be interacting w/ an external memory for larger storage.

lloyddean: I suspect your mental model of number representations, arrays and their initialization values may be off.

Your best bet is to explains what you are trying to do and possible why you think it needs to be done some way you got in your head.

My idea is to have a POV device (just really for learning purposes) that will use anywhere from 16-32 LEDs. When dealing with this many, I figured that I'd probably be best to deal (coding) with hex so rather than punching in a 32 bit binary for a single "column", I could simple type in something like 0xFF. I also figured that it would be easier using hex when interacting w/ an external memory (EEPROM) or something of the sort. Mostly I was thinking hex for coding purposes to easily wrap my mind around what's going on.

I didn't realize I'd run into this issue right off the bat. I really don't understand why storing a hex in an array would be such a problem. Am I going about the wrong way displaying the hex data? Does the arduion array not interpret it and sent it out the outputs like it does the raw binary?

I was simply putting a single string of binary

So when substituting hex for your sort of binary you must change your code as well.

so rather than punching in a 32 bit binary for a single "column", I could simple type in something like 0xFF.

And so you can (the leading 24bits would be padded with zeroes in this case). Hex or binary (or octal or decimal), the compiler doesn't care, they're all just a convenience and all end up as binary.

Can you read this image?

uint8_t image[] =
{
      0b00000000
    , 0b11111111
    , 0b00010000
    , 0b11111111
    , 0b00000000
    , 0b11111111
    , 0b10010001
    , 0b10010001
    , 0b00000000
    , 0b11111111
    , 0b10000000
    , 0b10000000
    , 0b00000000
    , 0b11111111
    , 0b10000000
    , 0b10000000
    , 0b00000000
    , 0b11111111
    , 0b10000001
    , 0b11111111
};

Grumpy_Mike:

I was simply putting a single string of binary

So when substituting hex for your sort of binary you must change your code as well.

I was initially following a blog post tut with that code, but now that I look at it more and with some of the help from you guys... I see that just isn't what I'm looking for. Pretty inefficient now that I look at it.

lloyddean: Can you read this image?

uint8_t image[] =
{
      0b00000000
    , 0b11111111
    , 0b00010000
    , 0b11111111
    , 0b00000000
    , 0b11111111
    , 0b10010001
    , 0b10010001
    , 0b00000000
    , 0b11111111
    , 0b10000000
    , 0b10000000
    , 0b00000000
    , 0b11111111
    , 0b10000000
    , 0b10000000
    , 0b00000000
    , 0b11111111
    , 0b10000001
    , 0b11111111
};

Of course I can. I see your point, but when you're putting that out in 32 bits length rather than 8, that's a lot of typing. Plus, I'm going to try coding up a simple GUI to handle the text -> hex for me, so I wont be hand coding it.

Grumpy_Mike:

When I was playing with POV I much preferred binary because it allowed me to visualise what I would output much better than hex would have done.

And I would say exactly the opposite, it is easy to visualise a pattern when it is in hex, but difficult in binary because there is so many digits it is much harder to see the pattern.

Each to their own but I know which of these 2 I can see a pattern in

byte BinPattern[]=
{
 B11100000,
 B01110000,
 B00111000,
 B00011100,
 B00001110,
 B00000111
};

byte HexPattern[]=
{
0xE0,
0x70,
0x38,
0x1C,
0x0E,
0x07,
};

UKHeliBob:

Grumpy_Mike:

When I was playing with POV I much preferred binary because it allowed me to visualise what I would output much better than hex would have done.

And I would say exactly the opposite, it is easy to visualise a pattern when it is in hex, but difficult in binary because there is so many digits it is much harder to see the pattern.

Each to their own but I know which of these 2 I can see a pattern in

byte BinPattern[]=

{
B11100000,
B01110000,
B00111000,
B00011100,
B00001110,
B00000111
};

byte HexPattern=
{
0xE0,
0x70,
0x38,
0x1C,
0x0E,
0x07,
};

Kind of stumped as to how to handle either a hex or byte and convert that to be displayed on proper led. So I’ve got the following arrary for the LEDs with a ledpin count.

int pins[] = {9,10,11,12};	// an array of pin numbers
int pinCount = 4;
int data[] = {B0000,B0001,B0010,B0011};  // array of data

Idea being the data set would be larger to walk through all 4 leds rather than just the first two. So what I guess I’m asking is how can you walk through the byte in the data array? I get how to walk through the data array (a simple for statement) but once you have accessed that byte, say the last B0011 (data[3]), how can each bit be assigned to an led?

Which bit of 'B0011' corresponds to say pin 9. Bits are numbered with 0 on the right thru 3 on the left just the right side of the 'B'

int pins[] = {9,10,11,12};  // an array of pin numbers
int pinCount = 4;
int data[] = {B0000,B0001,B0010,B0011};  // array of data

lloyddean: Which bit of 'B0011' corresponds to say pin 9. Bits are numbered with 0 on the right thru 3 on the left just the right side of the 'B'

int pins[] = {9,10,11,12};    // an array of pin numbers
int pinCount = 4;
int data[] = {B0000,B0001,B0010,B0011};  // array of data

So for instance, lets say 12 is most far right so in example of B0011 it would be pin9=0 pin10=0 pin11=1 pin12=1. I just don't understand how to take the bits from the data array (B0011) and assign them according to the corresponding pins. I'm just wondering how I access the individual bits of the byte so that I can assign them to the corresponding pins using the for loop of course.

Easy-peasy with a shift register !

There will be smarter ways of doing it in software I am sure but one method that comes to mind is to do a bitwise AND between your number and 1. If the answer is 1 then turn on pin 12. Shift your number right 1 and do the AND again. If the answer is 1 then turn on pin 11 and so on.

Drewski:
So for instance, lets say 12 is most far right so in example of B0011 it would be pin9=0 pin10=0 pin11=1 pin12=1. I just don’t understand how to take the bits from the data array (B0011) and assign them according to the corresponding pins. I’m just wondering how I access the individual bits of the byte so that I can assign them to the corresponding pins using the for loop of course.

You need to loop through the bits, of course, and a for loop is the most natural way to do that. Within the loop you test the value of a specific bit within the byte value, and output it to the corresponding output pin. You could test the bit value either by creating a bitmask and doing a bitwise AND of the mask and the value.

This gives you a value with the ith bit set, suitable to be used as a bitmask.

byte mask = 1 << i;

To apply the mask:

byte maskedValue = value & (1 << i);

If the masked value was zero, the bit was zero; otherwise it was one.

Alternative you can just use the Arduino bitRead() function (which presumably does the bitmasking itself behind the scenes). Hardly any saving in terms of source code size, but using the function saves you having to think about the bitmasking yourself.

Sorry for the slow response - very bad WiFi interference today!

#define ENTRIES(ARRAY)  (sizeof(ARRAY) / sizeof(ARRAY[0]))

int pins[] = { 9, 10, 11, 12 };
int pattern[] =
{
      B0000
    , B0001
    , B0010
    , B0011
};

void loop()
{
    for ( int i = 0; i < ENTRIES(pattern); i++ )
    {
        for (int mask = 0b1000, iPin = 0; mask; mask >>= 1, iPin++ )
        {
            digitalWrite(pins[iPin], ((pattern[i] & mask) ? HIGH : LOW));
            delay(10UL);
        }
    }
}

void setup()
{
    for ( i = ENTRIES(pins); i--; )
    {
        pinMode(pins[i], OUTPUT);
    }
}

UKHeliBob:
Easy-peasy with a shift register !

There will be smarter ways of doing it in software I am sure but one method that comes to mind is to do a bitwise AND between your number and 1. If the answer is 1 then turn on pin 12. Shift your number right 1 and do the AND again. If the answer is 1 then turn on pin 11 and so on.

I am going to actually try a serial shift register just for another way to learn how to do it.

PeterH:
You need to loop through the bits, of course, and a for loop is the most natural way to do that. Within the loop you test the value of a specific bit within the byte value, and output it to the corresponding output pin. You could test the bit value either by creating a bitmask and doing a bitwise AND of the mask and the value.

This gives you a value with the ith bit set, suitable to be used as a bitmask.

byte mask = 1 << i;

To apply the mask:

byte maskedValue = value & (1 << i);

If the masked value was zero, the bit was zero; otherwise it was one.

Alternative you can just use the Arduino bitRead() function (which presumably does the bitmasking itself behind the scenes). Hardly any saving in terms of source code size, but using the function saves you having to think about the bitmasking yourself.

This mask stuff… why have I missed this? I’ve got quite a bit a reading to do apparently.

lloyddean:
Sorry for the slow response - very bad WiFi interference today!

#define ENTRIES(ARRAY)  (sizeof(ARRAY) / sizeof(ARRAY[0]))

int pins = { 9, 10, 11, 12 };
int pattern =
{
      B0000
    , B0001
    , B0010
    , B0011
};

void loop()
{
    for ( int i = 0; i < ENTRIES(pattern); i++ )
    {
        for (int mask = 0b1000, iPin = 0; mask; mask >>= 1, iPin++ )
        {
            digitalWrite(pins[iPin], ((pattern[i] & mask) ? HIGH : LOW));
            delay(10UL);
        }
    }
}

void setup()
{
    for ( i = ENTRIES(pins); i–; )
    {
        pinMode(pins[i], OUTPUT);
    }
}

All I can say is WOW! Seriously, thanks a ton guys especially you lloyddean! This gives me a lot to work through, material to look up and read. Amazing community!