Skip to content

Latest commit

 

History

History
218 lines (150 loc) · 13.2 KB

Using-Motors-Run-Forever.md

File metadata and controls

218 lines (150 loc) · 13.2 KB

This page introduces the fundamental run_forever mode of the ev3dev motor driver. It's part of a series of wiki pages that describe using motors with the EV3 running ev3dev that includes:

Table of Contents

The simplest ev3dev motor driver operation is the so-called run_forever mode. You specify the pulses_per_second_sp attribute and the motor driver runs the motor until you tell it to stop. You can also use the regulation_mode attribute to affect how the driver handles changes in motor speed due to loading.

The examples below all assume we're starting from where we left off in the previous tutorial - Using Motors.

The run_mode attribute determines how the motor is going to run. The default run_mode when you plug in a motor is forever - which is exactly what we need here. Read the current run_mode of your motor to be sure it's set correctly. If it's anything other than forever, just unplug the motor for a few seconds and plug it in again to reset it.

user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/run_mode
forever

Here's where we encounter our first bit of potentially confusing information. We need to talk about regulation_mode before we describe duty_cycle_sp and pulses_per_second_sp.

The standard LEGO firmware, and previous versions of ev3dev used speed as a catch-all to describe how fast the motor should go. As you'll see shortly, the meaning of speed depends on whether the motor is running in regulated mode.

The regulation_mode attribute has two possible values on and off - the default is off. To turn on regulation, all you need to do is write on to the regulation_mode attribute, like this:

user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/regulation_mode
off
user@ev3dev:~$ echo on > /sys/class/tacho-motor/tacho-motor2/regulation_mode
user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/regulation_mode
on
user@ev3dev:~$ echo off > /sys/class/tacho-motor/tacho-motor2/regulation_mode
user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/regulation_mode
off

Let's start with regulation_mode set to off. In this mode, the motor driver uses the duty_cycle_sp to determine what percentage of the battery voltage to send to the motor.

If you run the motor at a fairly low duty_cycle_sp, and you try to stop the hub of the motor with your thumb, you'll find it's pretty easy to slow down or even stop the motor. In some cases, this is not what you want. You want the motor to "try harder" when it encounters resistance - and the regulation_mode attribute is going to help us with that.

When the regulation_mode attribute is set to on, the motor driver attempts to keep the motor speed at the value you've specified in pulses_per_second_sp. If you slow down the motor with a load, the motor driver tries to compensate by sending more power to the motor to get it to speed up. If you speed up the motor for some reason, the motor driver will try to compensate by sending less power to the motor.

To summarize:

regulation_mode Controlling Setpoint Actual Value
off (default) duty_cycle_sp duty_cycle
on pulses_per_second_sp pulses_per_second

Regulation can help when the batteries start running low. Remember that the duty_cycle_sp in unregulated mode just sends a percentage of the battery voltage to the motor. When the batteries get depleted, the percentage stays the same but the resulting voltage at the motor goes down in proportion to the battery, and the motor will run slower.

Turning regulation on in this case will make the EV3 driver the ports a little harder to compensate for the lower battery voltage to try and keep the speed at the pulses_per_second_sp.

Changing the regulation_mode while the motor is running can lead to unexpected operation, so avoid doing that.

The duty_cycle_sp is useful when you just want to turn the motor on and are not too concerned with how stable the speed is. The duty_cycle_sp attribute accepts values from -100 to +100. The sign of the attribute determines the direction of the motor.

It's easy to control the motor using this attribute - here's an example that sets the duty_cycle_sp to a series of values, including an illegal one. Note that the motor will not actually turn on yet, that's the next attribute we'll go over.

user@ev3dev:~$ echo   0 > /sys/class/tacho-motor/tacho-motor2/duty_cycle_sp
user@ev3dev:~$ echo   1 > /sys/class/tacho-motor/tacho-motor2/run
user@ev3dev:~$ echo  25 > /sys/class/tacho-motor/tacho-motor2/duty_cycle_sp
user@ev3dev:~$ echo  50 > /sys/class/tacho-motor/tacho-motor2/duty_cycle_sp
user@ev3dev:~$ echo -50 > /sys/class/tacho-motor/tacho-motor2/duty_cycle_sp
user@ev3dev:~$ echo 101 > /sys/class/tacho-motor/tacho-motor2/duty_cycle_sp
-bash: echo: write error: Invalid argument

Of course, you can read the duty_cycle_sp back using the by-now familiar cat command:

user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/duty_sycle_sp
-50

Yep, that was the last reasonable value that was set!

The run attribute is a numerical value - 0 means stop, anthing else means run

Here we will force the motor to run at the desired duty_cycle_sp forever. You can update the duty_cycle_sp while the motor is running.

user@ev3dev:~$ echo  50 > /sys/class/tacho-motor/tacho-motor2/duty_cycle_sp
user@ev3dev:~$ echo   1 > /sys/class/tacho-motor/tacho-motor2/run
user@ev3dev:~$ echo  75 > /sys/class/tacho-motor/tacho-motor2/duty_cycle_sp
user@ev3dev:~$ echo -50 > /sys/class/tacho-motor/tacho-motor2/duty_cycle_sp

You can read the position, speed, and state of the motor too:

user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/state
ramp_const
user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/pulses_per_second
-409
user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/duty_cycle
-50
user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/position
-9044

If you're paying attention, you'll be asking yourself what the ramp_const state could possibly be for. That will come in the next tutorial. For now, you can think of this state as one where the motor control setpoint is at a constant value.

And of course, you can stop the motor by writing 0 to the run attribute.

user@ev3dev:~$ echo 0 > /sys/class/tacho-motor/tacho-motor2/run
user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/state
idle

