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
NI LabVIEW Community
  • Products
  • Dev Tools
  • NI LabVIEW Community
  • More
  • Cancel
NI LabVIEW Community
LabVIEW Challenge Blogs RPM Calculator with Labview and Pi Pico (Trial Version)
  • Blog
  • LabVIEW Challenge Blogs
  • Forum
  • Documents
  • Quiz
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join NI LabVIEW Community to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: cbohra00627
  • Date Created: 27 Oct 2023 3:59 AM Date Created
  • Views 1249 views
  • Likes 3 likes
  • Comments 2 comments
  • labview 2023
  • pico and labview
  • pico
  • LAbVIEW challenge
  • labview
Related
Recommended

RPM Calculator with Labview and Pi Pico (Trial Version)

cbohra00627
cbohra00627
27 Oct 2023

Introduction:

In this blog, I will be creating a VI to calculate RPM. This VI will be a trial version. I will post a final blog later with the complete VI. I had already setup the pico board in my previous blog.

Components Used:

  • Raspberry Pi Pico
  • CPU Fan motor
  • Photo Interrupt Sensor
  • Relay Module

The plan was to use a BLDC motor with ESC so that I could control the motor speed by varying the duty cycle through pico. I first tested the motor on Arduino, it was working properly. But when I tried to implement the same on pico, it didn't work. So, I had to drop that idea and use a normal DC motor.

Circuit:

A rough circuit diagram is shown below:

imageimage

Working:

All the modules are supplied from the 3V3 source on pi pico. The relay controls the connection of the supply with the motor. The sensor and the relay by default has the supply. When the relay contacts are closed, the motor starts rotating. The motor has 7 blades on it. So, whenever a blade passes through the sensor, it generates data which is read by labview via the pico which is then used to calculate the RPM.

Labview VI:

In this section, I will be going through the subsections of the VI. I have uploaded the complete VI on github.

A snip of the complete VI is pasted below:

Block Diagram:

image

Front Panel:

image

1. Turning on the motor through relay (Digital Write):

image

The On/Off Switch can be used to turn on & off the motor through relay. The Digital Write Pin is set to 0 which corresponds to GP22 pin on pico for Digital Write. The GP22 is connected to the 'In' input of the relay module. When the switch is turned ON from the front panel, it sets the GP22 pin high and thus relay contact closes and motor turns on.

The motor fan has seven blades. A local variable 'count' is also initialized to keep count of how many blades has passed through the sensor. count = 7 means one revolution has completed. It will be used later

2. Reading from the photo interrupt sensor (Analog read):

image

The analog read pin is set to 0 which corresponds to GP26 pin of the pico for analog read. A waveform chart is connected to the output to continuously monitor the data. The analog read data can vary between 0 & 4095. A case structure is added with condition that it should run only when there is no object in front of the sensor. The sensor will produce high data (around 4000) when there is an object in front of it.

3. Waiting for current blade to pass:

image

The sensor will output high value (around 4000) as long as a blade is in front of it. I have added a while loop after the sensor detects no object (i.e. sensor data <= 1000) which would wait for the sensor data to go high (i.e. wait for the next blade to come in front of it). Once the subsequent logic completes, it will again wait for lower sensor data. This way the logic will run only once per pulse (posedge of sensor data).

4. Counting number of blades passed:

image

Once the positive edge of sensor data comes, it means, one blade has come in front of the sensor. When 7 posedge come, it means 7 blades have passed and one revolution is complete. In this section, it increments the 'count' variable that we declared earlier by 1 every time a blade passes.

5. One Revolution is complete:

image

When one revolution is complete (i.e. count >= 7), the next section of logic executes.

6. Calculating the RPM:

image

In this section, we calculate the time taken for one revolution and convert that into RPM. The time is calculated by taking difference between the current timestamp in ms and the timetstamp of the previous iteration (i.e. end of previous revolution) which was stored in a local variable 'time_stamp' in the previous iteration at a later section.

7. Taking Average of previous 5 RPMs:

image

In this section, we first modify the previous array of RPMs adding the new RPM value calculated in the current iteration. And then calculate the average and show on a meter.

This section was specially included to avoid abrupt changes in RPM values. 

8. Resetting the 'count' variable and setting 'time_stamp' for next iteration:

image

In this section, the 'count' variable is reset to 0 so that it can be used for the next iteration. And the 'time_stamp' variable is set.

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

