Fini McGlinchey – analogRead() Challenge

This question comes from Fini McGlinchey:

  • Arduino Course for Absolute Beginners, 2nd Edition
    • The Bread and Butter of Microcontrollers: Using Input and Output (IO)
      • Challenge #2: Add an LED to this circuit and do your best writing a program that uses the analog input from the potentiometer and then outputs that data to a digital pin using PWM (aka analogWrite()) on the pin you attach the LED.

Question

I wrote the program and then re-read the question. You introduced analogWrite in the question. My code does not have that. The LED does dim but it does not seem to be. -Fini McGlinchey

Code

//sketch using potentiaometer to demonstrate analogRead using the ADC
//analog pin where the sensor is attached
byte green = A0;

void setup() {
// set up the baud rate in bits per second
Serial.begin(9600);
pinMode (green, OUTPUT);
}

void loop() {
// take a reading of your analog pin and assign it to a variable
int sensorValue = analogRead(green);
//send value to Serial Port.
Serial.print ("Sensor Value = ");
Serial.println(sensorValue);

//Delay for ADC recovery
delay(1);

}

Your Challenge

Consider how you might use analogRead() to send information to analogWrite()

Solution

//sketch using potentiometer to demonstrate analogRead using the ADC
//analog pin where the sensor is attached
const byte pot = A0;
const byte LED_dim = 9;

void setup() {
// set up the baud rate in bits per second
Serial.begin(9600);
pinMode (pot, INPUT);
}

void loop() {
// take a reading of your analog pin and assign it to a variable
int sensorValue = analogRead(pot);

//send value to Serial Port.
Serial.print("Sensor Value = ");
Serial.println(sensorValue);

analogWrite(LED_dim, sensorValue);
//Delay for ADC recovery
delay(1);

}

Your Thoughts

These challenges can be a bear sometimes! Getting stuck is definitely part of the learning process. What have you been stuck on lately?

