I just got my "One" and tried to generate a square wave on an output pin with "configurable" frequency. On my Scope I soon realized that something like this
gives 2 pulses each 4 us long plus some 2.6 us "loop()-overhead", so the duty cycle is not 50:50 und the frequ. is limited below 100 kHz.
Can anybody tell if there is benefit to switch over to "due" since it runs at much higher clock freq. ? Can I produce higher frequencies of have at least more "programming overhead" due to higher processor clock ?
What would be the output frequency and duty cycle of the above program on the "due"?
Is there a "timebase" such as micros() with higher resolution than 1us on the due?
How many instructions can the "due" process during a 1 us ?
Any comments are highly appreciated. Thanks
Chris
p.s.: FinalIy I want to be able to instantiate several of these "Generator" objects in order to generate several different frequencies on different outputs. Some code to give the idea below…and please stop saying "don't program OO in order to be fast"
my question was not on how to toggle as fast as possible but rather whether the time resolution of the "due" is better than that of the "one" and if so how much.
I just would be happy if anybody simply could answer to my 4 clear questions at thread opening.
chnbr:
I just would be happy if anybody simply could answer to my 4 clear questions at thread opening.
Doing a square wave in a loop is just not the right way of doing it. Use a timer, that will give you an output of up to 8 MHz (a toggle every 62.5 nS).
There is no point in switching to a Due for that.
Your other questions are irrelevant if you use a timer.
thanks for the link. I did some study of the ATmega manual and when I finally understood what's going on, I came up with the code below which is exactly what I needed... a pulse width modulated "high" freq. pulsing with variable phase delay after an trigger pulse
I am really impressed by the possibilities of such a cheap hardware. Really great !
Regards
Chris
const long prescaler = 64L;
long freq_trigger = 7500L; // Hz
long freq_pulse = 45000L; // Hz
int duty_pulsetrain = 10; // 0...100 [%]
int phase_delta=10; // 0...100 [%]
ISR (PCINT2_vect) {
// if pin 3 now high, turn on toggling of OC1A on compare
if (PIND & _BV (3)) {
TCCR1A |= _BV (COM1A0) ; // Toggle OC1A on Compare Match
} else {
TCCR1A &= ~_BV (COM1A0) ; // DO NOT Toggle OC1A on Compare Match
}
}
void setup() {
pinMode (5, OUTPUT); // OC0B
pinMode (3, OUTPUT); // OC2B
pinMode (9, OUTPUT); // OC1B
// set up the LCD's number of columns and rows:
lcd.begin(20, 4);
lcd.clear();
GTCCR = (1<<TSM)|(1<<PSRASY)|(1<<PSRSYNC); // halt timers
// Timer 0
// Pin 5 (OC0B) -> trigger Pulse (1us every 1/2000kHz)
// intended for inverter
TCCR0A = _BV (WGM00) | _BV (WGM01) | _BV (COM0B1); // fast PWM Mode
TCCR0B = _BV (WGM02) | _BV (CS00) | _BV (CS01); // prescaler 64
OCR0A = 16000000L / freq_trigger / prescaler - 1;
OCR0B = 1;
// set up Timer 1 (OC1B)
// PIN 9 (OC1B) - gives us 50 KHz pulses
TCCR1A = _BV(COM1A0);
TCCR1B = _BV(WGM12) | _BV (CS10); // CTC, No prescaler
OCR1A = (16000000L / freq_pulse / 2) - 1; // zero relative, f=1/(62.5ns * OCR1A)
// Set up Timer 2
// Pin 3 (OC2B) -> pulse train envelope
// helper signal (envelope for pulse train bursts)
TCCR2A = _BV (WGM20) | _BV (WGM21) | _BV (COM2B1); // Fast PWM mode
TCCR2B = _BV (WGM22) | _BV (CS22) ; // prescaler of 64
OCR2A = 16000000L / freq_trigger / prescaler - 1; // frequency
OCR2B = OCR2A * duty_pulsetrain / 100; // duty cycle from 0...OCR2A
TCNT0 = 0; // sync timers
TCNT2 = 0; // offset of 1 for OCRA as TOP timer
GTCCR = 0; // restart timers
// pin change interrupt
PCMSK2 |= _BV (PCINT19); // want pin 3
PCIFR |= _BV (PCIF2); // clear any outstanding interrupts
PCICR |= _BV (PCIE2); // enable pin change interrupts for D0 to D7
}
// in loop() I change the frequ., duty and phase parameters with POTs, which is not interesting the part here…
please note that in the code above there are some wrong numbers in the comments. That is because during development the frequency settings changed but the comments stayed.. (as always ).