What's the max Digital Frequency atainable Mega2560

Hi, this is my 1st project. I'm testing frequency aspects of both Digital and analog inputs/Outputs.

Found enough on ADC clock manipulation around (fastest readings (though values look odd) is about 2us per sample, even faster with noInterrupts() but not sure that allows analog to pick up real readings).

But wanted to check with you if there is a way to make pulses faster than this on Digital ports (2.667MHz):

void loop() {
  // port toggle test, max rate
  while (true) {
      //delayMicroseconds(3);
      // Freq 2.667Mhz
      // duty cycle: 70% (because of the loop delay it's not 50%)
      PORTA  &= !B00000001; // Off
      PORTA  |= B00000001;  // On sets Arduino pin 22 (Digital)
  }
}

in this code, the time that the loop statement takes itself becomes noticeable.

Copy this lines and paste it 20 or 30 times one after an other. Test the frequency

1 Like

If you don't care about the state of the other bits in the register

PORTA = B00000000 ;
PORTA = B00000001 ;

might be faster since it doesn't require the Port register to be read before setting/resetting the bit of interest.

1 Like

Wow, I didn't notice the extra load there, thanks! it went up to 3.995MHz
Now duty cycle is much lower: 28%

(@b707 ) Copy-Pasting countless times to visit the while() loop less often duty cycle rises to 58%

Thanks a lot, don't think it can go higher than that (1/4 clock speed (16MHZ)). No change o overclock Arduino boards?

By using the counter timer you can get half the clock frequency out of a pin.

Read the data sheet and set the count and compare registers accordingly.

1 Like
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
    Serial.begin (115200);
    Serial.println ();
  
    ADCSRA &= ~(bit (ADPS0) | bit (ADPS1) | bit (ADPS2)); // clear prescaler bits
    // uncomment as required

    ADCSRA |= bit (ADPS0);                               //   2  
//  ADCSRA |= bit (ADPS1);                               //   4  
//  ADCSRA |= bit (ADPS0) | bit (ADPS1);                 //   8  
//  ADCSRA |= bit (ADPS2);                               //  16 
//  ADCSRA |= bit (ADPS0) | bit (ADPS2);                 //  32 
//  ADCSRA |= bit (ADPS1) | bit (ADPS2);                 //  64 
//  ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2);   // 128
}

// 1000 datapoints
int resultBuff[1000] = {};

// Only print once.
bool done = false;

void loop() {
    
    // port toggle test, max rate
//  while (true) {
//      // Freq 2.667Mhz
//      // duty cycle: 70% (because of the loop delay it's not 50%)
//      PORTA  = B00000001; // On
//      PORTA  = B00000000; // Off
//      PORTA  = B00000001; // On
//      PORTA  = B00000000; // Off
//      PORTA  = B00000001; // On 
//      PORTA  = B00000000; // Off 
//  }
  

    // Analog reading max rate test
    if (! done) {
  
        // Fast AnalogRead test
        noInterrupts();
        readSignal(false);
        interrupts();

        readSignal(true);
        done = true;
    } 
  
  // digitalWrite(healthPin, LOW);
  //delayMicroseconds(60);
}

/**
 * With 1000 datapoints I can describe at this sample rates:  
 *   500 Hz wave, 1.5 cycles. (good enouh to find max values)
 *   20KHz Is the max freq I Can describe accurately.  
 *   30KHz Is the max freq I Can describe accurately with noInterrupts() on.
 *   40KHz Still can see a signall, about 8 datapoints peak to peak with noInterrupts() on.
 *     Good to find max valtage in range.
 *  
 * Clock speed: 16MHz 
 * About 2x gains with `noInterrupt();` call before sampling.
 */
void readSignal(bool withInterrupts) {
    unsigned long startTime = micros ();

    for (int i = 0; i < 1000; i++) {
        resultBuff[i] = analogRead (A1);
         
    }
    
    unsigned long duration = micros () - startTime;
 
    for (int i = 0; i < 1000; i++) {
        Serial.println(resultBuff[i]);     
    }  

    Serial.print("Interrupts: ");
    Serial.println(withInterrupts ? "true" : "false");
    Serial.print("Duration: ");      
    Serial.println(duration);      
    Serial.println();
}

Something odd is Arduino seems to not read negative values, Scpe shows a nice sine wave while Excel plot just the positive peaks.

Where did you read that the ADC is bipolar?
C

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.