Robotics‎ > ‎Blimp‎ > ‎

Modify Your Code to Control DC Motors

Changes to your Arduino Code

Since the Blimp uses DC motors instead of servo motors, you'll need to use the MotorDriver library you created in the Learn to Use Motor Drivers video tutorial. Then, you'll need replace any code related to servo motors with code that uses your motor driver library.

Start by swapping the line that includes the servo library with the MotorDriver library:
#include <Servo.h> #include "MotorDriver.h"

Next, change how the motor objects are created:
Servo leftMotor; MotorDriver<16,5> leftMotor;
Servo rightMotor; MotorDriver<13,4> rightMotor;

Since your new library defines which pins are used when you create the motor objects, you can now delete the lines of code that attached your servos to pins:
  leftMotor.attach(10);
  rightMotor.attach(D4);

The manner in which we stopped the motors is different too. Instead of passing 1500 to the writeMicroseconds function to get the motors to stop, we now use the drive function in the library we created and send 0.
  leftMotor.writeMicroseconds(1500);  leftMotor.drive(0);
  rightMotor.writeMicroseconds(1500);  rightMotor.drive(0);

To control the motors, we must change the handleRemoteControl() function in a similar fashion.
  leftMotor.writeMicroseconds(1500 - server.arg("L").toInt());   leftMotor.drive(server.arg("L").toInt());
  rightMotor.writeMicroseconds(1500 + server.arg("R").toInt());  rightMotor.drive(server.arg("R").toInt());

Changes to your Cloud9 Web App Code

Rembmer that the esp8266 (the brain behind your Adafruit Huzzah Feather) has 10 bit DACs (digital to analog converters) which means they can accept 1024 distinct values (210 = 1024). Since the first value is a 0 instead of a 1, the range is between 0 and 1023. If we had motors that could handle all the voltage our motor drivers can supply, we would send our motors values that range ±1023. However, since our motors are only designed to handle 3.7 volts at most and our single cell LiPos reach 4.2 volts when fully charged, let's make the values we send ±800 (a little smaller than needed just to be on the safe side). Go to Cloud9 and pull up your code. To get values that are ±500, we multiplied the accelerometer axis by 60. Now we need to get values that are ±800, so try multiplying by 96 or thereabouts. Remember, you don't want to have to tilt your device 90 degrees to go or turn full speed.
  var power = Math.round(acceleration.z * 60);  var power = Math.round(acceleration.z * 96);
  var steering = Math.round(acceleration.y * 60);  var steering = Math.round(acceleration.y * 96);

One other issue we need to deal with is how to handle values that exceed our desired range. We don't need to worry about this when controlling servos because if we send a signal that is too high, they just continue going as fast as they can. However, if we send a value to our motor drivers that exceeds 1023, the count starts over. For example, if we sent 1025, the power level actually provided to the motors would be 2 since 1025 - 1023 = 2. Why would we need to worry about this if the values we are sending have a range of ±800? Keep in mind the way in which power and steering values are combined to create motor power levels. For the left motor we add them together. If you tilt your device forward and to the right, it is conceivable that you could send it 800 + 800, or 1600, which would yield an incorrect power less than 800 (1600 - 1023 - 577). Sending 600 + 600 would work, but would shorten the life of our motors. So, to prevent values that exceed our desired range, create a constrain function directly below the deviceMotionHandler() function. All this function will do is check to see if our motor power levels are too high or too low. If the value exceeds 800, it will bring the value down to 800. If the value is below -800 (for example, -900), it will bring the value up to -800.
        function constrainMotor(motorPower) {
            if (motorPower > 800)
                motorPower = 800;
            else if (motorPower < -800)
                motorPower = -800;
            return motorPower;
        }

To use our newly created constrain function, modify the lines at the bottom of the deviceMotionHanlder() function that set the power levels for your motors:
  leftMotor = power + steering;  leftMotor = constrainMotor(power + steering);
  rightMotor = power - steering;  rightMotor = constrainMotor(power - steering);

Comments