I hope someone can help me with my current Arduino project. I am trying to make a Digitaly Controlled Oscillator for a synthesizer, and as one part of that I need to be able to read an analogue voltage from the arduino.
I want to trigger an update of the ADC every time Timer0 overflows, and once the ADC has updated, have it throw and interupt.
From reading the data sheet I belive that this is possible but it doesnt work in my code. It works in free-running mode, but that will poll the ADC too fast for my needs. When triggering from the Timer0 overflow, the interupt routine never gets called, and I cant for the life of me seem to find out why.
I should point out that I am quite new to dealing with registers on the arduino so perhaps that will factor into this.
Timer 0 and the ADC are setup in the start_apm function.
Currently, the program should read an analogue voltage on Analogue Pin 0 and output a square wave of proportional frequency on pin 9.
I would be most greatfull for some assistance with this problem.
I am using the Arduino Duemilanove with the Atmega328p chip.
Your program starts with gAPM=0 which is a problem when you first call set_pll_freq() with a parameter of 0. That causes a division-by-error when computing lOCR.
Watch out for the number 0xFFFF. By default that's a signed 16-bit integer which is sign-extended to -1 as an int32_t (I think). So the comparison:
if ( lOCR > 0xFFFF )
could be interpreted as:
if (lOCR > -1)
Use 0xFFFFU to interpret this as an unsigned number.
Since the variables gPitchChange and gAPM are modified within an ISR they should be declared 'volatile'.
Thanks Rugged, you seem to have a realy good eye for spotting potential bugs.
While these suggestions didnt fix my problem, they are great in their own right.
You're configuring your timer in mode 4 (b0100) which causes an overflow on the MAX value, which is 0xFFFF, not OCR1A. So really, there's never going to be any overflow. Maybe try mode 11 (b1011) or mode 15 (b1111).
--
The Ruggeduino: compatible with Arduino UNO, 24V operation, all I/O's fused and protected
I am puzzled,
I think you could be looking at my timer1 code?
I say this because you quoted 0xFFFF as a max value.
The timer 1 code seems to work fine and generates a set frequency the same way as the Tone library does.
Having said that perhaps I have missed your point, but I cant find anything in the datasheet that
reffers to any timer having a mode > 7. This is the datasheet I have been looking at:
[edit]
Ok, I see that timer 1 has modes > 7 so I am sure that you are looking at my timer 1 code instead.
[/edit]
Just to clarrify Im having problems with my Timer0 code:
It is my understanding that Timer0 will increment until MAX, in this case 0xFF. At which point I assume that because its unsigned it will naturaly wrap around to 0 again. Will this not trigger an overflow? I have dissabled the Output Compare Units because I dont think they are needed, the timer still runs and overflows without them (?). In fact the only step I have taken to run the timer is to set the pre-scaler, since no prescaler is quoted in the data sheet as, TimerHalted or something like that.
I would have put in my own interupt routine to test for it overflowing but it seems some other part of the arduino library has already defined this interupt and it complains.
Good point, I think I confused Timer 1 with Timer 0.
So...the point of Timer 1 is just to generate a variable frequency waveform on pin 9? If so I think the code is overly complicated since pin 9 is OC1A and you can just drive this pin directly by connecting up the output compare through the TCCR1A register.
Anyways...you say that code works so no point picking on it.
I can't see why you wouldn't be getting A/D interrupts based on Timer 0. Perhaps put together a simpler sketch that just tests this one behavior. This will be easier to play with, read, and debug.
--
The Gadget Shield: accelerometer, RGB LED, IR transmit/receive, speaker, microphone, light sensor, potentiometer, pushbuttons
Yep timer 1 is just making a variable frequency on pin 9.
Thanks for pointing that out about OC1A, i'll try to hook it up to drive the pin directly, that would be more efficient.
Thats again some sound advice about testing just the A/D and timer 0, as another sketch.
I'll try that out tommorow since its bed time for me now. Thanks very much Rugged for your help so far.