IMPORTANT: If you find this video helpful then please leave a LIKE, SHARE and SUBSCRIBE to support me in making more videos like this. 👍 CODE and SCHEMATICS ARE AVAILABLE HERE geekeeceebee.com/PID%20Controller.html More videos: DC Motor Position Control: ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE--P-6bMbQh1E.html
Great vid, thanks! However the Interrupt service routine for the encoder could be much more simple: use this on one Hall sensor's pin: attachInterrupt(digitalPinToInterrupt(pin), ISR, mode), and the 'mode' should be 'RISING' And to get the direction in the 'interrupt service routine', you only have to check whether the other Hall sensor's pin is HIGH or LOW at that moment.
This is one of the best explanation for PID, I wish in the future that you add explanations comments to your code, this will be very helpful for Arduino bigenners like me, thanks allot
Thanks, great video, clear explanation. I'll use your code in my project for a ros driver for controlling 4 dc motors that received the cmd_vel command.
@29:53 Why do you advise serial printing inside an interrupt? And @13:57 Why do you use 900 if you are counting the 4 edges of the two pulse trains A & B Most encoder PPR specifications are as the pulses on one channel, to be read as a clock+dir pair on one edge of a clock signal. Counting on all 4 edges is more complicated, but quadruples the resolution. If you're using the 80RPM motor with spec'd at 900PPR and reading all 4 edges, the divisor should be 3600 counts/rev. Using 900 instead of 3600, you are probably getting only 25RPM when you call for 100RPM. At 100RPM it should take 0.6 sec to do a revolution or 1.6 rev/sec, not 2.4sec/rev or 0.4rev/sec like at 31:26.
@GeeKee Ceebee first off great informative video overall; thank you! I am uncertain about some things you explained though...at 10:45 when you're checking the status of the encoder pins to determine clockwise or counterclockwise direction, you're saying check if pinB is high and pinA is low to constitute an upcount and every other case is downcount...it makes sense for the portions of the signals that are clearly pinB high and pinA low...but what about right after that condition when the controller sees pinB high and pinA high - it would downcount (undo the upcount it just did)? What if the motor is idle or stalling with either conditions of pinA, pinB both low or one being high the other being low or both being high?
The video was really helpful. I have one query: I want to track Theta, how can I put the values of the desired theta in code, I mean in formula or in array form please describe with a short overview example?
what is the ppr for the encoder. Here rising and falling conditions for pinA and pinB are considered. Therefore, is EncoderCount counted 4 times per pulse of pinA and pinB? Does that mean 4*ppr=900?
Excellent video thank you. I have an application where I'm trying to on control a bypass around a supercharger using a drive by wire throttle body. The controlled parameter is supercharger discharge pressure, which is limited by bypassing an increasing amount of air around the supercharger as engine speed increases. I presume that I can have one PID loop for the pressure control, and a second PID loop that positions the throttle plate to the commanded position via PWM (throttle plate position feedback is via a potentiometer). I presume that is easily accomplished in the Arduino environment. Do you have any comments or helpful hints on that approach?
THANKS A LOT CAN YOU PLEASE POST VIDEO FOR THE (CONTROLLING OF DC MOTOR 'ACTUATOR ' PROGRAMABLE POSITION WITH MEMORY BUTTONS USING ARDUINO. BEST WISHES
There's a position control video on my channel. Im planning on making a video on cascading loop controller for Torque, speed and position in the future
Do you think is it possible to model the motor mathematically? I mean, doing a open loop test for example? Then , it is possible to design the PID controller accordingly to the system control theory.
Absolutely! However, you would need several motor parameters such as Torque constant, inductance of the winding, friction, torque speed curve, etc to model the motor. I believe these can be obtain experimentally aswell. Using the state space representation, modelling the whole system with PID is fairly easy.
Hiya I believe he is using a 900 counts per evolution encoder - ie it is made to cause 900 pulses on its output in one revolution. Number is supplied by the manufacturer.
I think he's using an "Encoder Metal Gearmotor 12V DC 80 RPM Gear Motor with Encoder for Arduino and 3D Printers" motor specified with 900PPR, but is counting 4 edges/pulse so is actually getting 3600 counts/rev.
You would need to create a desired Theta ( desired angular position) trajectory. And the motor will basically track this desired trajectory. So the error becomes Theta desired minus Theta actual( motor angular position). Note that angular position could be in deg or radians, so proceed accordingly. Error = Theta_d - Theta After that tweak the gain values as needed. PI controller should be sufficient. Hope this is helpful :)
How can I choose an RPM - say I want to run my motor anywhere from 0-10 RPM and I'd like to choose a single RPM or vary that RPM over time. Where in the code can I adjust that
Great vid, I've a question: Whati is the benefit of usint the "time interrupt" instead of telling the program to enter into the PID loop when >50ms elpased from previous entry??? Thanks!
@@GeeKeeCeeBee I'm not talking about delay(50). But sg like this: if millis() > (PreviousLoopEntryTime + 50){ PreviousLoopEntryTime = millis() Preform the remaining of the loop }
I have not tried that logic but I don't see issues with your code. Also, millis() is based on Timer0 which is pre-configured to count clock pulses every 1ms. Either approach is fine imo.
I am trying to control a DC motor using the writeMicroseconds as opposed to having a straight voltage put into like your motor driver function. Do you think this is viable?
I dont see an issue if you're simply trying to run the DC motor, however, if you're trying to implement tracking control on DC motor then it'll probably wont work. Reason is that the encoder and DC motor have to run on the same Timer clock. I believe writemicroseconds use a different clock which wont allow event synchronization. Hope that helps.
I pretty sure the schematic is correct. If you leave jumper in then motor should run at full speed (at max supply voltage). In your case, as jumper is removed I would suggest to check your PWM pin and value that your sending. If PWM value is zero then there's no voltage going to the motor.
My RPMs are wrong! Where does that 900 come from? How can I fix this problem? On my encoder I can read it gives 11 signals when rotating one circle. Thanks so much for helping me!
Mybad, I missed this topic in the video. Theta = EncoderCount/ CountPerRevolution. In my case, 900 comes from the combination of Encoder's count per revolution (CPR) and motor gear ratio. CPR may be different depending on your motor and encoder specifications. Check your gear ratio, if any, and Encoder CPR. Hope this helps.