INPUT or INPUT_PULLUP

Hi,

I read a lot of explanation of the difference between the two, however I can't get to understand which one I should use in each case. My first language isn't english so it makes the comprehension of their difference hard. I'm currently programming a wheel encoder. I'm wondering, should I put the digitalRead with INPUT or INPUT_PULLUP if I use an attachmentinterrup function to count the rotation of each wheel?

Like this:

pinMode(ENCODER1, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(ENCODER1), count1, CHANGE);
  pinMode(ENCODER2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(ENCODER2), count2, CHANGE);

Thank you, Max.

It really depends on what the output of the encoder is. Is it high low or is it just connected not connected.

Last is like with a switch. It only connects the pin to something (like GND/low) when you press it. But if you don't press it there is no connection. It's not automatically the opposite, it's floating. So you pull it up (or down) with a resistor. You can do this externally or use the internal resistor of the Arduino. That's a pull up (so the pin goes high when it's not pulled low by a switch or another sensor/encoder) and you activate it with INPUT_PULLUP

Using INPUT_PULLUP is what I use 90% of the time. You can use INPUT if the external cct. already has a PULLUP.

For reference: |500x457

septillion: It really depends on what the output of the encoder is. Is it high low or is it just connected not connected.

Last is like with a switch. It only connects the pin to something (like GND/low) when you press it. But if you don't press it there is no connection. It's not automatically the opposite, it's floating. So you pull it up (or down) with a resistor. You can do this externally or use the internal resistor of the Arduino. That's a pull up (so the pin goes high when it's not pulled low by a switch or another sensor/encoder) and you activate it with INPUT_PULLUP

Okay so if I understood well, if I use a switch I have to use PULLUP. But in my case, i want to have low with a voltage around 2,8V and high with around 4V. So I should use just INPUT?

LarryD: Using INPUT_PULLUP is what I use 90% of the time. You can use INPUT if the external cct. already has a PULLUP.

For reference: |500x457

It's interesting but I'm not using a switch. (If I understood well, this example is for switch.)

I actually have an issue with my encoder, my values spike and do false count. I was wondering if maybe I should of put only INPUT instead of INPUT_PULLUP.

MaxiMax07: But in my case, i want to have low with a voltage around 2,8V and high with around 4V. So I should use just INPUT?

No arrangements of resistors alone, will allow you to get a reliable reading of that on a digital input. You need some kind of voltage level translation circuit.

Or you can sample it at an analog pin, and use some code to detect the threshold. But, that is slower.

Please show us a schematic of how the encoder is connected, and provide a link to the encoder. It's possible you have it connected wrong.

aarg: No arrangements of resistors alone, will allow you to get a reliable reading of that on a digital input. You need some kind of voltage level translation circuit.

Or you can sample it at an analog pin, and use some code to detect the threshold. But, that is slower.

Please show us a schematic of how the encoder is connected, and provide a link to the encoder. It's possible you have it connected wrong.

Well the connection of the encoder is quite simple, I plug the ground to the ground. I plug the output of the encoder to the pin 2 and 3 (the only one working with attachmentinterrupt with arduino UNO) and (this is quite sketch) I plug my 5V supply to the 11 and 12 digital pin with and HIGH signal to provide a 5V supply. I can't use the 5V pin of the arduino because it's already used by my motorshield.

As for the voltage level translation and analog pin thing, I have no idea how to do that. I don't know much in electronic. What I'm thinking is trying to isolate a maximum the encoder from the light. So the readings will be lower.

However, for the programmation part, should I stay with INPUT_PULLUP or should i switch to INPUT if I can lower my readings by blocking the light coming into the encoder.

Thank you!

The output of your device is never floating, so INPUT will work, but the major problem is that your led emitter/sensor encoder is not really a digital device.

Pay attention to reply #4.

Some of your difficulties with these encoders were covered in your earlier thread http://forum.arduino.cc/index.php?topic=382726.msg2638529#msg2638529

I would recommend that you either get external hardware like a Schmitt trigger to process the output, or change the encoders for different led pair encoders which have built in digital conversion, or change over to magnetic(Hall Sensor)encoders.

MaxiMax07: Well the connection of the encoder is quite simple, I plug the ground to the ground. I plug the output of the encoder to the pin 2 and 3 (the only one working with attachmentinterrupt with arduino UNO) and (this is quite sketch) I plug my 5V supply to the 11 and 12 digital pin with and HIGH signal to provide a 5V supply. I can't use the 5V pin of the arduino because it's already used by my motorshield.

As for the voltage level translation and analog pin thing, I have no idea how to do that. I don't know much in electronic. What I'm thinking is trying to isolate a maximum the encoder from the light. So the readings will be lower.

However, for the programmation part, should I stay with INPUT_PULLUP or should i switch to INPUT if I can lower my readings by blocking the light coming into the encoder.

Thank you!

You're welcome. I have a few questions. - is it so hard to provide link to the encoder, so we can better evaluate your solution? -you say the input goes to pin 2 and pin 3. Why two pins? -an optical encoder often has a LED. How are you limiting the current to it (actually, you act as if it doesn't exist, which is suspicious) -what is biasing the phototransistor part of your optical encoder? -are you sure that the supply current of the optical encoder has not exceeded the capacity of the Arduino pins that you have chosen to power it with? -Since your connections are unconventional (you made no mention of it until now), can you post your software and a hand drawn schematic, so we can verify that it does what it should?

Unless you provide hard data about the encoder, and answer these questions, you are wasting your time here. Instead you would be better off just playing around. But it may or may not lead to success.

I followed the link to your previous thread. Essentially you have just restarted the same questions. What a time waste. If you don't have documentation for the encoder, you can at least say so again for the benefit of those who were not aware of your previous thread. Even better, take a photo of it and upload it as an attachment.

MaxiMax07:

I plug my 5V supply to the 11 and 12 digital pin with and HIGH signal to provide a 5V supply. I can’t use the 5V pin of the arduino because it’s already used by my motorshield.

Not sure which motorshield you have. With a board like the Arduino motorshield, you can simply wire the 5V pin on that board to the encoder (like you would do if you directly connected it to the Arduino).

A wiring diagram from your side might help to see if there will be implications. E.g. if the motor is also a 5V motor, you can have interference resulting in the Arduino reading false pulses from the encoder.

You're welcome. I have a few questions.
- Is it so hard to provide link to the encoder, so we can better evaluate your solution?
-you say the input goes to pin 2 and pin 3. Why two pins?
-an optical encoder often has a LED. How are you limiting the current to it (actually, you act as if it doesn't exist, which is suspicious)
-what is biasing the phototransistor part of your optical encoder?
-are you sure that the supply current of the optical encoder has not exceeded the capacity of the Arduino pins that you have chosen to power it with?
-Since your connections are unconventional (you made no mention of it until now), can you post your software and a hand drawn schematic, so we can verify that it does what it should?

-Here’s the link.
-Two pins because I have two encoders, one for each.
-Mine doesn’t seem to have any? Well, it doesn’t emit any light at least.
-Well, this is what I’m trying to figure out, I think I have too much light coming sideways when I try to use the encoder with the robot. I’ll do further tests after my exam tomorrow.
-No, I’m not, I followed an advice from a friend who used arduino for multiple projects.
-I didn’t make any mention of it because at the start of the post (one week ago), I was trying to figure out how to make the wheel encoder work. I had only one encoder, supplied correctly to the 5V pin of the arduino and GND. A few days ago I used a ruler to block the light and it worked well. My programmation seemed good too. When I put back the arduino on the robot, I put back the motorshield on the 5V pin letting me with no supply for the encoders. My friend then told me to use another pin for supply because encoders draw so little current that it should be fine.

Also for this post, I wanted to know if I should have used INPUT or INPUT_PULLUP. I was wondering if it could bring me some issues. I wanted to do further tests on the encoder before posting again about it if it couldn’t make it work.

This is my motorshield.

Here’s the montage, I put some pictures cause I figure out it’s maybe gonna be simpler to look at since I don’t have other wires connected to the arduino than the one for the encoders. The blue ones are the output of the encoders. The red ones the supply. The black one the ground.

cattledog:
The output of your device is never floating, so INPUT will work, but the major problem is that your led emitter/sensor encoder is not really a digital device.

Pay attention to reply #4.

Some of your difficulties with these encoders were covered in your earlier thread
http://forum.arduino.cc/index.php?topic=382726.msg2638529#msg2638529

I would recommend that you either get external hardware like a Schmitt trigger to process the output, or change the encoders for different led pair encoders which have built in digital conversion, or change over to magnetic(Hall Sensor)encoders.

I look for the definition of Schmitt trigger and it looks great. However I don’t know where to buy one in Canada. I’ll try, first of all, to make it work with blocking the light coming from sideways. Maybe paint the white piece of plastic with the holes. Then testing with the resistors to drop the voltage. If nothing works or if you tell me I should just get the trigger and not messing with the resistors, I’ll go for it.

Once I had the manual and information on the encoder, it took me literally 5 minutes to solve this problem. If you had shared this less grudgingly, you would have had a solution several days ago. There is a test program in the robot book for the encoders. Here it is:

/* The code below simply counts the number of changes, so a disc with 8x white sections and 8x cutouts will provide a count of 16 per 360 degree rotation. It is up to you to integrate it with
your code*/
int rawsensorValue = 0; // variable to store the value coming from the sensor
int sensorcount0 = 0;
int sensorcount1 = 0;
long count = 0;
void setup() {
int i;
for(i=5;i<=8;i++)
pinMode(i, OUTPUT);
Serial.begin(9600);
int leftspeed = 255; //255 is maximum speed
int rightspeed = 255;
}
void loop() {
analogWrite (10,255);
digitalWrite(12,LOW);
analogWrite (11,255);
digitalWrite(13,LOW);
delay(20);
rawsensorValue = analogRead(0);
if (rawsensorValue < 600){ //Min value is 400 and max value is 800, so state chance can be done at 600.
sensorcount1 = 1;
}
else {
sensorcount1 = 0;
}
if (sensorcount1 != sensorcount0){
count ++;
}
sensorcount0 = sensorcount1;
Serial.println(count);
}

Look at how they are reading the sensor. They are using analogRead. The catalog also calls it an “Analog encoder pair for Tamiya Twin-Motor Gear Box”. All through this thread, you have been stubbornly clinging to your “but is it INPUT or INPUT_PULLUP?”. Again, if you had followed my advice in reply #4 and cattledog in #6 and done a simple code experiment, or really paid attention to the manual, you would not have wasted so much of your time. So learn to listen to people. Also don’t double post. You are fishing around with the same question in the sensors forum.

aarg:
Once I had the manual and information on the encoder, it took me literally 5 minutes to solve this problem. If you had shared this less grudgingly, you would have had a solution several days ago. There is a test program in the robot book for the encoders. Here it is:

/* The code below simply counts the number of changes, so a disc with 8x white sections and 8x cutouts will provide a count of 16 per 360 degree rotation. It is up to you to integrate it with

your code*/
int rawsensorValue = 0; // variable to store the value coming from the sensor
int sensorcount0 = 0;
int sensorcount1 = 0;
long count = 0;
void setup() {
int i;
for(i=5;i<=8;i++)
pinMode(i, OUTPUT);
Serial.begin(9600);
int leftspeed = 255; //255 is maximum speed
int rightspeed = 255;
}
void loop() {
analogWrite (10,255);
digitalWrite(12,LOW);
analogWrite (11,255);
digitalWrite(13,LOW);
delay(20);
rawsensorValue = analogRead(0);
if (rawsensorValue < 600){ //Min value is 400 and max value is 800, so state chance can be done at 600.
sensorcount1 = 1;
}
else {
sensorcount1 = 0;
}
if (sensorcount1 != sensorcount0){
count ++;
}
sensorcount0 = sensorcount1;
Serial.println(count);
}



Look at how they are reading the sensor. They are using analogRead. The catalog also calls it an "Analog encoder pair for Tamiya Twin-Motor Gear Box". All through this thread, you have been stubbornly clinging to your "but is it INPUT or INPUT_PULLUP?". Again, if you had followed my advice in reply #4 and cattledog in #6 and done a simple code experiment, or really paid attention to the manual, you would not have wasted so much of your time. So learn to listen to people. Also don't double post. You are fishing around with the same question in the sensors forum.

I already found this code. However if I understood correctly, it’s a code that I have to run constantly. I can’t make an attachmentinterrupt with it. So I can’t run this program in the background of my code.
If it can’t work with attachmentinterrupt, I’ll try to find another solution or product.

I didn’t mean to double post. I was wondering about my code and the use of INPUT or INPUT_PULLUP. I was meant to be a simple question.
The last time I was wondering about the fact that I had issues getting values less than 3V.

You can call analogRead() from an ISR, can't you? Are you implying that you are not willing to write your own code (adapt an example for your own use)? Also, you wouldn't have been wondering about the values being less than 3V if you had really read either the catalog or the manual. It would have been obvious.

It's forgivable to misunderstand the difference between an analog and digital sensor, but to exhibit denial when it is repeatedly suggested to you, is not very wise.

It amazes me that you never mentioned this code before, which clearly would answer many questions about the sensor and how it is supposed to be programmed. No wonder it took so long to get an answer. It would have allowed readers to better analyze your idea of converting the signal to digital (which is possible, but might not be necessary). Or the obvious fact that it is an analog sensor.

Also that you misled everyone (I'm being generous here) about your availability of documentation, saying, "The hard part is that sadly I don't have any documentation and I can't find any on the web :/" (other thread). What a time waste.

aarg: You can call analogRead() from an ISR, can't you? Are you implying that you are not willing to write your own code (adapt an example for your own use)? Also, you wouldn't have been wondering about the values being less than 3V if you had read either the catalog or the manual. It would have been obvious.

I might have missunderstood the attachmentinterrupt function. I tought that for the arduino UNO it worked only with the digital pin 2 and 3. The link I used.

I'm not implying I'm not willing to write my own code. All my code is made by myself from the start and it's quite hard for me since I never had another programmation course other than one with MATLAB. I have to work with my research and it takes me a hell of a time to figure out how everything is working.

I read the manuel (its the manuel of an another robot). In the manuel there was only one exemple of a simple counting with analogue. However I wanted to have attachmentinterrup and that I understood that it worked only with digital pin. Also I didn't understood the values choice (400 and 800) because from today, I never used an analogue pin still and I don't know how they are used. I didn't understood that the value couldn't go under 3V.

Look I don't want to pick a fight or I don't know. I'm just trying to learn by myself and there is a lot to do. I also have all my course and exams. I don't get everything right by the first look.

Oh, that's a valid point. You can't trigger an interrupt with an analog reading. If you must have it interrupt driven, you need to use the Schmidt trigger circuit, or some other kind of circuit. I'm just saying you should have been more forthright about everything from the start. Many people asked for clarification, which they never got. All the post space that was devoted to non-solutions could have been addressing this problem specifically. The thing is, there are many optical sensors that do have a digital output.

Well you can trigger the analog comparator interrupt, if the signal is on the right pin...

aarg: Oh, that's a valid point. You can't trigger an interrupt with an analog reading. If you must have it interrupt driven, you need to use the Schmidt trigger circuit. I'm just saying you should have been more forthright about everything from the start. Then all the post space that was devoted to non-solutions could have been addressing this problem specifically.

Yeah I know. I'm trying to narrow my post because previously people told me I was too general and that they aren't here to do my work (I agree with that statement). So I tried to narrow my post to one question with less information so I won't overflow you and that I thought that the INPUT thing was maybe one issue (and I wanted to know what would be best for my code) but I was completely wrong. I first didn't want to post the link because it was the manuel of another robot and I didn't want people to waste their time reading it for one example alone with analoguereading if I'm using a digital pin. However it was my mistake again because with that fact, you could figure out why it wasn't working like I thought it should have. I don't have much back ground in electric or informatics and I have so much information to process that I pass by some things really important.

If I post another time, I'll try to find the right middle between the two.

Thank you for your help it's really appreciated.

Maybe this question sounds dumb, but when I find my solution in a post, should I up the post by posting an update of the situation and that it's working?

Either on-chip comparator (I don't think this is exposed with helper functions - you have to fiddle with a few registers to set it up - see datasheet. You'll probably need a reference voltage too), or an external comparator (like a '339) before wiring it to an interrupt pin.

(also - you can set digital interrupts on any pin using PCINTs - but this isn't the problem you have now, and they're harder to use in some ways than INT1/INT0 (the ones you can use with attachInterrupt) - just something to be aware of in the future).

Narrowing is something you do in the process of solving a problem, not at the beginning. It does help to have some clear precepts to begin with, but you have to be flexible and open to advice. When someone specifically asks for information, you can assume there is a good reason for it. Withholding it because you think it might not bear on the problem is really not “team playing”.

There are two good posts about the analog comparator, question is just whether it will work on two pins. The LM339 comparator would be configured with positive feedback, essentially becoming a Schmidt trigger.

You could also set up a periodic analog read on the ports, with a timer. Probably too much trouble, and slow.

MarkT: Well you can trigger the analog comparator interrupt, if the signal is on the right pin...

I made a small research and it seems quite hard to use. If i understood correctly, I should put a reference voltage to one pin. Than I could compare the voltage coming from my encoders to this pin and launch an ISR if it's below or higher?

DrAzzy: Either on-chip comparator (I don't think this is exposed with helper functions - you have to fiddle with a few registers to set it up - see datasheet. You'll probably need a reference voltage too), or an external comparator (like a '339) before wiring it to an interrupt pin.

(also - you can set digital interrupts on any pin using PCINTs - but this isn't the problem you have now, and they're harder to use in some ways than INT1/INT0 (the ones you can use with attachInterrupt) - just something to be aware of in the future).

I didn't understood the first part, you are talking about the Schmidtt Trigger?