Problem with analogRead

Hello everyone, I am having problems in analog reading. I use Arduino Uno. I want to analog read the voltage I supply with pin 9(pwm) through A0. I either read 5V or 0V. Could you help?

const int LED = 9;
const int sensor = A0;
int fade = 5;
int brightness = 0;
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  analogWrite(LED, brightness);
  brightness += fade;
  if (brightness <= 0 or brightness >= 255){
    fade = -fade;
  }
  // read the input on analog pin 0:
  int sensorValue = analogRead(sensor);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  Serial.println(voltage);
  delay(100);```


For brightness between 0-123, the serial monitor prints 0V, and for brightness between 123-255V, serial monitor prints 5V. I can't get the volts between 0V and 5V printed in serial monitor even though the brightness of my LED fades and increases continually.

The easier you make it to read and copy the code the more likely it is that you will get help

Please follow the advice given in the link below when posting code , use code tags and post the code here

What is connected to A0 ?

What kind of Arduino are you using? You cannot use analogWrite() on pin A1 on Uno for example.

@ulas_pac, your topic has been moved to a more suitable section of the forum.

You can, but it won't work quite how you expect.

It looks like your objective is to take an analog input on pin A1 and convert it to a PWM output on pin 5. So you want to map an analog input of 0 to 1023 to a PWM output of 0 to 255 to control the brightness of a LED. Would that be your objective? That would look a little like this:

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  // map pump speed percent of full scale
  percentValue = map (outputValue, 0, 255, 0, 100);
  // change the analog out value:
  analogWrite(pwmOutPin, outputValue);

  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(sensorValue);
  Serial.print("\t Speed Output = ");
  Serial.print(outputValue);
  Serial.print("\t Motor Speed Percentage = ");
  Serial.println(percentValue);

That is the basic idea and from something I wrote for a pump using PWM for pump speed. It uses the MAP function.

Ron

I am sorry, I am new to the forum, that's why I neglected to explain appropriately. I am using Arduino Uno, and I changed the code above, could you take a look at it again?

Don't do that again.

I think what @TheMemberFormerlyKnownAsAWOL meant to say is, "Please post the modified code, complete, in a new post. That's because if you edit the code in a previous post, the replies following it no longer make sense for someone trying to follow the thread."

Yeah, what he ^^^ said, but more menacing.

1 Like

analogWrite does not 'write' an analog signal. It 'writes' a PWM signal which is an alternating HIGH/LOW (for values that are not 0 or 255). So you will never see anything different from 0 or 1023 when using analogRead.

I will not change the code again, it makes sense that people who want to follow the forum won't be able to follow.

I am confused. So, I thought that when I use a PWM signal, I change the potential difference created on a certain pin between 0-5V. But you say that it alternates between HIGH/LOW which explains why I only get either 5V or 0V. Would having analogWrite through one of the analog pins work? Is there any way I could create fluctuating potential difference and read it? Thanks.

It can also make a person look like an idiot he talking about grass that got clipped under his feet.

Just sayin'.

a7

You are trying to take an analog reading from a signal that is only 0, or 5V, and the time the 5V exists varies, from 1/255 of 2mS up to 254/255 of the 2mS. (well, 1/488 seconds, which is close to 2mS).

If you after varying voltage level, you need an RC lowpass filter on the output, that will smooth the pulses into more of a DC level.
You can try a 1K to 10K resistor followed by a 1uF to 10uF capacitor to Gnd, and take the reading at the junction of the R and C.
Here is 10K and 4.7uF result for example, with analogWrite() from 0, 25, 50, 75, 100, 125, 150, 175, 200, 250, and then back to 0.


If you are driving an LED with the DC level, I would put the RC in parallel like this
LED-filtered-DC

Correct

Not on Uno. On Uno, and most other types of basic Arduino, the Analog pins are not able to output either a PWM (alternating HIGH/LOW) signal or a true analog output voltage.

Yes, by making a low-pass filter circuit connected to the PWM output of an Uno or other types of basic Arduino. Also, for more advanced types of Arduino, like Due or Zero, these have a true analog output pin, which is connected to their built-in Digital To Analog (DAC) converter.

1 Like

@ulas_pac: Read carefully what @PaulRB has just written - it is spot on!

Do you understand it fully?

To make it absolutely clear: if you want to create a smoothly varying signal, and then read it back into your Arduino, you need a low-pass filter on the PWM output, and connect the OUTPUT of the low-pass filter back to one of the analog inputs.

image