I was curious to see what frequency, duty, period, time on and time off to an output pin. So I connect to a 10 k resistor ( +5 V - 10 k resistor - gnd ) and upload the Blink without delay. I have a picture of the oscilloscope display.
The strange part is why it is not 50 % duty ? The Frequency , that slow ? So an instruction of digitalWrite (pin, state ) is about 4 uS ?
Here is my results : T on = 3.8 uS T off = 4.6 uS Period = 8.4 uS
Frequency = 119047.619 F = 1 / Period
Duty Cycle = 45.2380952 Duty Cycle = ( T on / Period ) * 100
The test code : The picture : V side = 1 V / div Time side = 2 uS / div
/*
size : 824 bytes
Blink
Without delay
To see what frequency the output is.
Connect the pin 12 with 1 10 K resistor
*/
byte myled = 12; // pin 12
void setup()
{
// init pin 12
pinMode(myled, OUTPUT);
}
void loop()
{ // display output 12 on/off without delay
digitalWrite(myled, HIGH); // set the LED on
digitalWrite(myled, LOW); // set the LED off
}
4us for a digitalWrite() makes sense. The digitalWrite() function has to map the pin number (13) to a port (PORTB) and a pin on that port (5) by doing array lookups. That takes time.
Also, it takes time to get from the bottom of the loop to the top, so there is some "down time" between writing LOW to the pin and writing HIGH, more than there is between writing HIGH and writing LOW. So it makes sense that the duty cycle is slightly less than 50%.
--
The MegaRAM shield: add 128 kilobytes of external RAM to your Arduino Mega/Mega2560
There will always be some loop() overhead time consumed to keep it from a perfect 50%
The Frequency , that slow ?
Yes, the digitalWrite function because it has to do a arduino 'abstracted' pin number to a actual AVR port & bit address conversion, does carry a speed penalty. Also because pin can be a variable rather then just a constant, that also adds to the converting.
So an instruction of digitalWrite (pin, state ) is about 4 uS ?
If maximum reading and writing to digital I/O pins is required then you can use direct port access methods. This will approach maximum speed possible per chip clock rate, but at the expense of not being portable between boards using 8/168/328 chips and ones using the 1280/2560 chip as they have different port & pin assignments.
Thank RuggedCircuits for your answer. I did this experiment to see what I will get. So top frequency is 119 k Hz - 4 uS on / off - minimum time. And that limitation has to take into consideration when designing certains applications / projects. Interresting.
If maximum reading and writing to digital I/O pins is required then you can use direct port access methods. This will approach maximum speed possible per chip clock rate, but at the expense of not being portable between boards using 8/168/328 chips and ones using the 1280/2560 chip as they have different port & pin assignments.
I saw you did that experiment, You measure 106.8 K Hz, mine is 119 K Hz, So your data is : Period = 9.363 uS Ton / T off = 4.681 uS. Interresting. It look like the Frequency average is 110 K Hz +/-10 K Hz Period = 9 uS +/- 1 uS. Not very precise. It look like to me that every board manufacture are the same spec, well more like +/- and are not precisely EXACT.
You measure 106.8 K Hz, mine is 119 K Hz, So your data is : Period = 9.363 uS Ton / T off = 4.681 uS.
I remember the output as being pretty close to a square wave. It was the faster direct port code where Ton and Toff drifted apart.
Interresting. It look like the Frequency average is 110 K Hz +/-10 K Hz Period = 9 uS +/- 1 uS. Not very precise.
When you use high-level functions like digitalWrite(), you're subject to changes in the library and/or compiler producing changes in timing. The thread I linked is almost three years old; that's several code versions ago. But notice the thread has additional info on:
different pins have different speed
getting higher speed using direct port access
high-speed square waves using the pin toggle feature.
Ok, so how can I program the same program ( Blink without delay) using the ports. I am not sure how to program it. Can you guys give me an example code. I read the info, but I am comfuse which pin is which, and afraided to code and screw my ATMega chip.
Like :
// variable examples
// maybe setup examples
void setup()
{
// an example in the setup
DDRB = B00111111; // Hope I am correct in the setup
}
void loop()
{
// example to display it
PORTB = B00010000; // hope that I am correct to display
PORTB = B00000000; // pin 12 on / off
}
Probably not. "PINB" would normally be the input port, and has a "magic" function of toggling the output when you write a 1 to some bit position (writing a 0 to PINB should do nothing.)
"PORTB" is the port where you write explicit ones and zeros and have them show up on the actual output pins (assuming that the pins are outputs.)
void setup()
{
pinMode(12, OUTPUT);
}
void loop()
{
while (1==1)
{
PINB=B00010000; // This line toggles D12 (turns it on if it's off, turns it off if it's on)
// PINB=B00000000; // This line does nothing but waste time which is why I didn't put it in.
}
}
The raison I put the line PINB=B00010000; and PINB=B00010000; I was still thinking digitalWrite(pin, HIGH); digitalWrite(pin, LOW);
And I also think that pin 12 will stay HIGH, not turn on/off. Because when you do digitalWrite( pin, HIGH); the pin will stay "lock" at HIGH until a instruction say otherwise.
But to my discovery, just PINB=B00010000; IT CHANGING STATE .... but it will not "lock" to HIGH just like a digitalWrite...Humm ? What about PORTB =B00010000; Will it "lock" the pin to HIGH ?
Anyway, I did 3 set of program using PINB. The frequency is ... a BIG change... Like in my first experiment ( digitalWrite ) , to my discovery a HUGH change, It like driving at 60 km/h <-- exp 1 and you drive at 80 km/h <--exp 2 that a big jump to 160 km/h <--exp 3. And in exp 4, just a small change in speed.
The next 3 post will be my results including a picture of the waveform and the code.
Ton = 0.8 uS Toff = 0.8 uS Duty = 50 % Period = 1.6 uS Frequency = 625 kHz
Code :
/*
size : 630 bytes
Blink without delay using ML instruction
by using PINB <--- Pins Port B
To see what frequency the output is.
Connect the pin 12 with a 10 K resistor.
With the help of johnwasser from the Arduino Forum.
*/
void setup()
{
// setup pin 12
pinMode(12, OUTPUT);
}
void loop()
{
// Methode A
// turn on and off pin 12.
PINB=B00010000;
PINB=B00000000;
}
but it will not "lock" to HIGH just like a digitalWrite...Humm ?
Yes, the output pin will 'lock' high, that is, until you issue another PINB=B00010000 or a PORTB =B00000000 or a digitalWrite(pin#, LOW).
What about PORTB =B00010000; Will it "lock" the pin to HIGH ?
Yes, same as PINB will. Whatever the last command to change a pin's output state, it will stay that state until another command is executed that changes it's state, or a hardware reset.
Ton = 0.24 uS Toff = 0.26 uS Duty = 48 % Period = 0.5 uS Frequency = 2 M Hz
Code :
/*
size : 630 bytes
Blink without delay using ML instruction
by using PINB <--- Pins Port B
To see what frequency the output is.
Connect the pin 12 with a 10 K resistor.
With the help of johnwasser from the Arduino Forum.
*/
void setup()
{
// setup pin 12
pinMode(12, OUTPUT);
}
void loop()
{
// another methode
// Turn pin 12 on and off
while (1==1)
{
PINB=B00010000;
PINB=B00000000;
}
}