Reputation: 27
I've made a basic waveform generator with an Arduino Uno and a resistor ladder on a breadboard. I change the voltage level as needed using the loop
function and micros()
to delay between each voltage change. It's not perfect but it works well with a piezo.
My problem is I set the signal frequency in my code and I would like to be able to change it using a pot for example. But as soon as I put an analogRead
somewhere in my code (all the code is in the loop()
function) the output signal changes. I found out that the analogRead
function can take up to 100µs to run, and that's greater than the delay between each voltage change so the actual signal period is not correct:
unsigned long now, next;
int freq;
void loop(){
//if I put analogRead() here it takes to much time
now = micros();
if(now >= next){
//Here I change the output analog value using a R-2R ladder
//then I change the value of next
}
}
I tried a few solutions including using switches instead of a pot but digitalRead
combined with if statement don't seem more efficient. I also tried switches with interrupts but the result is the same as with digitalRead
.
Does somebody know another solution?
Upvotes: 1
Views: 1173
Reputation: 3739
The analogRead
waits until conversion is done, so if you want to do something else, you have to handle it differently.
You can use ADC interrupt and free running mode. Or you can trigger the ADC conversion cycle by several sources like timer compare.
Or you can do it by "event" based approach - by checking that ADC conversion is done and reset it by writing logic one to that flag.
// in setup:
ADCSRA |= _BV(ADATE); // enable auto trigger mode
ADCSRB = 0; // free running mode for the auto trigger
// and in the loop:
if (ADCSRA & _BV(ADIF)) {
value = ADC; // get ADC value
ADCSRA |= _BV(ADIF); // reset flag by writing logic one into it
// whatever you want with the current value
// or ADCSRA |= _BV(ADSC); // start another conversion if you don't want free running mode
}
Btw: macro _BV(BIT)
is replaced to 1<<(BIT)
(if you wonder why I'm using it)
Upvotes: 2