The motor should gently "coast" to a stop. We'll discuss making the motor "brake" instead of coast a bit later.

So far we've covered running the motor with regulation_mode set to off - now let's see what happens when we set regulation_mode to on.

Recall that regulation_mode set to on uses a different control setpoint - pulses_per_second_sp. The motor driver attempts to keep the motor speed at the set value even in the face of varying loads. This is a much more reliable way to drive the motor at very low speeds.

The useful pulses_per_second_sp attribute range depends on the motor type. For the standard tacho motor it's about +/- 900. The new minitacho motor has a useful range of about +/- 1200 pulses per second.

We want to allow for future expansion, so the range of values accepted for pulses_per_second_sp is +/- 2000.

Here's an example of valid and invalid writes to the pulses_per_second_sp attribute:

user@ev3dev:~$ echo -400 > /sys/class/tacho-motor/tacho-motor2/pulses_per_second_sp
user@ev3dev:~$ echo  400 > /sys/class/tacho-motor/tacho-motor2/pulses_per_second_sp
user@ev3dev:~$ echo 1500 > /sys/class/tacho-motor/tacho-motor2/pulses_per_second_sp
user@ev3dev:~$ echo 2001 > /sys/class/tacho-motor/tacho-motor2/pulses_per_second_sp
-bash: echo: write error: Invalid argument

Of course, you can read the speed_setpoint back using the cat command:

user@ev3dev:~$ cat /sys/class/tacho-motor/tacho-motor2/pulses_per_second_sp
1500

Yep, that was the last reasonable value that was set!

By this time, you should be able to figure out how to play around with this atribute, but here's an example anyways:

user@ev3dev:~$ echo   on > /sys/class/tacho-motor/tacho-motor2/regulation_mode
user@ev3dev:~$ echo  500 > /sys/class/tacho-motor/tacho-motor2/pulses_per_second_sp
user@ev3dev:~$ echo    1 > /sys/class/tacho-motor/tacho-motor2/run
user@ev3dev:~$ echo  300 > /sys/class/tacho-motor/tacho-motor2/pulses_per_second_sp
user@ev3dev:~$ echo  100 > /sys/class/tacho-motor/tacho-motor2/pulses_per_second_sp
user@ev3dev:~$ echo -300 > /sys/class/tacho-motor/tacho-motor2/pulses_per_second_sp
user@ev3dev:~$ echo    0 > /sys/class/tacho-motor/tacho-motor2/run

You'll notice that when regulation_mode is on the motor tends to "jump" up to the setpoint, even overshooting the speed before settling down. This is most noticeable when there is very little load on the motor. In the next tutorial, we'll cover ramping the speed up and down to achieve smooth changes in speed.

If you have been following along with the examples, you'll notice that the motor does not stop immediately when run is set to 0. For some kinds of robots, a more precise method of stopping is needed - and that's where the stop_mode attribute comes in.

In previous versions of ev3dev this was a simple on and off attribute - but now it has three values. They are coast (the default) brake and hold. In coast mode, when the motor is turned off the internal H-bridge that drives the motors is left in a state where there is no load applied to the motor. When you set the stop_mode attribute to brake, the H-bridge applies a short across the motor terminals.

To see the effect of this in action, turn the hub of the motor when it is disconnected from the brick. Note the relative ease of turning the hub, and how it coasts after you stop spinning it.

Now attach the standard tacho motor to the other tacho motor in the kit, using one of the connection cables. Turn on of the motor hubs. Did you notice that it was a bit harder to turn? Did you notice that the hub of the other motor turned too? That's the effect of a motor in generator mode. Applying energy to the output of the motor (turning the hub) results in electricity being generated by the motor!

Now hold the hub of the one motor in fixed position while turning the hub of the other motor. Notice that the hub is much harder to turn now, and no longer "coasts" to a stop.

Notice the difference in how the motor stops in the following example:

user@ev3dev:~$ echo    on > /sys/class/tacho-motor/tacho-motor2/regulation_mode
user@ev3dev:~$ echo   500 > /sys/class/tacho-motor/tacho-motor2/pulses_per_second_sp
user@ev3dev:~$ echo     1 > /sys/class/tacho-motor/tacho-motor2/run
user@ev3dev:~$ echo     0 > /sys/class/tacho-motor/tacho-motor2/run
user@ev3dev:~$ echo brake > /sys/class/tacho-motor/tacho-motor2/stop_mode
user@ev3dev:~$ echo     1 > /sys/class/tacho-motor/tacho-motor2/run
user@ev3dev:~$ echo     0 > /sys/class/tacho-motor/tacho-motor2/run

You can update the stop_mode even while the motor is running, but you won't see its effect until the motor stops. Also note that the motor driver is left in brake mode, and that the motor hub is harder to turn than when it's in coast mode.

While the stop_mode attribute set to brake improves the ability of the motor to stop quickly, the hold value does it one better. This mode is used to tell the motor driver to hold its position after it has been turned off.

Be careful, this can consume quite a bit of power if you are trying to hold a large load stationary.

Note that this is the only attribute that has any effect on the motor when the motor run attribute is '0' - so you can test it right away. Enter the following commands if your motor is plugged in to Motor Port B, and then try and turn the motor hub!

user@ev3dev:~$ cat         /sys/class/tacho-motor/tacho-motor2/stop_mode
brake
user@ev3dev:~$ echo hold > /sys/class/tacho-motor/tacho-motor2/stop_mode
user@ev3dev:~$ cat         /sys/class/tacho-motor/tacho-motor2/stop_mode
hold

When you select the hold for the stop_mode, you'll notice a slight overshoot in position if the motor is running with little or no load. In the next tutorial, we'll cover ramping the speed up and down to achieve smooth hold mode operation.