I have 9 pins that are inputs from 9 IR LEDs. I want to combine all their results into one 9 bit number.
example: pin1 = high, pin2 = high, pin3 = high, pin4 = low, pin5 = high, pin6 = low, pin7 = low, pin8 = high, pin9 = low
9 bit number = 111010010
-
arduino.cc/en/Reference/BitshiftMajenko– Majenko2015年11月15日 23:35:51 +00:00Commented Nov 15, 2015 at 23:35
-
As far as I know, the minimum variable size is 1byte = 8 bits, so there is no bit type.Ikbel– Ikbel2015年11月15日 23:38:06 +00:00Commented Nov 15, 2015 at 23:38
3 Answers 3
In your code you would use a 16 bit unsigned integer as your variable. As there is no such thing as a 9 bit type.
If the pins correspond to different ports on your micro, you basically do this:
Read the pin value from the port register, and bit shift to the right bit position then OR with the variable.
Say you had 8 of the LEDS on PORTB (pin 0 - 7 )and the 9th on PORTC (pin 2)
unsigned int ir_inputs = 0
ir_inputs = PORTB; //just reads the register directly
ir_inputs = ir_inputs|((PORTC & 0x04)<<6); //reads the bit on pin 2 then shifts it 6 places to bit 8 (or the 9th bit remember bits always start at 0) and does not affect the other bits
something like that
actually you could put it into a function
unsigned int getIRinputs(void){
return (unsigned int)PORTB|((PORTC & 0x04)<<6);
}
Easy done
Even if you had the inputs on 9 separate ports the principle is the same. Read, Shift, OR
Something like this:
typedef union NUM_9_BITS_t {
unsigned int U;
struct NUM_9_BITS_FIELD {
unsigned int BIT0 : 1;
unsigned int BIT1 : 1;
unsigned int BIT2 : 1;
unsigned int BIT3 : 1;
unsigned int BIT4 : 1;
unsigned int BIT5 : 1;
unsigned int BIT6 : 1;
unsigned int BIT7 : 1;
unsigned int BIT8 : 1;
unsigned int BITO : 23;
} BITS;
} NUM_9_BITS;
NUM_9_BITS num;
num.BITS.BIT0 = digitalRead(PIN0);
num.BITS.BIT1 = digitalRead(PIN1);
num.BITS.BIT2 = digitalRead(PIN2);
num.BITS.BIT3 = digitalRead(PIN3);
num.BITS.BIT4 = digitalRead(PIN4);
num.BITS.BIT5 = digitalRead(PIN5);
num.BITS.BIT6 = digitalRead(PIN6);
num.BITS.BIT7 = digitalRead(PIN7);
num.BITS.BIT8 = digitalRead(PIN8);
Serial.print(num.U);
-
1+1 for the struct. Could you explain why you use
23
and not7
? As an int is only 16-bits. Is 32-bit the minimum size of a union or something?Gerben– Gerben2015年11月16日 16:16:18 +00:00Commented Nov 16, 2015 at 16:16 -
Thats a perfectly valid approach but seems like a lot lines for something that just needs basic logic and bit shifting.crowie– crowie2015年11月17日 14:36:00 +00:00Commented Nov 17, 2015 at 14:36
As @KiraSan said, You need something larger than a byte for 9 bits. However:
int tally;
tally=0;
for (char pin=1; pin<=9; pin++) {
if (digitalRead(pin)==HIGH) {
tally|=1<<(9-pin);
}
}
This is done from memory and is untested, if anyone spots any errors, let me know.
Explanation: tally is the sum (you should do something with this at the end, obviously, or it has no effect). It is defined and set to 0. Then, for each pin (1-9), read the pin; if the pin is high: take the number '1', and double it (9-pin) times; so if pin=9, it is doubled 0 times; for pin=2, it is doubled once (for a total of 2), and so forth. Set this bit on the tally.
Note that this reads digital pin 1 (which happens to be the second pin, the first being pin 0) - this should be marked as "tx" to set in the first bit, not the one referred to as "pin1" (which might be a constant or a variable, and therefore could point to any given pin). This method also assumes the pins are in order - you could easily change it to start from 0, or 7, but they have to be in order.
If you want arbitrary pins, or variable pins, you might try this:
const PIN_COUNT=9;
char pins[PIN_COUNT]={13,2,5,4,3,6,7,8,9};
int tally;
tally=0;
for (char pin=0; pin<PIN_COUNT; pin++) {
if (digitalRead(pins[pin])==HIGH) {
tally|=1<<pin;
}
}
Changes: add PIN_COUNT as a constant at the start, set the order of the pins (which can include any digital pins, including repeating a given pin if you feel so inclined, even after the start of the code.). You can also change them by doing: pins[0]=1;
- note that they are numbered from 0-8 for 9 pins. Since they now start at 0, the line with << is now adjusted accordingly, as is the line that starts with for...
.