Well, it seems the RPM calculated is not constant and changing continuously. The value seems to be between 2000 and 3000 rpm. I guess, I will have to do some modifications in the VI so that the rpm value doesn't change abruptly.

Summay:

This blog was expected to be the final project blog but it seems there are many improvements and changes that need to be done. So, I keep this blog as a rpm calculator trial and create another blog with improved VIs.

EDIT: Link to final project

  • Sign in to reply
  • cbohra00627
    cbohra00627 over 1 year ago in reply to Andrew J

    Hi Andrew J , first of all thanks for your insights. After going through your comment and looking at my VI, I think it definitely needs cleaning up. About the while loop (where it is checking if input is <= 3500), I think I have made a mistake. I thought it works like the C language loop i.e. the loop will keep running till the condition is true. But it seems it will stop if the condition is true which is not expected. I have also uploaded the working video. Although the rpm calculated is fluctuating so much, I think its still working upto some extent somehow. With the project deadline extended, I think I will improve it and post another blog.

    image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Andrew J
    Andrew J over 1 year ago

    First off, I want to be clear I’m not being critical in any way: LabVIEW is such a different approach to what you may be used to that getting this far in such a short time is a great achievement and you’ve picked an interesting project to start with.  Posting responses is always open to interpretation  versus being sat with someone so you look them straight in the eyes!

    I do want to ask how well this works and maybe give some pointers.  It’s hard to follow because of all the sequence structures and local variables.  I don’t understand why so many sequence structures as it breaks up the natural dataflow processing that LabVIEW uses; sometimes it has to be done because there’s no other way of controlling the dataflow mechanics needed but so many is a bit of a red flag.  Really you need to consider the mechanics of dataflow and controlling the execution that way.

    I thought at first that the while loop testing against a value of 3500 would never exit once it got going, but of course it never really starts, it only runs once.  The case statement is entered when the read value is less than or equal to 1000 then hits the while loop which exits when the value is less than or equal to 3500 which of course it always is.  I guess that means the code does only run when nothing is front of the sensor which is what you want.  Sort of: isn’t it only counting whenever something isn’t in front of the sensor which depending on the speed of LabVIEW execution vs speed of rotation could be multiple counts within one ‘gap’.  I think the whole timing of this is difficult actually and would need tuning through testing, probably involve testing for gaps and blades.  I may well have misunderstood what is happening here.

    Your use of local variables is almost guaranteed to cause race conditions, but it isn’t clear in every case what they are tied to.  For example you have an indicator timestamp but have created another one called time_stamp so you can have a local variable that isn’t tied to timestamp.  Look at image 8; you are updating the indicator and its local variable at the same time with the same value - it’s not necessary because they are the same thing.  You have the same thing going on in 7 with all the RPM variable updates.  Image 4 is a good example of a race condition: you are using the local variable representation of count, and all three elements in that image are the same thing.  So you read count, say value is 5, and 5 travels on the wire towards count and towards the increment (there is actually a +1 function by the way) where it changes to 6 and travels towards count.  Which gets there first and is count 5 or 6 at the end?  You can’t guarantee the order of execution because of dataflow.  I suspect you’ve been lucky and that the 5 reaches count before 6 does because it doesn’t go through the increment but it is just luck.

    As much as possible, you have to avoid local and global variables.  Sometimes they are needed - I’ve used them - but it’s always a potential source of race conditions in LabVIEW so you need to be really careful where they are read and updated because fundamentally LabVIEW controls the execution sequence, not you; you have to influence this by controlling the flow of data so parts of the code get executed when the data is available.  You can see how wacky this looks by running the VI with the data flow switch on (the lightbulb on the menu bar in the debug section) - it’s insightful to see which parts of the code run.

    Here are some pointers: take a look at Shift Registers for value updates through repetitions.  I can see you are using these for the visa session and error control/indicator on the outer loop.  These aren’t necessary actually, and I have the feeling that if an error was raised in one of the SCPI functions it would loop forever.  I suppose it does anyway, until Stop is signalled so it isn’t important, just not doing what you think it might be.  See if you can rewrite this without local variables or the sequence structures and come back here with questions so we can help.

    Can you post the front panel?  Video showing it working?

    Just to re-iterate, I’m not being critical I think you’ve had a good go on a complex dev tool that I’m assuming is new to you.  The challenge was to learn LabVIEW which you are clearly starting to get to grips with.  Perhaps someone else will come along and tell me where I’ve misunderstood something myself as I’m new to it as well.

    • 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