Using analog pin to read encoder signals

Hi,

I'm using Arduino UNO R3 and i've run out of digital pins for my robot, so i've no choice but to use the analog pins for the motor encoders.

I'm using the following guide: https://www.arduino.cc/en/Tutorial/AnalogInputPins

This is the code that i will be using:

pinMode(A0, INPUT_PULLUP);

I've enabled the pull up resistor, but that's because i read during my research that when reading the motor encoder signal, it's better to use the pull up to avoid leaving the pin floating.

But there is a warning on that page:

Be aware however that turning on a pull-up will affect the values reported by analogRead().

  1. I want to know how exactly will the values be affected? It's not mentioned on that page.
  2. Is it better and will the situation be remedied if i use INPUT instead of INPUT_PULLUP?

If you're using an encoder, then you will be using digitalRead, not analogRead. An encoder is a digital device.

So you don't care how it affects the analogRead.

Delta_G:
If you're using an encoder, then you will be using digitalRead, not analogRead. An encoder is a digital device.

So you don't care how it affects the analogRead.

But what if i ran out of digital pins? Is there no possible solution? I was hoping that the analog pins could be used instead? I want to stick to the Arduino UNO as i already soldered parts onto a PCB and plugged it on top of the UNO as a custom shield. If i were to change to a bigger board, like the MEGA, i would need to trash my shield. :frowning:

I am also using a NOKIA 5510 SPI LCD with the Adafruit library. But i don't think that i can just swap any of the digital pins to analog pins on the UNO... If that was possible, then i could have the encoder connected to digital pins.

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

// Software SPI (slower updates, more flexible pin options):
// pin 7 - Serial clock out (SCLK)
// pin 6 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);

// Hardware SPI (faster, but must use certain hardware pins):
// SCK is LCD serial clock (SCLK) - this is pin 13 on Arduino Uno
// MOSI is LCD DIN - this is pin 11 on an Arduino Uno
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
// Adafruit_PCD8544 display = Adafruit_PCD8544(5, 4, 3);
// Note with hardware SPI MISO and SS pins aren't used but will still be read
// and written to during SPI transfer.  Be careful sharing these pins!

Analogue pins are just normal digital pins, with the added functionality of analogue-in.

pinMode (A0, INPUT_PULLUP); // is correct if the switche(s) are between pin and ground

switchValue = digitalRead(A0); // is also correct

Leo..

Wawa:
Analogue pins are just normal digital pins, with the added functionality of analogue-in.

pinMode (A0, INPUT_PULLUP); // is correct if the switche(s) are between pin and ground

switchValue = digitalRead(A0); // is also correct

Leo..

Thanks for the clarification. :slight_smile:

From the page: https://www.arduino.cc/en/Tutorial/AnalogInputPins

The ATmega datasheet also cautions against switching analog pins in close temporal proximity to making A/D readings (analogRead) on other analog pins. This can cause electrical noise and introduce jitter in the analog system. It may be desirable, after manipulating analog pins (in digital mode), to add a short delay before using analogRead() to read other analog pins.

So, i will connect one motor encoder to A0 and the other encoder to A2. I will keep A1 free in between to avoid the electrical noise mentioned in the article.

So are you using a mix of analogueRead and digitalRead on pins A0-A5.
It seems you can ignore that warning if you only digitalRead those pins.
Leo..

Wawa:
So are you using a mix of analogueRead and digitalRead on pins A0-A5.
It seems you can ignore that warning if you only digitalRead those pins.
Leo..

I have A5 connected to a voltage divider to read the voltage from the battery and display it on the LCD. So, the pin A5 is connected to an analog signal. But A0 and A2 will get digital signals from both motor encoders. Do i need to change the analog pin setup for more stable/reliable readings?

pin A5 is connected to an analog signal

Avoid using pinMode(A5,INPUT_PULLUP).

jremington:
Avoid using pinMode(A5,INPUT_PULLUP).

Do you mean, avoid using INPUT_PULLUP in favour of INPUT? Or, avoid using A5 and use another analog pin instead to reduce noise?

I'll try again.

If you intend to use A5 as an analog input, DO NOT include the following statement in your program:

pinMode(A5, INPUT_PULLUP);

jremington:
I'll try again.

If you intend to use A5 as an analog input, DO NOT include the following statement in your program:

pinMode(A5, INPUT_PULLUP);

Could you please explain why? Is that a limitation on Arduino UNO? Normally, i have to define the pin as either input or output... I'm sorry, i'm a bit confused about what you mean.

Here's a pretty good discussion of pinMode(). https://www.baldengineer.com/when-to-use-arduinos-pinmode-and-why.html

It explains why pinMode() is not required for analog input. The Arduino reference page for pinMode() actually lists pinMode() under a heading called Digital I/O which is separate from Analog I/O.

If you do use pinMode() for a pin which you later use for analogRead(), and you use INPUT_PULLUP the internal resistor connected to 5V and the pin will influence the analog reading you get. The connection to the internal resistor is not "automagically" disconnected by analogRead().