17 Comments

  1. Robert Gast on May 7, 2020 at 6:09 pm

    Where is the range of analogRead on pin A0 converted to the appropriate range (0 to 255) on the analogWrite pin 9? I wrote sensorValue/4 as the argument for analogWrite on pin 9. I also tried the conversion using sensorValue = map(sensorValue, 0, 1023, 0, 255), just before the analogWrite statement. Both worked. I don’t understand where this conversion occurs in the example code above.

    • Michael Cheich on May 7, 2020 at 6:44 pm

      Hi Robert – in this case we don’t do the conversion using the Map function, we just pass the raw analogRead value to analogWrite.

      The reason it still kind of works, is because if analogWrite gets a a number larger than 255, it rolls over. So if analogWrite gets a value of say 900, it will roll over several times and end up at 153.

  2. Anthony lopez on May 29, 2020 at 6:50 pm

    I got the same results, roll over. It did dim but the dim had several roll over as I adjusted the Pot ctrl. In ascending or descending.

  3. Mike Carvill on August 29, 2020 at 12:50 am

    Hi
    I have used map to convert from 1023 to 255 but I also wanted to use map again to convert 1023 to 5 in the same sketch but couldn’t see a way to use multiple map functions. Refer Sketch below. Enjoying the course BTW.

    Regards
    Mike

    int potPin = A0;
    int val = analogRead(potPin);

    int ledPin = 3;

    void setup() {
    pinMode(potPin, INPUT);
    Serial.begin(9600);
    pinMode (ledPin, OUTPUT);
    }

    void loop() {
    val = analogRead(potPin);//Read value from pot
    int val1 = map(val,0,1023,0,255);//Convert from 0-1023 to 0-255 for led
    analogWrite (ledPin, val1);//Apply reading from pot to led

    Serial.print( “Volts = “);
    Serial.print(val * 0.00488 );/*Convert pot value taking into account slope
    M=(Y2-Y1)=5/1023 = 0.00488
    (X2-X1)*/

    Serial.print (” led Brightness = “);
    Serial.println(val1 );

    }

    • Michael Cheich on August 29, 2020 at 5:26 pm

      Hi Mike – great question!

      Not sure if I will answer this exactly correct or not, but you can use the map function multiple times in the same code.

      For example you could have…

      int val_First = analogRead(A0);
      int val_Second = analogRead(A1);

      int mapped_First = map(val_First,0,1023,0,255);
      int mapped_Second = map(val_First,0,1023,0,20);

      Does that make sense?

      Side note, the map() function acts a little peculiarly when you convert to smaller number like 5.

      I *think* this dives into the issue a bit: https://academy.programmingelectronics.com/decimal-points-with-map/

      I hope this helps some!

  4. Alex Code on September 19, 2020 at 2:26 pm

    I really enjoyed this lesson challenge, made a few mistakes and learned some valuable lessons, I used the “Kit on a Shield” that you offered to write this code

    // This sketch is to learn how to use the Potentiometre and analogRead function
    // Always declare your global variables up front.
    byte pot1 = A0; // Setting the Potentiometre input pin, or could have used Pin #14, chose “byte” as value is between 0 & 255 using only 1 bite of memory.
    byte waitTime = 100; // Setting up delay time
    byte led1 = 6; //Setting Pin 6 for LED that is PWM

    // Start of Setup
    void setup() {
    Serial.begin(9600); // Setting baud rate for monitor
    pinMode(A0, INPUT); // as all pins default to input mood, not necessary to declare just good habit.
    pinMode (led1, INPUT); // Setting the PWM pin as an input for led1
    }// End of Setup

    // Start of Loop
    void loop() {

    int potValue = analogRead(pot1); // Giving Potentiometer value a name, as well as reading it’s input and since will be greater then 255, used “int” data type

    // Sending value to serial port
    Serial.print(“Potentiometer Value = “);
    Serial.println(potValue);
    analogWrite(led1, potValue); // Setting up led1 to change in brightness with increase/decrease in potentiometer output
    delay(waitTime); // Delay for ADC recovery
    }// End of Loop

    • Michael Cheich on September 19, 2020 at 3:23 pm

      Nice work alex!

  5. Var Wrick on September 21, 2020 at 6:23 pm

    Hey Michael: I tried the challenge before I saw this video, and with some struggling, got it to work, here is what I learned. I remembered that the PWM function was only 8 bits, so I scaled the output of the ADC to get a relevant value for analogWrite [in your code it would be : analogWrite(led_dim, sensorValue*255/1023)]. That seemed like it should work, only I found the same up/down brightness behavior that you discussed above. I thought about it for a while and then used println of the scaled value to see what was going on. I finally realized that at high voltage settings with the potentiometer, I was exceeding the max value of an integer (sensorValue*255) before the division by “1023” in the scaling takes place. The fix here is to change from “int” to “long” when defining sensorValue and then the scaling works fine. Regards, Var

  6. Al Moore on December 10, 2020 at 8:11 pm

    My 1st approach was to just take the results of the sensorValue variable and divide by 4 to get the mapping to an ledBrightness variable .

    /int sensorValue = analogRead(sensorPin);
    byte ledBrightness = sensorValue / 4; //0 to 1023 divided by 4 = 0 to 255
    analogWrite(ledPin, ledBrightness);

    I then used map() with same results.

    • Michael Cheich on December 11, 2020 at 6:55 pm

      I love that first approach!

  7. Rafael A Riquelme Cabrera on May 5, 2022 at 7:15 pm

    I had no idea what I was doing in the challenge. I just followed the example of how to use map() in the Arduino IDE reference page, used it with what I already had sketched and, lo and behold, it worked just fine. It was like being in a battle, throwing an axe and killing the enemy with the blunt force of the axe handle.

    byte sensorPin = A0;
    byte ledPin = 6;

    void setup() {

    Serial.begin(9600);

    pinMode(sensorPin, INPUT);

    pinMode(ledPin, OUTPUT);

    }

    void loop() {

    int sensorValue = analogRead(sensorPin);

    sensorValue = map(sensorValue, 0, 1023, 0, 255);

    analogWrite(ledPin, sensorValue);

    Serial.print(“Sensor Value = “);
    Serial.println(sensorValue);

    delay(2);

    }

    I must say, though, that when I saw that LED dimming it felt to the non-technical me as if I had suddenly built a rocket for Mars. I really savor every step of the way.

    • Michael Cheich on May 5, 2022 at 8:27 pm

      Nice!

    • Michael Cheich on May 5, 2022 at 8:31 pm

      Nice! Sometimes these challenges are pretty tough, but I hope through doing it, it helped you understand some of the code more.

  8. Carl Lemieux on December 6, 2022 at 5:01 pm

    Here’s my program. I’m thankful it worked but I forgot to use pinMode for the led. Was it necessary?
    Thanks!

    //A program to demonstrate the Analog to Digital Convertor (ADC)
    //The analog pin where the sensor is attached
    byte sensorPin = A0;
    // the LED which varies in brightness
    int ledPin=11;
    void setup() {
    //Set the baud rate in bits per second
    Serial.begin(9600);

    }
    void loop() {
    //Take a reading from the analog pin and assign it to a variable.
    int sensorValue = analogRead(sensorPin);

    //Send the SensorValue to the sensor port
    //map the sensorvalue down to 255
    sensorValue = map(sensorValue, 0, 1023, 0, 255);
    // assign the mapped value to the LED
    analogWrite(ledPin, sensorValue);

    Serial.print(“sensorValue = “);
    Serial.println(sensorValue);

    //Delay for ADC recovery
    delay(1);
    }

    • Michael Cheich on December 6, 2022 at 5:23 pm

      Great question Carl! When using analogRead(), pinMode is unnecessary.

  9. Andrew Olson on May 22, 2024 at 1:54 am

    I really enjoyed this challenge. Here’s where I ended up.

    //Using analogRead() lesson

    //The analog pin where the sensor and LED is attached.
    byte sensorPin = A0;
    byte ledPin = 6;

    void setup(){

    //Start serial coms
    Serial.begin(9600);

    }

    void loop(){

    //Take a reading from the analog pin and assign it to the sensor value.
    int sensorValue = analogRead(sensorPin);

    //Map the input to brightness for the LED
    byte brightness = map(sensorValue, 0, 1023, 0, 255);

    //Convert the analog read to % for Serial
    byte brightnessPercent = map(sensorValue, 0, 1023, 0, 100);

    //Send PWM duty cycle to LED
    analogWrite(ledPin, brightness);

    //Send the values to the Serial Port.
    Serial.print(“Sensor Value = “);
    Serial.print(sensorValue);
    Serial.print(” Brightness = “);
    Serial.print(brightnessPercent);
    //Avg volts based on duty cycle (5 / 1023 = 0.00488)
    Serial.print(“% Avg Volts = “);
    Serial.println(sensorValue * 0.00488);

    //Delay for ADC recovery
    delay(1);

    }

    • Michael Cheich on May 24, 2024 at 1:27 pm

      Nice!!!

Leave a Comment