Showing posts with label Parallax. Show all posts
Showing posts with label Parallax. Show all posts

Wednesday, December 9, 2015

Parallax HB-25 Motor Control Library for Arduino

Moving AVA


We are using the Arlo robotics platform from Parallax to build up AVA. As you can see in the schematic below, this incorporates two HB-25 motor controllers (Part Number: #29144) which look after the left and right wheels.


After an exhaustive search we were not able to find an existing Arduino library for the HB25, so we were forced to write our own. This involved delving into the incomplete version of C++ which Arduino uses. Before getting to this, let's look at how you can control the HB25 just treating it as a servo, which will be fine for most folks.

Wiring the HB-25




If you are using the Parallax Motor Mount and wheel kits (part numbers #28962 - aluminium or #28963 - plastic) then the red cable should be connected to M1 on the HB-25 and the blue cable should be connected to M2. If these are reversed then the FORWARD and REVERSE commands will be reversed.



Make sure that the jumper is in place for mode 1 operation. In this mode, you need a separate digital output on your Arduino for each HB-25 that you want to control.

Controlling the HB-25


From the HB-25 data sheet, we can establish the following:

  1. The HB-25 operates like a servo. You only need to send a single pulse (in mode 1) to change direction or speed. Pulse width determines the HB-25 output.
  2. Valid pulse widths are 0.8 ms to 2.2 ms. If the HB-25 receives a pulse width which is outside this range, the motor will be stopped until it receives a valid pulse.
  3. The minimum time between pulses (HOLD_OFF_TIME) is 5.25 ms + pulse time (max 2.2 ms). Thus the worst case hold off time needs to be 7.45 ms. We have used 8 ms.
  4. The maximum time between pulses is unlimited, since a single pulse will be latched by the HB-25. An exception to this would be if the Communication Timeout feature of the HB-25 has been enabled. You can read more about this on the HB-25 data sheet (https://www.parallax.com/downloads/hb-25-motor-controller-product-documentation).
  5. Regardless of the mode, the HB-25 signal pin should be brought low immediately upon power up. The Library does this when you instantiate a HB25MotorControl object.
  6. Pulse width (1 ms = 1000 microseconds) will control the HB-25 as follows:

                        - 1.0 ms Full Reverse
                        - 1.5 ms Neutral (STOP)
                        - 2.0 ms Full Forward

Arduino Code


So making use of the above, we can control a HB-25 using the following Arduino code. Note that you will need to set controlPin to whatever digital output pin is connected to your HB-25. After you have initialised your HB-25 you can control it by writing a value between 1000 and 2000 to it using the servo.writeMicroseconds() method. You need to ensure that two commands are not sent within the minimum hold off time. This is taken care of for you in the library below.

#include <Servo.h>

#define REVERSE       1000
#define STOP          1500
#define FORWARD       2000
#define HOLD_OFF_TIME 8

Servo servo;

// HB-25 initialisation time (5ms)
delay(5);                                           
pinMode(controlPin, OUTPUT);
// Set control pin low on power up
digitalWrite(controlPin, LOW);  
// Attach HB-25 to the control pin & set valid range                    
servo.attach(controlPin, 800, 2200);
servo.writeMicroseconds(STOP);

Arduino Library


To make using the HB-25 a bit easier and to hide some of the complexity we wrote an Arduino library for it. This consists of four files (click to download):

1. HB25MotorControl.h;
2. HB25MotorControl.cpp;
3. Keywords.txt; and
4. HB-25_Test.ino

To use this library, you need to create a new folder in your Arduino libraries folder called HB25MotorControl. Copy HB25MotorControl.h, HB25MotorControl.cpp and keywords.txt into this folder. Then create a sub-folder called examples and place HB-25_Test.ino into that.

You need to restart the Arduino IDE (if it is already open) to be able to see and use this library.

The example sketch should demonstrate how you use the library, but at its simplest:

#include <Servo.h>
#include <HB25MotorControl.h>

const byte controlPin = 9;              //  Pin Definition

HB25MotorControl motorControl(controlPin);

void setup() {
  motorControl.begin();
  motorControl.moveAtSpeed(500);
}

void loop() {
  
}

Valid speed ranges for the forwardAtSpeed and reverseAtSpeed methods are 0 (stop) to 500 (maximum speed). For rampToSpeed and moveAtSpeed you can use from -500 (full reverse) to 500 (full forward). As before, a speed of 0 will stop the motor.

Feel free to modify and reuse the library as you like. If you do improve it, then let us know. Attribution is nice but not necessary, and as usual this library comes with no warranties, so use at your own risk.

Saturday, October 31, 2015

Sharp GP2Y0A02YK0F IR Distance Sensor (20-150 cm) Arduino Library

Distance Measuring Options


If you are building an autonomous robot then you need to have some sort of obstacle avoiding sensors. I have attached a Parallax PING ultrasonic sensor to the front of AVA using a servo (so that I can scan 180 degrees). Ultrasonic sensors are generally pretty accurate but since they use reflected sound to calculate distance, they don't perform well if the obstacle is sound absorbing. Ultrasonic sensors can also miss thin objects or objects that reflect the sound away from the sensor. However, the range of ultrasonic sensors is much better than IR. For the PING, the available sensing range is 2 cm to 3 m.

To address the ultrasonic issues, I also mounted a Sharp IR Distance Sensor (GP2Y0A02YK0F) above the PING. The IR sensors don't perform well outside but indoors there accuracy is good enough as long as you stay within the quoted detection limits. IR sensors are generally cheaper than ultrasonic, their beams are more directional (narrower) and reflectivity of the surface is more important than the sound absorbing properties of potential obstacles.

Putting the two sensors together is complementary and allows the short comings of both sensors to be addressed (to an extent).

Sharp GP2Y0A02YK0F IR Distance Sensor (20-150 cm) 



Sharp manufactures a range of IR Distance Sensors. For the front sensor I selected the GP2Y0A02YK0F, which has a usable detection range of 20 to 150 cm's.

The Sharp GP2Y0A02YK0F measures distances in the 20–150 cm range using a reflected beam of infrared light.  By using triangulation to calculate the distance measured, this sensor can provide consistent readings that are less influenced by surface reflectivity, operating time, or environmental temperature.  The Sharp GP2Y0A02YK0F outputs an analog voltage corresponding to the distance to the reflecting object.

If you have a look at the GP2Y0A02YK0F datasheet, you will see that the analog voltage output does not have a linear relationship to distance. You can also see that the values go crazy below about 20 cm.


Noah over at the Arduino Mega Blog has reversed engineered this plot to work out the relationship between distance and the output voltage.

distance = 10650.08 * sensorValue ^ (-0.935) - 10 cm

Sharp GP2Y0A02YK0F IR Distance Sensor Arduino Library


To connect to an Arduino and get a distance you could just use Noah's formula above, but sometimes it is easier to wrap the complexity up in a library. I did a search and didn't find an existing library, so I decided to do one myself. Partly because I haven't done one before.

I did find a library for the GP2Y0A21YK IR Distance sensor (10 - 80 cm), but the characteristics must be different to the GP2Y0A02YK0F as the distances provided by the library are way off. Noah's formula on the other hand, provides very good correlation with the distances measured by the PING. For consistency, I based my library on what jeroendoggen did for his.

You can download the Sharp GP2Y0A02YK0F IR Distance Sensor (20-150 cm) Arduino Library files, and then follow these instructions to use it:

Instructions:

  • Create a directory called GP2Y0A02YK0F within the libraries sub directory where your Arduino sketches are saved.
  • Copy GP2Y0A02YK0F.h, GP2Y0A02YK0F.cpp and keywords.txt into the GP2Y0A02YK0F directory.
  • Within the GP2Y0A02YK0F directory, create a sub directory called examples.
  • Copy DisplayCM.ino into the examples sub directory.
  • Restart the Arduino IDE to see the new library.

Sharp GP2Y0A02YK0F Mounted on AVA


The following photo shows the Sharp IR sensor mounted above the front PING on AVA. I have fitted a sensor shield to the Arduino Mega which makes it very easy to connect the various sensors to the micro controller.