bitRead/bitWrite - Having Trouble Storing/Using PINx References

Hello, everyone. I've been having issues trying to assign the PINx values in a variable. Here's what I've got after a few hours:

volatile uint8_t ports [] { PINB, PINC, PIND };

void setup () {
	Serial.begin (115200);
	while (!Serial);

	Serial.println ("READY");
	Serial.flush ();
}

void loop () {

	Serial.println (!bitRead (ports [2], 2));
	Serial.flush ();

	delay (10);
}

^ That code doesn't seem to behave properly.

Serial.println (!bitRead (ports [2], 2));

always returns 0. However...

void setup () {
	Serial.begin (115200);
	while (!Serial);

	Serial.println ("READY");
	Serial.flush ();
}

void loop () {

	Serial.println (!bitRead (PIND, 2));
	Serial.flush ();

	delay (10);
}

^ ...that code works

Could anyone point me in the right direction for the first code block? Would be much appreciated

Evidently, the compiler doesn't recognize an array element value as the symbol to execute a port read.

I would not expect it to do so, but even if that worked, such code would be hard to understand.

You will have to find another way to code that, like using switch/case statements. That is what the compiler would have to do anyway, as port reads would be hard coded into the load module.

Evidently, the compiler doesn't recognize an array element value as the symbol to execute a port read.

Noticed that. The only way the bitRead () would work was if I explicilty used 'PIND'.

but even if that worked, such code would be hard to understand.

Why?

You will have to find another way to code that, like using switch/case statements.

Every single time I want to read from the pin? I figured I'd be better off storing PINx in an array and simply referring to an index later. That'd make it extremely easy.

Every single time I want to read from the pin?

You can make a function that does the read, using switch/case.

You might take a look at all the code associated with the digitalRead() function.

Hello, everyone. I've been having issues trying to assign the PINx values in a variable.

'PIND' is a macro which reads the current value of port D and returns that value.

'bitRead' is a macro which takes a value and returns a bit from that value.

So, your second code works because PIND returns a value from the port and bitRead selects bit 2 from that value.

The array in your first block of code is NOT an array of 'port names', it is trying to be an array of values on those ports when it was created.

It is possible to create an array of port addresses like:

volatile uint8_t *portAddresses [] { 0x23, 0x26, 0x29 };

// read from the port address:

Serial.println (!bitRead ( *(portAddresses[2]) , 2));

BUT: this is not the way the Arduino API usually wants you to do things.
Those 'magic numbers' in the portAddresses array were taken from the Atmel ATmega328 datasheet, so they will only work on that one processor.

Usually you want your code to be able to work on a range of processors, so you use the Arduino macros which are translated into the actual processor addresses when it is compiled.

so you end up doing as has been suggested:

jremington:
You can make a function that does the read, using switch/case.

Yours,
TonyWilk

Thank you both for your advice! I'm gonna go the switch/case route.