I am currently trying to track rpm of a shaft that rotates up to 150,000 rpm using a DRV 5055 TI hall effect sensor and a teensy 4.1. I used the circuit down bellow to filter and turn the signal into a square wave, also shown. The problem is that the square wave has bouncing in the transitions causing my rpm reading to be way higher then it should be. Here is the code I am currently using to try and debounce but it will only ever read zero. Does anyone know a better way to debounce the code that is adaptive for when my shaft is spinning from 3,000 rpm up to 150,000 rpm. Thank you for you help in advance.
const int RPM_pin = 12;
// Start overall time
unsigned long startTime = 0; // Start time
const unsigned long PrintTime = 500; // Every 30s Used to print time, temp, and eventually RPM
unsigned long previousTime = 0; //Print loop timer
unsigned long Time = 0; //keep track of time since start
// RPM count
volatile unsigned long int count = 0;
float rpm = 0;
float TimeStep = 0;
volatile unsigned long currentRPMTime = 0;
volatile unsigned long pulseStart = 0; // Stores the time the pulse starts
volatile unsigned long pulseEnd = 0; // Stores the time the pulse ends
volatile unsigned long pulseDuration = 0; // Pulse duration
void setup() {
// Record the start time when the program begins
startTime = millis();
attachInterrupt(digitalPinToInterrupt(RPM_pin), countPulse, CHANGE);
// Start Serial communication for debugging
Serial.begin(9600);
}
void loop() {
//Igniter Heating Loop
//Serial.println("Igniter Heating");
unsigned long currentTime = millis();
Time = millis() - startTime; //Starting the Time
if (currentTime - previousTime >= PrintTime) {
TimeStep = PrintTime / 1000;
rpm = (count * 1000 / (PrintTime)*60);
Serial.print(count);
Serial.print(",");
Serial.println(rpm);
count = 0;
previousTime = currentTime; //Reset Print Loop Time
}
}
void countPulse() {
currentRPMTime = micros();
// Check if this is a rising edge (start of pulse)
if (digitalRead(RPM_pin) == HIGH) {
pulseStart = currentRPMTime; // Record the start time of the pulse
}
// Check if this is a falling edge (end of pulse)
else if (digitalRead(RPM_pin) == LOW) {
pulseEnd = currentRPMTime; // Record the end time of the pulse
pulseDuration = pulseEnd - pulseStart; // Calculate pulse duration
// Only count the pulse if it lasted longer than 50 microseconds
if (pulseDuration > 150) {
count++;
}
}
}
No it is not. See the noise is on both the high part of the trace on on the LOW part, which should be at ground level. Eliminate the noise problem and your RPM problem will go away. Wire leads are way to long or the ground for the scope probe is not at a real ground for the project. Use the scope trace to see what removes the noise signal.
Also, I believe that you have configured the hysteresis feed back resistor incorrectly for what appears to be an inverting comparator configuration. See: Comparator Hysteresis - Circuit Cellar but add some part numbers to that schematic and maybe redraw it so the ground tends to be towards the bottom of the picture.
I assume you have one hall sensor on the part that is going 150000 RPM, or can.
I don't understand why you are attempting to measure the pulse duration from leading edge to trailing edge.
RPM would be proportional to the frequency, which would require measurement from rising edge to the next rising edge.
I first calculated 2500 Hz and 400 us period . Then I did at again and got the same answer. Still ambitious for software debouncing. One loop I just tried only made 10000 readings per second.
Quite likely to be related to using an analog sensor! You are detecting the magnetic field from your motor shaft. The magnetic field is NOT a uniform, point field, as you are seeing on your scope. How is your magnetic field created?
AVRs have built-in schmitt triggers, and the Teensy 4.x have configurable schmitt triggers. If the noise is smaller than the hysteresis in the schmitt triggers or the stick-built comparator circuit, then you shouldn't have bouncing.
If the stick-built comparator ends up amplifing the noise, then a the schmitt trigger in the Teensy or AVR would follow.
What does the oscilloscope trace of the input signal/output of the hall sensor look like when the output of the comparator is bouncing?
Depending on the noise in the analog signal, (and it could perhaps be filtered a bit) it could be lower than the hysteresis of the built-in schmitt triggers.
I don't have the sensor, or a sensor trace, but from the DRV5055 datasheet, it looks like noise is in a mV range:
This is the signal coming out of the hall effect sensor. Would the teensy be able to turn this into a square wave with the variance only being 40mV from the high to the low.