Hi all,
I designed a custom Arduino board using an ATmega328 TQFP. When I was designing, I ran out of analog pins and put two inputs on ADC6 and ADC7. One monitors battery voltage and one monitors a light sensor. However, I do not receive values for either using analogRead(). Is this something I need to code myself from the datasheet? The most I can find is that 6/7 are supported in the Arduino-mini. Should analogRead() be working in the arduino software for those two pin already? The battery voltage is just a resistor divider so I should be getting something from that.
Thanks!
The analogRead function maps the pin number to a port and bit. It knows which port and bits are valid for each type of board. Pins 6 and 7 on the ATMega328 are not valid pin numbers, so, you will not be able to use analogRead to read them.
You might be able to use direct port access to read them.
Modifying the core isn't too difficult. But, if you do modify the core and want to keep it up-to-date, you'll have to make the modifications each time you upgrade.
If you decide to change the core I can probably help.
I think the best thing to do for me is to modify the core at this point. I've been going over some of the source files and trying to figure out how the pin mapping works.
If you don't mind giving some pointers on where to start that would be great. I've been doing a lot of Gumstix lately so my C++ shouldn't be too terrible! I have everything checked out and running on my linux box.
Looks like I should be modifying pins_arduino.c for the TQFP version of the ATmega328 in order to user ADC6/7. Still figuring out how the mapping functions work.
Thanks.
The code of interest is in...
{YourArduinoDirectory}\hardware\arduino\cores\arduino\wiring_analog.c
It looks like ADC6 and ADC7 should work. The first line of code...
ADMUX = (analog_reference << 6) | (pin & 0x07);
...sets the input channel based on the pin. Six and seven will pass safely through the expression so ADMUX should be properly set. The datasheet doesn't mention anything special that needs to be done to select channels 6 or 7. The rest of the code starts a conversion, waits for the conversion, and returns the result...
sbi(ADCSRA, ADSC);
while (bit_is_set(ADCSRA, ADSC));
low = ADCL;
high = ADCH;
return (high << 8) | low;
I can't see any reason that it wouldn't work.
Have you measured the voltage at the ADC6 and ADC7 connections?