Measuring rotational speed variation

I have an application where I need to measure RPM, and also measure the variations in speed during each revolution.

The rotating shaft will accelerate during half of the rotation, then decelerate during the other half. I need to determine the angle at which the switchover happens.

I'm using an AS5048A absolute angle encoder (outputs PWM or SPI), so I can take multiple angle samples during each rotation, and if I could be sure about the timing between samples, I could determine the angle at which the rotation stops accelerating and begins to decelerate.

My question, though, is how to get a timing counter that is not interrupted when I take the samples? I need to take at least 120 samples during each rotation (360 would be better), and the shaft RPM will vary from 1 to 2400.

Seems to me there's 2 ways to approach this: At each degree of rotation, note the time; or, at fixed time intervals, note the angle. Then I can compare successive results to determine whether the shaft is accelerating or decelerating. Not sure which approach would be better.

I'd greatly appreciate some guidance to cut down of the number of dead ends I pursue during the inevitable trial & error phase of this project.

Thanks in advance,

Dave

The most important detail, that you omitted, was how many encoder steps per revolution. The second most important was your code. How are you reading the encoder? using interrupts is best.

Use the encoder library. Make sure you use interrupt pins (2 and 3 on the UNO). Then you can try out either method. Time-based will be easier but since you need the angle, it might be better to be linked to the encoder steps.

Datasheet says 12400 updates/second, but how fast can Arduino read and process data from SPI? At that rate you could do 360 samples per rev up to about 2000 RPM.
At top of page, click the snapshot3.png icon and type “AS5048A”.

Ah, OK. Then the encoder library is not relevant. Disregard.

Paul & Morgan:

Thanks for your replies.

The encoder I'm using isn't a pulse type encoder. It is an absolute position encoder. That is, it returns the angle relative to its zero position, so I can't use interrupts or the encoder library.

My real question is how do I ensure accurate time measurements between angle measurements. The time intervals will be very short. I've never done anything where time measurements are critical, so I'm not familiar with things like whether processing other parts of a sketch interferes with time measurements.

I've not posted any code because I haven't written any yet. The purpose of my question was to see if someone could point me in the right direction, so I don't try a method that doesn't work when there's a better method.

Thanks for your help.

Dave

Edgemoron:

Thanks for your reply. You hit on my issue: how fast can the Arduino process the sensor information, and can it accurately measure time between updates, or will the process of reading the sensor throw off the timing? I don't know enough about how the timers work to know if what I want to do is possible.

What I need to find is the angle at which the shaft switches from accelerating to decelerating (DSwitchAngle), and vice versa (ASwitchAngle). The basic logic is:

OldSpeed = 0
OldAngle = 0
OldAccelerate = 0

Loop:
Angle = (read from sensor)
Time = millis()
Speed = (angle-OldAngle)/(Time-OldTime)
If Speed > OldSpeed
Accelerate = 1
Else
Accelerate = 0
If Accelerate != OldAccelerate
If Accelerate = 0
DSwitchAngle = Angle
Else
ASwitchAngle = Angle

OldAccelerate = Accelerate
OldSpeed = Speed
OldAngle = Angle

A tricky part I haven't figured out yet is how to reset everything each revolution, but before I tackle that problem I want to have some assurance that I'm not proceeding down an impossible path, or that I'm not missing a much easier or better way to do this.

Canadave:
The encoder I'm using isn't a pulse type encoder. It is an absolute position encoder. That is, it returns the angle relative to its zero position, so I can't use interrupts or the encoder library.

I don't think that encoder is suitable for what you want to do.

With a simple pulse type encoder and 120 pulses per revolution then at 40 rps (2400 RPM) you would need 4800 pulses per second or 1 pulse every 208 microsecs. (At 360 pulses per revolution the interval would fall to about 70µsecs which would probably be a challenge for a 16MHz Arduino.)

I don't think you could do anything that fast using SPI.

With a simple pulse encoder the Arduino can measure the time between pulses and figure out the RPM from that.

...R

That is, it returns the angle relative to its zero position

But how? SPI? I2C? Serial?

Canadave:
My question, though, is how to get a timing counter that is not interrupted when I take the samples? I need to take at least 120 samples during each rotation (360 would be better), and the shaft RPM will vary from 1 to 2400.

So you want to sample 360 times in 25ms (the 2400rpm case), which is 14.4kHz sample rate. Hard, possibly
doable, but hard.

But the main issue is you are using a non-linear rotary encoder to measure rotation linearity - not going to
work very well. This sort of encoder has a phase error of +/- about a degree and the phase error undulates
round the circle 4 times due to the magnetic field distortions, in a manner that is different for each magnet,
depends on accuracy of sensor placement, and varies with temperature.

The way I'd imagine performing this measurement is get a high resolution quadrature encoder, perform
frequency->voltage conversion, and measure the voltage. You'd need several ranges of conversion for
various speeds I think, and might well want that absolute encoder to reference the readings to the
phase of the shaft.

Thanks all. I may have to look at using a different encoder. The reason I chose this one is it is magnetic, and therefore introduces almost no friction or inertia. That’s important for this application.

As I mentioned in my original post, this encoder outputs both SPI and PWM. I don’t think PWM would be helpful here, as my understanding is that it takes longer to get each reading.

Regarding the processing speed issue: I do have an Arduino Due available. Would that help?

MarkT: Thanks for raising the linearity issue. I hadn’t appreciated that. I’ll look into that further.

To get a better understanding of what I’m doing: I’m trying to build an anemometer that can measure wind speed and direction without a separate wind vane. It does this by adding a tab to one of the cups. The cup with the tab has a larger surface area, so it is pushed faster downwind, then goes slower upwind. By determining the angle at which it switches from accelerating to decelerating, you determine the wind direction. The attached photo gives you an idea of what it looks like.

Rotovecta.png

Use an optical encoding disk rotating within a slotted optical switch.

If you have an extra optical detector and an extra mark on the disk so you tell when a revolution completes it will probably make it easier to assess the direction as it will give you a point of reference. I guess you could probably achieve the same thing by having one long gap among the encoder lines and use only one detector.

...R