element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Rube Goldberg Device
  • Challenges & Projects
  • Project14
  • Rube Goldberg Device
  • More
  • Cancel
Rube Goldberg Device
Blog The Junk-Pile Strobe Tachometer.....and it really works!
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Rube Goldberg Device to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: robogary
  • Date Created: 16 Jul 2022 6:15 PM Date Created
  • Views 73709 views
  • Likes 15 likes
  • Comments 3 comments
  • raspberry pi pico
  • rubegoldbergch
Related
Recommended

The Junk-Pile Strobe Tachometer.....and it really works!

robogary
robogary
16 Jul 2022

This project idea was inspired by a need to measure the speed of random - no nameplate DC motors salvaged from printers, cars, toys, and experimenter’s kits.

  • In the spirit of Rube Goldberg, I’d use as much workshop junk as possible to build this test instrument.
  • Clunkiness and awkwardness is encouraged in this build. The older the part the better, old technology is quaint.
  • Raspberry Pi Pico was selected as a controller based on its low cost, nice clock speeds and the easy way python programs with PWM.
  • More Rube-ness – My workdesk (ping pong table) has a Raspberry Pi dedicated to programming Raspberry Pi Picos in Thonny. A windows PC is used to VCN into the Raspberry Pi for control and WinSCP for the W10 PC to fetch the python code from the Raspberry Pi to the W10 PC.

A video of the strobe tach working: 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

photo of 1st version of prototype

image

  image

image

image

Key Points of Learning by Doing: 

1. I can’t believe it worked as well as it did. This project was really fun, very hard to put down.

2. In the Python libraries I found, PWM frequency is commanded using an integer --- which means pulse reference is in one Hz increments i.e. 1 Pulse per second. If measuring in rpm, the best rpm setpoint resolution achievable using pwm libraries is 60 rpm  L

3.The micropython PWM frequency integer setpoint has a low limit of 8 Hz. Values below 8 causes the python program to error.

4. In the spirit of Rube, the motor speed was synchronized best as possible using the strobe thumbwheel rpm speed setpoint, then the DC motor voltage was adjusted up or down to get strobe synchronization.

5. My design included a Duty cycle/intensity adjustment pot. I’d thought 50% duty might be too long to get a good synchronization with a rotating marker, and maybe too bright. I was unexpectedly learned that not only 50% duty was way too much, best results were seen at duty cycles of .01% - . 1%.

6. With a PWM duty cycle set so narrow, the pulse intensity needed to be increased. Just like with small LED being strobed at peak current 3X nominal,         significant improvement was seen after driving the LED floodlight at nearly 2X rated current, 3.5X the current I was driving them for steady state             lighting. The original power supply feeding the project was 2 amps.  To get higher current, the LED power was changed to feed from a 14Vdc 4.5A laptop supply, with a 2 ohm 70W resistor in series. After proving out the 2 ohm resistor solution was a good direction and analyzing the duty cycle range, the series resistor only needed to be a couple watts ( in spite of the fact the RMS watts are very low, the resistor needs to be mechanically able to take a 4A slug of current). 

I just happened to find 3.8 ohm 2W resistors in my eclectic resistor junk drawer. Qty 3 in parallel decreases the resistor ohms value  allowing more Floodlight LED current and the watts loss & peak current can be shared by the 3 resistors effectively. The 2W resistors are easily added to the MOSFET card. In further running, the resistors are cool to touch. 

 

 image

image

image

Now to the other surprising awesomeness details:

  • The LED floodlights were salvaged from my driveway floodlights that had failed the integral motion sensor.

  • The BCD thumbwheel switches were rescued from a dumpster. Wirewrap was used to attach the leads to the thumbwheels. I hadn’t used my wirewrap tools in about 35 years, but in all modesty, I still got the touch ( yes, just like the Peter Gabriel song. When Petey sings about wanting contact, he is referring to a low ohmic, tight and layered wire wrap). 

image   image

  • Analog pots were used for trim on frequency and duty cycle, not realizing how important the Duty cycle adjust would be and how insignificant the frequency adjust pot would be.
  • The motor rpm was checked using an industrial calibrated strobe tach. Amazingly the rpm values are within the 60 rpm accuracy window of the rpms seen with the Junk Pile Strobe Tach.

The conceptual one line

image

Thumbwheel wiring to Raspberry Pi Pico 

image

The rest of the schematic wiring

image

Now for the RPi Pico code 


from machine import Pin, PWM, ADC

# Pin uses the GPIO value , not the actual pin number
import utime

AliveLED = Pin(25,machine.Pin.OUT)
AliveLED.value(0)

Rpm_Adjust_Pot=ADC(Pin(28)) #GP28 is physical pin 34
DutyAdjustPot=ADC(Pin(27)) #GP27 is physical pin 32

# servo = PWM(Pin(10))# physical pin14
strobe = PWM(Pin(12))# physical pin 16
rpm=0
rps=0
rps_int=0
Finalrpm=0
#servo.freq(rps) # 50 Hz is 20 msec period
# 100% duty of PWM is 65535 counts
# 2 ms of 20 ms is 10% for full spd FWD 6553
# ( 1.5 ms / 20 ms ) * 65535 = 4875 for zero degrees
# 1 ms of 20 ms is full neg 3251 counts

#AliveLED.value(1)
count=0

