Measuring Revolutions: Analog to digital conversion (Comparators?) - Page 1
Forum section: electronics / projects

author: paeion
author_rank: Contributor
timestamp: May 14, 2022, 09:25:31 am
content: I am measuring the rotation of a shaft that will go from stationary to a few hundred RPM in both directions. To do so, I am using theAS5600magnetic rotary encoder and I am trying to use the analog output to create a digital signal to hardware interrupt my MCU (polling via I2C is not fast enough to accurately detect each revolution and I don't want to hog the processor):

author: Kleinstein
author_rank: Super Contributor
timestamp: May 14, 2022, 09:56:34 am
content: A comparator with hysteresis makes sense. The LM393 is fast enough, well faster than the sensor. If good performance at low speed is needed, one may consider 2 comparators for 2 (or 4) reference points per revolution.Some µCs already include a comparator and some even incluce hysteresis. So one may be able to get away even without the external comparator.With the relatively low speed it may also be an option to use a µC internal ADC and let the µC read the analog voltage.Alternatively one could use the I2C interface for the lower speed range. The I2C part may even be fast enough up to 1000 RPM, at least if the µC supports a fast clock and there are not many other chips on the bus.Directly triggering an interrupt may not be the best solution. Many µCs offer hardware for time measuring, like an input capture function of a HW timer. This could take case of most of the job and may even include some hardware debouncing.

author: paeion
author_rank: Contributor
timestamp: May 14, 2022, 10:14:25 am
content: Thank you for your reply Kleinstein, it is reassuring to be on track!For reference I am using the ESP32 micro, which unfortunately does not have a built-in comparator (as far as I know), but does feature a usefulpulse counterfor rising/falling edges. My idea for directly triggering interrupts was to determine the rotation direction (based on the time differences between the rising/falling edges) and using a hardware timer to determine the RPM directly.My experimentation with I2C let me sample relatively quick (> 1000Hz), however I could not detect the 0<–>360° transition reliably in software. I will take on the idea of 2 comparators for low RPMs!

author: Kleinstein
author_rank: Super Contributor
timestamp: May 14, 2022, 10:52:37 am
content: When sampling at 1000 Hz or faster, one should be able to get the 0 - 360 deg. transition, at least most of the time (except for a few points near the transition). The change in angle should be limited to relativelay small angles (e.g. 6 deg. at 1000 RPM).So the 0 - 360 transition is in a way to make the change in angle smaller. For the µC program one could extend the angle by adding or subtracting 360 degree as needed to keep the steps < 180 degree. From the than extended turn angle it is easy to calculate the speed, e.g. from linear regression or just difference over a window of maybe 100 readings.Going to the comparator only makes things more complicated with getting the direction of close to a stand still and reversing the direction.

author: langwadt
author_rank: Super Contributor
timestamp: May 14, 2022, 11:45:05 am
content: Quote from: paeion on May 14, 2022, 10:14:25 amdo you need to get each transition or do you just need to keep an accurate count of the angle over multiple rations?you can add the difference between last and current angle to an angle variable and it'll be accurate as long long as you sample faster than 180deg can pass (so you can detect the wrap)

author: Zero999
author_rank: Super Contributor
timestamp: May 14, 2022, 02:23:18 pm
content: Quote from: paeion on May 14, 2022, 09:25:31 amThe LM393 has a common mode range of V+ −1.5, which is 3.5V, when run off a 5V supply which is adequate.

author: jpanhalt
author_rank: Super Contributor
timestamp: May 14, 2022, 02:42:57 pm
content: Why not just use the PWM output and forget a comparator? (attachment)

author: Zero999
author_rank: Super Contributor
timestamp: May 14, 2022, 04:42:51 pm
content: Because he wants to read the analogue voltage from the sensor. You're got it backwards.

author: Doctorandus_P
author_rank: Super Contributor
timestamp: May 14, 2022, 05:01:47 pm
content: There is no need to attempt to capture the exact transitions.Bit of back of envelope math:Assume your max speed is 600rpm, that's 10 revolutions per second.Assume you sample the I2C bus at 100Hz, so that is at least 10 captures per revolution.I think the as5600 has a 10 bit resolution (does not matter much in this example).That means the difference between two captures is never more then:1024/10 = 102That means that if the previous capture was 980, and the last capture is 23, then a revolution happened.And with a steady sample rate of 100sps this can quite easily be done in software.Or, if you want to use an analog comparator, you can never get it to reliably trigger on the exact peaks, so just set it to (approx) the center position, to trigger at around 1.6V. (for a 3.3V signal)Then, every time the comparator flips read the signal. If it's between 1V and 2V, then you're at the slope. If it's below 500mV or above 3V, then the comparator triggered on a revolution transition.There is also no need whatsoever to use a fast comparator, @600rpm = 10 revolutions per second, the comparator flips at most 20 times per second.There is a chance that your shaft is jittering right around the point your AS5600 flips between high and low. You may miss comparator flips there if you're in bad luck. You will have to add a check for this in software to make it robust.

author: jpanhalt
author_rank: Super Contributor
timestamp: May 14, 2022, 05:19:49 pm
content: Quote from: Zero999 on May 14, 2022, 04:42:51 pmThe title says: Measuring Revolutions:And what the OP proposes is, "I can easily hardware interrupt the MCU on the rising/ falling edges of the comparator to indicate a revolution." So, he is not actually reading the voltage. His plan to use a comparator to effectively converts that voltage to a PWM signal.* A lot of sensors put out both digital and PWM signals. It is really simple to capture the edges of a PWM and convert that to the scalar that is desired continuously, limited only the the sampling frequency of the device.*A very common analog way to create PWM is to generate a triangle or sawtooth wave. Then use a comparator with variable threshold.

author: Ian.M
author_rank: Super Contributor
timestamp: May 14, 2022, 05:51:33 pm
content: The sensor in question, configured for analog output, and coupled to a continuously rotating shaft, produces a sawtooth, with the direction of the fast edge determined by the direction of rotation. Differentiating it then using two comparators to detect >90% full scale high going and low going spikes could give you separate pulse outputs for each direction suitable for clocking an up/down counter with separate clock inputs. Connect that to an I2C I/O expander with IOC functionality, and you could reliably track the shaft position and accumulated rotation count even if your controller goes off into LaLa land for seconds at a time.However, as many experts above have pointed out, that would be totally unnecessary. As long as your firmware can sample the position (by whatever means) at least once every 30ms, the direction of rotation and accumulated turn count isn't ambiguous for any shaft speed under 1000 RPM.

author: Kleinstein
author_rank: Super Contributor
timestamp: May 14, 2022, 06:15:01 pm
content: The sensor has 3 ways to read the result:1) I2C , which is fast enough and the natural choice2) a PWM output with a relatively limited frequency, though still fast enough and with a suitable µC that can measure PWM with hardware support (timer with capture function) would be a good option too3) an analog output via sensor internal DAC. This signal could be read by µC internal ADC for good resolution at low speed.Reading the signal with a comparator add a difficulty when at low speed and with changes in the direction. This may need a 2nd comparator, but would still add more complications than the first 2 methods.

author: langwadt
author_rank: Super Contributor
timestamp: May 14, 2022, 09:27:59 pm
content: Quote from: Kleinstein on May 14, 2022, 06:15:01 pmI guess if you wanted to be really clever you could convert the analog to two quadrature signals using three comparators, many mcu have timers that can quadrature decoding, that would work with any speed and direction changes

author: Doctorandus_P
author_rank: Super Contributor
timestamp: May 14, 2022, 10:29:43 pm
content: There are indeed quite a lot of microcontrollers that support quadrature encoders in hardware, but if you want to use this, use another sensor that supports quadrature output directly. There are plenty of such sensors available.

author: paeion
author_rank: Contributor
timestamp: May 14, 2022, 10:31:20 pm
content: A lot to read overnightI'll try give my reasoning for moving away from the I2C approach (which I agree is easiest as that is what I started with). The aim is to measure the power produced by the shaft, which can be done by calculating the changes in RPM. (P = torque x omega ... torque = Inertia x angular acceleration ... Inertia is known).Therefore, I don't care so much about the current angle state, just precisely when each revolution occurs so I can time between each 360°. I could also approach it the other way around and say every X milliseconds, obtain the number of revolutions gone past – both should work, might need to experiment which is more robust. I should note, I have tried periodically sampling the angle state via I2C and calculating the RPM that way, and it was grossly inaccurate...I am slightly concerned what happens at low RPMs, since larger timescales makes the linear interpolation very crude, but since small changes in RPM doesn't create a lot of power, it might be accurate enough. (For further reference, the shaft velocity profile will roughly be half-sinusoid).My other reason to avoid polling if I can, is because there will be a number of other things happening in the micro-controller background, so if I can avoid hogging the processor, the more juice I can squeeze out of the RTOS on the ESP32.

