Direct port manipulation

hello! I am trying to speed up a timer whereby a sensor takes Nano D10 low to start and D11 low to stop.
I (think) I have figured out digitalWrite setup( although that probably wont help speed up?) but cannot figure out how to replace digitalRead with direct port addressing......
THANKS

float elap ;
float X = 0;
unsigned long time1;
unsigned long time2;
#define firstsensor_1 10   //D10 input pin
#define secondsensor_2 11  //D11 input pin
void setup() {
  Serial.begin(9600);
  // pinMode (firstsensor_1, INPUT);
  //pinMode (secondsensor_2, INPUT);
  //digitalWrite(firstsensor_1, HIGH);
  //digitalWrite(secondsensor_2, HIGH);

  DDRB = B11110011;
  PORTB = B00001100;
}
void loop() {
  while (digitalRead(firstsensor_1) == 0);
  while (digitalRead(firstsensor_1));
  time1 = micros();

  while (digitalRead(secondsensor_2));
  time2 = micros();

  elap = time2 - time1;
  X = 196850 / elap;
  Serial.print(X);  //serialmonitor check

}

Read this:

PORTx will write the whole port. You already use this in setup.

PINx will read the whole port.
take a look here: Arduino Reference - Arduino Reference

To get the reading of one input pin you "grab" the appropriate bit.
For example (Arduino UNO or NANO):

  x = (PIND & bit (0)) == 0;   // digitalRead (0);
  x = (PIND & bit (1)) == 0;   // digitalRead (1);
  x = (PIND & bit (2)) == 0;   // digitalRead (2);
  x = (PIND & bit (3)) == 0;   // digitalRead (3);
  x = (PIND & bit (4)) == 0;   // digitalRead (4);
  x = (PIND & bit (5)) == 0;   // digitalRead (5);
  x = (PIND & bit (6)) == 0;   // digitalRead (6);
  x = (PIND & bit (7)) == 0;   // digitalRead (7);
  x = (PINB & bit (0)) == 0;   // digitalRead (8);
  x = (PINB & bit (1)) == 0;   // digitalRead (9);
  x = (PINB & bit (2)) == 0;   // digitalRead (10);
  x = (PINB & bit (3)) == 0;   // digitalRead (11);
  x = (PINB & bit (4)) == 0;   // digitalRead (12);
  x = (PINB & bit (5)) == 0;   // digitalRead (13);
  x = (PINC & bit (0)) == 0;   // digitalRead (A0);
  x = (PINC & bit (1)) == 0;   // digitalRead (A1);
  x = (PINC & bit (2)) == 0;   // digitalRead (A2);
  x = (PINC & bit (3)) == 0;   // digitalRead (A3);
  x = (PINC & bit (4)) == 0;   // digitalRead (A4);
  x = (PINC & bit (5)) == 0;   // digitalRead (A5);

Thanks U2, I had already read your reference, but still cannot see how I replace digitalRead in my example ?

jetstuff:
Thanks U2, I had already read your reference, but still cannot see how I replace digitalRead in my example ?

Do you understand D10 is bit port B bit 2 and D11 port B bit 3 ?

If so, what does this do ?

if(PINB & bit (2)) == 0)
{
...
}

Thanks! I think I've got it.....I needed to put some extra brackets in the first 'while' to get it to compile is that OK??
Now if I run the new program with D11 held low and initiating by taking D10 low to record time I get 5049212.... whereas before it would give 2524606....? so it seems exactly double??
ElapTime is .004... was.008 so twice as fast! interesting. The program byte size has hardly reduced though.... I was expecting more.

float elap ;
float X = 0;
unsigned long time1;
unsigned long time2;
#define firstsensor_1 10   //D10 input pin
#define secondsensor_2 11  //D11 input pin
void setup() {
  Serial.begin(9600);
  // pinMode (firstsensor_1, INPUT);
  //pinMode (secondsensor_2, INPUT);
  //digitalWrite(firstsensor_1, HIGH);
  //digitalWrite(secondsensor_2, HIGH);

  DDRB = B11110011;
  PORTB = B00001100;
}
void loop() {

  //while (digitalRead(firstsensor_1)==0);
  //while (digitalRead(firstsensor_1));
  while ((PINB & bit (2)) == 0);
  while (PINB & bit (2));

  time1 = micros();

  //while (digitalRead(secondsensor_2));
  while (PINB & bit(3));

  time2 = micros();

  elap = time2 - time1;
  X = 196850 / elap;
  Serial.print(X);  //serialmonitor check

}

Thanks 'George', but a few words would be preferable to more Arduino website links.

jetstuff:
Thanks 'George', but a few words would be preferable to more Arduino website links.

Well, they link to the right words, so what is your problem? Documentation exists so people don't have to yadda yadda all the time.

I was just looking for confirmation that the sketch that I have written is 'OK', it works, but is it 'correct' , website links don't help to answer my query.
Thanks everyone anyway, I'm sure its very clear to 'Anne Expert'

What does this division do?

X = 196850 / elap;

Smaller (i.e. quicker) would make X bigger.

I would think that elap is the number you are looking for.

jetstuff:
I was just looking for confirmation that the sketch that I have written is 'OK', it works, but is it 'correct' , website links don't help to answer my query.
Thanks everyone anyway, I'm sure its very clear to 'Anne Expert'

In fact, the documentation is absolutely the right place to find out whether what you're doing is correct. All you can get in a forum are educated opinions. You should eschew the sarcastic name calling, it makes you appear very immature.

CrossRoads:
What does this division do?

X = 196850 / elap;

Smaller (i.e. quicker) would make X bigger.

I would think that elap is the number you are looking for.

Thanks Crossroads, yes elap time exactly halved which made me suspicious that I have done something wrong in the program. I was also expecting some size reduction after getting rid of digitalRead, (but that's not a problem).
The 196850 just relates to distance between start/stop sensors.

Thanks aarg, I'm an immature 72 year old Python fan....but not the sort your thinking of :slight_smile:

aarg:
You should eschew the sarcastic name calling, it makes you appear very immature.

1 Like

Why are you using (or trying to use) while ?

I'm not an experienced coder, I just cobble together bits that work for me. Its a program that has worked well previously, I was just trying to speed it up for better timing accuracy, I didn't want to re-invent it, just speed it up by getting rid of digitalRead. Do you think there is a better option?

I think programming is fun, for me it's not a chore. I don't do it professionally.
I posted the links to while and do while to help you.

To "read a pin", whether by PINB or digitalRead, then just do it.

pinState = digitalRead(sensorpin);
OR
pinState = PINB & (3);

pinState = PINB & (3)

This would read pin0 and pin1

maybe you meant

pinState = PINB & (1<<3);

Note that sketches that depend on testing for (pinState == 1) or (pinState == HIGH) instead of testing for non-zero, will fail for the above code.

So, this digitalReads pin 11 and reports the result on pin 13.
(When 11 is Grounded, the LED goes Off.)

const byte testIn = 11;
byte result;

void setup() 
{
  pinMode (13, OUTPUT);
  pinMode (testIn,INPUT_PULLUP);
}

void loop() 
{
  result = (PINB & B00001000);
  if(result == 0)
  {
    PORTB = PORTB & B11011111;  // PORTB = PORTB & bit(3)
  } 
  else
  {
    PORTB = PORTB | B00100000; 
  }
}