Thousands_1 = Pin(0, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP0 is physical pin 1
Thousands_2 = Pin(1, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP1 is physical pin 2
Thousands_4 = Pin(2, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP2 is physical pin 4
Thousands_8 = Pin(3, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP3 is physical pin 5

Hundreds_1 = Pin(4, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP4 is physical pin 6
Hundreds_2 = Pin(5, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP5 is physical pin 7
Hundreds_4 = Pin(6, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP6 is physical pin 9
Hundreds_8 = Pin(7, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP7 is physical pin 10

Tens_1 = Pin(8, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP8 is physical pin 11
Tens_2 = Pin(9, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP9 is physical pin 12
Tens_4 = Pin(10, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP10 is physical pin 14
Tens_8 = Pin(11, machine.Pin.IN,machine.Pin.PULL_DOWN)#GP11 is physical pin 15


def Read_Thumbwheels():
rpm=0
if Thousands_1.value() ==1:
rpm=1000

if Thousands_2.value() ==1:
rpm=rpm+2000

if Thousands_4.value() ==1:
rpm=rpm+4000

if Thousands_8.value() ==1:
rpm=rpm+8000

if Hundreds_1.value() ==1:
rpm=rpm+100

if Hundreds_2.value() ==1:
rpm=rpm+200

if Hundreds_4.value() ==1:
rpm=rpm+400

if Hundreds_8.value() ==1:
rpm=rpm+800

if Tens_1.value() ==1:
rpm=rpm+10

if Tens_2.value() ==1:
rpm=rpm+20

if Tens_4.value() ==1:
rpm=rpm+40

if Tens_8.value() ==1:
rpm=rpm+80
print (rpm)
Rpm_Adjust_Pot_Counts=0.0010*(Rpm_Adjust_Pot.read_u16())# converts U16 to float
if (rpm>1000):
Rpm_Adjust_Pot_Counts=0.005*(Rpm_Adjust_Pot.read_u16())# converts U16 to float
if (rpm>5000):
Rpm_Adjust_Pot_Counts=0.010*(Rpm_Adjust_Pot.read_u16())# converts U16 to float
print (Rpm_Adjust_Pot_Counts)
Finalrpm=(rpm+Rpm_Adjust_Pot_Counts)
# print (Finalrpm) 
# rps=rpm/(60) #revs per sec defines PWM frequency
# rps_int=int(rps)
# strobe.freq(rps_int) # 50 Hz is 20 msec period revs per second is the same as freq
# strobe.duty_u16(32000)
# print(rps)
return Finalrpm

while True:
# ServoDutyCounts=3250
AliveLED.toggle()
# Read_Thumbwheels()
rpm=0
if Thousands_1.value() ==1:
rpm=1000

if Thousands_2.value() ==1:
rpm=rpm+2000

if Thousands_4.value() ==1:
rpm=rpm+4000

if Thousands_8.value() ==1:
rpm=rpm+8000

if Hundreds_1.value() ==1:
rpm=rpm+100

if Hundreds_2.value() ==1:
rpm=rpm+200

if Hundreds_4.value() ==1:
rpm=rpm+400

if Hundreds_8.value() ==1:
rpm=rpm+800

if Tens_1.value() ==1:
rpm=rpm+10

if Tens_2.value() ==1:
rpm=rpm+20

if Tens_4.value() ==1:
rpm=rpm+40

if Tens_8.value() ==1:
rpm=rpm+80
# print (rpm)
Rpm_Adjust_Pot_Counts=0.0010*(Rpm_Adjust_Pot.read_u16())# converts U16 to float
if (rpm>1000):
Rpm_Adjust_Pot_Counts=0.005*(Rpm_Adjust_Pot.read_u16())# converts U16 to float
if (rpm>5000):
Rpm_Adjust_Pot_Counts=0.010*(Rpm_Adjust_Pot.read_u16())# converts U16 to float
# print (Rpm_Adjust_Pot_Counts)
Finalrpm=(rpm+Rpm_Adjust_Pot_Counts)
# print (Finalrpm)
rps=rpm/(60) #revs per sec defines PWM frequency
if (rps<8):
print ("RPM Clamped to Low Limit Value")
rps =8 # low limit clamp
rps_int=int(rps)
print ("PPS=", rps_int)
strobeDuty=(DutyAdjustPot.read_u16())# converts U16 to float
if (strobeDuty<600):
strobeDuty=600 ## low clmap of 10%
if (strobeDuty>32768):
strobeDuty=32768 ## max clmap of 50%
#print ("Strobe Duty = ", strobeDuty)
strobe.freq(rps_int) # 50 Hz is 20 msec period revs per second is the same as freq FREQ WILL NOT ALLOW BELOW 8 Hz
strobe.duty_u16(strobeDuty)
# print(rps)
# return Finalrpm
# utime.sleep(1) # slow down for print statements
if Finalrpm==0:
break

  • Sign in to reply
  • ntewinkel
    ntewinkel over 3 years ago

    Very cool!

    Bonus points for not harming any amoebas! Smile

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • robogary
    robogary over 3 years ago in reply to DAB

    Plenty of time left to build a Rube Goldberg project with thumbwheels, or maybe can suggest a thumbwheel project themed competition.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB over 3 years ago

    I have some of those switches somewhere in my stash, I need to find them and set them up for a project.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube