Troubleshooting ADC coding for Arduino Uno
Moderators: adafruit_support_bill, adafruit

Troubleshooting ADC coding for Arduino Uno

by Papasquat12 on Sun Jan 29, 2012 10:19 pm

I am trying to code the Arduino Uno to run an analog to digital conversion. I have a pot connected to the A0 pin and am simply trying to input the analog value it reads from A0 and the digital output into the serial monitor. I have troubleshooted this quite a bit and am not getting anything on the serial monitor. Sorry i have to do this but here is my code, if you see my problems can you please help. Thanks

Code: Select all | TOGGLE FULL SIZE
/*  ADC Test
    For an Atmega 48 88 or 168
    Sends ADC results to the serial port
    Set your terminal to 2400 N 8 1
   
    Atmega168 DIP TX   PD1 (pin3)
    Atmega168 DIP RX   PD0 (pin2)
    Atmega168 DIP ADC2 PC2 (PIN25) */
   
#define F_CPU 1000000UL
#define UBRR_1200 51
#define UBRR_2400 25        // for 1Mhz

const int analogInPin = A0; // Analog input pin that the potentiometer is attached to
int sensorValue = 0; // value read from the pot
int inputValue = 0; // value output to the PWM (analog out)
int adc_temp = 0; // value read from the pot

// #define UBRR_2400 207    // for 8Mhz with .2% error
// #define UBRR_9600 51     // for 8Mhz with .2% error
// #define UBRR_19200 25    // for 8Mhz with .2% error

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>

void read_adc(void);        // Function Declarations
void adc_init(void);
     void setup() {   // initialize serial communications at 9600 bps:
      Serial.begin(9600);

      adc_temp = analogRead(analogInPin);
      inputValue = map(adc_temp, 1 , 1023, 1, 4);
      Serial.print("ADC = " );
      Serial.print(inputValue);
   }

 
int main(void)
{
     
   adc_init();             // Initialize the ADC
   
     
   _delay_ms(125);         // wait a bit

   while(1)
   {   

      read_adc();

 
     _delay_ms(125);        // wait a bit

   }
}

/* INIT ADC */

void adc_init(void)
{

   /** Setup and enable ADC **/
   ADMUX = (0<<REFS1)|    // Reference Selection Bits
           (1<<REFS0)|    // AVcc - external cap at AREF
           (0<<ADLAR)|    // ADC Left Adjust Result
           (0<<MUX2)|     // Analog Channel Selection Bits
           (1<<MUX1)|     // ADC2 (PC2 PIN25)
           (0<<MUX0);
   
   ADCSRA = (1<<ADEN)|    // ADC ENable
           (0<<ADSC)|     // ADC Start Conversion
           (0<<ADATE)|    // ADC Auto Trigger Enable
           (0<<ADIF)|     // ADC Interrupt Flag
           (0<<ADIE)|     // ADC Interrupt Enable
           (1<<ADPS2)|    // ADC Prescaler Select Bits
           (0<<ADPS1)|
           (1<<ADPS0);
                   // Timer/Counter1 Interrupt Mask Register
    TIMSK1 |= (1<<TOIE1); // enable overflow interrupt
   
   
    TCCR1B |= (1<<CS11)|
           (1<<CS10);     // native clock
}

/* READ ADC PINS */

void read_adc(void)
{
   unsigned char i = 4;
   adc_temp = 0;
   while (i--)
   {
      ADCSRA |= (1<<ADSC);
      while(ADCSRA & (1<<ADSC));
      adc_temp+= ADC;
      _delay_ms(50);
   }
   adc_temp = adc_temp / 4;  // Average a few samples
   
    Serial.print("conversion = " );
      Serial.print(adc_temp);
      delay(10);

}
Papasquat12
 
Posts: 4
Joined: Sun Jan 29, 2012 10:07 pm

Re: Troubleshooting ADC coding for Arduino Uno

by philba on Sun Jan 29, 2012 11:15 pm

Reading an analog value on an arduino is falling-off-a-log simple. Not sure why you are messing with those registers - the arduino libs do all that for you. I'd dump all your init code.

look here for something very similar to what you are trying to do. http://arduino.cc/en/Tutorial/AnalogInOutSerial
philba
 
Posts: 387
Joined: Mon Dec 19, 2011 5:59 pm

Re: Troubleshooting ADC coding for Arduino Uno

by Papasquat12 on Sun Jan 29, 2012 11:23 pm

Thank you for your input sir. I am quite aware of how to read an analog pin, but I need to convert the values I am getting to digital... hence the ADC coding for Arduino Uno title. I can read the analog signal in a separate code, but what I am simply looking for is the digital conversion to be displayed.
Papasquat12
 
Posts: 4
Joined: Sun Jan 29, 2012 10:07 pm

Re: Troubleshooting ADC coding for Arduino Uno

by jamesc4s on Sun Jan 29, 2012 11:41 pm

Like this?

Code: Select all | TOGGLE FULL SIZE
Serial.print(adc_temp, BIN);
User avatar
jamesc4s
 
Posts: 115
Joined: Sun Sep 26, 2010 10:49 pm
Location: Austin, TX

Re: Troubleshooting ADC coding for Arduino Uno

by Papasquat12 on Mon Jan 30, 2012 12:06 am

It didn't work by replacing it with that. I am new to this board and not sure if this code is even doing what I want at this point. If you have a sample code for ADC with this board I'd really appreciate it.
Papasquat12
 
Posts: 4
Joined: Sun Jan 29, 2012 10:07 pm

Re: Troubleshooting ADC coding for Arduino Uno

