faulty readings from analogread

I am using a potentiometer-type position sensor. I have set up a voltage division circuit, and the voltage differential from the sensor to ground currently reads about 2V on a multimeter.

However, when I read it at pin 9 with the following code, it reports 1023, which should indicate 5V or more.

I am using a brand-new Ruggeduino, but had the same problem with an Uno.

`` V0=analogRead(9);
Serial.print(V0);


Any ideas what I am doing wrong?

Thanks!

philraf:
Any ideas what I am doing wrong?

There is no Analog Input pin called 9. There are usually six analog inputs numbered 0 to 5.

Doh.

I was confusing the PWM capability with ability to read analog inputs.

Is there any way to get more than 6 analog inputs?

Thx

philraf:
Doh.

I was confusing the PWM capability with ability to read analog inputs.

Is there any way to get more than 6 analog inputs?

Thx

Why? Did you run out of analog inputs? Use Arduino MEGA with 16 inputs. Otherwise you need an analog multiplexer chip.

Yes, I ideally need 7 or 8 analog inputs (pressure transducers, position sensor). I had read something about multiplexing, but it looks too complicated for now. I will get by with 6 at first, and then look into it. If you have any suggestions on a good chip/program package for newbies, I'd appreciate it.

Also, do you know if I can use Uno shields on the Mega, or would I have to start from scratch?

Many thanks for your quick response last night!

Phil

Phil,

Many UNO shields still work with MEGA. It depends on the shield so you will need to post links to shields you have.

Not all the sensors have an analog output, for example DHT11 uses digital communication. Many other uses I2C, and something uses also SPI.
You can save some analog pins choosing different types of sensors :wink:

philraf:
Yes, I ideally need 7 or 8 analog inputs (pressure transducers, position sensor). I had read something about multiplexing, but it looks too complicated for now. I will get by with 6 at first, and then look into it. If you have any suggestions on a good chip/program package for newbies, I'd appreciate it.

Pro minis usually have 8 analog inputs: arduino pro mini for sale | eBay

(the surface mount version of the Mega328 has 4 more pins than the one in the Uno... they just connect them up)

Pro Minis are compatible with the Arduino Uno. If you're going to build a gadget you can put one of those in it.

Pro Mini's are also smaller and cheaper, but don't have a USB interface, you'd need
a USB->serial converter of some sort.

Only the surface mount versions of the ATmega328 bring out the A6 and A7 pins,
note, which is why they are not standard on most Arduinos.

Another option for lots of analog inputs is to use an analog multiplexor chip
to route your signals to one Arduino analog input - several digital outputs are
used to set the multiplexer source.

I solved my problem, by replacing statements like:

V1 = AnalogRead(A1)*5/1023

with

R1 = AnalogRead(A1)
V1 = R1*5/1023

... but I don't understand why the first statement doesn't work.

Any ideas?

Is r1 float or int?

philraf:
I solved my problem, by replacing statements like:

V1 = AnalogRead(A1)*5/1023

with

R1 = AnalogRead(A1)
V1 = R1*5/1023

... but I don't understand why the first statement doesn't work.

Any ideas?

You're using integers so the compiler does integer math.

I'm betting "R1" is a float in the second one.

You could also do:

V1 = float(AnalogRead(A1))*5.0/1023.0;

You could even fix your bug and do:

V1 = float(AnalogRead(A1))*5.0/1024.0;

philraf:
I solved my problem, by replacing statements like:

V1 = AnalogRead(A1)*5/1023

with

R1 = AnalogRead(A1)
V1 = R1*5/1023

... but I don't understand why the first statement doesn't work.

Any ideas?

Yes, integer division truncates, you must force the expression to float before
dividing by 1023 (actually its 1024, not 1023).

  float V1 = analogRead(A1) * 5.0 / 1024.0 ;

To be absolutely as accurate as possible the really correct way is

  float V1 = (analogRead(A1) + 0.5) * 5.0 / 1024.0 ;

Since the ADC splits the input voltage range into 1024 equal-sized voltage ranges,
adding 0.5 gives an unbiased estimate of the actual voltage. But that's probably
more accurate than the hardware can actually achieve!

Float

Thanks, MarkT.

This is what I think I have understood:

  1. It is ok to use AnalogRead() in an algebraic statement.
  2. The "native type" of a value from AnalogRead() is indeed float.
  3. However, dividing a float by an integer (a number without a decimal point) yields an integer. (Not true for multiplication, I gather?)
  4. So all I really needed to do was to replace "/1023" with "/1023.0".
  5. The other improvements are duly noted.

Did I get it right?

Thanks again ...

Phil

"2) The "native type" of a value from AnalogRead() is indeed float."

Nope:
From the docs, which you should read:

Returns

int (0 to 1023)

This is the problem of not reading a book on C. If you get a book, the first couple of chapters cover the data types and conversions. Any known programming language tries to preserve accuracy when converting different types of data into the same type, when they are involved in a calculation. Your thinking is just the opposite. But when all data are in the same type, say int for analogRead(), 5, and 1024, the programming language does NOT do any conversion, so integer math applies.

Example: 100*5=500, 500/1024=0

The above is expected behavior and much of computing depends on this behavior. You having an issue with this behavior only means you should use other data type, not the behavior is wrong.