ATMega328P PINC vs analogRead for A6 & A7

Hello ,

I'm facing difficulties to perform analogic read operation using PINC on an Arduino mini pro equivalent.

I'm doing analog reading without any issue for ports 0 to 5 through code like PINC & B00100000 (port 5) but for analog port 6 PINC & B01000000 or port 7 PINC & B10000000 it doesn't work when a analogRead(A6 or A7) works !

Would you see a reason for this behavior ?

Yes, A6 & A7 are analog input only. They connect internally only to the ADC multiplexer. They have no digital circuit behind them like the other analog pins do. You can't use digitalRead() or PINC with them.

It is not an "analog reading', with PINC you can read a digital pin level (LOW / HIGH) only

Thank you b707,

let's be more precise, my code does the following from, A0 to A6

while(!(PINC & B00000001)); port A0

PORTD |= B00100000;

delayMicroseconds(100);

PORTD &= B11011111;

until

while(!(PINC & B00100000)); port A5

PORTD |= B00100000;

delayMicroseconds(100);

PORTD &= B11011111;

while(!(PINC & B01000000)); port A6

PORTD |= B00100000;

delayMicroseconds(100);

PORTD &= B11011111;

All PINC are working as expected except A6 (or A7) and same code with a analogRead(A6) worksTexte préformaté

Please point the line where you are reading the analog value from the pin in that code?

while(!(PINC & B01000000)); port A6

And where is? Arduino analog value has a range from 0 to 1023. Where do you reading something like it? And after reading, where are you store the readied value?
The expression inside the while condition in the given line can outputs 0 or 1 ONLY.

Your code has nothing to do with reading the analog signal

We keep trying to tell you that A6 & A7 will only respond to an analogue read. They will not respond to a digital read, in any way shape or form.
The results you are getting are correct, it is your expectations that are wrong.

so let's forget what the code aims at performing :grinning:

why this code while(!(PINC & B01000000)); ends up in infinite loop (the signal goes from 0 to 500mv) when while(!(analogRead(A6))); doesn't ?

Because that is the way the ATmega328 processor is made. It has no connections inside it between anything digital for those two pins, but does for an analogue read .

How many people do you want to tell you the same thing before you believe it?

Because PINC & B01000000 will never be true

Thank you Grumpy_Mike

I guess I don't understand the answer you guys provided despite the repetition.

According to your answers, PINC should not work for A6 or A7 but this is not what this link is saying https://docs.arduino.cc/hacking/software/PortManipulation

PORTC maps to Arduino analog pins 0 to 5. Pins 6 & 7 are only accessible on the Arduino Mini

DDRC - The Port C Data Direction Register - read/write

PORTC - The Port C Data Register - read/write

PINC - The Port C Input Pins Register - read only

One more time!
Arduino analogRead() function has nothing to do with PINC register.
Below is the source code of the function:

int analogRead(uint8_t pin)
{
	uint8_t low, high;

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
	if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega32U4__)
	if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
	if (pin >= 24) pin -= 24; // allow for channel or pin numbers
#elif defined(analogPinToChannel) && (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__))
	pin = analogPinToChannel(pin);
#else
	if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif
	
#if defined(__AVR_ATmega32U4__)
	pin = analogPinToChannel(pin);
	ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#elif defined(ADCSRB) && defined(MUX5)
	// the MUX5 bit of ADCSRB selects whether we're reading from channels
	// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
	ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#endif
  
	// set the analog reference (high two bits of ADMUX) and select the
	// channel (low 4 bits).  this also sets ADLAR (left-adjust result)
	// to 0 (the default).
#if defined(ADMUX)
	ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif

	// without a delay, we seem to read from the wrong channel
	//delay(1);

#if defined(ADCSRA) && defined(ADCL)
	// start the conversion
	sbi(ADCSRA, ADSC);

	// ADSC is cleared when the conversion finishes
	while (bit_is_set(ADCSRA, ADSC));

	// we have to read ADCL first; doing so locks both ADCL
	// and ADCH until ADCH is read.  reading ADCL second would
	// cause the results of each conversion to be discarded,
	// as ADCL and ADCH would be locked when it completed.
	low  = ADCL;
	high = ADCH;
#else
	// we dont have an ADC, return 0
	low  = 0;
	high = 0;
#endif

	// combine the two bytes
	return (high << 8) | low;
}

There is NO PINC reference in the code. NOWHERE!

I think you are misunderstanding the information in that link.

It is saying that you can only get access to A6 and A7 on a pro mini, it does not say that the access will include getting a digital signal on A6 & A7.

The access to A6 & A7 is possible because the size of the processor package (number of pins it has not physical size) allows the extra inputs to the A/D converter to be tracked out to pins on the side of that board.

If you want the definitive information you need to look into the data sheet of the ATmega 328 chip itself.

1.1.9 ADC7:6 (TQFP and QFN/MLF Package Only)

In the TQFP and QFN/MLF package, ADC7:6 serve as analog inputs to the A/D converter. These pins are powered from the analog supply and serve as 10-bit ADC channels.

They do not mention these pins being available as digital outputs / inputs.

Thank you again Grump_Mike,
I guess I got confused by this link about port manipulation mentioning port 6 and 7 in a chapter about PINC

If you look at the pinout diagrams in the ATmega328P datasheet you will find that no pin is labeled PC7 (Bit 7 of PORTC) and the pin labeled PC6 is the Reset pin, not the ADC6 pin.

You can use PC6 as a data pin only if you set the fuse to disable the Reset function. After that, you can't reprogram the chip without a High Voltage Serial Programmer or High Voltage Parallel Programmer

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.