Projects

Part 3: SAM v1.2

Radar-Like Ultrasonic Scanning

Oliver Higgins

Issue 5, November 2017

This article includes additional downloadable resources.
Please log in to access.

Log in

DIYODE’s resident Semi-Autonomous Machine (SAM) takes the time look left, then right, then left. We can overcome some simple design issues with the introduction of a single servo motor.

With the last iteration of SAM, we added increased functionality to include two additional ultrasonic sensors. With this modification, SAM was able to manoeuvre its way around objects much more fluently by slowing the drive on one side, thus enabling a slow turn. While the desired outcome was a much better solution regarding the functionality, it came at considerable cost to the form, since the additional ultrasonic sensors increased the width, and the number of data lines required; the code became less efficient and our annoyance levels increased because the Arduino’s USB port was no longer easily accessed. There was also some ongoing debate about the optimum angles for the side-facing sensors. Each iteration of the caddy yielded different results when we changed the angles. Not better or worse necessarily, but different certainly.

So with this iteration, we want to design a more streamlined solution for SAM to evaluate its surrounding world. If we can reduce the number of sensors, we can reduce the bulk; but how can we still gain the range we require if using a single sensor? Taking inspiration from the traditional radar station, we will allow SAM’s single ultrasonic to rotate and scan the area in front of it.

HOW IT WORKS

Similar to the concept of a radar, the ultrasonic sensor sends out a burst of ultrasonic sound, and measures the time it takes to come back, thus allowing us to measure the distance to an object. Combine that with a servo motor, and we can sweep it across the oncoming path, and then evaluate if there are any objects it needs to avoid.

Parts Required:Jaycar Altronics
1 x Compatible 4WD Chassis Kit KR3162 K1092
1 x Arduino Uno R3 or Mega 2560 XC4410 Z6240
1 x Ultrasonic Module XC4442 Z6322
1 x L298 Motor Controller XC4492 Z6343
1 x SG90 Servo with Screws and Horns YM2758 Z6392
1 x LED Matrix XC4499 Z6362
8 x AA Batteries SB2333 S4955B
1 x 8xAA Battery Holder PH9209 S5034
2 x 2.5mm Screws
2 x 20mm M3 Bolts
4 x M3 Nuts
1 x 3D Printed Radar Head Chassis
1 x 3D Printed Body (for Uno R3 OR Mega 2560)

You'll require jumper wires and standard prototyping hardware.

BUILDING THE SYSTEM

If you have already built a previous version of SAM, you can skip to the third paragraph. If you do not already have an assembled 4WD chassis kit, please take the time now to get it all up and running. This kit has the wires pre-soldered into place on the motors; however, if for some reason your unit does not include this, be mindful when soldering on your leads that you keep the same colours for the same tabs on the motors. This will make wiring it up later, much easier. Place these on the motor body and run the cables towards the back of the unit. Make sure that all the motor supports are in place, and tight, as a loose unit will affect SAM’s ability to roam in a straight line.

Next, take the battery pack and place it towards the front of the unit with the connection wires towards the back (Note: we would recommend placing the batteries in now, because once it’s wired up, they can be a little difficult to get out.). Run the motor cables and the battery cables through the various holes at the back of the unit.

You will need two 3D printed items: the first is the robot body or chassis. We have had lots of great feedback about SAM, and as such have included two different units – one for the Arduino Uno R3 and one for the Arduino Mega 2560. Both robot bodies will fit on most of the 4WD chassis kits without any issues. We have provisioned a place for a SG90 servo and have made a small rectangle to allow the three-wire cable to pass through. We tested printing this with and without supports, and both worked successfully (but results will vary depending on your own printer).

schematic
The wiring is mostly identical to the previous version, with the obvious removal of the other two ultrasonics, and addition of the servo. The full diagram is available in the digital resources.

You will also need to print a single radar “head unit”. This is the unit that will rotate the ultrasonic sensor, to scan for objects that may be in its path. This print mounts on top of the servo motor.

Once you have the main body piece, please take your SG90 servo and run the lead through the rectangular hole on the right-hand side (when looking down on it from above – see image).

sg90 servo

This should pass easily. Now depending on your plastic you may or may not have enough flex to push the servo into its slot. We tried two different PLAs from the same company, and one was fine but the other would not budge. If it is the latter, then take a Dremel, rotary tool or small cutter, and cut out the back edge of the rectangle. This will easily allow the servo to slide in and move the cable into place. Once the servo is in place, affix it using the supplied screws.

Next we’ll add the Arduino itself, wiring up the motor drive unit first. Make sure you pull the 5V jumper off on the right-hand side of the motor board, to avoid SAM springing into action when you are not ready. Take care also to then wire up the two pairs of drive motor cables. Leave the main power off for the moment, as we need to power up the Arduino. Wire up the SG90 servo; the orange wire goes to pin 2 with the red to positive and the brown to negative.

MATRIX DISPLAY

The pinouts for the 8x8 LED matrix remains the same as previous versions, but due to the introduction of the head unit, we needed to find a better hardware design than the previous implementation.

Instead of mounting it internally, which relied on friction and was a bit of a pain to print, we have added a bulkhead to the front of SAM. Due to the position and rotation of the servo, we will just use two points to mount it on. This is not an issue, as this particular part bears no load other than itself.

To offset the unit and make sure his “mouth” is the right spot, we have pushed the bulkhead across to the right. The matrix itself is not able to sit flush against the bulkhead due to the underside solder points. To address this, take two M3 bolts and place them through the right-hand side (when looking down on it from above).

matrix display