author: jpanhalt
author_rank: Super Contributor
timestamp: May 14, 2022, 11:30:46 pm
content: You haven't said which MCU you plan to use.Timer 1 is a type of timer in PIC's and probably other MCU's. Look up the CCP or ECCP module (CCP = compare, capture, PWM). For what you are doing the capture mode is ideal. You can use it either interrupt driven or by polling the interrupt flag. The following description is for 8-bit PIC's. Others are very similar.Basically, you let Timer1 run continuously. It can use its own time base or system clock, and there is a prescaler. With its own timebase, you can measure quite long intervals. Given a defined event (e.g, rising edge, falling edge, or alternating rising and falling edges), it captures the timestamp of each event and stores it in a 16-bit register (i.e., CCPRxH/L). You then transfer from the CCP registers to user defined registers and do the math. Unlike starting and stopping or reading on the fly, clock ticks are not missed. Resolution is limited by the clock frequency.

author: langwadt
author_rank: Super Contributor
timestamp: May 14, 2022, 11:42:11 pm
content: Quote from: paeion on May 14, 2022, 10:31:20 pmso it is only one direction? the analog signal directly into a timer input would probably work

author: paeion
author_rank: Contributor
timestamp: May 15, 2022, 12:20:04 am
content: Quote from: langwadt on May 14, 2022, 11:42:11 pmNo the shaft will switch directions when it slows down at the bottom of half-sinusoid. My thought here was that the order in which the rising/ falling edges arrive from the comparator to the MCU will determine which direction the shaft is rotating.EDIT: I realise now a full-sinusoid might better describe the velocity of the shaft...Quote from: jpanhalt on May 14, 2022, 11:30:46 pmI have mentioned that I am using theESP32MCU. Not sure it has a CCP/ ECCP module in-built, but I can setup a hardware timer for each the comparator rising/ falling edges to achive just what you are describing.

author: langwadt
author_rank: Super Contributor
timestamp: May 15, 2022, 01:16:45 am
content: Quote from: paeion on May 15, 2022, 12:20:04 amif you are only calculating acceleration to get torque du you really need direction?anyway, maybe some ideas herehttps://www.esp32.com/viewtopic.php?t=4983

author: paeion
author_rank: Contributor
timestamp: May 15, 2022, 05:14:49 am
content: Quote from: langwadt on May 15, 2022, 01:16:45 amAcceleration is a vector quantity just like velocity, so I will need the direction to give me the sign on top of the magnitudeEveryone's given me a lot of helpful guidance, I think I have all the tools now to test it out this week!

author: jpanhalt
author_rank: Super Contributor
timestamp: May 15, 2022, 09:56:31 am
content: I have used the AMS AS5048A to measure angles on equipment. It is very similar to what you have, but is not what I would choose if all I wanted was precise RPM velocity and acceleration. Something that gives distinct pulses per revolution (say, 8) would be simpler. I have not checked whether such is available in a magnetic version. Magnetic coupling is convenient, so long as you have a radially magnetized disk or mount a small bar magnetic appropriately.

author: Kleinstein
author_rank: Super Contributor
timestamp: May 15, 2022, 12:01:47 pm
content: Reading the I2C bus should not be so much work for the µC, at least if the µC has hardware to support I2C directly. Something like 1 reading every 1-10 ms is not that much time needed.It looks like the digital data that can be read via I2C are the primary data and the way via internal DAC + comparator can only make things worse. Especially at lower speed (e.g. up to some 100 RPM) the comparator solution would not give much information. There is essentially no way the analog + comparator solution would give a better result than directly reading the I2C data - it is more like to expect some 10x higher noise with the indirect way.The real alternative would be a different sensor, like an optical quadrature encoder with more like 32 to 1024 steps per revolution, if the µC include an encoder interface.

author: langwadt
author_rank: Super Contributor
timestamp: May 15, 2022, 12:50:27 pm
content: Quote from: paeion on May 15, 2022, 05:14:49 amif the end goal is power you are either accelerating or decelerating, doesn't matter which direction

author: paeion
author_rank: Contributor
timestamp: May 15, 2022, 11:59:45 pm
content: Quote from: langwadt on May 15, 2022, 12:50:27 pmIt took me a bit to realise but you are correct sir. The changes in velocity will provide the sign in the acceleration, so for all that matters, the shaft can spin whichever direction it likes.