The only reason I can see to NOT use pull up on that pin is because it could influece battery measurements.
Especially if a series resistor or voltage divider is used.

AFAIK not a problem to use pull up on an analogue pin if for example you measure light with an LDR.
My day/night sensor uses pull up on the analogue pin and an LDR between pin and ground.
Leo..

Could you please explain why? Is that a limitation on Arduino UNO?

No not a limitation of anything, it is just how it works.

Let’s keep this simple because the OP is failing quite spectacularly to understand something very simple here.

Any use of pin marked as an analogue input but used as a digital input should have the pull up resistors enabled and not use any external pull down resistor.

Any use of pin marked as an analogue input and used as an analogue input should not have the pull up resistors enabled. In fact you should not be calling pinMode on them at all.

OK,

Grumpy_Mike:
No not a limitation of anything, it is just how it works.

Let’s keep this simple because the OP is failing quite spectacularly to understand something very simple here.

Any use of pin marked as an analogue input but used as a digital input should have the pull up resistors enabled and not use any external pull down resistor.

Any use of pin marked as an analogue input and used as an analogue input should not have the pull up resistors enabled. In fact you should not be calling pinMode on them at all.

There are some conflicting information from my research and this thread, but i think i get it now.

I have a voltage divider connected to pin A5 for measuring the battery voltage, Vin.


Vout is connected to pin A5. Since, there is a pull-down resistor connected to A5, then i will omit pinMode() and actually, not even use it in my code.

For the 2 DC motor encoders, i will use pinMode(A0, INPUT_PULLUP) and pinMode(A2, INPUT_PULLUP). I will leave A1 unused to avoid close proximity which would add electrical noise.

Due to not enough digital pins on the UNO, i am thinking of using a few analog pins for my SPI LCD display and connect the motor encoders to the digital pins instead which might be better in terms of accurate readings, but i'm not sure if connecting the LCD pins via software SPI will work for analog pins - it does work for any digital pins using the Adafruit library.

I will leave A1 unused to avoid close proximity which would add electrical noise.

Absolutely not necessary. You completely misunderstood the blurb you posted that led you to that conclusion. It was talking about close proximity in time. And it was only talking about taking analog readings.

Due to not enough digital pins on the UNO, i am thinking of using analog pins for my SPI LCD display and connect the motor encoders to the digital pins instead which might be better in terms of accurate readings, but i'm not sure if connecting the SPI via software SPI will work for analog pins - it does work for digital pins using the Adafruit library.

That would be foolish. Those digital pins that also have analog function are NO DIFFERENT from any other digital pin except that they also have the ability to connect to the ADC. In the code you describe the pins from the encoders never will be. So just forget that those are or ever were analog able. Treat them as regular old digital pins. Don't associate the word analog with them at all. You're not using them that way. Forget that they were ever analog. Stop trying to treat them special. They're regular old digital pins until you use analogRead. How many different ways can we say this?

The arduino has a hardware SPI port. Using that will save you code space, time, effort... There is literally no reason not to use it. Slowing your code down with software SPI just because you don't understand that those pins with the A in their name are really just regular old digital pins would be incredibly foolish.

There are some conflicting information from my research and this thread,

No there is no conflicting information, only information that applies to different circumstances.

I will leave A1 unused to avoid close proximity which would add electrical noise.

You can happily use this pin you will have no problem.

and connect the motor encoders to the digital pins instead which might be better in terms of accurate readings

No there will be no effect no matter what you use. All pins are digital pins, it is just the analogue ones have extra capabilities as well, if you don’t use these they are exactly the same as those marked only as digital.

but i'm not sure if connecting the LCD pins via software SPI will work for analog pins - it does work for any digital pins using the Adafruit library.

Yes with a bit banged SPI you can use any pins. It is only if you want to use the hardware SPI do you need to use pins that are connected to the internal SPI hardware.

Thanks everyone for your patience and help. I was asking questions about the analog pins simply because i have rarely worked with them before so i didn't have a proper understanding. I also spent a long time working on a PCB which is meant to be a shield for my UNO and i already soldered a bunch of components and wires onto it. There were some shorts which damaged some parts and made me almost give up but i replaced the damaged motor driver and managed to sort it out. So, i really wanted to avoid any change in pins at this point, hence why i was considering not using hardware SPI pins for my LCD which are already taken up (unfortunately, that's my mistake) by the motor driver, and the only usable pins left were the analog ones for connecting the 2 motor encoders. I have a buzzer on one digital pin, as well as Bluetooth module on RX and TX pins, LED on 13, etc, so that's why all the digital pins are taken. But if i can find enough time, i will consider remaking the PCB and using the hardware SPI pins.

Most people make sure that the breadboard or other type of trial circuit works perfectly, before designing a PCB.

That tends to save a lot of time and effort.

jremington:
Most people make sure that the breadboard or other type of trial circuit works perfectly, before designing a PCB.

That tends to save a lot of time and effort.

And money