Pages: 1 [2]   Go Down
Author Topic: Why does Hex not read out in an array for LED "clock"?  (Read 1189 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 24
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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'

Code:
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.
Logged

East Anglia (UK)
Online Online
Faraday Member
**
Karma: 118
Posts: 4400
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:
byte mask = 1 << i;

To apply the mask:
Code:
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.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
#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);
    }
}
« Last Edit: February 02, 2013, 07:18:21 pm by lloyddean » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 24
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.


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.
Code:
byte mask = 1 << i;

To apply the mask:
Code:
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.

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

Code:
#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!
« Last Edit: February 02, 2013, 07:38:48 pm by Drewski » Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34725
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So what I guess I'm asking is how can you walk through the byte in the data array?

Have a read of this:-
http://www.thebox.myzen.co.uk/Tutorial/Arrays.html
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 24
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys, thanks so much for your help. I've got one more question, but mostly I wanted to share with you my end result for you to maybe point out any issues but also to share with anyone now or in the future that may be looking for similar code. One last question. Any materials that I could read to understand more of the masking method? I'm going to be stepping into ARM here soon and I know libraries are vastly different and want to understand the raw code of masking.
Edit: What's the easiest way to determine size of an array. I'd rather not have a pinCount and arrayCount but Sizeof doesn't seem to work on arrays. I know I could probably put together some for loops to do the counting for me but I was hoping there'd be some function that could do it for me.

Code:
int pins[] = {9,10,11,12}; // an array of pin numbers
int pinCount = 4;
int data[] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};// array of data
int arrayCount = 16;
int timer = 1000; //1 sec delay

void setup() {
  for (int thisPin = 0; thisPin < pinCount; thisPin++)  { //Initialize pins[] as outputs
    pinMode(pins[thisPin], OUTPUT);     
  }
}

void loop()
{
  for (int a = 0; a < arrayCount; a++)  //Cycle through the data[]
   {
     for (int b = 0; b < pinCount; b++)  //Cycle through bits in each data[] entry
     {
       digitalWrite(pins[b], bitRead(data[a],b)); //Write to the corresponding pins[] the corresponding data in data[]
     }
     delay(timer);
   }
}
« Last Edit: February 03, 2013, 05:21:23 pm by Drewski » Logged

East Anglia (UK)
Online Online
Faraday Member
**
Karma: 118
Posts: 4400
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Size of array as in number of bytes it occupies or number of elements ?
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What's the easiest way to determine size of an array. I'd rather not have a pinCount and arrayCount but Sizeof doesn't seem to work on arrays. I know I could probably put together some for loops to do the counting for me but I was hoping there'd be some function that could do it for me.

Again - right in my last post!!!

Code:
#define ENTRIES(ARRAY)  (sizeof(ARRAY) / sizeof(ARRAY[0]))
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 24
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What's the easiest way to determine size of an array. I'd rather not have a pinCount and arrayCount but Sizeof doesn't seem to work on arrays. I know I could probably put together some for loops to do the counting for me but I was hoping there'd be some function that could do it for me.

Again - right in my last post!!!

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


Sorry for that part. I glazed over that because I don't really understand that. Would you mind just stepping through it? What I do understand is your defining the a function "Entries" and a parameter "array". I just don't understand what exactly is going on after, or I should clarify in that I'm not following. I see your using the sizeof function with that array parameter and dividing by the first element of the array. I guess I'm missing the logic here as to why your dividing by the first element in the array.
Example. Entries(pins[]) = (sizeof(pins[])/sizeof(pins[0])) = 4/9???

Size of array as in number of bytes it occupies or number of elements ?
Size of array as in number of elements.
« Last Edit: February 03, 2013, 11:43:01 pm by Drewski » Logged

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not a function but a MACRO.  If gets expanded in place where ever it is used.

'sizeof()' is a compile time function that returns the amount of memory, in bytes, if its parameter.

'sizeof(pins)' returns the number of bytes the array 'pins' occupies, which in this case is the 4 entries in the array times the size of an 'int' which is 2 bytes for a total of 8 bytes.  This is divided by the number of bytes an element of the array occupies, in this case element 0 (an array must have at least 1 element so we chose that element) which is an 'int', or 2 bytes.  8 (bytes) divided by 2 (bytes) equals 4 entries in the array.  Again this is a calculated at compile time the the compiler and inserted as constants in the code.

If you find your eyes glazing over it's probably the time to ask a question.
« Last Edit: February 04, 2013, 01:52:41 am by lloyddean » Logged

Pages: 1 [2]   Go Up
Jump to: