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 DC motor rpm monitor & control using Pi Pico and Labview
  • 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: 3 Nov 2023 3:06 PM Date Created
  • Views 1990 views
  • Likes 7 likes
  • Comments 4 comments
  • labview 2023
  • pico and labview
  • pico
  • LAbVIEW challenge
  • labview
  • A Course in LabVIEW and Test Automation
Related
Recommended

DC motor rpm monitor & control using Pi Pico and Labview

cbohra00627
cbohra00627
3 Nov 2023

Introduction:

As my final project, I am making a dc motor rpm monitor & control system using pi pico & labview. DC motor rpm will be temperature controlled. The motor rpm will keep decreasing as the temperature increases. If the temperature crosses a certain threshold, it will trip the circuit & the motor will stop.

Components Used:

  • Pi Pico
  • Labview
  • 3v DC Motor
  • Relay Module
  • HC-89 Interrupt Sensor
  • TIP122 NPN transistor
  • KY-028 Digital Temperature Sensor (will be using analog pin)

SubVIs:

In this section, I will be going through the SubVIs that I used in my project.

Duty Cycle Control:

To be able to change the motor rpm, I am using a transistor as a switch which will turn on/off rapidly to control the supply voltage to the motor. For 3v supply, I am using the voltage pin of arduino. For switching, I am using the PWM in the pi pico. The VI is shown below:

image

The duty cycle needs be passed in %. The subsequent logic will convert it to a real number in range (0, 4095). 4095 corresponds to highest duty cycle i.e. 100%.

I couldn't check & verify the pwm pulses generated as I don't have an oscilloscope Sweat smile. But I checked the output dc voltage value on pin 0 (i.e. GP16) in a digital multimeter. At 50% duty cycle, it shows 1.64v & at 100% it shows 3.27v. So, I think it should work.

I connected a MOSFET (TIP122) between the motor and the supply. As can be seen in the video below, the motor doesn't start unless the duty cycle is >75% but once it starts, I can reduce the duty cycle to control its speed.

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

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

Getting temperature sensor data:

I have used a temperature sensor to keep monitoring the environmental temperature. The motor speed will keep changing based on the value read from this sensor. The higher the temperature, the lower will be the motor speed which will be controlled by varying the duty cycle.

By checking the analog reading from the sensor multiple times, I have identified the range between which the sensor data can vary. The range is (500, 600). 500 being hot and 600 being normal room temperature. If the sensor data reads value >600, 100% duty cycle will be applied. Below this value, the duty cycle will vary thus changing the motor speed. I am using 550 as the lower limit, if the sensor data reaches below that, the relay will disconnect the motor from the supply and the motor will stop. I am using an electric iron to increase the temperature.

Now, to be able to convert the sensor data to duty cycle value, I have created a simple linear relationship using the line equation: y=mx+c. The two endpoints of the line are (600, 100) & (550, 50).

m = (y2 - y1)/(x2 - x1) = (50 - 100)/(550-600) = 1

And c = 100 - 1*600 = -500

So, the line equation: y = x - 500

image

RPM Calculator:

I had written a blog earlier on calculating rpm. But that had some issues as suggested by community members. So, in this blog, I have taken their kind suggestions into account and tried my best to come up with an efficient rpm calculator.

I am using a photo interrupt sensor. It generates high data whenever an object comes in its front. I have a cpu cooler motor with 7 blades. So whenever a blade comes in front of the sensor, it will generate high data. Two consecutive high values mean 1/7 revolution has completed. Time difference between two consecutive high values can be used to calculate the rpm of the motor.

I have explained the rpm calculator part in the below sections:

Sensor Data Read:

So, the below is the basic VI which read sensor data from pin 0 (i.e. GP26). I have put it in a while loop, so that it will continuously read the sensor data. I have also added a waveform chart temporarily to monitor the sensor data.

image

Detecting the positive edge of the sensor data:

To detect when the blade passed through the sensor, it is very important to detect the positive edges of the data. I have used 1500 & 3500 as thresholds. If the sensor data is <1500, that means there is no object in front of the sensor, if it is >3500, that means there is an object passing through the sensor.

To implement the edge detection I have created an FSM using case structures & shift registers (to use values across loop iterations). I have pasted a code below for a case structure. The FSM works exactly like the below case statement will work if placed inside a while loop. Here SD means sensor data & shift means the value on the shift register.

case(shift)
	True:  (SD > 3500) ? (shift = False) : (shift = True);
	False: (SD < 1500) ? (shift = True) : (shift = False);
endcase

imageimageimage

Calculating time between two consecutive blade passes:

Now since we have detected the passing blade, we need to calculate the difference between the current timestamp & the previous timestamp. For this, I have used another shift register to store the previous timestamp & then subtract it from the current timestamp inside the inner case structure.

image

The timestamp should only get updated when a blade passes through the sensor (i.e. sensor data > 3500). In any other cases, it shouldn't get updated or we can say hold the previous value.

imageimage

Calculating RPM:

Now this time_diff (difference in timestamps in ms) can be used to calculate the rpm. My motor fan has 7 blades. So, this time_diff is for when one blade passes.

time_diff (for one revolution) = time_diff * 7

rpm = (1/time_diff)*60000

I have added one more shift register for storing time_diff and done direct connection with previous value for other cases to have some valid value even when the inner case structure is not running (i.e. case select is False).

image

There is one problem in the above VI. The rpm meter is fluctuating very much between 2000 & 5000. Maybe that is because the time_diff value is also fluctuating between 3 &4. To avoid this I need to calculate the average rpm over some values.

Calculating average rpm:

To calculate average rpm, I have increased the number of elements in the shift register I created for storing the time_diff values. So, now I am storing the previous 10 time_diff values calculated and then taking their average and then calculating the rpm.

image

Its still fluctuating a little bit but its better than before. I think it will become more smooth if I add more elements but for now I will proceed with this.

The first video is without averaging & the next video is with averaging the rpm.

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

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

Till this point everything was working fine, but then suddenly my motor stopped workingSlight frown. I took another dc motor but I couldn't remove the fan from my previous motor. So, I had to create my own flywheel and cut a slot out of it. With new flywheel & only a single slot I had to do some minor adjustments in my VI. I replaced 1500 with 3000, '<' sign with '>', 3500 with 1000 & '>' sign with '<'. And now I have to multiply the time_diff by 1 instead of 7 since I have only single slot now. This motor is old and not performing that well but I don't have any other option right now.

Adding duty cycle control VI:

Now, I added the duty cycle control VI to my main VI to change the speed of the motor. For now I have created a slider to control the duty cycle from 0 to 100 %. The motor stops below 50%. But we can vary the speed between 50% & 100%.

image

Adding temperature control to VI:

This is the last step. Since we can now control the motor speed using duty cycle, we are now going to control the duty cycle with temperature. To emulate high temperature, I am using an electric iron. As the temperature increases, the sensor data decreases. When it reaches below 550, the relay disconnects the supply and the motor stops.

image

Final Video:

 

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

The motor doesn't work properly, so I had to push it a little bitSweat smile. I guess that is okay.

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

Circuit Diagram:

image

Conclusion:

Before starting the project, I thought it would be simple. But as I proceeded, it became clearer that there are many things that we need to keep in mind while using labview. Thanks to community members' suggestions, I was able to improve my VI but still there is some fluctuations in rpm calculated. There can be several reasons for this: old motor not working properly, fluctuations in current supplied from the arduino etc. But right now I don't any other option.

But even with these issues, I was able to see the rpm decreasing with temperature increase. So, I think the project is working.

I would also like to thank all the community members who helped in resolving issues that I faced and would like to welcome suggestions for any improvements in my project. This was a great experience working on this project and I am very positive that this experience will prove out to be very useful in future.

Github link for files.

  • Sign in to reply
  • DAB
    DAB over 1 year ago

    Very nice update.

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

    Well, I did not know this: https://www.ni.com/docs/en-US/bundle/labview/page/passing-multiple-values-to-the-next-loop-iteration.html.  Looks useful so I'm glad you used it. I realise now you said it again that you changed to a 1-slot motor.

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

     Andrew J , we can understand it with the help of a fifo. When a value is inserted from the back, one value pops out from the front. Consider a shift register with 3 elements. In the first loop iteration, the first element will get the value. In the second iteration this value will pass to the second element and the first element will get some new value. This will continue for other elements also.

    image

    Actually, I was using a different motor (a small cpu fan) earlier which had 7 blades (7 slots). So, I had to multiply the time_diff by 7 to get time for one complete revolution. But then it stopped working, so I had to use another motor and make a flywheel with a slot. Since, there is only one slot now, I am multiplying by 1 only to get time for 1 revolution.

    Thanks!

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

    Wow this is some change, well done!  Teach me something now: how is that shift-register averaging working?  You are passing one value out (time difference) and it is looping back into 10 values???  That's not something I've seen before so I'd like to know more.

    Also, after doing the div by 10, you are only multiplying by 1 in the last VI image instead of 7, why is that?

    It's a nice project and it's great that you persevered with it.

    • 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