Chick92 / PWMMotorControl

Arduino library to control brushed DC motors by PWM and uses optional attached encoders to drive fixed distances..

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PWMMotorControl

Available as Arduino library "PWMMotorControl"

Version 2.0.0 - work in progress

License: GPL v3 Installation instructions Commits since latest Build Status Hit Counter

  • The PWMDcMotor.cpp controls brushed DC motors by PWM using standard full bridge IC's like L298, SparkFun Motor Driver - Dual TB6612FNG, or Adafruit_MotorShield (using PCA9685 -> 2 x TB6612).
  • The EncoderMotor.cpp.cpp controls a DC motor with attached encoder disc and slot-type photo interrupters to enable driving a specified distance.
  • The CarMotorControl.cpp controls 2 motors simultaneously like it is required for most Robot Cars.
  • To compensate for different motor characteristics, each motor can have a positive compensation value, which is subtracted from the requested speed if you use the setSpeedCompensation() functions. For car control, only compensation of one motor is required.

The motor is mainly controlled by 2 dimensions:

  1. Direction / motor driver control. Can be FORWARD, BACKWARD, BRAKE (motor connections are shortened) or RELEASE (motor connections are high impedance).
  2. Speed / PWM which is ignored for BRAKE or RELEASE. Some functions allow a signed speed parameter, which incudes the direction as sign (positive -> FORWARD).

Basic commands are:

  • init(uint8_t aForwardPin, uint8_t aBackwardPin, uint8_t aPWMPin).
  • setSpeed(uint8_t aRequestedSpeed, uint8_t aRequestedDirection) or setSpeed(int Signed_RequestedSpeed).
  • setSpeedCompensated(uint8_t Unsigned_RequestedSpeed, uint8_t aRequestedDirection) or setSpeedCompensated(int Signed_RequestedSpeed) and setSpeedCompensation(uint8_t aSpeedCompensation).
  • stop() or setSpeed(0).
  • getSpeed(), getAverageSpeed(), getDistanceMillimeter() and getBrakingDistanceMillimeter() for encoder motors.

To go a specified distance use:

  • setDefaultsForFixedDistanceDriving() to set start speed and driving speed. Minimal speed is the PWM value where the motors start to move. It depends of the motor supply voltage.
    Drving speed is the PWM value to use for driving a fixed distance. The software generates a ramp up from start to driving speed at the start of the movement and a ramp down to stop.
  • calibrate() to automatically set start speed for encoder or IMU supported cars.
  • startGoDistanceMillimeter(unsigned int aRequestedDistanceMillimeter, uint8_t aRequestedDirection) or setSpeed(uint8_t aRequestedSpeed, uint8_t aRequestedDirection) - for non encoder motors a formula, using distance and the difference between minimal speed and maximal speed, is used to convert counts into motor driving time.
  • updateMotor() - call this in your loop if you use the start* functions.

2 wheel car from LAVFIN with 2 LiPo batteries case, and IR receiver, wires not shortened. 2 wheel car Arduino Plotter diagram of PWM, speed[rpm] and encoder count for USB 3.8 volt supply and a Mosfet bridge. Timebase is 50 ms per plotted value. Generated by the PrintMotorDiagram example. USB powered Diagram of PWM, speed[rpm] and encoder count for 2 LiPo (7.5 volt) supply and a Mosfet bridge. 2 LiPo powered

Compile options / macros for this library

