Pages: [1]   Go Down
Author Topic: Using bit math with larger than bits  (Read 793 times)
0 Members and 1 Guest are viewing this topic.
Canada
Offline Offline
Sr. Member
****
Karma: 0
Posts: 318
Sometimes teaching, always learning,
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello all,

I'm working on a program to turn relays on/off (for christmas lights ect.) and I am using bit math to make it simple. I have the example below working. Each "menu selection" will cycle through the bytes and turn on/off the relays according to the bits. (Because there can be up to 32 cycles per menu, the first bit is 1 to show that it is not a null entry.)

I have this working for 6 relays, and want to expand up to 16 relays. However, something like B11010100111101010 doesn't work (probably because it's not a byte..).

Is there a solution? How can I make an integer in binary format and still use the bitmath?

Code:
byte RelaySequence[menuSelections][32] = {  //up to 32 cycles per menu
  {                                   //menu selection 1
    B1100000,
    B1000000                    }
  ,
  {                                  //menu selection 2
    B1110000,
    B1011000,
    B1001100,
    B1000110,
    B1000011,
    B1100001       }
}
Logged


Yorkshire England
Offline Offline
Sr. Member
****
Karma: 2
Posts: 267
Arduino good init
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://arduino.cc/en/Reference/LowByte
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1257
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You just need to select the size that gives you the right number of bits (for your application) if you want to manipulate it as a number:
* (unsigned) byte or uint8_t - 8 bits
* (unsigned) int or uint16_t - 16 bits
* (unsigned) long or uint32_t - 32 bits

Of course you can still use your array of bytes and combine them into int/long just before you need to use them if that makes more sense form a programming point of view.

Also note that the numbers Bnnnnnnnn are defined in the Arduino header file (not really sure why). Standard C/C++ allows you to define binary numbers by 0bnnn..nn (simlar to hex numbers being 0xnnnn). This definintion does not depend on any header file and allows arbitrary length bit strings. You still need to respect that the bits have to fit in your variable, though.
« Last Edit: May 13, 2012, 05:58:24 pm by marco_c » Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

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

Perhaps you could make your question less vague.

How many (max) relays per sequence entry.
What is the (max) length of a sequence.

... anything else you think will help take out the guess work as to WHAT you are trying to accomplish using MORE EXACT WORDING.
Logged

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 64
Posts: 2102
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is a set of helper macros I have ported for use in my code.
These will allow you to use up to 32 bits.

Code:
/*
    Binary constant generator macro
    By Tom Torfs - donated to the public domain
    All macro's evaluate to compile-time constants
*/

/*
    HEX__(n)

        Turn a numeric literal into a hex constant ( avoids problems with leading zeroes ).
        8-bit constants max value 0x11111111, always fits in unsigned long
*/

#define HEX__(n) 0x##n##LU

/* 8-bit conversion function */
#define B8__( x ) ( ( x & 0x0000000FLU ) ? 1 : 0 ) + ( ( x & 0x000000F0LU ) ? 2 : 0 ) + ( ( x & 0x00000F00LU ) ? 4 : 0 ) + ( ( x & 0x0000F000LU ) ? 8 : 0 ) + ( ( x & 0x000F0000LU ) ? 16 : 0 ) + ( ( x & 0x00F00000LU ) ? 32 : 0 ) + ( ( x & 0x0F000000LU ) ? 64 : 0 ) + ( ( x & 0xF0000000LU ) ? 128 : 0 )

/* for upto 8-bit binary constants */
#define B8( d ) ( ( uint8_t ) B8__( HEX__( d ) ) )

/* for upto 16-bit binary constants, MSB first */
#define B16( dmsb, dlsb ) ( ( ( uint16_t ) B8( dmsb ) << 8 ) + B8( dlsb ) )

/* for upto 32-bit binary constants, MSB first */
#define B32( dmsb, db2, db3, dlsb ) ( ( ( uint32_t ) B8( dmsb ) << 24 ) + ( ( uint32_t ) B8( db2 ) << 16 ) + ( ( uint32_t ) B8( db3 ) << 8 ) + B8( dlsb ) )

Use them like this:

Code:
uint8_t u_8BitData  = B8(01010101); //85
uint16_t u_16BitData = B16(10101010,01010101); //43605
uint32_t u_32BitData = B32(10000000,11111111,10101010,01010101); //2164238933

Could use in your code like this:

Code:
int RelaySequence[menuSelections][32] = {  //up to 32 cycles per menu
  {                                   //menu selection 1
    B16( 1100000, 1100000 ),
    B16( 1000000, 1000000 )                    }
  ,
  {                                  //menu selection 2
    B16( 1110000, 1110000 ),
    B16( 1011000, 1011000 ),
    B16( 1001100, 1001100 ),
    B16( 1000110, 1000110 ),
    B16( 1000011, 1000011 ),
    B16( 1100001, 1100001 )       }
}
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

However, something like B11010100111101010 doesn't work (probably because it's not a byte..).

I would wean myself off these rather annoying defines:

Code:
#define B101101 45
#define B0101101 45
#define B00101101 45
#define B101110 46
#define B0101110 46
#define B00101110 46
#define B101111 47
#define B0101111 47
#define B00101111 47
#define B110000 48
#define B0110000 48
#define B00110000 48
#define B110001 49
#define B0110001 49
#define B00110001 49
#define B110010 50
#define B0110010 50
#define B00110010 50
#define B110011 51
#define B0110011 51


Just use what the compiler actually supports:

Code:
0b11010100111101010

As in:

Code:
void setup ()
{
  Serial.begin (115200);
 
  long i = 0b11010100111101010;
 
  Serial.println (i);
}
void loop () {}

Output:

Code:
109034

See? It works. smiley-wink
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25759
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I'm working on a program to turn relays on/off (for christmas lights ect.)
Christmas lights  AND electro-convulsive therapy?
In May?

Skip binary for anything long than about five bits; do what the grown-ups do and learn hex.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Canada
Offline Offline
Sr. Member
****
Karma: 0
Posts: 318
Sometimes teaching, always learning,
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks all, I will give it a try. Hopefully it's ready by christmas...
Logged


Pages: [1]   Go Up
Jump to: