Quadrature Encoder Square Wave

I am trying to read the signal from a Quad Encoder to accurately determine the speed of a shaft spinning inside it.

I saw @jpearman reading the square wave signal from a Quad Encoder using ConVEX (thread: https://vexforum.com/t/how-fast-can-a-quad-encoder-detect-movement/29408/1). I tried to install ConVEX with PROS to do the same, but PROS runs on Atom now, so ConVEX did not work for me. I will now try to install ConVEX independent of PROS, but in the meantime, are there any other ways that I can read a Quad Encoder Signal?

If you’re already using PROS, can’t you just use encoderInit to identify the encoder and then later use encoderGet as needed? It’s worked fine for us.

If you’re just trying to get the values independently yourself to run your own math, can you not just use digitalRead on each of the two ports separately? We didn’t do that, but I don’t see why it would be a problem if you need to go beyond what encoderGet allows.

If the shaft is really spinning that fast, wouldn’t you want to measure on a shaft spinning more slowly? The motor itself isn’t spinning ridiculously fast, so if you’re having trouble with something spinning fast I would assume you’ve geared it to spin faster. But that means you have other shafts that are not spinning nearly as quickly which could be read and then converted.

I don’t think that I was very clear in what I wanted to read from the encoder. I am trying to estimate velocity by measuring the time between two consecutive edges on the Encoder output signal. Do I have access to those encoder edges on the cortex?

If you rapidly read the digital ports, you can find the edges. You can’t really directly read the edges, though. They don’t exist in that sense because you’re just looking at high or low. What the edges are is moment between reading high and reading low or between reading low and reading high. So if you use digitalRead repetitively on one of the ports and record the prior value, you’ll know when it switches from high to low or from low to high. When one of those switches occurs, record the time. Two recorded times will give you a pretty good estimate of the time between edges.

Yea, there’s really no need to do it this way and without using interrupts your chance of getting accurate measurements is pretty low.
Just take the current encoder count every 20mS (as an example, depending on your application a longer time may be better) and calculate velocity based on that.

This may help
https://vexforum.com/t/how-to-calculate-motor-flywheel-velocity-in-robotc/32336/1

Ok, thanks for the reply.

I already calculate velocity by finding the slope between two encoder values at different times, and I was just wondering if there was a more accurate way. How did you track the encoder edges through an oscilloscope?

An oscilloscope allows viewing the changing voltage of a signal over time. To capture those oscilloscope traces I was probing the white wires on the two encoder connections to the cortex. That’s independent of any software that may be running, the reason for doing it in the thread you linked was to determine maximum velocity it would be possible to run the encoder at and still be able to detect the edges.
What are you trying to achieve ? Flywheel velocity measurement or something else ?

I am trying to accurately determine the velocity that a motor is running at. I have heard that using square waves can more accurately determine the velocity read by an encoder.

Try converting this pseudo code to pros


wait for an encoder input to go low by reading digital input
note time in microseconds ( micros() function )
wait for an encoder input to go high by reading digital input
note time in microseconds ( micros() function )
take difference between the two times, convert to rpm

There are issues with this type of approach, if another task runs at the wrong point (ie. between polling the input and calling micros(), the time measurement will be inaccurate. It’s an inefficient use of the cpu to keep polling a digital input, while you are doing this other code will not be running.

A better approach would be to use interrupts, there is a ioSetInterrupt function in PROS, set a handler that triggers on both edges and use a similar technique. I don’t know if you can configure digital inputs to use an interrupt handler as well as configuring it as an encoder.

Thanks, I will try. Is there a way to do this in RobotC? It’s what I currently use.

Also, is there any way to get ConVEX with PROS now, even though it is run through Atom?

PROS is not ‘run through Atom’ – PROS instead operates completely independently of Atom.

Atom (technically a variant thereof) has merely been adopted as the official editor for PROS; it has no effect on PROS’ functionality and is not required to use PROS.

The only thing Atom does is run PROS CLI commands, as can be done from the OS command line and by virtually any decent modern IDE.

Ok, thanks. Does this mean that I can run ConVEX through PROS?

Theoretically it should still be possible to run ConVEX through PROS.

The first two paragraphs of this should still apply (although it should probably say ChibiOS_2.6.2 instead of ChibiOS_2.6.0).

Don’t bother with the Eclipse plugin.

I believe this constitutes the default/demo project.

Thanks. I will tinker around with ConVEX to see what I can do.

Also, is there any way to do this (below) on RobotC?

There’s not any easy way to do that in ROBOTC as it does not have uS timer available. I don’t remember if I had uS timer available as part of the API in ConVEX but it looks like PROS does. Obviously you could hook a uS timer up to the exiting encoder interrupts in ConVEX pretty easily, have a look at the sonar code, that already does something similar.

Yes, that’s what I had suggested, though less precisely than you, doing in PROS. It can check the ports individually and rapidly and the timer well. But there is still that whole issue of other things being done at the same time.

Is there any sample code out there for task interrupts (preferably on RobotC or PROS)?

[

](https://pros.cs.purdue.edu/cortex/api/index.html#iosetinterrupt)
[

](https://pros.cs.purdue.edu/cortex/api/index.html#ioclearinterrupt)