Port manipulation with bitread

Hi everybody.

I want to use the bitRead function:
Serial.println(bitRead(PORTD,3)); //Reads bit 3 of register PORTD which contains the current state (high/low) of pin 3.
But when I want to replace PORTD with a string containing "PORTD", it does'nt work.
How can I do that?

Thank you

You don't replace the PORTB with "PORTB", you shouldn't need to.

PORTB is a constant that contains the register number for the B port. "PORTB" is a string that the Arduino has not way of knowing what it means.

Why do you want to replace the constant with the string>

Because I want to read somes registers depending on variables.
so, no way?
Patrick

pchatill:
Because I want to read somes registers depending on variables.
so, no way?
Patrick

I'm sure there is a way, just not by using port names as strings. Perhaps if you could explain what you need to do rather then how you think you should do it, we might better be of help.

I think you want this - just need a 2nd print statement:

Serial.print("PORTD" ); 
Serial.println(bitRead(PORTD,3));

pchatill:
Because I want to read somes registers depending on variables.
so, no way?
Patrick

If/elseif

PORTS are addresses to memory mapped registers, they are defined as: volatile uint8_t *

Check the following code (use at own risk) it gives some idea how it works under the hood.

void setup() 
{
  Serial.begin(115200);
  Serial.println("\nprint addresses or well known ports\n");

  Serial.println((int)(&PINB), HEX);
  Serial.println((int)(&DDRB), HEX);
  Serial.println((int)(&PORTB), HEX);

  Serial.println((int)(&PINC), HEX);
  Serial.println((int)(&DDRC), HEX);
  Serial.println((int)(&PORTC), HEX);

  Serial.println((int)(&PIND), HEX);
  Serial.println((int)(&DDRD), HEX);
  Serial.println((int)(&PORTD), HEX);

  Serial.println("\nuse a variable for a well known port\n");
  volatile uint8_t * myport = &DDRC;
  Serial.println((int)(&DDRC), HEX);
  Serial.println((int) myport, HEX);
  
  Serial.println(DDRC, HEX);
  Serial.println(*myport, HEX);
  
  *myport = 0x0A;                           //  write 0x0A to address of DDRC 
  Serial.println(DDRC, HEX);        // check
  Serial.println(*myport, HEX);   // double check 
}

void loop() 
{
}

so you can use myport to point to one of the "hard coded ports"

Another possibility is to create an array (can be in PROGMEM) to contain the different port addresses your interested in and then use your variable to choose which element of the array you will work with. Something like this:

#include <Arduino.h>
#include <avr/io.h>

void setup()
{
  volatile uint8_t PortVariables[] = { PORTB, PORTD };
  uint8_t SelectionVariable = 1;  // Setting it to default to PORTD

  Serial.begin(9600);
  
  // Send the value of bit 3 of PORT D to serial console
  Serial.println(bitRead(SelectionVariable,3));

  SelectionVariable = 0; // Setting it to PORTB

  // Send the value of bit 3 of PORT B to serial console
  Serial.println(bitRead(SelectionVariable,3));

}

void loop()
{
}

HI Wanderson!

I tried to work with your code, but it doesn't work.
See my comments on the code
Regards, Patrick

digitalWrite(26, HIGH) ;
digitalWrite(10, HIGH) ;

//For ATMega 2560: A4= PIN26 value B4= PIN10 value
volatile uint8_t PortVariables[] = { PORTA, PORTB };
uint8_t SelectionVariable = 1; // Setting it to default to PORTB

Serial.begin(9600);

// Send the value of bit 4 of PORT B
client.println(bitRead(PORTB,4));//OK: Return 0 or 1 depend if Pin 10 is HIGH or Low
client.println(bitRead(SelectionVariable,4));//Not OK:always return 0

SelectionVariable = 0; // Setting it to PORTA

// Send the value of bit 4 of PORT A
client.println(bitRead(PORTA,4));//OK: Return 0 or 1 depend if Pin 10 is HIGH or Low
client.println(bitRead(SelectionVariable,4));//Not OK:always return 0

No need to store anything separately, it can be stored directly inline.

If you have an Uno, you will need to remove PORTA, or possibly add some on a Mega, however here is the basic principle which can be expanded for PIN and DDR registers too.

Also #define can be used to mask missing ports on different AVR's

static struct{
  inline volatile uint8_t &operator []( char i ){
    switch( i ){
      case 'A': return PORTA;
      case 'B': return PORTB;
      case 'C': return PORTC;
      case 'D': return PORTD;        
    };
    return GPIOR0;  //For safety we can return GPIO on error
  }
} port;

Access the ports like this:

port[ 'A' ] = 0b11001100;

port[ 'B' ] = port[ 'C' ];

Edit: modified switch :slight_smile:

 Serial.println(bitRead(SelectionVariable,3));code]
You're not indexing the array.

Thank you everybody, specialy pYro_65 !!

It works fine!!