
here’s a treat for anyone that’s into the audio side of arduino. it’s an 8-bit two-timer based LFO Generator using timer 0/2 on an ATMega328p. i’m only using timer2 for output in this code. i’ve started implementing the LFO code into my 8-bit melotronium where timer 2 is dedicated for the audio output. in the larger code base, timer0 just stores values in an unsigned integer that the other timer grabs and modulates the output mathematically. for now, this should be a good reference to anyone looking for the outline of an LFO with seven different wave forms.
#include
#include
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
uint8_t sineTable[] = {
127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,
192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,
239,240,242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,
254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,
233,231,229,227,225,223,221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,
181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,
115,111,108,105,102,99,96,93,90,87,84,81,78,76,73,70,67,64,62,59,56,54,51,49,46,44,
42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,
0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31, 33,35,37,39,42,
44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124
};
uint8_t tWave = 128;
uint8_t sWave = 255;
uint8_t ruWave = 128;
uint8_t rdWave = 128;
uint8_t rWave = 128;
int i = 0;
int rate;
int waveform;
byte d = HIGH;
void setup() {
Serial.begin(9600);
pinMode(6, OUTPUT);
pinMode(5, OUTPUT);
pinMode(3, OUTPUT);
setupTimer();
OCR0A = 128;
}
void loop() {
waveform = map(analogRead(0),0,1023,1,7);
rate = map(analogRead(1),0,1023,255,0);
OCR0A = rate;
}
ISR(TIMER0_COMPA_vect) {
if(i == 255) i = 0;
switch(waveform) {
case 1:
analogWrite(3,sine(i));
break;
case 2:
analogWrite(3,triangle(i));
break;
case 3:
analogWrite(3, square(i));
break;
case 4:
analogWrite(3, rampUp(i));
break;
case 5:
analogWrite(3, rampDown(i));
break;
case 6:
analogWrite(3, rand(i));
break;
case 7:
analogWrite(3, white(i));
break;
}
i++;
}
void setupTimer() {
cli();
/*--- TIMER2 CONFIG ---*/
sbi(TCCR2A,WGM20);
sbi(TCCR2A,WGM21);
cbi(TCCR2A,WGM22);
sbi(TCCR2B, CS20);
cbi(TCCR2B, CS21);
cbi(TCCR2B, CS22);
sbi(TCCR2A,COM2B1);
cbi(TCCR2A,COM2B0);
/*--- TIMER0 CONFIG ---*/
cbi(TCCR0B,CS00);
cbi(TCCR0B,CS01);
sbi(TCCR0B,CS02);
sbi(TCCR0A, COM0A1);
cbi(TCCR0A, COM0A0);
cbi(TCCR0A, WGM00);
sbi(TCCR0A, WGM01);
cbi(TCCR0A, WGM02);
cbi(TIFR0,OCF0A);
sbi(TIMSK0,OCIE0A);
sei();
}
int sine(int i) {
return sineTable[i];
}
int triangle(int i) {
if(tWave >= 255) d = LOW;
if(tWave <= 0) d = HIGH;
if(d == HIGH) tWave++;
if(d == LOW) tWave--;
return tWave;
}
int rampUp(int i) {
ruWave++;
if(ruWave > 255) ruWave = 0;
return ruWave;
}
int rampDown(int i) {
rdWave--;
if(rdWave < 0) rdWave = 255;
return rdWave;
}
int square(int i) {
if(i >= 128) sWave = 255;
if(i <= 127) sWave = 0;
return sWave;
}
int rand(int i) {
if(i == rWave) rWave = random(255);
return rWave;
}
int white(int i) {
return random(255);
}