Go Down

### Topic: 4 digital reads to Dec/Int (Read 1 time)previous topic - next topic

#### Mavromatis

##### May 10, 2013, 09:11 pm
What is the most efficient way to do the following --

int _pin1 = digitalRead(25); // PIN 1
int _pin2 = digitalRead(24); // PIN 2
int _pin4 = digitalRead(23); // PIN 4
int _pin8 = digitalRead(22); // PIN 8

And convert to a byte (0-15) -- the rotary encoder only goes to 16 positions?

#### AWOL

#1
##### May 10, 2013, 09:13 pm
Define "efficient"
"Pete, it's a fool (who) 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.
I speak for myself, not Arduino.

#### Mavromatis

#2
##### May 10, 2013, 09:15 pm

Define "efficient"

Most elegant?   I was thinking of doing a conditional statement -- but I feel like the same can be accomplished by bitwise operations or some other "algorithm".

#### AWOL

#3
##### May 10, 2013, 09:21 pm
Shifts and ORs for me.
But Arduino offers bitWrite.
"Pete, it's a fool (who) 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.
I speak for myself, not Arduino.

#### Sembazuru

#4
##### May 10, 2013, 10:35 pm
Based on AWOL's reminder of the bit functions, there is this:
Code: [Select]
`byte inputNibble;  // variable to hold the input 0b0000 to 0b1111. Initializes to zero.byte inputPins[] =  // array to hold the pin numbers.{  // Using Mavromatis's pin numbers. Is this a Mega or Due? Just curious.  25,  // PIN 1 (LSb)  24,  // PIN 2  23,  // PIN 4  22  // PIN 8 (MSb)};void setup(){  for (byte i = 0; i < 4; i++)  {    pinMode(inputPins[i], INPUT);  // Set the input pins to INPUT.  }}void loop(){  for (byte i = 0; i < 4; i++)  {  // Set the bit at i to be the state of input pin i    bitWrite(inputNibble, i, digitalRead(inputPins[i]));  }}`

Another method for quick and efficient capture is as long as the 4 input pins are on the four LSb of a hardware port and bit order is the same, directly read the port through a bitmask. But that starts tiptoeing out of Arduino programming and pokes it's nose into AVR programming.
http://www.catb.org/jargon/html/I/I-didn-t-change-anything-.html

#### Sembazuru

#5
##### May 10, 2013, 10:50 pm
Interesting...

Taking my code in my previous post as is, it compiles in 1.0.4ERW to 1,030bytes. If I just make my array of pins a constant, the compilation size drops to 1,022bytes. (Estimated SRAM usage is 14bytes for both.)
Also, taking the same code and compiling through 1.5.2 I get 1,014bytes. Making the array a constant gets 1,006 bytes. (1.0.3 gets the same compile sizes as 1.5.2., and I don't have normal 1.0.4 installed.)

I wonder if this has to do with short vs. long addressing at the opcode level...
http://www.catb.org/jargon/html/I/I-didn-t-change-anything-.html

#### Mavromatis

#6
##### May 10, 2013, 10:55 pm
Using a mega -- and thanks!  Bitwrite is the answer I was looking for.

This works great --

Code: [Select]
` byte inputPins[] =  // array to hold the pin numbers. {  25,  // PIN 1 (LSb)  24,  // PIN 2  23,  // PIN 4  22  // PIN 8 (MSb) };byte decoder(){      byte tmpBin;    for (byte i = 0; i < 4; i++)  {  // Set the bit at i to be the state of input pin i    bitWrite(tmpBin, i, digitalRead(inputPins[i]));  }  Serial.println(tmpBin, DEC);  return tmpBin;   }`

#### Sembazuru

#7
##### May 10, 2013, 11:01 pm

Using a mega -- and thanks!  Bitwrite is the answer I was looking for.

Glad it works for you. Yeah, I knew it was either a Mega or Due. I never see pin numbers that large with my two UNOs.
http://www.catb.org/jargon/html/I/I-didn-t-change-anything-.html

#### guix

#8
##### May 11, 2013, 12:02 amLast Edit: May 11, 2013, 12:07 am by guix Reason: 1
Considering your 4 pins are on the same port (PA), you could do without an array, for loop, calls to digitalRead... using something like that:

Code: [Select]
`byte decoder(){  return ( PORTA & 0xF0 ) >> 4;}`

I think that's the most efficient/elegant/faster/whatever

#### Sembazuru

#9
##### May 14, 2013, 06:02 pm

Considering your 4 pins are on the same port (PA), you could do without an array, for loop, calls to digitalRead... using something like that:

Code: [Select]
`byte decoder(){  return ( PORTA & 0xF0 ) >> 4;}`

I think that's the most efficient/elegant/faster/whatever

But not really portable across Arduino platforms and restricts what pins can be used. But I do agree that it is really fast (just a couple clock cycles), and elegant in that it actually does describe what is actually being done at the hardware level. The loop I suggested takes longer (probably a couple dozen clock cycles), but it is elegant in its own way by describing the intent of what is being done.

So, yeah... Six of one and half a dozen of the other.
http://www.catb.org/jargon/html/I/I-didn-t-change-anything-.html

Go Up