To customize the library to different requirements, there are some compile options / macros available.
Modify it by commenting them out or in, or change the values if applicable. Or define the macro with the -D compiler option for global compile (the latter is not possible with the Arduino IDE, so consider using Sloeber.
Some options which are enabed by default can be disabled by defining a inhibit macro like USE_STANDARD_LIBRARY_FOR_ADAFRUIT_MOTOR_SHIELD.

Macro Default File Description
USE_ENCODER_MOTOR_CONTROL disabled PWMDCMotor.h Use slot-type photo interrupter and an attached encoder disc to enable motor distance and speed sensing for closed loop control.
USE_MPU6050_IMU disabled CarIMUData.h Use GY-521 MPU6050 breakout board connected by I2C for support of precise turning and speed / distance calibration. Connectors point to the rear.
USE_ACCELERATOR_Y_FOR_SPEED undefined CarIMUData.h The y axis of the GY-521 MPU6050 breakout board points forward / backward, i.e. connectors are at the left / right side.
USE_NEGATIVE_ACCELERATION_FOR_SPEED undefined CarIMUData.h The speed axis of the GY-521 MPU6050 breakout board points backward, i.e. connectors are at the front or right side.
USE_ADAFRUIT_MOTOR_SHIELD disabled PWMDcMotor.h Use Adafruit Motor Shield v2 connected by I2C instead of simple TB6612 or L298 breakout board.
This disables tone output by using motor as loudspeaker, but requires only 2 I2C/TWI pins in contrast to the 6 pins used for the full bridge.
For full bridge, analogWrite the millis() timer0 is used since we use pin 5 & 6.
USE_OWN_LIBRARY_FOR_
ADAFRUIT_MOTOR_SHIELD
enabled PWMDcMotor.h Disable macro=USE_STANDARD_LIBRARY_
FOR_ADAFRUIT_MOTOR_SHIELD.
Disabling savesaves around 694 bytes program memory.

Default car geometry dependent values used in this library

These values are for a standard 2 WD car as can be seen on the pictures below.

Macro Default File Description
DEFAULT_CIRCUMFERENCE_MILLIMETER 220 PWMDCMotor.h At a circumference of around 220 mm this gives 11 mm per count.
ENCODER_COUNTS_PER_FULL_ROTATION 20 EncoderMotor.h This value is for 20 slot encoder discs, giving 20 on and 20 off counts per full rotation.
FACTOR_DEGREE_TO_MILLIMETER_DEFAULT 2.2777 for 2 wheel drive cars, 5.0 for 4 WD cars CarMotorControl.h Reflects the geometry of the standard 2 WD car sets. The 4 WD car value is estimated for slip on smooth surfaces.

Other default values for this library

These values are used by functions and some can be overwritten by set* functions.

Macro Default File Description
VIN_2_LIPO undefined PWMDCMotor.h If defined sets FULL_BRIDGE_INPUT_MILLIVOLT to 7400.
FULL_BRIDGE_INPUT_
MILLIVOLT
6000 or 7400 if VIN_2_LIPO is defined PWMDCMotor.h The supply voltage used for the full bridge.
MOSFET_BRIDGE_USED undefined PWMDCMotor.h If defined sets FULL_BRIDGE_LOSS_MILLIVOLT to 0.
FULL_BRIDGE_LOSS_
MILLIVOLT
2000 or 0 if FULL_BRIDGE_LOSS_MILLIVOLT is defined PWMDCMotor.h The internal voltage loss of the full bridge used, typically 2 volt for bipolar bridges like the L298.
FULL_BRIDGE_OUTPUT_
MILLIVOLT
(FULL_BRIDGE_INPUT_MILLIVOLT - FULL_BRIDGE_LOSS_MILLIVOLT) PWMDCMotor.h The effective voltage available for the motor.
DEFAULT_START_
MILLIVOLT
1100 PWMDCMotor.h The DC Voltage at which the motor start to move / dead band voltage.
DEFAULT_DRIVE_
MILLIVOLT
2000 PWMDCMotor.h The derived DEFAULT_DRIVE_SPEED is the speed PWM value used for fixed distance driving.
DEFAULT_MILLIMETER_
PER_SECOND
320 PWMDCMotor.h Value at DEFAULT_DRIVE_MILLIVOLT motor supply. A factor used to convert distance to motor on time in milliseconds using the formula:
computedMillisOf
MotorStopForDistance = 150 + (10 * ((aRequestedDistanceCount * DistanceToTimeFactor) / DriveSpeed))

Modifying compile options with Arduino IDE

First use Sketch > Show Sketch Folder (Ctrl+K).
If you did not yet stored the example as your own sketch, then you are instantly in the right library folder.
Otherwise you have to navigate to the parallel libraries folder and select the library you want to access.
In both cases the library files itself are located in the src directory.

Modifying compile options with Sloeber IDE

If you are using Sloeber as your IDE, you can easily define global symbols with Properties > Arduino > CompileOptions.
Sloeber settings

Full bridges

This library was tested with the bipolar full bridge IC L298 and the MOSFET IC MTB6612. L298 board TB6612 board

The L298 has a loss of around 2 volt, which the reason for the attached heat sink, the MTB6612 has almost no loss.

Internals

  • PWM period is 600 µs for Adafruit Motor Shield V2 using PCA9685.
  • PWM period is 1030 µs for using AnalogWrite on pin 5 + 6.

Examples

Start

To check the default values of StartSpeed and DriveSpeed. One motor starts with StartSpeed for one second, then runs 1 second with DriveSpeed. After stopping the motor, it tries to run for one full rotation (resulting in a 90 degree turn for a 2WD car). Then the other motor runs the same cycle. For the next loop, the direction is switched to backwards.

Square

4 times drive 40 cm, then 90 degree left turn. After the square, the car is turned by 180 degree and the direction is switched to backwards. Then the square starts again.

PrintMotorDiagram

Prints PWM, distance and speed diagram of an encoder motor.

Diagram for free running motor controlled by an MosFet bridge supplied by 7.0 volt Diagram for free running motor controlled by an L298 bridge supplied by 7.6 volt
7.0V MosFet free run 7.6V L298 free run

TestMotorWithIMU

Diagram for car controlled by an MosFet bridge Diagram for car controlled by an L298 bridge
2WD Smart Car Lafvin car

RobotCarBasic

Template for your RobotCar control. Currently implemented is: drive until distance too low, then stop, and turn random amount.

RobotCarFollowerSimple

The car tries to hold a distance between 20 and 30 cm to an obstacle. The measured distance is converted to a pitch as an acoustic feedback.

RobotCarFollower

The car tries to hold a distance between 20 and 30 cm to an target. If the target vanishes, the distance sensor scans for the vanished or a new target.

RobotCarBlueDisplay

Enables autonomous driving of a 2 or 4 wheel car with an Arduino and a Adafruit Motor Shield V2.
To avoid obstacles a HC-SR04 Ultrasonic sensor mounted on a SG90 Servo continuously scans the environment. Manual control is implemented by a GUI using a Bluetooth HC-05 Module and the BlueDisplay library.

Just overwrite the function doUserCollisionDetection() to test your own skill.
You may also overwrite the function fillAndShowForwardDistancesInfo(), if you use your own scanning method.

Compile options / macros for RobotCar example

To customize the RobotCar example to cover different extensions, there are some compile options available.

Option Default File Description
USE_LAYOUT_FOR_NANO disabled RobotCar.h Use different pinout for Nano board. It has A6 and A7 available as pins.
CAR_HAS_4_WHEELS disabled RobotCar.h Use modified formula for turning the car.
USE_US_SENSOR_1_PIN_MODE disabled RobotCar.h Use modified HC-SR04 modules or HY-SRF05 ones.
Modify HC-SR04 by connecting 10kOhm between echo and trigger and then use only trigger pin.
CAR_HAS_IR_DISTANCE_SENSOR disabled RobotCar.h Use Sharp GP2Y0A21YK / 1080 IR distance sensor.
CAR_HAS_TOF_DISTANCE_SENSOR disabled RobotCar.h Use VL53L1X TimeOfFlight distance sensor.
DISTANCE_SERVO_IS_MOUNTED_HEAD_DOWN disabled Distance.h The distance servo is mounted head down to detect even small obstacles.
CAR_HAS_CAMERA disabled RobotCar.h Enables the Camera button for the PIN_CAMERA_SUPPLY_CONTROL pin.
CAR_HAS_LASER disabled RobotCar.h Enables the Laser button for the PIN_LASER_OUT / LED_BUILTIN pin.
CAR_HAS_PAN_SERVO disabled RobotCar.h Enables the pan slider for the PanServo at the PIN_PAN_SERVO pin.
CAR_HAS_TILT_SERVO disabled RobotCar.h Enables the tilt slider for the TiltServo at the PIN_TILT_SERVO pin..
MONITOR_LIPO_VOLTAGE disabled RobotCar.h Shows VIN voltage and monitors it for undervoltage. Requires 2 additional resistors at pin A2.
VIN_VOLTAGE_CORRECTION undefined RobotCar.h Voltage to be subtracted from VIN voltage. E.g. if there is a series diode between LIPO and VIN set it to 0.8.

If you find this library useful, please give it a star.

Pictures

Connection schematic of the L298 board for the examples. If motor drives in opposite direction, you must flip the motor to L298 connections. L298 connections Connections on the Arduino and on the L298 board.
Sensor shield connections L298 connections

2 wheel car with encoders, slot-type photo interrupter, 2 LiPo batteries, Adafruit Motor Shield V2, HC-05 Bluetooth module, and servo mounted head down. 2 wheel car 4 wheel car with servo mounted head up. 4 wheel car Encoder slot-type photo interrupter sensor Encoder slot-type photo interrupter sensor Servo mounted head down Servo mounting VIN sensing VIN sensing

SCREENSHOTS

Start page MStart page Test page Manual control page Automatic control page with detected wall at right Automatic control page

  • Green bars are distances above 1 meter or above double distance of one ride per scan whichever is less.
  • Red bars are distanced below the distance of one ride per scan -> collision during next "scan and ride" cycle if obstacle is ahead.
  • Orange bars are the values between the 2 thresholds.
  • The tiny white bars are the distances computed by the doWallDetection() function. They overlay the green (assumed timeout) values.
  • The tiny black bar is the rotation chosen by doCollisionDetection() function.

Revision History

Version 2.0.0 - work in progress

  • Support of off the shelf smart cars.
  • Added and renamed functions.
  • Converted to voltage based formulas.

Version 1.0.0

  • Initial Arduino library version.

About

Arduino library to control brushed DC motors by PWM and uses optional attached encoders to drive fixed distances..

License:GNU General Public License v3.0


Languages

Language:C++ 88.7%Language:C 11.3%