digitalWrite and digitalWriteFast

Steve_AU

Member
Hi all,

digitilWrite() and digitalWriteFast comparison:

I have been playing around with Teensy 4.1 and noticed that there isn't a material difference between digitalWrite() and digitalWriteFast().
I set up a simple loop test, repeating a pin toggle on pin13 (LED_PIN) 100,000 times to see if there was any time difference, and there was nothing, maybe a few parts in ~10,000. Is that reasonable to assume? Have I missed anything obvious?

Code:
#include <TeensyThreads.h>
#include <digitalWriteFast.h>
int LED_PIN = 13;  // pin 13 is the orange LED
int i = 0;
void setup() {
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(115200);
   Serial.println("System starting...");
 }
void loop() {
  elapsedMicros elapsedTime;  
 
elapsedTime = 0;
   for (i = 0; i < 100000; i++) {
    digitalWrite(LED_PIN, HIGH);
    digitalWrite(LED_PIN, LOW);
  }
  Serial.print("digitalWrite: ");
  Serial.print(elapsedTime); 
  Serial.println(" us");  // Measure time taken by digitalWrite() - sometimes this would be 9506, sometimes 9513, or 9511


  elapsedTime = 0;
  for (i = 0; i < 100000; i++) {
    digitalWriteFast(LED_PIN, HIGH);
    digitalWriteFast(LED_PIN, LOW);
  }
  Serial.print("digitalWriteFast: ");
  Serial.print(elapsedTime);
  Serial.println(" us");             // Measure time taken by digitalWriteFast()  - sometimes this also would be 9506, sometimes 9513, or 9511
  delay(1000);  // Wait for 1 second
}

Serial Monitor:
Also, the Serial monitor has started to get flaky after behaving perfectly for at least 3 weeks. As suggested in the notes on help in the min web pages, I rebooted the hosting computer from power off, and that sorted it for a while. Soon enough, it showed 'Teensy not connected' at the bottom panel again, and the Serial monitor was not kicking off reliably. Program uploads work fine, though. The computer is a HP Pavilion with SSD disk and 16GB RAM. Has anyone else noticed this serial monitor behaviour?

Thanks,
Steve
 
Don't include digitalWriteFast.h. It's (probably) overriding the actual digitalWriteFast from the core library.

Also use const for the pin number, and keep the loop count as a local variable. And read the elapsed time before calling anything Serial. Like this...

Code:
#include <TeensyThreads.h>
//#include <digitalWriteFast.h>  <-- do not use!!
const int LED_PIN = 13;  // pin 13 is the orange LED
void setup() {
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(115200);
  Serial.println("System starting...");
}
void loop() {
  elapsedMicros elapsedTime;

  elapsedTime = 0;
  for (int i = 0; i < 100000; i++) {
    digitalWrite(LED_PIN, HIGH);
    digitalWrite(LED_PIN, LOW);
  }
  uint32_t t1 = elapsedTime;
  Serial.print("digitalWrite: ");
  Serial.print(t1);
  Serial.println(" us");  // Measure time taken by digitalWrite() - sometimes this would be 9506, sometimes 9513, or 9511
  delay(10);

  elapsedTime = 0;
  for (int i = 0; i < 100000; i++) {
    digitalWriteFast(LED_PIN, HIGH);
    digitalWriteFast(LED_PIN, LOW);
  }
  uint32_t t2 = elapsedTime;
  Serial.print("digitalWriteFast: ");
  Serial.print(t2);
  Serial.println(" us");             // Measure time taken by digitalWriteFast()  - sometimes this also would be 9506, sometimes 9513, or 9511
  delay(1000);  // Wait for 1 second
}
 
Thanks Paul,
I'll sort these items out and have another look.

1) I guess "write fast" must now be in the main library, so there is no need to include it explicitly.
2) Noted, too, about variable scope(s)!

Earlier, I did a separate non-looped test (one sketch with digitalWrite() and another sketch with digitalWriteFast() ) to see what things looked like on the oscilloscope, and they looked exactly the same. Hence, I tried a looped version, and your suggestions would explain why it's no different.

Still, this means a port bit toggling at around ~10.5 MHz! That level of 'bit-banging' is unheard of with my other processors (Typically STM32 stuff). That's 100,000 pin toggles in ~9.5 milliseconds. Even there, it's huge.

In the meantime, I'll experiment with your suggestions and see where we go. These processors are unique and well worth the effort to learn about.

Thanks again,
Steve
 
1) I guess "write fast" must now be in the main library, so there is no need to include it explicitly.

It was first created as part of the Teensy core library. There has never been a need to include it on any Teensy boards.

When the Arduino developers decided not to adopt digitalWriteFast into their boards, other people created a library to bring it to non-Teensy boards. But their code (probably) only copied the special code for the Teensy 2 and 3 boards which existed at that time. For everything else, it will just fall back to using regular digitalWrite. So if you try to use such a library with Teensy 4, you're just overriding the copy that's built into Teensy's core library.

As a matter of history, digitalWriteFast began on Teensy, even though the idea is pretty "obvious". Libraries to implement it on other boards came later.
 
Back
Top