Reply To: Rotation Count Question

HomeForumsMonoBrick EV3 FirmwareRotation Count QuestionReply To: Rotation Count Question

#3674
Author Image
Anders Søborg
Keymaster

Hi again.

Let me start off by “reviewing” your program. For whatever reason you have the following code when waiting for the tacho count to exceed 3600.


while(motor.GetTachoCount() <= 3600){
   System.Threading.Thread.Sleep(1);
}

On Windows the minimum sleep time is something like 20-30 ms – what it is on the EV3’s ARM processor I am not aware off but you could do some measurements to find out. Moreover Thread.Sleep is not guaranteed to sleep for exactly the specified amount of time – so that is why you get different results each time. So instead of suspending the current thread with a sleep do busy polling like shown below.


using System;
using MonoBrickFirmware;
using MonoBrickFirmware.Movement;
using MonoBrickFirmware.Display;
using MonoBrickFirmware.UserInput;

namespace MotorExample
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			  
			  Motor motor = new Motor(MotorPort.OutA);
			  motor.ResetTacho();
			  motor.On(100);
			  while(motor.GetTachoCount() <= 3600){}
			  motor.Brake();
			  LcdConsole.WriteLine("Tacho count: " + motor.GetTachoCount());
			  Buttons btns = new Buttons();
			  btns.GetKeypress();
                          motor.Off();       
		}
	}
}

When I run this program the motor stops at the same position each time (+/- 1 degree). However the position it stops at is 3625 due to that fact that when you “ask” the motor to stop it will have a certain moment of inertia so physically you can not stop strait away. When you run the above program you will probably get a different result – your motor might stop at 3619 each time – why? You might be using rechargeable batteries which has a lower voltage so your motor will actually run slower when you apply full “speed” by calling motor.On(100). Another option could be that your motor might have a slightly larger internal resistance (more friction or even a different internal ohmic resistance). This is the reason why this is a bad solution for position control. Another reason is that the motor might have a large load (a large robot that it has to move) and when you try to brake instantly when it is running at full speed – it will take longer to brake compared to a motor without a load. The position it stops at even depends on the surface on which the robot is running… for some project the code above might be sufficient but if you want to be sure that you end up at the exact position you need to use some sort of control loop.

With a control loop you calculate the difference between where you want to move and the current position. This difference is most often called “the error”. The error is then fed into the controller. Based on the current error (and the previous errors) a new output value is calculated and applied. This is repeated until the error is zero (or within some limits). A control loop is not only limited to controlling the position but can also be applied to control the speed.

The function build into the MonoBrick firmware calls the “kernel” driver which uses a PID controller with a build in ramp generator. This is fine for most motor movements. What is wrong with the ramp of this function?

Posted in

Make a donation