Go Down

Topic: reading - writing multiple pins simultaneously. (Read 5 times) previous topic - next topic

neurascenic

Hey all,

Is there a way to read a byte into a variable all at once?  Or do I have to look at each pin individually? and build up the value of the variable accordingly?

Same questions applies to writing out to pins.    i.e.    can I load a variable that contains   00101110  to all the pins at once?

I don't see anything in the ref file, but that doesn't mean much...   :P

thanks,

ñ
 

neurascenic

Was this a real dumb question?


Hmmm, let me rephrase this.

Is there a memory location or register that I can send a value to that is in effect the "pins" themselvs?

Thanks!

ñ

mellis

You can use PORTD as a variable to read from or write to pins 0 to 7 (the low bit is pin 0, the high bit is pin 7) and PORTB for pins 8 to 13 (the low bit is pin 8).  PORTC has the analog input pins (the low bit is pin 0).  To set the mode of a port, use DDRx (where x is the letter of the port): 1 to set the pin to output mode, 0 for input mode.  For example, this sketch sets pins 0 to 7 as outputs and then blinks them:

Code: [Select]

void setup()
{
 DDRD = 0xff;
}

void loop() {
 PORTD = 0xff;
 delay(1000);
 PORTD = 0x00;
 delay(1000);
}


At some point, we'll add Wiring-compatible functions to Arduino for this: portMode(port, mode), portWrite(port, value), portRead(port).  We just need to decide what should be passed as the "port" parameters (probably just 0, 1, and 2).  

neurascenic

Mellis,

That is perfect!  Exactly what I needed.

With regards to the future function.  For most people, some operations would be easier not in hex.
Maybe two functions.  One hex and another where it can be loaded directly with 1's and 0's.

Or I suppose it could be a two function operation.  Not a big deal.

Thank you so very much!

ñ

coldham

re: hex vs. binary,

I just tried changing the hex to bin in mellis' example, and it compiles just fine. I didn't test it on the board, but it looks like you might not have to translate hex if you don't want to.

void setup()
{
 DDRD = 11111111;
}

void loop() {
 PORTD = 11111111;
 delay(1000);
 PORTD = 00000000;
 delay(1000);
}

mellis

coldham: that's not doing what you expect.  Those are numbers are being treated as decimal integers (base 10), e.g. 111 is one hundred and eleven, not seven.

coldham

That's too bad. I also find it cumbersome to count on my fingers to translate between bin and hex. Could you make portWrite accept binary? It would be more readable to have the value look like what the register is doing.  :)

macsimski

and how would you read the pins?

digitalRead(PORTB); //

or

someVariable = PORTB;
--
"We're all in this together..."

CosineKitty

You could define a C++ macro to convert from binary to hex for you:

#define BINARY(a,b,c,d,e,f,g,h)  (a<<7|b<<6|c<<5|d<<4|e<<3|f<<2|g<<1|h)

Then you could use a line of code like this:

PORTD = BINARY(1,1,1,1,1,1,1,1);

The C++ compiler will expand the macro, then notice that all the values are constant, and pre-calculate the correct value (known as "constant folding").

chris_s

THANK YOU THANK YOU THANK!  I've been wanting something like that for quite a while now!  I'm gonna give that a shot as soon as I get home tonight.

Quote
You could define a C++ macro to convert from binary to hex for you:

#define BINARY(a,b,c,d,e,f,g,h)  (a<<7|b<<6|c<<5|d<<4|e<<3|f<<2|g<<1|h)

Then you could use a line of code like this:

PORTD = BINARY(1,1,1,1,1,1,1,1);

The C++ compiler will expand the macro, then notice that all the values are constant, and pre-calculate the correct value (known as "constant folding").


CosineKitty

This is really cool!  I've been playing around a little bit with using PORTB and PORTD, and apparently the compiler is set up to recognize this as an alias for a hardware port.  Here is a simple code example along with its disassembly (obtained using objdump.exe, part of the Arduino distribution):

   PORTD |= BINARY(0,0,0,0,0,1,0,1);
  4:      82 b3             in      r24, 0x12      ; 18
  6:      85 60             ori      r24, 0x05      ; 5
  8:      82 bb             out      0x12, r24      ; 18

This example will turn on output pins 0 and 2, but leave all the other pins at their current value.
The compiler-generated code reads the hardware port 0x12 into the register r24, then does a bitwise-OR with 5, i.e. the value that BINARY(0,0,0,0,0,1,0,1) expands to, then writes the result back to hardware port 0x12.  If you wanted to toggle the existing values, you could do:

  PORTD ^= BINARY( /*whatever*/ );    // use XOR to toggle bits

And to answer macsimski's question, you would do:

   someVariable = PORTB;

mellis

We're actually planning to include in Arduino 0007 constants like B10010 to represent binary numbers (up to 255).

Go Up