NanoRama

Enter Your Project for a chance to win a Nano Grand Prize bundle for the most innovative use of Arduino plus a $400 shopping cart!

Back to The Project14 homepage

Project14 Home
Monthly Themes
Monthly Theme Poll

 

Happy Birthday Arduino and Arduino Nano. As my contribution to the Arduino Birthday Celebrations and Nanorama Day I decided to make a DC motor version of a one dimension ultrasonic mobile robot. This robot only moves in one direction: forwards! I have to pick it up to put it back on the starting position. It uses 3D printed guides to follow a 5 ft ruler placed on a flat surface. The ultrasonic rangefinder is used to measure the distance to the nearest object directly in front of the mobile robot and then accelerates, coasts and then de-accelerates to come to a stop just before the object.

 

 

As shown in the video it mostly works. It is not so good at the shorter distances as the acceleration and de-acceleration periods are fixed so there is a minimum distance the vehicle will always move. Plus, there is some wheel slip especially when first accelerating and this leads to some variability in the acceleration distance. The circuit is fairly straight forward as illustrated below. The Nano produces a varying PWM signal to drive one of the H bridge drivers on the DRV8833 board using D2 and D3 and the Trig and Echo connections of the HC-04 ultrasonic rangefinder are connected to D6 and D7.

 

Circuit Diagram for the 1DUltraBot DC Motor Version

 

For the software I wrote a function to handle the generation of the PWM signal, see below:

 

void DCmotorpwm(int mark, int total, int count, int inhigh, int inlow)

{

int countindex, pwmindex;

countindex = 0;
pwmindex = 0;
 
digitalWrite(inhigh, HIGH);   // Set the motor direction
digitalWrite(inlow, LOW);


for (countindex = 0; countindex < count; countindex++)
  {
    for (pwmindex = 0; pwmindex < mark; pwmindex++)
      {
        digitalWrite(inhigh, HIGH);
        delayMicroseconds(10);       
      } /* for */
    for (pwmindex = mark; pwmindex < total; pwmindex++)
      {
        digitalWrite(inhigh, LOW);
        delayMicroseconds(10);       
      } /* for */
  } /* for */

//digitalWrite(inhigh, LOW);   // Set the motor off
//digitalWrite(inlow, LOW); 
} /* DCmotorpwm */

 

The function is passed five parameters as I wanted to use it for acceleration and de-acceleration. The first parameter passed to it is the mark length of that. There is no error checking (who has time for fun projects) so the user has to ensure all values passed are less than the maximum pulse duration. The second parameter is the maximum duration and I used 100 for that. The third parameter is the number of PWM pulses to be generation that this specific MARK:SPACE ratio. The final two parameters are the two connections to be used for driving the H bridge. By swapping these two numbers the motor can be reversed as well as allowing the second H-bridge to be controlled if needed without the need for any additional functions.

 

This function is then used in an acceleration phase, followed by a constant velocity phase where the duration is a multiple of the distance measured, followed by a de-acceleration phase, see below:

 

while (1)
  {
    Serial.println("1DUltraABot Robot DC " );
    Serial.println("Dubbie Dubbie : Just for Fun " );
    Serial.println(" 21st March'20 ");
    Serial.println();
    delay(500);

while(1)
  {
    dist_value = 0;
    dist_value = range();
    Serial.print("Distance is ");
    Serial.println(dist_value) ;   
//  } /* while */
 
// Acceleration period   
    for (accel = 20; accel < 60; accel = accel + 10)
      {
        DCmotorpwm(accel, 80, 100, motor2, motor1);
      } /* for */
   
// This is the constant speed section
    DCmotorpwm(50, 100, dist_value * 6, motor2, motor1);   

 

// De-acceleration period   
    for (accel = 50; accel > 10; accel = accel - 10)
      {
        DCmotorpwm(accel, 80, 100, motor2, motor1);
      } /* for */

             
// Everything off
    digitalWrite(motor1, LOW);
    digitalWrite(motor2, LOW);

 

while(1)
  {
    // Wait for a reset
  } /* while */

 

Although I used while loops, the main section only runs once and then enters an infinite while loop where it does nothing. This was to enable me to position the vehicle correctly on the guide ruler at the beginning and makes it much easier to handle. Pressing the reset button on the Nano causes the whole thing to perform another forward manoeuvre.

 

It is not the best programme in the world as I wrote much of it quickly this morning and now it is lunch time, but it works. I was very pleased with how the whole thing worked out. Regretfully I was not able to get the pre-existing toy car body to fit back onto the chassis, maybe I'll do that another day. There is also a problem when it is de-accelerating as the motor does not provide much (if any?) braking so it does overrun quite a bit. I'm not sure what to do about this. I tried inserting a short reversing period at the end of the de-acceleration period but that just made it jerk. I did think I could try regenerative braking by shorting the DC motor using the H bridge driver, but that sounded like it might break something so I didn't try it.

 

I'm now looking forward to seeing everyone else's Nanorama and Arduino Day projects.

 

Dubbie