author: eugene
author_rank: Frequent Contributor
timestamp: May 16, 2022, 09:53:35 pm
content: Do I understand correctly that what you want, in the end, is a measure of acceleration? Be warned that measuring acceleration in this way is conceptually simple, but fraught with problems of unstable, noisy results. The basic idea is to measure position at two different times. The change in position divided by the change in time is velocity, right? Yes, but a small error in your measurement of time results in a larger error in your velocity calculation. And we're not done. We want to know acceleration, so we have to calculate velocity at two different times then calculate change in velocity divided by change in time to get acceleration. And again, a small error in time results in a large error in calculated acceleration. Combine that with the already large error in velocity, and it's easy to end up with a number for acceleration that is of little value. (Note that this method requires three position data points. It's easy to calculate acceleration directly from those three points, without calculating velocities, but this does not improve the quality of the result.)The way to reduce the error is to use more than three data points to calculate acceleration. There are lots of ways to perform the calculations, but in the end, you can get arbitrarily clean results by combining an arbitrarily long string of data points in the calculation. The cost is that the calculation becomes more complicated with larger datasets and thus takes more clock cycles to perform. You have not told us the details of your requirements, but I'm thinking you'll need more than one data point per revolution of the motor.So, my suggestion is to record data more frequently. You need both the position (angle) and the precise time that the measurement was made. I can think of two ways to do that:1. Use the PWM output on the AS5600 and the RMT module in the ESP32. The RMT module will directly measure the duty cycle of the incoming PWM and dump the results in a memory block (aka buffer.) This is done entirely in hardware, so no attention is required by your code. There are a couple of things about this method that I would need to work out. One of them is deciding when to pull data from the buffer and calculate acceleration. The problem is that the only interrupt that the module can trigger in receive mode is when the end of the message is reached (basically, a time out.) But the pulse train from the AS5600 never stops, so the RMT never detects an end to the incoming message. I suppose you could use a periodic interrupt to stop the RMT, pull data from the buffer, then start the RMT again. The memory block can be configured as a ring buffer, and there is likely information in one of the RMT registers telling where the tail is; where the most recent sample is buffer. That way you could be sure of using only data that was acquired at consecutive time intervals. The other problem is determining precisely the time of each measurement. Really, we only need the time between samples, and that's determined by the rate that the pulses are coming in. Unfortunately, that rate is not well controlled by the AS5600. Maybe use the ESP32 to first measure the frequency of pulses, then collect a bunch of data? I don't know.2. The other method that I can think of is using the analog output on the AS5600 and the ADC on the ESP32. This way the time between samples is controlled by the ESP32. Assuming you're using a stable clock, the time base can be controlled precisely. So, the basic routine would be to setup an ADC to convert continuously at some configurable rate, and then put a configurable number of samples into a global buffer. I'm not super familiar with ESP32, but I know that it's possible to configure an ADC to write directly to memory using DMA. In this way, all the work is done with hardware so that the processor is free to do other things while data is being collected. I'd have to figure out how, but it must be possible to have the ADC acquire a fixed number of samples, put them in a global array, and then trigger an interrupt. (Look for sample code somewhere.) I would expect this method to give more accurate time values, but less accurate angle values than method (1) above.So how do you use the data to calculate acceleration? There are a number of ways. The easiest to understand might be to go through the array of position (angle) data and calculate another array of velocity values, one for each pair of angles. Then go through the velocity data and calculate another array of accelerations. Maybe then average all of the accelerations into one number. You might want to go through the position and velocity arrays and perform some kind of smoothing. That might help if the data is really noisy, but my intuition is that it wouldn't be very useful.Another way that is a little more complicated conceptually, but would give better results, is to fit a straight line to the velocity data. The least squares line fit returns two numbers: slope and offset. The slope (of velocity vs time) is acceleration. Least squares fitting sounds scary, but there are libraries that could be used.Or, we can eliminate the intermediate velocity calculations and fit a second order polynomial to the raw position data. For a second order fit, the least squares routine returns three numbers. The third one is the acceleration (really 1/2 the acceleration.) This can be computationally expensive, and the expense goes up fast with the number of data points involved. But this method will make the best possible use of the data. In fact, this the go-to method for analyzing noisy data. Doing it in real time may or may not be crazy depending on your processor, the number of data points in each set, and how often you need to perform the calculation. I think it could be made to work in your application with your hardware.Let me know if you're interested in trying what I've just suggested. If you need help setting up the RMT module or the ADC, then a ESP32 forum would probably be the best place to go. If you want help performing least squares analysis on the raw data, then I can help with that.

author: jpanhalt
author_rank: Super Contributor
timestamp: May 16, 2022, 10:31:23 pm
content: I spent some time today looking at the datasheet for that encoder. It can probably be made to work, but its intended function is clearly not for measuring RPM, but rather position. I think it is the wrong encoder for the job and again recommend something that will easily give more than one data point per revolution. I suspect those encoders will require a physical connection to the shaft. If that is not possible, then perhaps the TS will flow chart his plan. It's easy to see how one "click" per revolution can be obtained with a comparator set, say, to Vdd/2, but I wonder how noisey that would be.