Hi Guys
Im searching for a Code example to read from Hall effect Sensor to get RPMs.
But i would like to achive this without a sleep/wait command,
because i have some other things going on and need a fast loop.
Has anybody somthing to share?
That would save me a lot of time.
Thanks a lot!
Chris
Feather2040 - CircuitPython - VSC - Hall Sensor on GPIO (3.3 - 0V)
Code RPM with Hall Sensor but without wait/sleep
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- christofeugster
- Posts: 29
- Joined: Sun Jan 02, 2022 2:46 am
- mikeysklar
- Posts: 13824
- Joined: Mon Aug 01, 2016 8:10 pm
Re: Code RPM with Hall Sensor but without wait/sleep
You can look into asyncio with CircuitPython if you wish to run multiple things at once.
https://learn.adafruit.com/cooperative- ... o/overview
The fidget spinner guide provides from code for determinig revolutions per second / minute.
https://learn.adafruit.com/fidget-spinn ... cuitpython
https://learn.adafruit.com/cooperative- ... o/overview
The fidget spinner guide provides from code for determinig revolutions per second / minute.
https://learn.adafruit.com/fidget-spinn ... cuitpython
- CircuitFlyer
- Posts: 21
- Joined: Thu Sep 17, 2020 11:01 pm
Re: Code RPM with Hall Sensor but without wait/sleep
I use pulseio.Pulsein https://docs.circuitpython.org/en/lates ... io.PulseIn to measure the period of a tachometer input. Just let it do its thing in the background and when you are ready, pause it, total up the pulses and calculate RPM then resume.
- christofeugster
- Posts: 29
- Joined: Sun Jan 02, 2022 2:46 am
Re: Code RPM with Hall Sensor but without wait/sleep
Thanks for your answer.mikeysklar wrote: ↑Thu Nov 17, 2022 7:42 pm You can look into asyncio with CircuitPython if you wish to run multiple things at once.
https://learn.adafruit.com/cooperative- ... o/overview
The fidget spinner guide provides from code for determinig revolutions per second / minute.
https://learn.adafruit.com/fidget-spinn ... cuitpython
I need something that lets the loop flowing.
As far is i understand asyncio, it waits for multiple tasks to start simultaneously. But then
i also have to wait for each task.
I want a loop that constantly ask if some condition is met and only execute if true.
I guess i have to play with time.
- christofeugster
- Posts: 29
- Joined: Sun Jan 02, 2022 2:46 am
Re: Code RPM with Hall Sensor but without wait/sleep
Thanks, that is actually helping a lot. I will try to combine pulseio with time.monotonic and ask how long it took since the last pulse.CircuitFlyer wrote: ↑Thu Nov 17, 2022 9:28 pm I use pulseio.Pulsein https://docs.circuitpython.org/en/lates ... io.PulseIn to measure the period of a tachometer input. Just let it do its thing in the background and when you are ready, pause it, total up the pulses and calculate RPM then resume.
Thanks
- christofeugster
- Posts: 29
- Joined: Sun Jan 02, 2022 2:46 am
Re: Code RPM with Hall Sensor but without wait/sleep
Is it possible to send me this section of code from you. That would probably save me a ton of time as the documentation on adafruit isnt that detailed as i could wish.CircuitFlyer wrote: ↑Thu Nov 17, 2022 9:28 pm I use pulseio.Pulsein https://docs.circuitpython.org/en/lates ... io.PulseIn to measure the period of a tachometer input. Just let it do its thing in the background and when you are ready, pause it, total up the pulses and calculate RPM then resume.
That would be very kind.
I get pulses but two each pass?
Thanks
- CircuitFlyer
- Posts: 21
- Joined: Thu Sep 17, 2020 11:01 pm
Re: Code RPM with Hall Sensor but without wait/sleep
You can collect as many pulses as you like. It records the length of each pulse in microseconds. So if you have one magnet then it should record one high pulse length and one low pulse length for each revolution.
I’ll see if I can dig up a code snippet for you. In the meantime, there is some useful info here https://learn.adafruit.com/ir-sensor/circuitpython.
I’ll see if I can dig up a code snippet for you. In the meantime, there is some useful info here https://learn.adafruit.com/ir-sensor/circuitpython.
- CircuitFlyer
- Posts: 21
- Joined: Thu Sep 17, 2020 11:01 pm
Re: Code RPM with Hall Sensor but without wait/sleep
Here is the code I used to test my set-up. I was measuring the RPM of a DC brushless motor that had 14 magnet poles. In my case I have 14 highs & lows/revolution so you may need to change the math for your use case. Note: my signal conditioning circuit allowed some short duration spikes to get through. I chose to just ignored them. It didn't effect what I was trying to accomplish.
Hope it makes sense.
Hope it makes sense.
Code: Select all
# RPM sensor test output using Pulseio
# using QTPy RP2040
from board import D10
import pulseio
from time import monotonic
def getRPM():
global RPM, valid_samples, now # needed function updates these
global total # although local use only it needs to be initiated at a value of 0
global number_of_poles # not needed as function only references this value
global start_time # needed, function updates this
if (now - start_time) > .02: # set max sample time to collect all required samples at the desired resolution
pulses.pause()
if (len(pulses) >= 6): # if there is the minimum number of samples
for i in range(len(pulses)): # If the RPM conditioining circuit is unable to filter out some short spikes they get summed and throw the calculation off.
if pulses[i] < 40: # this throws out any short spikes that make it through. Test sample had spikes up to 28usec long.
#print(pulses[i]) # test print to show invalid pulse lengths
pass
else:
total += pulses[i] # only valid pulses totaled up
valid_samples += 1 # only the number of valid samples to be used in RPM calculation to give true RPM numbers.
try:
RPM = (int(((1_000_000/total)*60)/(number_of_poles/valid_samples)/10))*10 # need to divide by number of motor poles here. Minimum resolution 10RPM
except ZeroDivisionError:
RPM = 0
if (RPM > 60_000): # needed to read 0 RPM (if total = 1 then RPM is 60,000,000)
RPM = 0
if (len(pulses) < 6): # minimum samples
RPM = 0
total = 0
valid_samples = 0
pulses.clear()
start_time = now
pulses.resume()
print((RPM,)) # for plotting the results
return RPM
else:
return # if maximum sample time has not finished yet then return None
number_of_poles = 14
total = 0
RPM = 0
valid_samples = 0
start_time = 0
samples = 14
pulses = pulseio.PulseIn(D10, maxlen=samples, idle_state=False)
while True:
now = monotonic()
getRPM()
- Rcayot
- Posts: 321
- Joined: Sat Feb 08, 2020 6:48 pm
Re: Code RPM with Hall Sensor but without wait/sleep
I prefer using:
The counter counts pin rises or falls. The difference is that you cn count for a long time, in the example below, it collects pin counts for 180 seconds.
you can set the time for counting pulses as short or long as you want, just keep track of the elapsed time for the time part of the function.
Altyhough it looks like you did a great job using pulsein.
Roger
Code: Select all
pin_counter = countio.Counter(board.GP13, edge=countio.Edge.RISE)
Code: Select all
async def fanspeed(interval):
now = time.monotonic()
while True:
lapsed_time = time.monotonic() - now
print("elapsed time = ", lapsed_time)
if lapsed_time >= fan_speed_time:
fan_count = pin_counter.count
print("count = ", fan_count)
rpm = ((fan_count/2)/(lapsed_time))*60
print("rpm = ", rpm)
F2tag = str(8)
F2packet = (F2tag + str(rpm))
print(F2packet)
pin_counter.reset()
print(pin_counter.count)
now = time.monotonic()
if not rfm9x.send_with_ack(F2packet.encode("utf-8")):
print("No Ack F")
await asyncio.sleep(interval)
Altyhough it looks like you did a great job using pulsein.
Roger
- Rcayot
- Posts: 321
- Joined: Sat Feb 08, 2020 6:48 pm
Re: Code RPM with Hall Sensor but without wait/sleep
here is the noctura white paper
- christofeugster
- Posts: 29
- Joined: Sun Jan 02, 2022 2:46 am
Re: Code RPM with Hall Sensor but without wait/sleep
Thanks a lot!
CircuitFlyer wrote: ↑Sat Nov 19, 2022 3:49 pm Here is the code I used to test my set-up. I was measuring the RPM of a DC brushless motor that had 14 magnet poles. In my case I have 14 highs & lows/revolution so you may need to change the math for your use case. Note: my signal conditioning circuit allowed some short duration spikes to get through. I chose to just ignored them. It didn't effect what I was trying to accomplish.
Hope it makes sense.
Code: Select all
# RPM sensor test output using Pulseio # using QTPy RP2040 from board import D10 import pulseio from time import monotonic def getRPM(): global RPM, valid_samples, now # needed function updates these global total # although local use only it needs to be initiated at a value of 0 global number_of_poles # not needed as function only references this value global start_time # needed, function updates this if (now - start_time) > .02: # set max sample time to collect all required samples at the desired resolution pulses.pause() if (len(pulses) >= 6): # if there is the minimum number of samples for i in range(len(pulses)): # If the RPM conditioining circuit is unable to filter out some short spikes they get summed and throw the calculation off. if pulses[i] < 40: # this throws out any short spikes that make it through. Test sample had spikes up to 28usec long. #print(pulses[i]) # test print to show invalid pulse lengths pass else: total += pulses[i] # only valid pulses totaled up valid_samples += 1 # only the number of valid samples to be used in RPM calculation to give true RPM numbers. try: RPM = (int(((1_000_000/total)*60)/(number_of_poles/valid_samples)/10))*10 # need to divide by number of motor poles here. Minimum resolution 10RPM except ZeroDivisionError: RPM = 0 if (RPM > 60_000): # needed to read 0 RPM (if total = 1 then RPM is 60,000,000) RPM = 0 if (len(pulses) < 6): # minimum samples RPM = 0 total = 0 valid_samples = 0 pulses.clear() start_time = now pulses.resume() print((RPM,)) # for plotting the results return RPM else: return # if maximum sample time has not finished yet then return None number_of_poles = 14 total = 0 RPM = 0 valid_samples = 0 start_time = 0 samples = 14 pulses = pulseio.PulseIn(D10, maxlen=samples, idle_state=False) while True: now = monotonic() getRPM() [/quote]
Please be positive and constructive with your questions and comments.