3

Consider the following code:

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  }
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

The line buttonState = digitalRead(buttonPin); checks the input voltage.

But how is that checked internally?

I mean at what rate the input is checked?

user16307
  • 237
  • 2
  • 4
  • 15

3 Answers3

3

When I get time, I will provide more definitive answers.

I did follow through with this, and the result is here, towards the end of the page: https://dannyelectronics.wordpress.com/2016/05/01/the-price-of-avr-arduino/

the short answer is: digitalRead() takes 4.9us to execute on a 16MIPS Arduino Uno, or 79 ticks (=instructions).

the fastest you can read digitalRead() is then 200KHz (= 1/4.9us).

Hope it helps.

dannyf
  • 2,813
  • 11
  • 13
3

It read a port just like it reads memory (to which it's mapped.) So speed is how fast an instruction can read memory. EEPROM is a different animal.

Might get it a little faster by replacing

buttonState = digitalRead(buttonPin);
with
buttonState = PORTB & _BV(buttonPin);

Assuming it's PORTB that you are using. This will alleviate at least one function call, I would think, and will generate a single instruction to read the port into the variable. It may require an instruction to load the variable address, but that's up to the compiler. The replacement may be more trouble porting to other micros. Normally you don't see a variable as a parameter although legal, usually a constant in a #define.

_BV(INPUT_PIN_X) is a macro (BV is for 'bit value') that expands to
(1 << INPUT_PIN_X)

dannyf times seem quick to me, but it sounds like he's done the testing. Is he taking into account the complete function call as part of the time? I run at 1Mhz normally, so it's more difficult to relate.

Take Majenko advice and start reading the generated assembler :)

Best of luck.

Jack Wilborn
  • 116
  • 2
2

That depends on the frequency your Arduino runs at.

It's basically once per iteration of the loop, and that depends on everything that is happening in the loop.

You can examine the assembly language output of the compiler (disassemble the .elf file using avr-objdump -h -S <elf file>) and count the number of clock cycles per iteration (the datasheet has the number of clock cycles per instruction). However that is tedious.

If you want to read the input at a specific frequency then you should do it using a timer interrupt.

Majenko
  • 105,851
  • 5
  • 82
  • 139