Once through, place an M3 nut on, and do it up firmly but not too tight. Then place the matrix on SAM, pushing the two bolts through the holes in the bulkhead. Take another two bolts and tighten them up – just enough so that they do not come loose. Now wire up the matrix interface to the Arduino as per the diagram.

HEAD UNIT

head unit

Take your time now, to fit the ultrasonic sensor to your 3D printed ultrasonic head unit. You will probably need to Dremel or file the holes in order to get a good fit. Turn the unit over, and you’ll see there are several guide holes in the unit; we found the first to be adequate. Take the long double-ended control horn and 2x2.5mm screws and take your time to ensure they are secured in properly, as they will create a squarer mounting angle for the head unit. Once complete, connect your Arduino to your machine and upload the following code:

#include <Servo.h>
Servo myservo;
void setup() {
  myservo.attach(2);  // attaches the servo on pin 2 to the servo object
}
void loop() {
  myservo.write(90);
}

This serves two purposes: firstly, it’s the simplest implementation of the servo object. The first line imports the servo library, then we create the servo object and call it “myservo”. In setup, we attach the myservo object to pin number 2. In the main loop, we call the myservo object and use the “write” command. We specify where in the rotation we want the servo to move. This makes using the servo incredibly easy, but it does mean that we need to know where our starting point is. To do this, we move the servo to the 90-degree position. You can manually rotate the servo, but this is useful too.

Once the servo is at 90 degrees, place the head unit on top of the servo – perpendicular to the body – and gently screw the horn into the base. Get it as close to 90 as possible, being mindful that the top of the servo control has a spline on it. Once you have firmly screwed it down, you can connect the ultrasonic as per the diagram.

You should now have a cool looking SAM V1.2! Referring to the wiring diagram above, you can now ensure that your ultrasonic sensor, servo, and matrix display are connected as indicated, playing close attention to ensure it's accurate.

THE CODE / SETUP / OTHER

With our previous versions, SAM would simply poll each sensor (or the single sensor) and move (or not) before repeating the process. Of course, we now only have one-third the number of sensors, but we do have the servo to provide some control. The servo will move our ultrasonic around in a half circle to check for objects.

SERVO CONTROL

When we tested SAM V1.1, we tried 90, 45 and 30 degrees. All three had positive and negative design and functional elements. Taking this on board, we have set up SAM’s basic programming to scan at the 75, 45 and 15-degree inclinations on each side, before scanning straight ahead (i.e. 90 degrees) and moving to the opposite side. To achieve this, we need to create two loops, each incrementing in 30-degree steps. Following is the code for the main loop. This first loop moves the head from 15 degrees to the 165-degree mark. Making the servo sweep across the front of SAM. While scanning we use the “ping” command to get the distance to the object in front, and compare it to the object distance variable. If it is within this setting, then we call the “checkScan” function to act upon this information. The loop waits a moment before the servo returns to the starting point. Once complete it will reengage the forward drive.

Load and compile _005_Robot_001.ino onto your Arduino.

for (pos = 15; pos <= 165; pos += 15) { 
    myservo.write(pos); 
    if (pingSonar() <= objectDistance) { 
      checkScan(pos); 
    } 
    delay(100); 
  } 
  for (pos = 165; pos >= 15; pos -= 15) { 
    myservo.write(pos);         
    if (pingSonar() <= objectDistance) { 
      checkScan(pos); 
    } 
    delay(100); 
  } 
  forward();

The contents of the main loop basically maintain the cycle of rotating the servo and proceding.

The checkScan function takes an integer argument to communicate the current position of the sensor. From this, we can decide if the object is located off to the side or in front of SAM. We have used a Switch/Case with the position. This means if it’s on the left, it will slow the right wheels enabling SAM to turn right, or if it’s on the right then it slows the left. The original code remains in place so if the object comes straight in front of SAM then it will stop, reverse and turn before continuing on its way. It has been made this way to emulate the V1.1 programming. We did, however, feel that version did not capitalise on the information we now have to use, so this is why we have included a second sketch (_005_Robot_001_1). In this we’ve changed the “slowLeft” and “slowRight” functions to include a float variable. This variable replaces the 0.25 multiplier, and in its place is the “motorSpeed” variable. This allows us to change the turn rate of the robot, thus the closer an object gets to the front (i.e. the more likely SAM will run into it), the quicker we can turn the robot. The current sketch has SAM turning at 0.75 (75%) for 15 degrees, to 0.25 (25%) when the sensor is in the 75-degree position.

WHERE TO FROM HERE?

As SAM evolves, it opens up more ideas and questions. There are a few things here that could easily improve SAM. For example, currently, we only compare a single distance variable. Would it not be more effective to start the vehicle doing a slower turn when we sense objects side-on?

Perhaps set the distance the ultrasonic will trip to be further on the wider angles of the rotation so that the unit is more likely to move around an object to the front rather than halting. Or what about starting to bring a level of intelligence into SAM?

For example, what happens when we have objects on both sides? We could define an array of seven integers, perform a scan and store all the data before evaluating which sensor angle presents the most danger to the robot. Or perhaps you don’t think it scans fast enough? You could change the delay after the loop. Does it not enough sample enough scans? Change the increment value in the loop to a smaller number; you could go as low as one-degree increments.

There are so many avenues you could pursue with SAM. And, as always, we’d love to see and hear about the results of your experiments!

Part 1: This is Sam

Part 2: SAM v1.1: Upgraded Senses

Part 4: SAM v1.3: Setting SAM Free

Part 5: SAM v1.4: Talk Back with SAM