analogRead Problems

Hello all,

I'm having difficulty comparing voltage readings over time using an Arduino UNO Rev 3.

Using analogRead on a analog pin to measure RPM with a rotating disc and optical sensor. When a solid part of the disc passes through the optical sensor, the voltage from the sensor should read 0. Otherwise, it should read a positive value based upon a voltage draw (I got 7mV before my computer said it was drawing too much current). Whenever the voltage rises, "counts" should increment by 1. Unfortunately, the counts vary wildly with time (sometimes it was in the hundreds), so I decided to try to perform counts in intervals, but I was getting random counts when nothing was in between the emitter and sensor on the optical sensor.

I suspected that the voltage readings were very sensitive to small voltage changes, thus, it would fluctuate crazily and give me "counts" as every rising value. Using Serial.print(analogRead(analogPin)) returns a integer value (based upon 5V/1023 increments as I understand it). But when I store the analogRead(analogPin) as a variable, it gives me all the crazy counts. I'm suspecting that Serial.print(analogRead(analogPin)) does not give me the real variable value that's stored... am I correct? And if so, what is the best method of getting an RPM reading.

In addition, I tried using attachInterrupt with the "RISING" parameter, but it wasn't sensitive enough since the voltage changed by a small number of milli-volts.

I attached a basic circuit diagram and below is my code (I'm sorry if it's really amateurish; I just started playing with Arduinos and barely know the syntax):

//This program uses a optical sensor and rotating disc with
//gear shapes cut out to measure RPM as the disc rotates.

//Variable to measure time
unsigned long time1 = 0;
unsigned long time2 = 0;

//Variable to store RPM
unsigned long rpm = 0;
//Variable for number of rises in voltage for a given time
int counts = 0;
//Set variable for pin for voltage reading
int analogPin = 0;
//Initialize variable to store value of voltage
unsigned long v = 0;
unsigned long voltage = 0;
unsigned long voltage1 = 0;
unsigned long voltage2 = 0;
//Set variable for time between RPM calculations
unsigned long RPMperiod = 500000;
unsigned long samplePeriod = 100000;
//Number of slots cut into the disc
int slots = 8;

void setup() {
Serial.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly:
time1 = micros();

voltage1 = analogRead(analogPin);
if ((voltage1 - voltage2) > 4.5 && (voltage1 >= 0) && (voltage2 >= 0)){
//Serial.println(voltage1);
//Serial.println(voltage2);
counts++;
voltage2 = voltage1;
}
else if (voltage1 < voltage2){
voltage2 = voltage1;
}

if ((time1-time2) > RPMperiod){
time2 = time1;
Serial.print("Voltage:");
Serial.print("\t");
voltage = analogRead(analogPin);
Serial.print(voltage);
Serial.print("\t");
Serial.print("Count:");
Serial.print("\t");
Serial.print(counts);
Serial.print("\t");
Serial.print("RPM:");
Serial.print("\t");
rpm = counts*60000000/slots/RPMperiod;
Serial.print(rpm);
Serial.print("\n");
counts = 0;
}
}

The output from your device is 0 or 5 volts so why are you using analog input?

I suspect you have wired the optical sensor incorrectly. Make a pencil drawing of your circuit and post a photo of it. Also provide a link to the datasheet for the optical sensor.

The sensor I have works perfectly well with digital I/O.

...R

I'm using analog because I'm getting a residual voltage reading even when I grounded the breadboard to the Arduino and I have something blocking the emitter or sensor completely. It's to negate any interference so I can still have two voltage readings to compare rather than one pin always being HIGH for an unknown reason if I used digital.

I attached a png file to my original post. I'll attach it again with the optical sensor datasheet.

OPB852-OPB853.PDF (200 KB)

Your schematic shows PNP phototransistor, but data sheet says NPN. Change /swap emmiter - collector, +5V should go to collector. Where you put resistor only invert the logic, and not really matter

Hi
Is the gnd of the circuit you posted connected to the gnd of the arduino?

What is the application, there should not be any "residual" voltage with 1k5 resistor to gnd.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

Tom...... :slight_smile:

Yes, the ground of the circuit is connected to the grid of the Arduino.

It appears that the Arduino measures a different voltage from the emitter side of the NPN sensor than my DMM. It's reading between 19 and 24 mV instead of the 7.9 mV from my DMM. I checked the reading with other known voltages (such as the 5V coming out of the board) and it reads fine. I'm quite confused.

I attached my circuit diagram in my previous post. As "Magician" noted, it's an NPN sensor, not a PNP sensor as indicated on the drawing.

analog pin 0?

Surely you mean A1 or the like?

//Set variable for pin for voltage reading
int analogPin = 0;

Should be:

//Set variable for pin for voltage reading
int analogPin = A0;

pinMode(analogPin,INPUT);

As far as the rest of your code...I have no idea why there are 2 voltage readings whne you only have one incoming?

Surely just measuring the analog pin and if it is greater than say 100, increment count by 1.

Ideally, youd have 2 of these sensors so the increment only occurs when the gap in the disk has passed 2 sensors to avoid "bouncing".

Sorry to carry on but also spotted another potential issue:

Also the LED in that sensor is 1.7V forward with a rating of 20mA.

This gives a resistor value of 180Ohm.

Your 400Ohm may be too much resistance to fully turn on the transistor in the first place.

(5-1.7)/20E-3
http://led.linear1.org/1led.wiz

Hi,

It's reading between 19 and 24 mV instead of the 7.9 mV from my DMM.

How do you know the arduino is measuring between 19 and 24mV?
The value you get when you use the analog input is not directly read as volts.

What volts do you measure with the DMM on the analog pin.
A when the LED is shining on the transistor. and what is the arduino's analog input reading.
B when the LED is obstructed from shining on the transistor and what is the arduino's analog input reading.

Tom.... :slight_smile:

Johnny010:
//Set variable for pin for voltage reading
int analogPin = 0;

There is nothing wrong with doing this, your comments are rubbish.