Generated frequency is not as expected











up vote
1
down vote

favorite












This code sets a pin HIGH for 1 microsecond and then LOW for 1 microsecond. The expected frequency should be about 500 kHz. When measuring the output the frequency is about 96.4khz. Why ?



int del = 1;

void setup() {
// put your setup code here, to run once:
pinMode(3, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:

digitalWrite(3, HIGH);
delayMicroseconds(del);
digitalWrite(3, LOW);
delayMicroseconds(del);

}









share|improve this question









New contributor




deadpixel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Your code says 1 microsecond, but delayMicroseconds is actually much slower than that. Also the loop has some overhead. Try putting the code inside while(true){ }. Recent versions of the Arduino IDE have got better at making code faster, but if you want timing accuracy it is better to use low-level timer/counters of the AVR.
    – MichaelT
    2 days ago















up vote
1
down vote

favorite












This code sets a pin HIGH for 1 microsecond and then LOW for 1 microsecond. The expected frequency should be about 500 kHz. When measuring the output the frequency is about 96.4khz. Why ?



int del = 1;

void setup() {
// put your setup code here, to run once:
pinMode(3, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:

digitalWrite(3, HIGH);
delayMicroseconds(del);
digitalWrite(3, LOW);
delayMicroseconds(del);

}









share|improve this question









New contributor




deadpixel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Your code says 1 microsecond, but delayMicroseconds is actually much slower than that. Also the loop has some overhead. Try putting the code inside while(true){ }. Recent versions of the Arduino IDE have got better at making code faster, but if you want timing accuracy it is better to use low-level timer/counters of the AVR.
    – MichaelT
    2 days ago













up vote
1
down vote

favorite









up vote
1
down vote

favorite











This code sets a pin HIGH for 1 microsecond and then LOW for 1 microsecond. The expected frequency should be about 500 kHz. When measuring the output the frequency is about 96.4khz. Why ?



int del = 1;

void setup() {
// put your setup code here, to run once:
pinMode(3, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:

digitalWrite(3, HIGH);
delayMicroseconds(del);
digitalWrite(3, LOW);
delayMicroseconds(del);

}









share|improve this question









New contributor




deadpixel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











This code sets a pin HIGH for 1 microsecond and then LOW for 1 microsecond. The expected frequency should be about 500 kHz. When measuring the output the frequency is about 96.4khz. Why ?



int del = 1;

void setup() {
// put your setup code here, to run once:
pinMode(3, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:

digitalWrite(3, HIGH);
delayMicroseconds(del);
digitalWrite(3, LOW);
delayMicroseconds(del);

}






arduino-leonardo frequency






share|improve this question









New contributor




deadpixel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




deadpixel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 2 days ago









Michel Keijzers

6,16341736




6,16341736






New contributor




deadpixel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 2 days ago









deadpixel

61




61




New contributor




deadpixel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





deadpixel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






deadpixel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • Your code says 1 microsecond, but delayMicroseconds is actually much slower than that. Also the loop has some overhead. Try putting the code inside while(true){ }. Recent versions of the Arduino IDE have got better at making code faster, but if you want timing accuracy it is better to use low-level timer/counters of the AVR.
    – MichaelT
    2 days ago


















  • Your code says 1 microsecond, but delayMicroseconds is actually much slower than that. Also the loop has some overhead. Try putting the code inside while(true){ }. Recent versions of the Arduino IDE have got better at making code faster, but if you want timing accuracy it is better to use low-level timer/counters of the AVR.
    – MichaelT
    2 days ago
















Your code says 1 microsecond, but delayMicroseconds is actually much slower than that. Also the loop has some overhead. Try putting the code inside while(true){ }. Recent versions of the Arduino IDE have got better at making code faster, but if you want timing accuracy it is better to use low-level timer/counters of the AVR.
– MichaelT
2 days ago




Your code says 1 microsecond, but delayMicroseconds is actually much slower than that. Also the loop has some overhead. Try putting the code inside while(true){ }. Recent versions of the Arduino IDE have got better at making code faster, but if you want timing accuracy it is better to use low-level timer/counters of the AVR.
– MichaelT
2 days ago










2 Answers
2






active

oldest

votes

















up vote
5
down vote













Welcome to SE.



digitalWrite() takes a few microseconds to execute as well. There is also some overhead around the delayMicroseconds() function.



I you need exactly 500 kHz, you would want to consider using a timer.
You can read up on how to set one up in the microcontrollers datasheet.



Unfortunately, I don't have access to an Arduino Leonardo, but here is an example code for the ATmega328P. The register names will be different, but you should be able to adapt the code to fit your Arduino.



// 500 kHz frequency

void setup() {
cli(); //Disable interrupt during setup
TCCR2A = 0;
TCCR2B = 0;

TCCR2B |= (1 << CS20); //Enable timer without prescaler
OCR2A = 15; //Do interrupt TIMER2_COMPA after reaching this counter value
TIMSK2 |= (1 << 1); //Enable TIMER2_COMPA interrupt

DDRD |= (1 << PORTD3); //Set Digital Pin 3 as Output Pin
sei(); //Enable interrupts again
}

ISR(TIMER2_COMPA_vect) { //If the counter has reached the point where the output needs to be low
TCNT2 = 0;
PIND |= (1 << PORTD3); //Toggle Digital Pin 3
}

void loop() {
//your looping code here
}


Explanation:
TIMER2 is an 8-bit timer, which means it will always count from 0 to 255, regardless of what the CPU is doing.



Normally, it counts up at the Arduino's clock frequency, like 16 MHz.



When the counter hits 15, a special code is immediately executed, called an "Interrupt Service Routine". In this code, we reset the timer and change the state of your outpin pin, resulting in a 500 kHz square wave on that pin.



We count to 15 since there are 16 steps in between "0" where the counter begins and 15, where we reset it.



16'000'000 Hz / 1 (no prescaler) / 16 (counter) / 2 = 500 kHz



The divisor of 2 comes from the fact that we need to change the pin state twice for every full square of the output signal.






share|improve this answer



















  • 2




    Sometimes you write 500kHz, then you write 500Hz. As calculated the code is for 500Hz. As the OP asked for 500kHz, the prescaler could be set to 1 and the compare value (at which the timer fires the interrupt) to 16. In my calculation this gives you exactly 500kHz. Am I right?
    – chrisl
    2 days ago










  • But as you wrote, digitalWrite() takes to long, so bit manipulation on the port registers are the right way to go: arduino.cc/en/Reference/PortManipulation
    – chrisl
    2 days ago










  • Yes, of course, I'm so sorry. This is what happens when you recycle code after a long work day. I'll fix it. And you're also right, digitalRead and -Write are too slow for 500 kHz, I'll implement it via the registers.
    – Tobias Weiß
    2 days ago






  • 1




    You could use one of the hardware time outputs like OC2A or OCRB and avoid the ISR/digitalWrite/bitbanging overhead entirely.
    – Dave X
    2 days ago












  • It's fixed now - so sorry again. My scope isn't fast enough for 500 kHz, but it works as intended for 50 kHz. The "standard" outputs are nice, but you're then limited to the two pins per timer. Is that already necessary at 500 kHz?
    – Tobias Weiß
    2 days ago




















up vote
0
down vote













delayMicroseconds() has a minimum lower value of 3-4 us per the IDE documentation. It won't do 1.



loop() also adds some delay mechanisms doing it's background stuff.



You will see better results with a while() :



loop(){
while (1){
digitalWrite(3, HIGH);
delayMicroseconds(del);
digitalWrite(3, LOW);
delayMicroseconds(del);
}
}


with direct port manipulation in place of the digital writes.



There will also be jitter from the millis() background time keeping, if you want a smoother signal it will be best to turn off interrupts as well.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("schematics", function () {
    StackExchange.schematics.init();
    });
    }, "cicuitlab");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "540"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });






    deadpixel is a new contributor. Be nice, and check out our Code of Conduct.










     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f57925%2fgenerated-frequency-is-not-as-expected%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    5
    down vote













    Welcome to SE.



    digitalWrite() takes a few microseconds to execute as well. There is also some overhead around the delayMicroseconds() function.



    I you need exactly 500 kHz, you would want to consider using a timer.
    You can read up on how to set one up in the microcontrollers datasheet.



    Unfortunately, I don't have access to an Arduino Leonardo, but here is an example code for the ATmega328P. The register names will be different, but you should be able to adapt the code to fit your Arduino.



    // 500 kHz frequency

    void setup() {
    cli(); //Disable interrupt during setup
    TCCR2A = 0;
    TCCR2B = 0;

    TCCR2B |= (1 << CS20); //Enable timer without prescaler
    OCR2A = 15; //Do interrupt TIMER2_COMPA after reaching this counter value
    TIMSK2 |= (1 << 1); //Enable TIMER2_COMPA interrupt

    DDRD |= (1 << PORTD3); //Set Digital Pin 3 as Output Pin
    sei(); //Enable interrupts again
    }

    ISR(TIMER2_COMPA_vect) { //If the counter has reached the point where the output needs to be low
    TCNT2 = 0;
    PIND |= (1 << PORTD3); //Toggle Digital Pin 3
    }

    void loop() {
    //your looping code here
    }


    Explanation:
    TIMER2 is an 8-bit timer, which means it will always count from 0 to 255, regardless of what the CPU is doing.



    Normally, it counts up at the Arduino's clock frequency, like 16 MHz.



    When the counter hits 15, a special code is immediately executed, called an "Interrupt Service Routine". In this code, we reset the timer and change the state of your outpin pin, resulting in a 500 kHz square wave on that pin.



    We count to 15 since there are 16 steps in between "0" where the counter begins and 15, where we reset it.



    16'000'000 Hz / 1 (no prescaler) / 16 (counter) / 2 = 500 kHz



    The divisor of 2 comes from the fact that we need to change the pin state twice for every full square of the output signal.






    share|improve this answer



















    • 2




      Sometimes you write 500kHz, then you write 500Hz. As calculated the code is for 500Hz. As the OP asked for 500kHz, the prescaler could be set to 1 and the compare value (at which the timer fires the interrupt) to 16. In my calculation this gives you exactly 500kHz. Am I right?
      – chrisl
      2 days ago










    • But as you wrote, digitalWrite() takes to long, so bit manipulation on the port registers are the right way to go: arduino.cc/en/Reference/PortManipulation
      – chrisl
      2 days ago










    • Yes, of course, I'm so sorry. This is what happens when you recycle code after a long work day. I'll fix it. And you're also right, digitalRead and -Write are too slow for 500 kHz, I'll implement it via the registers.
      – Tobias Weiß
      2 days ago






    • 1




      You could use one of the hardware time outputs like OC2A or OCRB and avoid the ISR/digitalWrite/bitbanging overhead entirely.
      – Dave X
      2 days ago












    • It's fixed now - so sorry again. My scope isn't fast enough for 500 kHz, but it works as intended for 50 kHz. The "standard" outputs are nice, but you're then limited to the two pins per timer. Is that already necessary at 500 kHz?
      – Tobias Weiß
      2 days ago

















    up vote
    5
    down vote













    Welcome to SE.



    digitalWrite() takes a few microseconds to execute as well. There is also some overhead around the delayMicroseconds() function.



    I you need exactly 500 kHz, you would want to consider using a timer.
    You can read up on how to set one up in the microcontrollers datasheet.



    Unfortunately, I don't have access to an Arduino Leonardo, but here is an example code for the ATmega328P. The register names will be different, but you should be able to adapt the code to fit your Arduino.



    // 500 kHz frequency

    void setup() {
    cli(); //Disable interrupt during setup
    TCCR2A = 0;
    TCCR2B = 0;

    TCCR2B |= (1 << CS20); //Enable timer without prescaler
    OCR2A = 15; //Do interrupt TIMER2_COMPA after reaching this counter value
    TIMSK2 |= (1 << 1); //Enable TIMER2_COMPA interrupt

    DDRD |= (1 << PORTD3); //Set Digital Pin 3 as Output Pin
    sei(); //Enable interrupts again
    }

    ISR(TIMER2_COMPA_vect) { //If the counter has reached the point where the output needs to be low
    TCNT2 = 0;
    PIND |= (1 << PORTD3); //Toggle Digital Pin 3
    }

    void loop() {
    //your looping code here
    }


    Explanation:
    TIMER2 is an 8-bit timer, which means it will always count from 0 to 255, regardless of what the CPU is doing.



    Normally, it counts up at the Arduino's clock frequency, like 16 MHz.



    When the counter hits 15, a special code is immediately executed, called an "Interrupt Service Routine". In this code, we reset the timer and change the state of your outpin pin, resulting in a 500 kHz square wave on that pin.



    We count to 15 since there are 16 steps in between "0" where the counter begins and 15, where we reset it.



    16'000'000 Hz / 1 (no prescaler) / 16 (counter) / 2 = 500 kHz



    The divisor of 2 comes from the fact that we need to change the pin state twice for every full square of the output signal.






    share|improve this answer



















    • 2




      Sometimes you write 500kHz, then you write 500Hz. As calculated the code is for 500Hz. As the OP asked for 500kHz, the prescaler could be set to 1 and the compare value (at which the timer fires the interrupt) to 16. In my calculation this gives you exactly 500kHz. Am I right?
      – chrisl
      2 days ago










    • But as you wrote, digitalWrite() takes to long, so bit manipulation on the port registers are the right way to go: arduino.cc/en/Reference/PortManipulation
      – chrisl
      2 days ago










    • Yes, of course, I'm so sorry. This is what happens when you recycle code after a long work day. I'll fix it. And you're also right, digitalRead and -Write are too slow for 500 kHz, I'll implement it via the registers.
      – Tobias Weiß
      2 days ago






    • 1




      You could use one of the hardware time outputs like OC2A or OCRB and avoid the ISR/digitalWrite/bitbanging overhead entirely.
      – Dave X
      2 days ago












    • It's fixed now - so sorry again. My scope isn't fast enough for 500 kHz, but it works as intended for 50 kHz. The "standard" outputs are nice, but you're then limited to the two pins per timer. Is that already necessary at 500 kHz?
      – Tobias Weiß
      2 days ago















    up vote
    5
    down vote










    up vote
    5
    down vote









    Welcome to SE.



    digitalWrite() takes a few microseconds to execute as well. There is also some overhead around the delayMicroseconds() function.



    I you need exactly 500 kHz, you would want to consider using a timer.
    You can read up on how to set one up in the microcontrollers datasheet.



    Unfortunately, I don't have access to an Arduino Leonardo, but here is an example code for the ATmega328P. The register names will be different, but you should be able to adapt the code to fit your Arduino.



    // 500 kHz frequency

    void setup() {
    cli(); //Disable interrupt during setup
    TCCR2A = 0;
    TCCR2B = 0;

    TCCR2B |= (1 << CS20); //Enable timer without prescaler
    OCR2A = 15; //Do interrupt TIMER2_COMPA after reaching this counter value
    TIMSK2 |= (1 << 1); //Enable TIMER2_COMPA interrupt

    DDRD |= (1 << PORTD3); //Set Digital Pin 3 as Output Pin
    sei(); //Enable interrupts again
    }

    ISR(TIMER2_COMPA_vect) { //If the counter has reached the point where the output needs to be low
    TCNT2 = 0;
    PIND |= (1 << PORTD3); //Toggle Digital Pin 3
    }

    void loop() {
    //your looping code here
    }


    Explanation:
    TIMER2 is an 8-bit timer, which means it will always count from 0 to 255, regardless of what the CPU is doing.



    Normally, it counts up at the Arduino's clock frequency, like 16 MHz.



    When the counter hits 15, a special code is immediately executed, called an "Interrupt Service Routine". In this code, we reset the timer and change the state of your outpin pin, resulting in a 500 kHz square wave on that pin.



    We count to 15 since there are 16 steps in between "0" where the counter begins and 15, where we reset it.



    16'000'000 Hz / 1 (no prescaler) / 16 (counter) / 2 = 500 kHz



    The divisor of 2 comes from the fact that we need to change the pin state twice for every full square of the output signal.






    share|improve this answer














    Welcome to SE.



    digitalWrite() takes a few microseconds to execute as well. There is also some overhead around the delayMicroseconds() function.



    I you need exactly 500 kHz, you would want to consider using a timer.
    You can read up on how to set one up in the microcontrollers datasheet.



    Unfortunately, I don't have access to an Arduino Leonardo, but here is an example code for the ATmega328P. The register names will be different, but you should be able to adapt the code to fit your Arduino.



    // 500 kHz frequency

    void setup() {
    cli(); //Disable interrupt during setup
    TCCR2A = 0;
    TCCR2B = 0;

    TCCR2B |= (1 << CS20); //Enable timer without prescaler
    OCR2A = 15; //Do interrupt TIMER2_COMPA after reaching this counter value
    TIMSK2 |= (1 << 1); //Enable TIMER2_COMPA interrupt

    DDRD |= (1 << PORTD3); //Set Digital Pin 3 as Output Pin
    sei(); //Enable interrupts again
    }

    ISR(TIMER2_COMPA_vect) { //If the counter has reached the point where the output needs to be low
    TCNT2 = 0;
    PIND |= (1 << PORTD3); //Toggle Digital Pin 3
    }

    void loop() {
    //your looping code here
    }


    Explanation:
    TIMER2 is an 8-bit timer, which means it will always count from 0 to 255, regardless of what the CPU is doing.



    Normally, it counts up at the Arduino's clock frequency, like 16 MHz.



    When the counter hits 15, a special code is immediately executed, called an "Interrupt Service Routine". In this code, we reset the timer and change the state of your outpin pin, resulting in a 500 kHz square wave on that pin.



    We count to 15 since there are 16 steps in between "0" where the counter begins and 15, where we reset it.



    16'000'000 Hz / 1 (no prescaler) / 16 (counter) / 2 = 500 kHz



    The divisor of 2 comes from the fact that we need to change the pin state twice for every full square of the output signal.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 2 days ago

























    answered 2 days ago









    Tobias Weiß

    3104




    3104








    • 2




      Sometimes you write 500kHz, then you write 500Hz. As calculated the code is for 500Hz. As the OP asked for 500kHz, the prescaler could be set to 1 and the compare value (at which the timer fires the interrupt) to 16. In my calculation this gives you exactly 500kHz. Am I right?
      – chrisl
      2 days ago










    • But as you wrote, digitalWrite() takes to long, so bit manipulation on the port registers are the right way to go: arduino.cc/en/Reference/PortManipulation
      – chrisl
      2 days ago










    • Yes, of course, I'm so sorry. This is what happens when you recycle code after a long work day. I'll fix it. And you're also right, digitalRead and -Write are too slow for 500 kHz, I'll implement it via the registers.
      – Tobias Weiß
      2 days ago






    • 1




      You could use one of the hardware time outputs like OC2A or OCRB and avoid the ISR/digitalWrite/bitbanging overhead entirely.
      – Dave X
      2 days ago












    • It's fixed now - so sorry again. My scope isn't fast enough for 500 kHz, but it works as intended for 50 kHz. The "standard" outputs are nice, but you're then limited to the two pins per timer. Is that already necessary at 500 kHz?
      – Tobias Weiß
      2 days ago
















    • 2




      Sometimes you write 500kHz, then you write 500Hz. As calculated the code is for 500Hz. As the OP asked for 500kHz, the prescaler could be set to 1 and the compare value (at which the timer fires the interrupt) to 16. In my calculation this gives you exactly 500kHz. Am I right?
      – chrisl
      2 days ago










    • But as you wrote, digitalWrite() takes to long, so bit manipulation on the port registers are the right way to go: arduino.cc/en/Reference/PortManipulation
      – chrisl
      2 days ago










    • Yes, of course, I'm so sorry. This is what happens when you recycle code after a long work day. I'll fix it. And you're also right, digitalRead and -Write are too slow for 500 kHz, I'll implement it via the registers.
      – Tobias Weiß
      2 days ago






    • 1




      You could use one of the hardware time outputs like OC2A or OCRB and avoid the ISR/digitalWrite/bitbanging overhead entirely.
      – Dave X
      2 days ago












    • It's fixed now - so sorry again. My scope isn't fast enough for 500 kHz, but it works as intended for 50 kHz. The "standard" outputs are nice, but you're then limited to the two pins per timer. Is that already necessary at 500 kHz?
      – Tobias Weiß
      2 days ago










    2




    2




    Sometimes you write 500kHz, then you write 500Hz. As calculated the code is for 500Hz. As the OP asked for 500kHz, the prescaler could be set to 1 and the compare value (at which the timer fires the interrupt) to 16. In my calculation this gives you exactly 500kHz. Am I right?
    – chrisl
    2 days ago




    Sometimes you write 500kHz, then you write 500Hz. As calculated the code is for 500Hz. As the OP asked for 500kHz, the prescaler could be set to 1 and the compare value (at which the timer fires the interrupt) to 16. In my calculation this gives you exactly 500kHz. Am I right?
    – chrisl
    2 days ago












    But as you wrote, digitalWrite() takes to long, so bit manipulation on the port registers are the right way to go: arduino.cc/en/Reference/PortManipulation
    – chrisl
    2 days ago




    But as you wrote, digitalWrite() takes to long, so bit manipulation on the port registers are the right way to go: arduino.cc/en/Reference/PortManipulation
    – chrisl
    2 days ago












    Yes, of course, I'm so sorry. This is what happens when you recycle code after a long work day. I'll fix it. And you're also right, digitalRead and -Write are too slow for 500 kHz, I'll implement it via the registers.
    – Tobias Weiß
    2 days ago




    Yes, of course, I'm so sorry. This is what happens when you recycle code after a long work day. I'll fix it. And you're also right, digitalRead and -Write are too slow for 500 kHz, I'll implement it via the registers.
    – Tobias Weiß
    2 days ago




    1




    1




    You could use one of the hardware time outputs like OC2A or OCRB and avoid the ISR/digitalWrite/bitbanging overhead entirely.
    – Dave X
    2 days ago






    You could use one of the hardware time outputs like OC2A or OCRB and avoid the ISR/digitalWrite/bitbanging overhead entirely.
    – Dave X
    2 days ago














    It's fixed now - so sorry again. My scope isn't fast enough for 500 kHz, but it works as intended for 50 kHz. The "standard" outputs are nice, but you're then limited to the two pins per timer. Is that already necessary at 500 kHz?
    – Tobias Weiß
    2 days ago






    It's fixed now - so sorry again. My scope isn't fast enough for 500 kHz, but it works as intended for 50 kHz. The "standard" outputs are nice, but you're then limited to the two pins per timer. Is that already necessary at 500 kHz?
    – Tobias Weiß
    2 days ago












    up vote
    0
    down vote













    delayMicroseconds() has a minimum lower value of 3-4 us per the IDE documentation. It won't do 1.



    loop() also adds some delay mechanisms doing it's background stuff.



    You will see better results with a while() :



    loop(){
    while (1){
    digitalWrite(3, HIGH);
    delayMicroseconds(del);
    digitalWrite(3, LOW);
    delayMicroseconds(del);
    }
    }


    with direct port manipulation in place of the digital writes.



    There will also be jitter from the millis() background time keeping, if you want a smoother signal it will be best to turn off interrupts as well.






    share|improve this answer

























      up vote
      0
      down vote













      delayMicroseconds() has a minimum lower value of 3-4 us per the IDE documentation. It won't do 1.



      loop() also adds some delay mechanisms doing it's background stuff.



      You will see better results with a while() :



      loop(){
      while (1){
      digitalWrite(3, HIGH);
      delayMicroseconds(del);
      digitalWrite(3, LOW);
      delayMicroseconds(del);
      }
      }


      with direct port manipulation in place of the digital writes.



      There will also be jitter from the millis() background time keeping, if you want a smoother signal it will be best to turn off interrupts as well.






      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        delayMicroseconds() has a minimum lower value of 3-4 us per the IDE documentation. It won't do 1.



        loop() also adds some delay mechanisms doing it's background stuff.



        You will see better results with a while() :



        loop(){
        while (1){
        digitalWrite(3, HIGH);
        delayMicroseconds(del);
        digitalWrite(3, LOW);
        delayMicroseconds(del);
        }
        }


        with direct port manipulation in place of the digital writes.



        There will also be jitter from the millis() background time keeping, if you want a smoother signal it will be best to turn off interrupts as well.






        share|improve this answer












        delayMicroseconds() has a minimum lower value of 3-4 us per the IDE documentation. It won't do 1.



        loop() also adds some delay mechanisms doing it's background stuff.



        You will see better results with a while() :



        loop(){
        while (1){
        digitalWrite(3, HIGH);
        delayMicroseconds(del);
        digitalWrite(3, LOW);
        delayMicroseconds(del);
        }
        }


        with direct port manipulation in place of the digital writes.



        There will also be jitter from the millis() background time keeping, if you want a smoother signal it will be best to turn off interrupts as well.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 2 days ago









        CrossRoads

        9437




        9437






















            deadpixel is a new contributor. Be nice, and check out our Code of Conduct.










             

            draft saved


            draft discarded


















            deadpixel is a new contributor. Be nice, and check out our Code of Conduct.













            deadpixel is a new contributor. Be nice, and check out our Code of Conduct.












            deadpixel is a new contributor. Be nice, and check out our Code of Conduct.















             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f57925%2fgenerated-frequency-is-not-as-expected%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

            Mangá

            Eduardo VII do Reino Unido