Creating an LFO / Timer question

Hello,

I'm trying to find how to generate an LFO using a PWM output, I searched the web without success though there are innumerable examples, I only found either sketches using delay() which I want to avoid, or stuff way too complicated for my noobish understanding. I chose to post here rather than in the audio forum because it seemed a rather basic coding thing.

I have no idea how to proceed... The method I tried seems to be completely wrong (waiting for a number of milliseconds between each output value in/decrementation, which makes a 511ms duty cycle for a complete sweep up and down through all 256 values when the delay is 1ms).

How should this be done instead? (Besides I want to be able to output more waveforms than stupid triangles or sawteeth)

Any help appreciated!

Thanks!

Use a timer, basically it almost like you did, only more precision with interrupt driven increment in PWM. You can generate a sine if you feed linearly changing value to sin(2*pi* i/256) function (math.h), or check on a link how it's done with LUT: http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/

Thanks, I searched the web for timer tutorials and found this interesting blog post: http://letsmakerobots.com/node/28278

I loaded that sketch:

#define ledPin 13

void setup()
{
pinMode(ledPin, OUTPUT);

// initialize timer1
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;

OCR1A = 31250; // compare match register 16MHz/256/2Hz
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts
}

ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine
{
digitalWrite(ledPin, digitalRead(ledPin) ^ 1); // toggle LED pin
}

void loop()
{
// your program here…
}

I played with OCR1A to change frequency, but I really don’t get what this means (among other lines):

TCCR1B |= (1 << WGM12);

I know nothing about bitwise operators so I searched again and I found out it’s like:

TCCR1B = TCCR1B | (1 << WGM12);

Now I’m wondering what “1 << WGM12” means… I think I understand this:
A = 0011 1100
B = A << 2
which makes B = 1111 0000, but in this example A is a series of 0s and 1s and the shifter is a decimal, but it isn’t the case in the code line, which is confusing me. Can anyone help me understand that code?

Thanks!

Ok I finally understood that WGM12 is a decimal and equals 3 (just printed it out via serial), but where does this 3 come from?

Is

TCCR1B |= (1 << WGM12);

the same as

TCCR1B |= 1000;

?

Visit Atmel.com and download datasheet for your uCPU (depends on board, for UNO - AtMega328). There is an extract, which show 16! different modes of timer settings. WGM12 is a bit, or position in the register, it's not "3" or number, rather a "switch" in line of 16 others switches, which you could turn on or off.

Mode WGM13 WGM12 WGM11 WGM10 (CTC1) (PWM11) (PWM10) Timer/Counter Mode of TOP Update of TOV1 Flag Operation OCR1x at Set on 0 0 0 0 0 Normal 0xFFFF Immediate MAX 1 0 0 0 1 PWM, Phase Correct, 8-bit 0x00FF TOP BOTTOM 2 0 0 1 0 PWM, Phase Correct, 9-bit 0x01FF TOP BOTTOM 3 0 0 1 1 PWM, Phase Correct, 10-bit 0x03FF TOP BOTTOM 4 0 1 0 0 CTC OCR1A Immediate MAX 5 0 1 0 1 Fast PWM, 8-bit 0x00FF BOTTOM TOP 6 0 1 1 0 Fast PWM, 9-bit 0x01FF BOTTOM TOP 7 0 1 1 1 Fast PWM, 10-bit 0x03FF BOTTOM TOP 8 1 0 0 0 PWM, Phase and Frequency ICR1 BOTTOM BOTTOM Correct 9 1 0 0 1 PWM, Phase and Frequency OCR1A BOTTOM BOTTOM Correct 10 1 0 1 0 PWM, Phase Correct ICR1 TOP BOTTOM 11 1 0 1 1 PWM, Phase Correct OCR1A TOP BOTTOM 12 1 1 0 0 CTC ICR1 Immediate MAX 13 1 1 0 1 (Reserved) – – – 14 1 1 1 0 Fast PWM ICR1 BOTTOM TOP 15 1 1 1 1 Fast PWM OCR1A BOTTOM TOP

Where do I learn about all this? I can't read a datasheet, I don't even know what a register is for instance...

Isn't there a way to do it without using a timer?

I found this to be a good tutorial on AVRs:

You don't have to study all registers, following basic motto of C++ language "use a library and save a time". In this circumstances, libraries are: http://arduino.cc/en/Reference/Libraries Or you can copy-paste code linked in reply #1. What is your spec for LFO, freq. range, stability, distortion?

jfenwick:
I found this to be a good tutorial on AVRs:
AVR GUIDE - QEEWiki

The table of contents looks like my last night’s dream come true! Thanks!

Magician:
You don’t have to study all registers, following basic motto of C++ language “use a library and save a time”. In this circumstances, libraries are: http://arduino.cc/en/Reference/Libraries
Or you can copy-paste code linked in reply #1.
What is your spec for LFO, freq. range, stability, distortion?

I found this library as I was searching for tutorials about timers: http://arduino.cc/playground/Code/Timer1
I thought I might give it a try.

Actually what I want to do is generate waveforms and send them over MIDI, and beeing able to change the frequency/amplitude with sensors. Ideal frequency range would be 2 to 80Hz (I’m that bad) though I might consider a lower high end (and a higher low end) if the tweaking can’t be precise enough. I was thinking about generating CV curves as well, which actually seems simpler but I really want to send them over MIDI.

Timers seem a little difficult for me to master quickly so I thought I'd focus on the MIDI communication and sensors, which is essential to my project, and reprogram the AVR later when I learn more about timers, to add the LFO functions.

I need to know one important thing before I start thinking more seriously about the features of my controller: can I use the PWM outputs to dim LEDs if I use timers? If I understood correctly, I can't use pins 9 & 11 when I'm using timer1, am I right?

Thanks!