arduino quadrature encoder
Now all the examples you’re going to see in this video we’ll be using the Arduino, but really you could use any microcontroller, so let’s let’s get started now. I’M. Not going to really get into the details of the pros and cons between using a rotary encoder and a potentiometer because I’m, assuming that, if you’re watching this video you’ve already made that decision, but real quick, rotary, encoder, just spins forever. Okay gives you incremental position, feedback, meaning you don’t actually know exactly where it is it’s, not absolute. It only gives you the position of where you were previously so in relation to where you were previously, which is why it’s called an incremental encoder and it provides digital data to the microcontroller. You can think of it like digital, but it’s, really not like, like a serial protocol, communication type digital signal and we’ll get into that a little bit more it’s, very easy to use. As soon as you understand what it’s outputting. This will all make sense. The one I’m using here is from Sparkfun I’ll, put a link down below to this actual encoder, just in case you want to follow along, but I probably shouldn’t have them plug that. While I had power on but uh anyway. Let me get this back in there. Real quick, hopefully it still works okay anyway, little delay, alright, so anyways. Basically, let me show you another thing: real, quick. If I could get it up, let’s see if it still works, no, it doesn’t.
I have a. I have a program running on the computer here that I want to show you in processing. Okay, as I rotate the encoder, the line on the screen will rotate at the exact angle. Is the encoder okay, so kind of cool anyways I’ll get into some of that code too? But let’s start talking about how this thing works, how you wire it up and etc? Alright, so I can get this out of the way. So basically, when you look on the website – and I didn’t think I was going to actually have to get into this, but when you go and look at the datasheet, they show a few wiring diagrams on how to hook this up. Basically, this encoder is kind of cool too, because it has a bicolor LED and a switch. But when you push it in it actually it’s like a little tactile switch but anyways I’m not going to get into that I’m. Going to assume that you know how to wire up an LED in a switch, so the other three pins on the other side are a C and B like that. Okay and they actually recommend you. You tie you put a 10k ohm resistor. Here you get a 10k ohm resistor here you tie both of these to 5 volts off your microcontroller and then basically the encoder itself is like little switches here where you have a switch here and a switch here, and then this would be your a signal, and This would be your B signal that you would wire up to, and then these would both be wired to this is pin C, but this would be wired up to your common pin on your Arduino or ground okay.
So, basically, what your output B and a will either be either pulled up high or when the switch here is closed internally to the encoder. It pulls that signal to ground. Now, who knows what is actually happening here? I don’t know these specifics of what’s inside that encoder, but for now, we’ll just assume it’s, either high alone, so go ahead and wire that up and you’ll find it does not work. Didn’T work in my case or it works very poorly. So if you keep reading on in the datasheet you’ll see that they talk a little bit about bounce on the the circuit and a little bit of noise. So they recommend you still have this 10k ohm here. But then you wire up another 10k ohm here and then a capacitor here that you also tie the ground and then the same thing over here, which is also tied to ground. This is a 10k ohm, now I’m, not labeling these capacitors. Yet, for reason this would be your a wire then, and this would be your B wire or your B signal. Now they recommend using 0.01 micro farad’s, which is a 102 cap. I tried that works a little better, still, not great. So I decided to use point 1 micro, farad capacitors on both sides: micro farad, capacitors that’s, a 104 package 104, and it works great, so that’s how I actually wired it up and that’s what this circuit is up here, it’s the 210 case with the point 1 Micro farad it’s, going to ground okay, so that’s how you wire it up, but now you need to understand what these signals are a and B and what what do they mean? How do you work with them? So for this this is probably the most important part.
We got to draw some waveforms, okay, so let’s terrible at drawing waveforms let’s make this here a this is your a signal which could either be put just make a big a so when you look at it, this could either be five volts or zero volts or Tied to ground right, we showed that from the last drawing it could be either of these two things. So, as you move through time, if, as you rotate, the encoder you’ll notice that the a signal global go from high to low and then this just repeats I’m only showing one period of this or one single pulse. So, as you rotate it, you know the period of this. This a pulse will occur faster or longer over time, so I mean right now, it’s stopped it could be either at five volts or zero volts. I don’t know it depends on where you left it. So, as you rotate it you’ll get these pulses and the the datasheet actually says you get twenty four of these pulses per revolution per Rev. Sometimes you see this as PPR or just P P. R. That doesn’t matter, but what’s funny is, is that this P, P R value kind of is misleading because it makes you think that you’re only getting 24 pulses. Total of resolution per single rotation and that’s not true and I’ll, get into that in a little bit. But if you just look at a signal, you know one channel of the encoder, which is a you, will get 24 of these rises.
Okay, you’ll get 24 times, it’ll be up to 5 volts. If that makes sense, you know because over time this just it looks like a big square wave, you know and you get 24 of those in one revolution, so that’s the a signal. But you know, if you think about that, maybe you could use that for position, but it really doesn’t give you a lot of information if you don’t know which way you’re rotating the knob, which is why we have a second channel. You know because if we rotate it forward, the a signal is falling and rising right. If you rotate it backwards, we’re just moving this way now, it’s still just falling and rising, so it doesn’t give you any perspective direction. You could use the a signal just for velocity feedback if you wanted to just speed feedback, you can measure these pulses and it would give you some speed, but still, you would not know direction, which is important, so the B signal what they do with this. Is it is let’s see if I can draw this up? The B signal is exactly ninety degrees. Out of phase with the a signal and again this is only going from zero volts to five volts. So this this starts to get a little confusing here, but not really it’s, just a square wave that’s, exactly 90 degrees out of phase with a so again. At any point time, if you measure this B, pin or signal from you know two with reference to ground, it will be either high or low.
But now that we have two of these signals here, we can actually start to figure out which direction we’re going in just based on the trigger events, all right so let’s, say you’re you’re, looking at all of these signals and let’s at any given point in time. As you’re rotating it only one of these signals either A or B will actually change States. You know you’re not going to get an a change and a B change at the same time, so let’s see as you’re rotating it a signals. High B signal is low, so you’re rotating it one way. Now, all of a sudden, you get a change on your B signal B signal goes from zero to high, while a is high. That means you’re rotating it forward. We know that we’ll put that in the code you continue to rotate on the a signal Falls. While the B signal is still high. That means we’re rotating forward. Okay and you just keep going through it and then all of a sudden, you get a change in the B signal from high to low, while the a signal is still low. That means we’re moving forward, so you code all this into your code, so that you understand exactly which direction is so you have all these different states that it could be in and depending on which event happens, and what the other signal is at. You can determine direction because if you move the other way now, you know B signals.
Lo, a signal is low. You get a change in the state from the B signal from low to high, while the a signal is still low. That means you’re moving, Reverse so it’s the same exact thing. You know you just keep going through it. You either you just move in time now you don’t have to get so hung up on, which is a and B. This could easily just be B na up here. It doesn’t matter, you know, and if you’re configure or you’re confused about how you’re going to wire this thing up it that still doesn’t matter, you could have your a and B signal completely backwards. As long as this algorithm that you write in your code is true that these states are always here – and you know, some people call this like gray code, where you have a 1 0, then 1, 1. 1. 0. You know you just go through it as different states, but I prefer to do it just on these events. You know my a signal falls. Is my B state hi? Yes, that means we’re moving forward, all right, so kind of try to put that into the ROM of your brain. For now, because when we go to the code we’re going to have to use this this exact graph – and hopefully I can pull one up on a datasheet, so we can kind of go back and forth all right now I want to talk about this 24 pulses Per revolution let’s see we can, since we have two signals and we have all of these different changes of states.
We can actually increase that revolute or that resolution a little bit right, because we have the a signal can go. If you just count here, you basically have one two, three, four states that this thing can happen, so there’s going to be four events in a single period. You know right because we’re going to assume for now that this is the first event. This would be a arise in a that’s, a one pulse, okay, so that’s one that tells us something has moved when when you went when you get that first, a rise, then you get your second event. When the B signal Rises now we’re at to keep moving. As you keep rotating, the a signal Falls that’s. Your third event keep going. The B signal then Falls that’s your fourth event, and then you keep going on and it repeats. So what you actually get is twenty four times four events, basically we’re going to call home. Whatever you want to call these, these four changes of state, which gives you an effective resolution of 96 pulses, if you just measure, pulses and that’s what we’re going to measure it’s, either a pulse high or pulse low, okay, so so you’re going to notice. Is that as we rotate it we’re actually going to get 96 because we’re going to count each one of these events as a change in state as a pulse and we’ll count those up. So as you move the knob full 360, you get 96 pulses.
Sometimes they call these encoders quadrature because of this okay so anyway, that is basically how this whole thing works. We’Re going to wire up the a and B signals, as I show in that circuit, into the interrupts of the Arduino, because you want to catch these very quickly. You know if you, if you miss one, then you don’t know when you’re going to lose your your actual resolution, so let’s shoot over now to decode all right guys. So let’s take a quick look at the code here. We’Ll go through it line by line make sure we cover everything in here. I may even go into the processing code here, a little bit. I kind of just fumble my way through processing so I’m, not really an expert there. I usually just copy code out of other projects. You know this kind of gives you this effect with the the line kind of going around. I might cover that oops want to run it again. I also have a nice little thing here in the code to show this the actual position of the encoder in the serial monitor here and just to verify. As you do rotate it. You know 360 degrees. You do get 96 counts. Okay and we’ll go over that a little bit and how that all works, so let’s go through the code. Here we start off. We initialize few variables. No big deal we’ll cover what these do in a sec.
In the setup we attach the interrupts interrupts. Zero is digital pin to interrupt one is digital pin, 3 and we’re going to trigger the a rise subroutine and the B rise subroutine off the rising edge of both of those. For now. This is just to get things rolling. Okay, because the as you’ll see the code is sort of interlocked together, this is just to catch the initial start of everything. Okay, so then we start up the the serial monitor no big deal. The loop actually does nothing in this. We do all of everything we need to get position: feedback from that encoder in the interrupts. Okay, so let’s let’s walk through this and by the way I I couldn’t. I couldn’t find a good diagram of this, so I took a picture of my whiteboard, so you’ll have to bear with me on that. So let’s uh let’s talk about this a little bit and we we have the at interrupts, triggering the rising event of either the a signal or the B signal. So let’s start at point: zero and just walk through the code as if we’re rotating through this okay. So right now, we’re at zero let’s say that the encoder is sitting at zero zero, which would be somewhere out here or basically right here, because this thing does repeat itself, so it would be right around here: zero zero. So we start rotating it through and we hit this point right here.
The a signal goes from a zero state to a rising state and, like I showed here that does trigger and interrupts, and you know who cares, which is which a wire or B wire you can always switch the wires on your board. But for now let’s just say that that is the a wire okay, so we get the we trigger the a rise subroutine here. The first thing we do is detach the interrupt on that pin and I’ll get to why this is important in a second, we make the a signal which is just a variable. We change its value to a 1, so that’s only going to be from a 0 to a 1 or go back to 0, no big deal there and then we do a little bit of a figure. This is the Direction detection part of the code. So if you look here, we check and see if the B signal is at 0 or if the B signal is at 1. So if you look here right, we’re right at this point here, we just changed state from a 0 to of 1, so meaning we’re going this way and that’s all about change in time. So this time versus this time, what changed the a signal? 1, from a 0 to a 1 or a 0 to 5 volts, the a the B signal sits there at 0 volts. So if you look here, if B signal is 0, that means we’re moving forward so increment the pulses by 1.
If the B signal is 1, then that means so the a single one from a 0 to 1, while the B signal was a 1 that would have meant we’re going this way right change in time from this time. To this time, the a signal 1 from a 0 to a 1, while the B signal was high, that would have meant moving in Reverse and then we do a serial dot print of the pulses and then attach the reattach the interrupt. But this time we trigger it on a falling edge and we trigger the a false subroutine, which is another separate subroutine here, and the reason I do this is very important. You I think, in the code and in my opinion this is the only way to do it, or that makes sense. Is that if you miss a pulse, if you simply just do the, if you simply just do a change in state from either high to low or low to high, you have to trust your code that you’ll catch each pulse. If you miss a pulse and you don’t detect it, then you’ll there’s a good chance that your counts will actually switch directions on you. What you don’t want that’s last thing: you want the worst thing that could happen in my code here is that you’ll miss a pulse and you’ll miss some resolution, that’s it because you’ll catch it on the next pulse, then alright, so anyways. This make a little bit more sense as we go so now I mean we just we know we’re not going to rise again.
Basically is what I’m saying you know. We went from a 0 to 1 there’s. Nowhere to go but down you know once you hit 5 volts, if mean, if suddenly you do start rotating at the other direction, it will fall in the same way over here. So you once you’re up on on the actual pulse. It will fall so it makes sense to just reinitialize the interrupts on a falling edge. Ok, so anyways let’s continue walking through it. So now we went from a 0 to 1, while the B signal was low. We keep rotating it forward. All the sudden, we get a change in state on the B signal from 0 to 1. Ok, so if we go down to the code here, I actually we, if you remember, we attached the interrupts to a B rise here, so we go down here. We now change the B signal from a 0 to a 1, what we detach the interrupts, the same exact thing: we did in the a signal code and then we do the direction detection so let’s see what what happened. Here. We went from a 0 to 1, while the a signal was high, which means we’re moving forward. So if a signal is equal equal to 1, we increment the pulses if the a signal had been low. While we went from a zero to a one like right here right so if this was zero, so we went from zero to one on the B signal from this point to this point, while the a signal is low, that means we were moving in this direction.
The reverse direction so we’re rotating it the other way right. That would so we would have decremented the policies. So the same thing we do is serial dot print of the pulses, and then we reattach the interruptus time on a befall falling. So now, if we just let’s continue rotating it forward so we’re at this point here, alright, we continue rotating. All the sudden. The a signal Falls from a 5 volts to zero bolts. While the B signal is high, so let’s go to the a fall subroutine here. We D to detach the interrupts, make the a signal low or a zero. The B signal was high, which means we’re moving forward if it had been zero, meaning we fell, while the B signal was was zero. That would have meant right at this point right here. So we went from five volts to zero blows I’m, not showing it just because this this thing repeats itself. So right here, this continues out like this, so this went from five volts to zero volts, while to be signal is low. That would have been going in this direction. Reverse the other way. Okay, so of course, we then just reattach that interrupt to the rising edge again, no change there, because we know that once we’re once below it can only go up continue rotating through now. The B signal changes from a high state to a zero state. Okay, so we go to the B fall, detach the in turn up make the B signal low.
Do the direction Tet detection. So if the a signal was zero, which it is because we went from this state to this state, while the a signal was low, meaning we’re moving forward, if the a signal was high, when we went from a high to low change, that would have meant we Went from this to this, so we wouldn’t, we would have been moving in the reverse direction. From this point to this point: okay, it’s. All about your change in time. You know where you’re at in the waveform, if that makes sense. Okay, so the B Falls yeah same thing: we do the detection, the pulses, we print them out and then we reattach the inter up to a rising edge, and that is the entire code, and that will do this. I mean it just tells you the position and counts it up, and you know like if you, if you look at your initialization here, of what these a signals really doesn’t matter. Eventually, it will figure out where it’s at so it’ll kind of self balance itself. So as simple as as that, I wasn’t really going to go into the processing code, but one more thing you know about incremental encoders. You know it always starts at zero. So there’s, no you’re not getting your absolute position of of the wheel. You know, because on power down I could right now I could be spinning this a hundred times and it’s powered down as soon as you power up there’s, no way to know where the wheel is right now so it’s, all incremental from where you last were, and That’S, how it figures it out? Okay, so I wasn’t going to go into the processing code, but basically I mean this is pretty simple.
I usually just copy this code out of other projects, but you know. Basically, we get that data in that I’m printing out and we convert it into zero to 360 byte, because we know that 96 counts is equal to 360 or 48. Half of that must equal, PI or 180 degrees, so 3.14 blah blah blah, and then we do. The sine cosine of that that you know wherever that angle is and then we basically draw a line in the center of the screen with an angle at our rotational angle. So we make our setpoint equal to the sine and cosine value of that angle, basically that’s. How we do with a magnitude of the window so and then we do some color change. I’Ll put all this code up on the website and you guys can hack at it. If you want just, I mean by no means of processing expert, so anyways.
arduino quadrature encoder Video
arduino quadrature encoder news
Posted on Tuesday January 02, 2018Rotary encoder decode for Arduino Electronics WeeklyIt is amazing how many Arduino programmes for decoding rotary encoders start with something like: “I looked at all the available rotary encoder sketches an. … Continue Reading »
Posted on Thursday December 13, 2018Every Computer Deserves A Rotary Encoder HackadayIn the era of touch screens and capacitive buttons, we’d be lying if we said we didn’t have the occasional pang of nostalgia for the good old days when … … Continue Reading »
Posted on Wednesday January 11, 2017Encoders Spin Us Right Round HackadayRotary encoders are great devices. Monitoring just a few pins you can easily and quickly read in rotation and direction of a user input (as well as many other … … Continue Reading »
arduino quadrature encoder Social