by philba on Mon Jan 30, 2012 1:39 am

I'm not tracking your question at all. When you read it, it IS digital - that's the D in ADC. Once you have done x = analogRead(pin); you are good. You've got the digital value in x. you can print it via Serial.print or lcd.print if you have an LCD display. All that monkeying with the registers is just confusing the arduino libraries. Maybe you need to do a reset on what you think is supposed to be happening. Look at the link I posted earlier that does pretty much you are asking for.

oh, ps, don't forget to open up the monitor to see the messages that Serial.print sends.
philba
 
Posts: 387
Joined: Mon Dec 19, 2011 5:59 pm

Re: Troubleshooting ADC coding for Arduino Uno

by Papasquat12 on Mon Jan 30, 2012 5:18 am

Yes, i do understand this will give me a digital output on the serial monitor... but I need to get a digital output faster then the board does this by only sampling an analog input. See, I need to sample ADC at a rate which is acceptable for music quality. After calculating the frequency with the nyquist rate it is converting A to D at nearly 45kHz, which needs to be cut in half to sample music at a rate which ears work at which is about 20kHz. I am directly inserting into registers because I need it to sample faster.
Papasquat12
 
Posts: 4
Joined: Sun Jan 29, 2012 10:07 pm

Re: Troubleshooting ADC coding for Arduino Uno

by mtbf0 on Mon Jan 30, 2012 7:39 am

talk about frankencode...

are you compiling this using the arduino tools? if so, where is loop()? you can't define a function main(), because arduino supplies that.

are you compiling this using avr-gcc without arduino? if so, you can't use the arduino serial code.

you've enabled an interrupt, but have no interrupt handler. that will halt your mega lickitty split.

i would imagine that you're getting a ton of compile errors, in which case looking for anything on the serial monitor is premature.

maybe i'm missing something. it's still awfully early here on the left coast.
"i want to lead a dissipate existence, play scratchy records and enjoy my decline" - iggy pop, i need more
User avatar
mtbf0
 
Posts: 1645
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Re: Troubleshooting ADC coding for Arduino Uno

by jamesc4s on Mon Jan 30, 2012 8:31 am

Papasquat12 wrote:Yes, i do understand this will give me a digital output on the serial monitor... but I need to get a digital output faster then the board does this by only sampling an analog input.


Your posts are almost as confusing as your code.

Please step back and clearly state the problem you are trying to address. Is it a speed issue? Is it a formatting issue? In your original post you never mentioned anything about sampling rate being important. Which, I don't see how it is if you are averaging in the code and using long multi-millisecond delays. 10ms = 100Hz, 125ms = 8Hz, no where near your 20kHz.

I have a feeling you mean "in binary" differently than how it is normally used. However, you haven't clearly stated what you are trying to do so it is difficult to give you an answer.

Perhaps you meant you didn't want ascii characters sent over serial. In that case, use "Serial.write()" instead of "Serial.print()". However, you won't be able to see that data in the Serial Monitor, since it is just binary bits and not ASCII.
User avatar
jamesc4s
 
Posts: 115
Joined: Sun Sep 26, 2010 10:49 pm
Location: Austin, TX

Re: Troubleshooting ADC coding for Arduino Uno

by mtbf0 on Mon Jan 30, 2012 10:06 am

this tells the compiler that your clock is 1MHz. the arduino runs at 16MHz. some variants run at 8MHz. none tun at 1MHz.
Code: Select all | TOGGLE FULL SIZE
#define F_CPU 1000000UL


you cannot define a function called main in an arduino sketch. this is defined automatically and calls your setup function once, then calls your loop function repeatedly.
Code: Select all | TOGGLE FULL SIZE
int main(void)


you are enabling an interrupt without supplying an interrupt service routine. when the interrupt occurs, your sketch will stop deader than a door nail.
Code: Select all | TOGGLE FULL SIZE
                   // Timer/Counter1 Interrupt Mask Register
    TIMSK1 |= (1<<TOIE1); // enable overflow interrupt
   
   
    TCCR1B |= (1<<CS11)|
           (1<<CS10);     // native clock

}

you have not defined a loop() function. everything that you put in main() should go into loop, except adc_init should probably be called from setup().

i would guess that what you'll eventually want to do is set up a timer interrupt to occur at your desired sample rate then sample the analog pin in the interrupt service routine. since you'll be sampling audio data which is presumably constantly changing you probably don't want to average the inputs.

what then? if you just want to ship the data out to a pc, why bother? a pc has a pair of perfectly good adc's already optimized for audio.

it would be really helpful if you would describe your project in specific rather than general terms.
"i want to lead a dissipate existence, play scratchy records and enjoy my decline" - iggy pop, i need more
User avatar
mtbf0
 
Posts: 1645
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Re: Troubleshooting ADC coding for Arduino Uno

by philba on Mon Jan 30, 2012 10:48 am

Papasquat12 wrote:Yes, i do understand this will give me a digital output on the serial monitor... but I need to get a digital output faster then the board does this by only sampling an analog input. See, I need to sample ADC at a rate which is acceptable for music quality. After calculating the frequency with the nyquist rate it is converting A to D at nearly 45kHz, which needs to be cut in half to sample music at a rate which ears work at which is about 20kHz. I am directly inserting into registers because I need it to sample faster.

At least you finally explained what you want to do.

learn how to do interrupts. especially the ADC conversion complete interrupt which will help you to drive the ADC at it's fastest. For what it's worth, 10 bit ADCs are pretty mediocre for music.
philba
 
Posts: 387
Joined: Mon Dec 19, 2011 5:59 pm