ATMega644p Analog ports mixup :(

I'm using my own PCB with ATMega644p chip w/ Sanguino bootloader (and standard Sanguino hardware profile loaded into Arduino 1.0.1 IDE). It works great, except I cannot figure out why Analog port 1 only works as port 0 :frowning:
Let me explain.
ADC0_PA0 (pin 40) is connected to DS18B20 (and works just fine). I address it as A0.
I'm trying to connect ADC1_PA1 (pin 39) to photo-resistor to measure light and I address it as A1. But it doesn't work. As soon as I change it to A0 it starts to work and shows actual photo-resistor value (which changes with light amount).
I have absolutely no idea why. Pins are not connected to each other, I tested with DMM...
Here's simple code and schematic (JP2 is where photoresistor connected to pin 39 and pulldown resistor):

    int photocellPin = A1; // the cell and 10K pulldown are connected to a1 (and doesn't work)
    int photocellReading; // the analog reading from the sensor divider
    void setup(void) {
      Serial.begin(9600);
    }
    void loop(void) {
    photocellReading = analogRead(photocellPin);
    Serial.print("Analog reading = ");
    Serial.println(photocellReading); // the raw analog reading
    delay(1000);
    }

Please help me :slight_smile:

Could be an error in the pins_arduino.h file.

CrossRoads:
Could be an error in the pins_arduino.h file.

Hmmm, I can't tell :frowning: I'm attaching pins_arduino.h file.
It looks like PA0 and PA1 also mapped to 31 and 30. I tried them instead of A0 and A1 and they seem to correspond. When I change it to A1 (which is supposed to be right port) I'm actually always getting reading of 1023. I tried other port such as A2-A3 and getting random readings which makes me believe something is not connected right in the schematic maybe?

pins_arduino.h (6.95 KB)

Try playing with this line

#define analogInputToDigitalPin(p) ((p < 7) ? (p) + 24 : -1)

I don't know how to read that, it maps the pins somehow.

I have no idea if it is or is not correct but this is a way to write it that is hopefully more legible...

int analogInputToDigitalPin( int p )
{
  if ( p < 7 )
  {
    return( p + 24 );
  }
  else
  {
    return( -1 );
  }
}

I think it should maybe say (p <= 7). Also, I think the Sanguino, like all the manicbug
pinouts other than Bobuino, have the ADC channels backwards to the Bobuino/Arduino
ordering, ie, in the same order as on the chips.

Yes, maniacbug reversed the ordering for me so that A0 is near the power header, going out to A5 (and A6, A7) near the corner of the board, thus I could bring analog port pin 7 to A0 with a short trace from the uC pin to the header pin.

Thanks guys I'll give a try tonight. But I don't think it's really reversed (in my case). A0 seems to map to both PA0 and PA1...and looks like A1 is not mapped to anything analog because I always get AnalogRead (A1) = 1023, otherwise I would get almost random reading... Maybe it's mapped to digital port... Anyone knows what happens if you do AnalogRead on digital pin that's not connected? :slight_smile:
Only sure way to know would be to use raw PORT command, but I have no idea how to AnalogRead physical port...

oric_dan:
I think it should maybe say (p <= 7). Also, I think the Sanguino, like all the manicbug
pinouts other than Bobuino, have the ADC channels backwards to the Bobuino/Arduino
ordering, ie, in the same order as on the chips.

Didn't work :frowning:
Does it look from schematic that I wired it wrong?

Yes, looks like A0 normally High, and A1-2-3-4 normally Low if nothing external is connected.

Analog read on those ports should return 1023,0,0,0,0 due to the resistors you have.

CrossRoads:
Yes, looks like A0 normally High, and A1-2-3-4 normally Low if nothing external is connected.

Analog read on those ports should return 1023,0,0,0,0 due to the resistors you have.

Actually when polling all 6 analog ports (nothing connected) I get:
Analog reading from A0: 0
Analog reading from A1: 1023
Analog reading from A2: 769
Analog reading from A3: 476
Analog reading from A4: 332
Analog reading from A5: 0
Analog reading from A6: 0
Analog reading from A7: 0

That's because I pull A2-A4 down with 10K resistors. But A1 has same 10K resistor, yet I always get 1023 reading on that pin for some reason :frowning:

So it looks like
intended actual
A0 A1 (pulled low)
A1 A0 (pulled high)
A2 A7 (floating)
A3 A6 (floating)
A4 A5 (floating)
A5 A4 (pulled low)
A6 A3 (pulled low)
A7 A2 (pulled low)

I am not sure what to manipulate in pins_arduino.h to fix that
Sketch-wise, you could read the pin where you know something is now as a workaround.

:smiley: I think so...
And when I connect PhotoResistor to physical A1 I get reading:
Analog reading from A0: 615 (or varies depending on how much light I get).

I will try using other analog ports instead to see if I can find one that will work and redesign my PCB based on that. Thanks!

You don't need to redesign - just read from different port names.
Eventually we'll get the mapping corrected in pins_arduino.h, or wherever it needs to be.
I have it right in bobiuno pins file, we can take that and flip it end for end or something.

CrossRoads:
You don't need to redesign - just read from different port names.
Eventually we'll get the mapping corrected in pins_arduino.h, or wherever it needs to be.
I have it right in bobiuno pins file, we can take that and flip it end for end or something.

Sorry not sure I understand :cold_sweat:
I connected photoresistor to A1 and tried reading from all 8 ports and it only responds to A0. But I already have digital temperature sensor connected A0(physical) ... So I have 2 physical ports, but both correspond to same port in pins definitions :slight_smile:

Try replacing your pins_arduino.h with this one.

Ah - what you said just sunk in.
Yes, you can't use a pin as both a digital pin and an analog pin at the same time. That mapping needs to be fixed.

So what I think is that the pins_arduino.h you are using needs some adjustment in the lines similar to these:
Bobuino pinout (DIP)

// ATMEL ATMEGA1284P on Bobuino
//
//                       +---\/---+
//           (D 4) PB0 1 |        | 40 PA0 (D 21) AI 7
//           (D 5) PB1 2 |        | 39 PA1 (D 20) AI 6
//      INT2 (D 6) PB2 3 |        | 38 PA2 (D 19) AI 5
//       PWM (D 7) PB3 4 |        | 37 PA3 (D 18) AI 4
//   PWM/SS (D 10) PB4 5 |        | 36 PA4 (D 17) AI 3
//     MOSI (D 11) PB5 6 |        | 35 PA5 (D 16) AI 2
// PWM/MISO (D 12) PB6 7 |        | 34 PA6 (D 15) AI 1
//  PWM/SCK (D 13) PB7 8 |        | 33 PA7 (D 14) AI 0
//                 RST 9 |        | 32 AREF
//                VCC 10 |        | 31 GND 
//                GND 11 |        | 30 AVCC
//              XTAL2 12 |        | 29 PC7 (D 29) 
//              XTAL1 13 |        | 28 PC6 (D 28) 
//      RX0 (D 0) PD0 14 |        | 27 PC5 (D 27) TDI
//      TX0 (D 1) PD1 15 |        | 26 PC4 (D 26) TDO
// INT0 RX1 (D 2) PD2 16 |        | 25 PC3 (D 25) TMS
// INT1 TX1 (D 3) PD3 17 |        | 24 PC2 (D 24) TCK
//     PWM (D 30) PD4 18 |        | 23 PC1 (D 23) SDA
//      PWM (D 8) PD5 19 |        | 22 PC0 (D 22) SCL
//      PWM (D 9) PD6 20 |        | 21 PD7 (D 31) PWM
//                       +--------+
//

and the start of the pin mapping code

#define NUM_DIGITAL_PINS            32
#define NUM_ANALOG_INPUTS           8
#define analogInputToDigitalPin(p)  ((p < NUM_ANALOG_INPUTS) ? 21 - (p) : -1)

extern const uint8_t digital_pin_to_pcint[NUM_DIGITAL_PINS];
extern const uint16_t __pcmsk[];
// comment next line to solve SPI problem?
//extern const uint8_t digital_pin_to_timer_PGM[NUM_DIGITAL_PINS];  

#define ifpin(p,what,ifnot)	    (((p) >= 0 && (p) < NUM_DIGITAL_PINS) ? (what) : (ifnot))
#define digitalPinHasPWM(p)         ifpin(p,pgm_read_byte(digital_pin_to_timer_PGM + (p)) != NOT_ON_TIMER,1==0)

#define digitalPinToAnalogPin(p)    ( (p) >= 14 && (p) <= 21 ? (p) - 14 : -1 )
// #define analogPinToChannel(p)	    ( (p) < NUM_ANALOG_INPUTS ? NUM_ANALOG_INPUTS - (p) : -1 )
#define analogPinToChannel(p)       ( (p) < NUM_ANALOG_INPUTS ? (NUM_ANALOG_INPUTS-1) - (p) : -1 ) // test to see if A0-A7 are off by 1

pins_arduino.h (6.26 KB)

Try writing a program that simply reads out the pin#'s to see how they come out,

for( int i=0; i<=7; i++)  Serial.println( analogInputToDigitalPin(i) );
Serial.println( A0 );
for( int i=0; i<=7; i++)  Serial.println( analogInputToDigitalPin(A0+i) );

CrossRoads:
Try replacing your pins_arduino.h with this one.

That did it (replacing pins_arduino.h)! A1 now works, but everything else is broken :slight_smile: It's ok I'll try to mix and match pin defintions from both pins_arduino.h files.

Ain't software fun?

CrossRoads:
Ain't software fun?

LOL, yeah, but as messed up as it is, I'm relieved that my hardware design wasn't culprit :smiley:
If I can't figure out this pin definition plan be would be to try uploading Mighty Optiboot Bootloader instead of Sanguino, and hope that my program will work with it :slight_smile: