8 lose bits to 1 binairy number to convert.


I have searched before posting couldn't find anything of help so here's the problem: I've got 8 Data pins, which can be high or low, a high is a 1, and low a 0.

now I got these bit's and need to print the as one value or binary number, and convert this to DEC for the python script to read it.

so any thought's on how I can combine these loose bit's to form 1 binairy number that i can convert to DEC?


This ought to do it

  const int pinsToRead[] = { 1, 2, 3, 4, 5, 6, 7, 8 };    // the first pin in this list will be the topmost bit in the result (i.e. if it's the only bit that's HIGH, the result will be 128)
  const unsigned numberOfPins = sizeof( pinsToRead ) / sizeof( pinsToRead[ 0 ] );
  unsigned result = 0;
  for ( unsigned index = 0; index != numberOfPins; ++index )
    result = ( result << 1 ) + ( ( digitalRead( pinsToRead[ index ] ) == HIGH ) ? 1 : 0 );

  Serial.println( result, 10 );    // writes number, in decimal, to serial port then newline.

(Compiled but not tested.)

Awesome! thank you kerthyn.

result = ( result << 1 ) + ( ( digitalRead( pinsToRead[ index ] ) == HIGH ) ? 1 : 0 );

Oh C, how I love ya, how I hate you. :wink:

I can read it and even understand it, however I could never go, oh, here is how I will do that. :wink:


I dearly love C++; it’s like writing jiyuritsu haiku with a demonically possessed chainsaw.

One could get rid of the entire ternary operator by relying on the fact that HIGH is 1 and LOW is 0, and that will probably never change due to the way how avr-libc works with regard to the port/pin registers.

relying on the fact that HIGH is 1 and LOW is 0, and that will probably never change

It's true, Dominik, one could do that. And it would probably not cause problems in the future.

But, for me, probably isn't good enough. I've developed a number of habits over the years based on shortcuts just not being worth the trouble. One of these is never to assume that a macro won't change; I won't rely on anything other than the contract a macro implies. I have seen numerous problems caused by doing otherwise.

In this case, I actually the like the result of this habit; the code says "if the input is high, insert a 1, otherwise insert a 0." It's nicely self-documenting, and I like that, especially in code I write for somebody new to the environment.

If you wanted to be slick, you could do it quite easily (and a lot faster, with a lot less code) using the port input pins register.

Assuming you used pins 0-7 (yes, using the RX/TX may not be safe =), you could quickly do:

result = PIND;

Yup, that's it =)

PIND = one bit per state, where the first bit (Bx) is pin 7 and the last bit (B0000000x) is pin 0. Thus, Binary one = B00000001, and only having pin 0 high would cause PIND's value to be B00000001. If you spread the pins across two registers, you'd need to do some bit-shifting and some and operations to get the right values in place, but that's pretty easy to do.

The drawbacks? You have to use PIND which may change on different processors. The benefits? If you're doing time-sensitive stuff, this will run eons faster than 8 digitalRead()s, and will compile to a lot less code.


The drawbacks?

Also not portable across several different AVR chips supported by the Arduino platform.