2

Yesterday I played with a SRAM 621024 SRAM 1 Mbit IC and since I use a lot of pins, digitalReads and digitalWrites are needed including shift registers (see Example

Since it took a long time for reading/writing one byte, I checked for faster ways and found some posts, one of them was using digitalWriteFast: Library

However, it did not make any difference... is it possible that the (fast) digitalWrite is already implemented in the default Arduino IDE/library?

Update: I found out I made a stupid mistake and the library was not used.

Now I get different values:

  • Writing 397.880 us per byte
  • Reading 386.524 us per byte

Without the fast library:

  • Writing 502.152 us per byte
  • Reading 483.752 us per byte

Note, there is also a digitalReadFast, but this does not affect the speed.

I did some more testing and found out that a digitalReadFast/digitalWriteFast cost just about 8-12 us, a pinModeFast is 0 us (negligable), however a shiftOut for setting the address cost 120-124 us ... since 3 shifts are needed to set an address, this results in 360-372 us. Subtracting this from the measured times above, writing takes around 25-38 us and reading 15-27us. I possibly can maybe optimize the bit operations a little bit.

However, the end result for using this RAM chip with enough speed is to either change the shift register to a faster one or remove the shift registers at all. This would mean about 30 pins needed for the SRAM only. The conclusion is: better use a 3K256, 23LC1024 or similar variant.

(Note: I tried a ShiftOutFast file), which reduces a shiftout to 36 us but 3 times 36 is still over 100 us, too much to compare to a 3K256/23LC1024 solution.

Michel Keijzers
  • 13,014
  • 7
  • 41
  • 58

1 Answers1

4

I just tried to time digitalWrite() against direct port access with the following code:

void setup()
{
    uint16_t overhead, start, end;

    Serial.begin(9600);
    TCCR1A = 0;
    TCCR1B = 1;

    // Time digitalWrite().
    overhead = 7;
    cli();
    start = TCNT1;
    digitalWrite(2, HIGH);
    end = TCNT1;
    sei();
    Serial.print("digitalWrite(): ");
    Serial.print(end - start - overhead);
    Serial.println(" cycles");

    // Time direct port access.
    overhead = 4;
    cli();
    start = TCNT1;
    PORTD &= ~_BV(PD2);
    end = TCNT1;
    sei();
    Serial.print("direct port access: ");
    Serial.print(end - start - overhead);
    Serial.println(" cycles");
}

void loop(){}

The result was:

digitalWrite(): 78 cycles
direct port access: 2 cycles

I used an old Arduino core (1.0.5), but that function has not changed since. You can try with your current core and see.

PS: In this program, the correct value for overhead can only be determined by examining the generated assembly. It's a count of the cycles you are measuring but do not directly belong to the operation you really want to measure.

Edgar Bonet
  • 45,094
  • 4
  • 42
  • 81