Situation: I'm using a brushed DC motor to open and close the vents of a greenhouse and I would like to know the exact motor location for more granular temperature control. Motor moves at different speeds depending on wind and whether it moves up or down, so I cannot use time as a reliable unit to infer the motor's position.

However, the revolutions of the motor are fixed in terms of distance, so I would like to know how often the motor has rotated. As installing additional sensors (e.g., hall sensor along motor path) would add to project complexity, I was hoping to achieve this without any extra external sensors.

Here is where I would like to infer the number of motor revolutions by measuring the current ripples, similar to what's described in this paper, but I'm honestly way over my head.

Hardware setup:

  • Arduino Uno connected to a
  • ACS712 current sensor to take the readings
  • 24V brushed DC motor with 12 armatures and 2 permanent magnets and 2 brushes, moving at ~3.7 RPM (Pictures below)
  • bench power supply for testing and
  • 120W 24V meanwell power supply for actual deployment```

Data processing:

  1. Read log file
  2. Truncate data

Here is a plot of the raw readings. Y axis is the current reading from the sensor, x axis is time in 10 millisecond intervals (~14 seconds). Raw data

  1. Apply a fast fourier transform
  2. Set cutoff frequency to denoise the readings
  3. Transform back into time dimension

Result of this is shown here: Reverse fourier result

My questions: I have no idea whether I am even on the right track with this approach. Specifically:

  • Is the current sensor sensitive enough?
  • Is there too much interference to reliably infer motor rotations with this setup?
  • The paper uses a different specialized MCU for this. Is an Arduino or ESP32-S2 even usable?
  • If overall approach is appropriate, what am I even looking for in the data? I assume that the armatures are creating current differences as they move along the poles, correct?
  • If that's the case, should we see 12 * 3.6 spikes per minute?

Raw data: Here is the raw measuring data that I saved using Putty over serial.

Arduino code:

const float VCC = 5.0;
float sensitivity = 0.185;

const float QOV = 0.5 * VCC;
float voltage;

void setup() {
  // initialize serial communication at 9600 bits per second:

void loop() {
  float voltage_raw = (5.0 / 1023.0)* analogRead(VIN);
  voltage = voltage_raw - QOV + 0.012;
  float current = voltage / sensitivity;
  Serial.print(", ");
  delay(10);        // delay in between reads for stability

Motor 1 Motor 2 Motor 3 Motor 4

  • 1
    \$\begingroup\$ You’re concerned about project complexity and you want to do this? Keep it simple and you’ll have a better chance of success. \$\endgroup\$
    – Kartman
    Commented Jan 13, 2021 at 5:28
  • \$\begingroup\$ Thank you for your comment. Could you be more specific what you mean by 'keep it simple'? Simple as in: 'don't try to infer motor position from revolutions in the first place'? What would be your suggested alternative then? \$\endgroup\$ Commented Jan 13, 2021 at 5:35
  • 1
    \$\begingroup\$ The common solution would be to have some means to measure the motor rotation - reluctor, hall sensor, optical sensor etc. Even a distance sensor to measure the flap position. As well, you might want a limit switch for redundancy. 3.7 RPM seems awfully slow - is there a gearbox involved? \$\endgroup\$
    – Kartman
    Commented Jan 13, 2021 at 6:23
  • \$\begingroup\$ Thanks, that was pretty much the reality check I was looking for. Yes, there is a gearbox, so the real motor speed is of course faster. I haven't opened up the gearbox though since I was afraid of having to put it back together. 2 limit switches for movement in both directions are already included with the motor. \$\endgroup\$ Commented Jan 13, 2021 at 8:27
  • 1
    \$\begingroup\$ Add some external position sensor. Vastly simpler than attempting SOTA research (sensorless position detection will bring up thousands of current papers) to a trailing edge tech (brushed DC motor) \$\endgroup\$
    – user16324
    Commented Jan 13, 2021 at 13:07

2 Answers 2


To get good waveform fidelity you need to sample at ~10 times the highest frequency of interest. At 10 ms per sample your effective bandwidth is only ~10 Hz. With a 12 segment commutator that corresponds to just 50 rpm at the motor. Actual motor speed will probably be thousands of rpm, so your sample data won't accurately resolve the current spikes.

Sample at the highest rate you can, and send the data as raw 8 bit integers without timestamp at the highest possible serial data rate (you can infer the sample rate from the number of samples received per second). At 11520 baud you should be able to achieve ~10,000 samples per second (100 μs per sample). Then evaluate the signal to see if the motor speed can be resolved.


Your approach is admirable in terms of complexity but I'd be afraid to try it.

A possible solution since you appear to have limit switches and if movements are not too frequent is to just run a calibration timing cycle and then base the movement on time.

enter image description here

Figure 1. Timer-based solution flowchart.

The advantage is simplicity and the calibration cycle can be used to monitor the operation of the mechanism. You might want to add in some monitoring timeouts so that the motor switches off if position is not achieved in a reasonable time.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.