Tuesday, September 22, 2015

Kula6: Schematic mistake

From the beginning of this project I had a mistake in my schematic that I was too embarrassed to recognize. My AVR ADCs were not working!!! I originally thought that I had somehow broken my processor, but turns out that I was wrong. If you see my schematic in this post you will notice that the AREF is connected to ground... wrong!!! it needs to be connected to VCC (or whichever is your reference for the analog signals). Here is a picture of how the connection should be:

 
I actually added a 100nF capacitor to ground also, which is not pictured in the schematic.

I was only planning on using the ADC for debug purposes, don't have much plans on using it on the final result, but it was frustrating that I could not get it to work.

And here is the code to read from the ADC connected to ADC0 in pin40:

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

void adc_init()
{
 // Select Vref=AVcc
 ADMUX |= (1<<REFS0);
 //set prescaller to 128 and enable ADC
 ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN);
}


uint16_t adc_read(uint8_t ADCchannel)
{
 //select ADC channel with safety mask
 ADMUX = (ADMUX & 0xF0) | (ADCchannel & 0x0F);
 //single conversion mode
 ADCSRA |= (1<<ADSC);
 // wait until ADC conversion is complete
 while( ADCSRA & (1<<ADSC) );
 return ADC;
}

int main(void)
{
    adc_init();

    DDRC |= (1<<0);     //Set PortC Pin0 as an output
    PORTC |= (1<<0);        //Set PortC Pin0 high to turn on LED

    _delay_ms(500);
    PORTC ^= (1<<0);

    while(1) {
        uint16_t adc_result0 = adc_read(0);      // read adc value at PA0

        if(adc_result0>512) {
            PORTC |= (1<<0);
        }
        else {
            PORTC &= ~(1<<0);
        }

        _delay_ms(500);
    }

    return 0;
}