Multiple Analog Voltage Reading

Good afternoon

I would like to ask why this doesnt work?

I want to monitor my lightbulb if it is "ON" or "OFF" through my android device by using voltage output back to analog pin.

Here is the code.

const float referenceVolts = 5.0; const int voltagecheck0 = A0; const int voltagecheck1 = A1; const int voltagecheck2 = A2; const int voltagecheck3 = A3; const int voltagecheck4 = A4; const int voltagecheck5 = A5; float volts0 = 0.0; float volts1 = 0.0; float volts2 = 0.0; float volts3 = 0.0; float volts4 = 0.0; float volts5 = 0.0; int val0 = 0; int val1 = 0; int val2 = 0; int val3 = 0; int val4 = 0; int val5 = 0; void setup() { Serial.begin(9600); }

void loop() { val0 = analogRead(voltagecheck0); val1 = analogRead(voltagecheck1); val2 = analogRead(voltagecheck2); val3 = analogRead(voltagecheck3); val4 = analogRead(voltagecheck4); val5 = analogRead(voltagecheck5); volts0 = (val0 / 1023.0) * referenceVolts; volts1 = (val1 / 1023.0) * referenceVolts; volts2 = (val2 / 1023.0) * referenceVolts; volts3 = (val3 / 1023.0) * referenceVolts; volts4 = (val4 / 1023.0) * referenceVolts; volts5 = (val5 / 1023.0) * referenceVolts; Serial.print(volts0); Serial.println(" "); Serial.print(volts1); Serial.println(" "); Serial.print(volts2); Serial.println(" "); Serial.print(volts3); Serial.println(" "); Serial.print(volts4); Serial.println(" "); Serial.print(volts5); Serial.println(" "); delay(500); }

I would like to ask why this doesnt work?

What do you mean by “doesn’t work” ?

When doing a succession of analogRead()s it is often advised to do 2 readings of the pin and discard the first to allow the ADC to settle between reads.

When I put a regulated +5 volts to A0, all analog pins go up to 5.00-4.89 in serial monitor and when I put another voltage in A1 nothing happpens.

I can't show your the screecshot but it looks like this.

4.98 4.78 4.77 4.78 5.00 4.89 4.77 4.80

When I put a regulated +5 volts to A0

Do you leave the other analogue pins floating at an unknown voltage ?

when I put another voltage in A1 nothing happpens.

Do you mean that nothing happens or that nothing changes ?

Did you note my comment about taking 2 readings from each input ?

Does the voltage source that you are using have a common GND with the Arduino ?

I can't show your the screecshot

Select all (CTRL + A) and copy (CTRL + C) works the Serial output in Windows as does something similar on a Mac

nothing changes,

i observe it with just an arduino, without putting electronic parts, like resistor.
just uploading and watching serial monitor.

for example,

after uploading

1.89 1.45 1.63 2.01
1.67 1.63 1.44 1.88

i have a 5 volt dc adaptor and i insert the ground to GND and +5 to port A0.
4.98 4.78 4.77 4.78
5.00 4.89 4.77 4.80

if i short the GND to A0
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00

Can you please show or explain why this happen?

What can i do to get this result if i put a voltage in A0

5.00 0.00 0.00 0.00
5.00 0.00 0.00 0.00
5.00 0.00 0.00 0.00

also in A0 and A1

5.00 5.00 0.00 0.00
5.00 5.00 0.00 0.00
5.00 5.00 0.00 0.00

thanks!

What can i do to get this result if i put a voltage in A0

Hold the input to the other inputs LOW.

Have you implemented double reading yet to stabilize the inputs ?

I'm sorry what do you mean by double reading? is it a pull down resistor? and also what do you mean hold the inputs to low? A pulldown resistor or a code like pinMode(A0, LOW)? I'm sorry but I can't understand some of the terms.

Double reading: val0 = analogRead(voltagecheck0); val0 = analogRead(voltagecheck0); val1 = analogRead(voltagecheck1); val1 = analogRead(voltagecheck1); val2 = analogRead(voltagecheck2); val2 = analogRead(voltagecheck2); val3 = analogRead(voltagecheck3); val3 = analogRead(voltagecheck3); val4 = analogRead(voltagecheck4); val4 = analogRead(voltagecheck4); val5 = analogRead(voltagecheck5); val5 = analogRead(voltagecheck5);

If the inputs are not connected to anything, the readings will return somewhat random values between 0 and 1023. You can make them stable by adding a 10K to 100K resistor from each pin to either Ground (for 0) or 5V (for 1023). You can also use the internal pullup to 5V by adding this in setup: pinMode (A0, INPUT_PULLUP); for each analog pin. If you leave them unconnected, the act like little antennas and the readings react to electrical fields in the air, and it doesn't take much to affect them.

UKHeliBob: When doing a succession of analogRead()s it is often advised to do 2 readings of the pin and discard the first to allow the ADC to settle between reads.

I don't know where this nonsense comes from, and would love to see some objective proof that such a "problem" actually exists. I've certainly never seen any such behavior in ANY of the dozens of MCUs I've worked with over the last 30+ years, including Arduinos....

Unless whatever you're trying to read has an insanely high impedance (which will preclude EVER getting a correct reading), there is no reason whatsoever to read an input twice. The A/D is perfectly capable of switching inputs, and getting a good reading on the first try. It would be pretty darned useless if it were not.

Regards, Ray L.

I don't know where this nonsense comes from,

I do not know whether it is true or not, hence the cautious tone of my original reply. I believe that the theory is that there is only one DAC shared between inputs, hence the need for a settling period when reading successive pins. This, of course, could be an urban myth

RayLivingston:
I don’t know where this nonsense comes from, and would love to see some objective proof that such a “problem” actually exists.

It’s not a proof, but there is a comment and commented line in analogRead

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

a double read after channel switch would fix that problem.

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

#if defined(analogPinToChannel)
#if defined(__AVR_ATmega32U4__)
	if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#endif
	pin = analogPinToChannel(pin);
#elif 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
#else
	if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif

#if 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)
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
	ADMUX = (analog_reference << 4) | (pin & 0x07);
#else
	ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif
#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;
}

It would be nice to provide actual facts, rather than repeating speculation and rumor that likely originated with people who didn't know what they were doing. From the '328 data sheet:

The ADC is optimized for analog signals with an output impedance of approximately 10 k or less. If such a source is used, the sampling time will be negligible. If a source with higher impedance is used, the sampling time will depend on how long time the source needs to charge the S/H capacitor, with can vary widely. The user is recommended to only use low impedance sources with slowly varying signals, since this minimizes the required charge transfer to the S/H capacitor.

As I suggested, slow acquisition is almost entirely a function of the external hardware, NOT a characteristic of the A/D itself. Exactly this type of hardware has been used on thousands of different MCUs for literally decades, and it would be pretty much the kiss of death for any MCU to be incapable of reliably changing input channels on every conversion. And, from a purely technical standpoint, there is absolutely no justification for such a restriction, short of appallingly inept design of the on-chip A/D circuitry.

Regards, Ray L.

Hello, im putting 100k resistors on every port to ground as pulldown and putting 5 volts switch to it from my diffirent external voltage and all the ground voltage to arduino GND. Is this correct?

Hello, thank you for the replies. and it seems ok now. the pull up and pull down works.