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)
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(2pi 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/
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?
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
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: Libraries - Arduino Reference
Or you can copy-paste code linked in reply #1.
What is your spec for LFO, freq. range, stability, distortion?
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: Libraries - Arduino Reference
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: Arduino Playground - 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?