Serial interface for our steering object - P2 Spin2/Pasm2 for our 6.5" Hub Motors with Universal Motor Driver Boards
There are two objects in our motor control system. There is a lower-level object (isp_bldc_motor.spin2) that controls a single motor and there's an upper-level object (isp_steering_2wheel.spin2) which coordinates a pair of motors as a drive subsystem.
This document describes the serial interface of the steering object which controls a dual motor robot platform.
The drive subsystem currently uses two cogs, one for each motor. A third cog privides motor position sense. Conceptually, the drive system is always running. It is influenced by updating control variable values. When the values change the drive subsystem responds accordingly. The public methods of the steering object simply writes to these control variables and/or read from associated status variables of the sensor cog returning their current value or an interpretation thereof.
This steering object makes it easy to make your robot drive forward, backward, turn, or stop. You can adjust the steering to make your robot go straight, drive in arcs, or make tight turns. This steering object is for robot vehicles that have two motors, with one motor driving the left side of the vehicle and the other the right side.
With each public method of this object we've added the serial command and response values. in this example:
SER drivedir {pwr} {dir}
SER Returns: OK | ERROR {errormsg}
... we see the first line represents the command to be sent from the connected device (RPi, Arduino, etc.) to the P2 via serial. On the second line we see "Returns:" meaning that the P2 upon receiving the command will return the specified response.
Generally speaking when driving a robot using these serial commands one expects to see:
commandA
ok
commandB
ok
commandC
ok
... the non OK responses are there to help us detect problems early in the development of our control routines. We don't expect to be getting non-OK responses once we've developed our drive code. The exception to this would be if our drive code generates values which would be out of the range of legal values for a given command.
The object isp_steering_2wheel.spin2 provides the following methods:
Steering Interface | Description |
---|---|
>--- CONTROL | |
PUB driveDirection(power, direction) SER drivedir {pwr} {dir} |
Control the speed and direction of your robot using the {power} and {direction} inputs. Turns both motors on at {power, [(-100) to 100]} but adjusted by {direction, [(-100) to 100]}. AFFECTED BY: setAcceleration(), setMaxSpeed(), holdAtStop() |
PUB driveForDistance(leftDistance, rightDistance, distanceUnits) SER drivedist {ltdist} {rtdist} {d-u} |
Control the forward direction or rate of turn of your robot using the {leftDistance} and {rightDistance} inputs. Turn both motors on then turns them off again when either reaches the specified {leftDistance} or {rightDistance}, where {*distance} is in {distanceUnits} [DDU_IN, DDU_CM, DDU_FT or DDU_M]. AFFECTED BY: setAcceleration(), setMaxSpeedForDistance(), holdAtStop() |
PUB driveAtPower(leftPower, rightPower)SER drivepwr {ltpwr} {rtpwr} |
Control the speed and direction of your robot using the {leftPower} and {rightPower} inputs. Turns left motor on at {leftPower} and right on at {rightPower}. Where {*Power} are in the range [(-100) to 100]. AFFECTED BY: setAcceleration(), setMaxSpeed(), holdAtStop() |
PUB stopAfterRotation(rotationCount, rotationUnits)SER stopaftrot {count} {r-u} |
Stops both motors, after either of the motors reaches {rotationCount} of {rotationUnits} [DRU_DEGREES, DRU_ROTATIONS, or DRU_HALL_TICKS]. USE WITH: driveDirection(), drive() |
PUB stopAfterDistance(distance, distanceUnits)SER stopaftdist {dist} {d-u} |
Stops both motors, after either of the motors reaches {distance} specified in {distanceUnits} [DDU_IN, DDU_CM, DDU_FT or DDU_M]. USE WITH: driveDirection(), drive() |
PUB stopAfterTime(time, timeUnits)SER stopafttime {time} {t-u} |
Stops both motors, after {time} specified in {timeUnits} [DTU_IN_MILLISEC or DTU_IN_SEC] has elapsed. USE WITH: driveDirection(), drive() |
PUB stopMotors()SER stopmotors |
Stops both motors, killing any motion that was still in progress AFFECTED BY:holdAtStop() |
PUB emergencyCutoff()SER emercutoff |
EMERGENCY-Stop - Immediately stop both motors, killing any motion that was still in progress |
PUB clearEmergency()SER emerclear |
clear the emergency stop status allowing motors to be controlled again |
>--- CONFIG | |
PUB start(eLeftMotorBasePin, eRightMotorBasePin, eMotorVoltage)SER N/A |
Specify motor control board connect location for each of the left and right motor control boards |
PUB stop() SER N/A |
Stop cogs and release pins assigned to motor drivers |
PUB setAcceleration(rate)SER setaccel {rate} |
NOT WORKING, YET Limit Acceleration to {rate} where {rate} is [??? - ???] mm/s squared (default is ??? mm/s squared) |
PUB setMaxSpeed(speed)SER setspeed {speed} |
Limit top-speed to {speed} where {speed} is [1 to 100] - DEFAULT is 75 and applies to both forward and reverse |
PUB setMaxSpeedForDistance(speed)SER setspeedfordist {speed} |
Limit top-speed of driveDistance() operations to {speed} where {speed} is [1 to 100] - DEFAULT is 75 and applies to both forward and reverse |
PUB calibrate() SER N/A |
NOT WORKING, YET (we may need this?) |
PUB holdAtStop(bEnable)SER hold {true | false} |
Informs the motor subsystem to actively hold postiion (bEnable=true) or coast (bEnable=false) at end of motion |
PUB resetTracking()SER resettracking |
Resets the position tracking values returned by getDistance() and getRotations() |
>--- STATUS | |
PUB getDistance(distanceUnits) : leftDistanceInUnits, rightDistanceInUnitsSER getdist {d-u} |
Returns the distance in {distanceUnits} [DDU_IN, DDU_CM, DDU_FT or DDU_M] travelled by each motor since last reset |
PUB getRotationCount(rotationUnits) : leftRotationCount, rightRotationCount SER getrot {r-u} |
Returns accumulated {*RotationCount} in {rotationUnits} [DRU_DEGREES, DRU_ROTATIONS, or DRU_HALL_TICKS], since last reset, for each of the motors. |
PUB getPower() : leftPower, rightPower SER getpwr |
Returns the last specified power value for each of the motors (will be zero if the motor is stopped). |
PUB getStatus() : eLeftStatus, eRightStatusSER getstatus |
Returns status of motor drive state for each motor: enumerated constant: DS_MOVING, DS_HOLDING, DS_OFF, or DS_Unknown |
PUB getMaxSpeed() : maxSpeed SER getmaxspd |
Returns the last specified {maxSpeed} |
PUB getMaxSpeedForDistance() : maxSpeed4dist SER getmaxspdfordist |
Returns the last specified {maxSpeedForDistance} |
NOTE1 {power} whenever used is [(-100) - 100] where neg. values drive backwards, pos. values forward, 0 is hold/stop
NOTE2 {direction} whenever used is [(-100) - 100] A value of 0 (zero) will make your robot vehicle drive straight. A positive number (greater than zero) will make the robot turn to the right, and a negative number will make the robot turn to the left. The farther the steering value is from zero, the tighter the turn will be.
NOTE3 A HALL TICK is 4° for our 6.5" Dia. Motors.
NOTE4 {e*MotorBasePin} is one of: PINS_P0_P15, PINS_P16_P31, or PINS_P32_P47
NOTE5 {eMotorVoltage} is one of: PWR_7p4V, PWR_11p1V, PWR_12V, PWR_14p8V, PWR_18p5V, or PWR_22p2V
If you like my work and/or this has helped you in some way then feel free to help me out for a couple of ☕'s or 🍕 slices!
Parallax, Propeller Spin, and the Parallax and Propeller Hat logos are trademarks of Parallax Inc., dba Parallax Semiconductor
Licensed under the MIT License.
Follow these links for more information: