Introduction: Obstacle Avoidance Robot Using TI Launchpad MSP432

This project started because I was given a TI Launchpad MSP432 board. One of the 1st things I did with it was just a multi-thread demo - I believe I had it running 22 or 23 threads.

At one of the Automation Technology Club meetings (where I did the demo)

https://www.meetup.com/Automation-Technology-Club/

I said that the MSP432 would be a good board to replace the controllers in my Hero Jr. project.

https://www.instructables.com/id/Heathkit-Hero-Jr-R...

It was suggested to start on something smaller, and get some tests and ideas done. So that is were this project was born. I wasn't really thinking about doing an instructable for this project while I was making it. (So I don't really have any build pictures). But after it was done (or at least done to the point I want to share it), I thought it might just be a good project for here. At least I can say some of the things I learned while doing it.

You'll need some light soldering skills for the motors, and maybe the pins on the level shifter.

From a code stand point this is an intermediate to advanced project.

So let's get started.

Step 1: Gather Up the Parts:

For mine I decided to use a quad-wheeled robot - The way the motors are hooked up it acts like a 2 wheeled robot. The biggest difference is turning. My chassis is a very early prototype made from a friend of mine on his laser cutter. Any 2 wheeled or 4 wheeled robot chassis should work thou.

** It should also be noted that my robot was never meant to be a permanent install - and was only meant to do some demos, learn a bit more about the MSP432, and move that knowledge to the Hero Jr. Because of this and other factors, glue, zip ties, a USB battery pack (with USB cable to power the micro controller), and a 2nd 9v battery to power the motors where used. The Hero Jr uses 12v batteries, and already has a some voltage regulators in it for the 5v needed. My construction is meant to be taken back apart. **

Let's get some parts together - some of these you may already have, some you'll need:

Tools Needed: Screw Driver (Phillips head, small slotted), Solder Iron, possibly a small drill, or rotary tool

*Miscellaneous stuff I used: Glue, alligator clips, battery pack, 9v (AAA battery pack), zip ties, bread board, dupont wire, electrical tape, some screws and washers. solder, flux.

Important Parts:

  1. TI LaunchPad MSP432 - These boards are multi-thread right out of the box and cost about $13.00 U.S. have a lot of PWM and GPIO Pins. http://www.mouser.com/new/Texas-Instruments/ti-msp...
  2. 2 to 4 motors and wheels. Depending on your chassis kit you may or may not need to get motors and wheels. This are fairly inexpensive on eBay around $2.00 U.S. for a set - if you look you can find even better deals if you buy more - but $2.00 isn't bad. http://www.ebay.com/itm/1pc-Useful-smart-Car-Robot...
  3. Robot chassis Most of the chassis on eBay do come with wheels/motors and some even come with encoder discs. I'm not going to put a link to any because this really is a personal choice. I will say that I would not recommend going "cheap" on these - I've found over many years of buying the cheap chassis is they break very easy, and don't hold the motors very well. I'd plan on something like $25 plus for a chassis, you can go cheap, but in the long run spend the money get something better.
  4. 1 Dual H Bridge Motor Driver L298N Board - these are normally around $2.00 U.S. - Other motor drivers may work, my robot chassis was designed with this board in mind. I've used these in the Hero Jr to drive the large stepper and drive motor with no problems. I use them in just about all my robot projects. http://www.ebay.com/itm/Dual-H-Bridge-Stepper-Moto...
  5. Nokia 5110 Display - This is optional, I don't think it will make a difference if it's not on the robot (difference as far as the code goes.) These are around $2.00 U.S. - there are a couple of different model of these (mostly I think it has to do with pin arrangement, and color of the PCB, maybe backlight color) They all should work the same thou. http://www.ebay.com/itm/84-48-LCD-Module-White-bac... I say these are optional, you don't need to display information while the robot is moving, but it does give a handy output for debugging problems.
  6. Ultrasonic sensor - HC-SR04 these are very common, and pretty good for something that only cost $1.00 U.S. dollar. http://www.ebay.com/itm/1pcs-HC-SR04-Ultrasonic-Mo... These are 5v devices, so they need a level shifter when using them with the MSP432
  7. 5v/3v bi-directional level shifter - I know some people will say just use resistors, or not to worry about it. I never liked the idea of using resistors for this, so I always use a level shifter, I also know it adds a little more that could go wrong to the design. I used a 8-channel level shifter, which is more than you need for this project - but in some ways it's nice to have the ability to add more later if needed. About $3.00 U.S. http://www.ebay.com/itm/8-channel-Bi-Directional-L...
  8. Optical Encoder for DC TT Motor - Look around for a better deal, this is the one I found quickly (I will say I like how these are designed a bit better than the ones I have - but for the money I'll put up with mine) These are about $10.00 U.S. http://www.ebay.com/itm/2x-Optical-Encoder-for-DC-...

Optional (Depending on robot chassis):

Ultrasonic mount. My robot had a place to mount the ultrasonic sensor - most of the low cost chassis don't come with a holder (thou some do), and this part is optional, there are dozen different way people have mounted the ultrasonics. But for .99 cents it would make it a bit easier. http://www.ebay.com/itm/Cartoon-Ultrasonic-Sensor-...

Total Cost: Between $56 and $100 (Robot Chassis is the factor here!)

Step 2: The Build - Install Motors, and L298 Motor Driver

As I said in the begining instructables wasn't really a thought when I started this project, so I don't have any pictures of the build. It would be pretty hard to tell you how to build your chassis too since you'll probably end up with chassis different than mine.

I ended up taking some pictures of mine as I took it apart, so I could try and show it, rather than try to explain it.

So here are some things to keep in mind, go slow, (this is extra true on the really cheap chassis) don't over tighten anything, the plastic chassis may be thin and break. Try to get the motors on as secure and straight as possible. I've found that the wheels sometimes either bow inwards or bow outwards. The motors are all a little different too, but much less noticeably.

Before you build your chassis, you'll want to solder wire to your motors. A note depending on your chassis the front and rear motors may go in with the backs facing each other. In other words, the motor pole on the front motor will be the motor pole on the bottom of the back motor.

Mount the L298 motor driver board to you robot, for mine it's mounted on the lower deck.

My chassis has the motors back sides facing each other, causing the one on the back to be upside down from the one on the front.

Since we are only using one motor driver - this robot really acts like a two wheeled robot - with the difference being how it turns. We could make this 4 wheel independent drive by adding a 2nd motor driver, and changing the code quite a bit. (That is beyond this instructable, at this point).

Each side now has a front motor and rear motor (or back motor) - to hook these up so they spin the same direction - the top pole of the front motor needs to be connected to the bottom pole of the rear motor, and the bottom pole of the front motor needs to be connected to the top pole on the rear motor. On each side.

*** Some notes - If your motors face the same direction, the TOP poles of each should be connected together, as well as the bottom poles of each together. ** Using a two wheel robot chassis - you don't need to worry about the other motors at all :-) **

I just did a simple hand twist of the wires together. Next you'll want to put each set of wires into the motor driver out for each side of the L298. (My board is marked Out 1, Out 2, Out 3, Out 4)

I believe I had the front motor top/rear motor bottom wired to OUT 1 and OUT 4 (respectfully) and the other two sets connected to OUT 2 and OUT 3. That being said, I'm going to tell you how to test the setup and change the pins as needed in a later step. So as long as the TOP poles of the motors are connected to the Bottom poles of the other motor, and as long as you have 2 wires coming out of each of the OUTs you should be ok.

This is probably the most confusing part of the build. and now it's out of the way.

You have 2 more things to do for your motor driver, and we can then move on.

You need to run power to it - for a variety of reasons, I went with two batteries on this, one for the motors (9v battery pack), and one for the Micro-controller 5v battery pack (with USB out). My reasons were to try and keep this simple, with out needing to run a voltage regulator. While it did save on a few extra things needed, it meant I need a extra ground wire to run to the micro-controller. There is a connector marked VCC/GND/5V - I just put a red male/male dupont cable for the VCC, and two black dupont male/male cables for the GND (One of these will connect to the battery pack, the other to the GND on the micro-controller)

Next I used 4 (different color) female/female dupont cables connected to IN1, IN2, IN3, IN4 - leave the enable jumpers in place - if your board doesn't have ENA ENB jumpers, you'll want to find some. We can use 4 PWM pins, to get direction and speed control. Make a note of which color wire you hook up to the IN pins - this will make it easier to identify them when it comes time to hooking them to the micro-controller.

Once again, I'll show you in a later step how to test this out and make changes in software - so the hardware can be left alone.

Step 3: The Build Wheel Encoders

My encoders are like the ones pictured above, These work great, but honestly the pins are on the wrong side of the PCB - if you are up to it, and have good desoldering skills - I would un-solder the pins, and put them on the other side. (I didn't do this, but next time I build something like this I will), I think because I didn't do this, I couldn't get the sensor to stay in the right place - my solution was low cost but effective (electric tape) to hold them in place.

You'll need 6 wires total, 2 for VCC, 2 for GND, and 2 for the Output of the sensor. In this case, we are using the DO (digital out), for what we are doing, we just need to count transitions. The sensor pictured also has analog out (AO). I have found a couple of these cheap sensors have the AO and DO silk screening mixed up, so before you mount it, you might just want to test it first.

* Testing the sensor VCC to 5v, GND to GND

While it's not in the robot - hook the D0 pin to pin 30 (P5.5) on the Launchpad MSP432. Upload this little program, open the serial monitor - you should see the output window change (1 and 0) when you move a peice of paper of something between the sensor.

void setup() {

Serial.begin(9600);

pinMode(30, INPUT);

}

void loop() {

Serial.println(digitalRead(30));

}

If you don't see the expected output, try moving from D0 to A0 on the sensor, and try again. Test your 2nd sensor to make sure it's the same. *****

If you did the little test above, unhook the sensor, and install it in the robot, making sure that it doesn't stick too far up on the encoder disc, I know my picture isn't great - but it gives an idea about where it should be sitting. Get it as straight as you can.

Before we release the robot we will test it and adjustments can be made if needed then.

put wires on the pins - I try to use RED for VCC, and black for GND. and I'd use two different colors for the DO - take note of the colors and which sensor they go to. Again this can be adjusted in software.

For my robot facing the ping sensor - the LEFT is your RIGHT, and RIGHT is your LEFT - but again this can all be adjusted in software.

Step 4: The Build - Ultrasonic Sensor

The ultrasonic operates at 5v, the TI Launchpad MSP432 is a 3v board. So we need a level shift for this step.

The one I used and like is a bit over-kill for this project, but does leave room for adding more 5v sensors.

But I think first we need to mount everything. The ultrasonic should be facing the front of the robot as long as it has a clear path to "see" objects in front of it.

I used a zip tie to hold mine in place - but depending on your mount you might need some small screws, or maybe a bit of electrical tape to hold it in place.

I also used a little glue and mounted a small bread board to the top level of my robot. I used this for the level shift, and to make it a bit easier to get 5v and 3v where it was needed.

At this point, we are just going to wire to the 5v side of the level shift. You'll want to mark one rail of your breadboard as 5v and one rail as 3v (it's important to know which is which). The level shift board is marked 3v on the A side and the 5v on the B side - so I matched voltage rails to the A/B side. In other words, if I was looking down at the breadboard the 3v rail would be close to the A side of level shift. (I know that doesn't make since right now, but I think once you get it on a breadboard it will).

Off the ultrasonic you have 4 pins, VCC, ECHO, TRIG, GND. The VCC of the ultrasonic goes to the 5v rail of the breadboard, GND goes to a ground rail of the bread board. ECHO will go to the PIN marked B2 on the level shift, and TRIG to the PIN marked B1 on the level shifter.

The level shifter, as stated has a 3v side and a 5v side - it's very important to keep these sides right.

The pin marked VCCB should go to the 5v rail of the breadboard. VCCA should go to the 3v rail of the breadboard. and the GND should go to the ground rail of the breadboard.

You'll also want to put to more wires one on PIN marked A1 and one on PIN marked A2 of the level shifter. We are going to hook these to the micro-controller so a male/female cable should work nicely here.

If it all possible, try to use color wires that you have not used before, make a note of the colors and what pins they go to. Using a unique color for each wire will make it a little easier to keep track of.

Step 5: We Are Almost There!

Intermission...... Monty Python reference.... (get it?) :-)

I thought at this point we should take a little break, enjoy a video.

No seriously, we are almost done, We only need to mount the micro-controller, and the Nokia 5110 display.

finish wiring, and start doing some testing.

It would be a good idea to go back and check your wiring up to this point, make sure you have good notes on what color wires are hooked to what pin/device. This is a good idea, because here comes putting those wires where they belong on the micro-controller. (It could get messy from here)

Enjoy a the video.....

Step 6: The Build - Mounting the Board.

I was given one of the 1st models of the MSP432 board (the black board), the RED board is functionally the same with some improvements based on feedback from developers. I believe it also has mounting holes, but since I don't own that board I don't know for sure.

My board has 4 mounting holes one in each corner. Depending on your robot chassis you may already have some holes drilled out that will work for mounting, or you may need to drill out some, or you may choose to do what I did and just wire tie the board to the chassis.

My method of wire tie did work, however I ended up bending a couple of the pins in the process - not bad, and they were easy enough to straighten back up. But it is something to be aware of.

I'm pretty much leaving how you mount this up to you, it's your board, it's your robot. I will tell you I powered mine via the USB port, this was both a good and bad thing. There is a jumper on it that you can remove and power the board via the 3v bus - it has to be 3v - this is a 3v board. The TI website has information on how to do this - it's a bit beyond the scoop here.

Mount it somewhere that you can get to the pins easy. I used the male side of the board - but you could just as easy use the female side.

take care to not bend the pins, or at least don't bend them too much :-)

Step 7: The Build - (Optional) Nokia 5110 Display

This is kind of an optional step, I don't think it will effect how the robot works. It is a good way to get an idea of what it is doing thou should there be a problem.

The sketch I made displays - a "count", a "avg", and the left and right encoder count.

The count is how many times the ping sensor is returning a good distance. Avg is the average distance of the ping sensor. and the left & right encoder count is showing what each wheel is doing (with in reason)

With a little re-write you can have it display just about anything you want.

I will also say that where I mounted mine was not the best spot, but short of adding more stuff to this, it was ok.

I did have to pick the robot up to read the display - and "simulate" it moving in my hands. But it did help to trouble shoot a few issues I had.

*** The next issue I had was with the new Energia IDE (v18) and the Nokia Library I found - seems that the library was either written for a different board (MSP430) or a different IDE version (or both) I simply couldn't get it to work with the latest IDE - I ended up using Energia v17 which does support threads and this library, and works with the MSP432 ***

To help save time, I've included the library in my github repository.

Some of my other demo code for this board is also in the repository if you are interested in any of that.

This Nokia 5110 is a SPI device.

Step 8: The Build - Wire It Up!

So, here is were the fun comes in - wiring time!

As you can see in the picture above TI put the Port/Pin number on the board, the IDE uses a "common" number

So, P3_2 on the board is pin 3 in the IDE, P3_3 is pin 4, etc... I'll give you the board pins here to make it a bit easier to hook up, but just remember inside the IDE these are replaced by what I'm calling a "common" number.

Just like the Arduino, many of these pins can do different things.

So you can see from above there are a lot of pins that can do PWM (analogWrites), there are a number of analog pins as well. There are 2 user buttons, and 4 user LEDs (Ok, that's sort of not ture, there are 2 LEDs, and one is an RGB 3 pins are used to control it) There are jumpers on it so you can use the LED or Button pins for something else. And there is a large un-populated header (J5) that is also user accessible.

So this board has a lot of IO, and a lot of PWM.

HOOK UP:

Remember earlier we had a 3v rail, and a 5v rail on the bread board. Look at the MSP432 board you should see a couple of 5v pins, and a couple of 3v pins, as well as 6 ground pins.

We need to run one of the 5v pin to the 5v rail on the bread board, one of the 3v pins to the 3v rail on the bread board, one of the grounds to a ground rail on the bread board. While we are at it, let's connect the ground from the L298 motor driver to one of the grounds on the MSP432.

Nokia 5110 (optional)

LCD side MSP432

RST P5_0

CE P3_0

DC P5_7

DIN P1_6

CLK P1_5

HL P2_5

VCC 3v rail

GND GND rail

Level Shifter MSP432

(voltages and B side should already be hooked up, but another good time to double check)

A1 P3_7

A2 P3_5

VCCA 3v rail

VCCB 5v rail

GND GND rail

B2 Ping Sensor Echo Pin

B1 Ping Sensor Trig Pin

L298 Motor Board MSP432

(Check your notes on which color wires you used and....)

IN1 P2_7

IN2 P2_6

IN3 P2_4

IN4 P5_6

(Remember, we can change these in software if something isn't working, but keep your notes)

Remember if looking at the front of the robot the right side is your left and the left side is your right. So now we need to hook up the encoder.

Check your notes for the color wire you used and:

Right Encoder (DO) to P5_4

Left Encoder (DO) to P5_5

Both encoders VCC to the 5v rail, and GND to the GND rail.

POWER HOOK UPs:

You probably have figured this out by now, the USB battery is used to power the MSP432 board with a USB cable.

and the motor driver board, VCC hooks to a 9v battery pack positive, and GND hooks to the 9v battery pack negative. (I used alligator clips for the negative side, so I could "turn-off" the motors while I was programming it, or while testing it sitting on a table - you can add a switch which is what I'd do if this wasn't a temporary demo)

At this point you DO NOT want power to the motor driver, we will power everything after we get some tests up and running.

That should take care of wire hookup.....

Step 9: Intermission......

Monty Python reference.... (get it?) :-)

This is a good time to check your wiring, and take a look at some of the miscellaneous extra pictures I have of my robot.

Step 10: The Code.

If you haven't already downloaded the Energia IDE you'll need to now. http://energia.nu/

At the time of this writing you'll want to Energia 0101E0017 for your platform. This can be found on the downloads page, look for Previous versions. http://energia.nu/download/

The new version (v18 at this time) is following a similar approach that the 1.6.x version of Arduino is following.

There really isn't much difference between the Arduino IDE and the Energia IDE, and a lot of Arduino programs can be used with the TI Boards with only minor changes. Libraries are a different story however (this will change, I'm sure) I've found a limited number of libraries that work.

The code can be found here: (clone it, or download the zip)

https://github.com/automation-technology-club/TILa...

This is a repository of all of my TI Launchpad code so far (all my demos, and projects). So we will need to go to the Energia/Energia-0101E017 Projects/ directory, here you'll see a libraries directory, and various projects.

You'll want to copy the libraries in the libraries directory to your Energia directory. And you'll want the "bittybot quad rover project" directory in your Energia directory for code.

Start Energia IDE, and click on the Sketch tab, and then Import Library and verify that LCD_5110 is in the list.

if it's not, there you've got the library stuck in the wrong spot, and you'll need to exit the Energia IDE and try again.

If it's there, you should be good to go.

Click File, and Open - browse to the location of "bittybot_quad_rover_project" and open the program.

You should get 5 tabs in the IDE window. "bittybot_quad_rover_project", "encoder", "lcd", "motor", "ping"

For the MSP432 board, each tab is treated as it's own thread, this is nice!

Variables defined in the main tab become global and are easy to share across all tabs (I got that from the Energia website) (It seems to me that other variables also become global, but I've not verified that)

Next I'll explain each of my tabs, and hopefully the logic of what I've done will make since.

(If you don't really care how the code works, jump to step 16 for instructions on testing)

Step 11: Bittybot Quad Rover Project Tab.

This is the main thread, my logic for this tab is to do all of the setup routines, and define my global variables.

You may notice that I actually have more variables defined than I really use - the reason for this was to be able to expand this example easier. Or to add features later easier. This board has plenty of space for this, and is only using 39k of the 256k available. So plenty of room for additions.

In this tab we can make changes to how/what the pins are hooked up to.

You'll see a section for each tab with variables that are used by that tab or shared between tabs

The sections are: Encoder, Ping, Nokia 5110 LCD, Motor variable setup

We also set pinMode for the various pins, get the LCD setup and ready, and make sure the motors are turned off.

Step 12: Encoder Tab

This pretty much does what you'd think, it reads the wheel encoders. I did NOT use any interrupts to do this.

Why? Because this is running in it's own thread - it's running all time. What I am counting here is any change on the encoder pins. And comparing the two encoder reading over time (which is defined in the main tab)

This is also where error corrections are made in an attempt to keep the robot moving straight - in practice however, I've found that it does still drift slightly when going over a long distance. For short distances this appears to work pretty good.

I have the left motor as the master motor - the right motor attempts to match speed (encoder count) of the left.

You'd need to make some small changes here if you wanted the right motor to be the master.

I have defined a couple of "flags" the isRunning flag is a boolean value that tells the encoder thread if the wheels should be running. It is used to help figure out if the wheels have stalled, IE: one side or the other stop spinning.)

For my demo isRunning is set to zero when the robot is turning, or when the robot is backing - more flags could be set for these functions, but my reason was I just need it to turn slightly, I don't need to know if it always turns the same amount. With encoders however you can figure just how far it has turned. (But not if the robot is moving backward or forward, for that you'd need one more encoder on each wheel)

The other flag is isStalled it is also a boolean value, and tells the motor thread if the motors need to be stopped the robot also goes into reverse and turns slightly to over come the stall condition.

In a stall condition, and if the robot isRunning condition is zero, all the counts are reset to zero, and LastMills are updated to CurrentMillis

* It probably should be noted that the multiplier I use to help keep this straight may not work well on all surfaces, or with all motors, and is something that just needs to be adjusted. For me the 1st number I tried seemed to work pretty good, and I didn't adjust it - You may need to however *

*** You might notice that in each of the thread tabs we don't have the typical setup() and loop() functions - well they are there, but are renamed to something unique for that thread, in this instance setup() is setupEncoder()

and loop() is loopEncoder() - you'll also notice there is nothing in the setup function, this was taken care of in the main thread. Each tab has it's own setup() and loop() function ***

Step 13: Motor Tab

This is where a lot of the magic happens. Seriously if this was any other project I'd call this the main loop.

I did adapt this part from some code I found here on instructables:

https://www.instructables.com/id/Simple-2-way-motor...This (instructable) is a very very bad way to connect a motor to a arduino, but the code seemed like it was a good place to start. I'd NEVER hook a motor up like how this person did.

I considered adding better timings to this as well, and in the end just decided for what I was doing this would work well. (A robot I made based on the Arduino Mega has better timings with a library I wrote. It can be found here, for those who are interested: https://github.com/automation-technology-club/Bitt... This robot also uses 6 wires on the L298 motor board)

Anyway, got a little side tracked there....back to the Motor tab:

starting off you can see the functions used in this tab. I tried to keep that simple.

(Looking at my code now, I see I did still leave some of my testing code in it...this is fine, and doesn't seem to matter).

In the setupMotor() function we see a 5 second delay - I need this so the robot doesn't start off moving, it gives it time to get some data from the ping sensor, and start up some of the other tabs. (After building a few robots, I have found that it is good idea to just not have them start moving until most, if not all, the sensors come up and start working) 5 seconds may be a little longer than is needed, but because I didn't put a master power switch or a motor power switch, this also give me time to set it on the floor.

So the idea of this robot is keep moving forward, unless you get to about 10 inches of something, or unless your motors stall (one side or the other). This idea is handled in the loopMotor() function.

The robot always wants to move forward - and the isRunning flag is set to 1 - meaning moving.

the left and right motor are both set (at the beginning the same PWM rate) and a delay is set to none (zero). Why no delay? The way this works is until the PWM is turned off the motors will continue, the right motor is constantly changing because it's being compared to the left motor from the encoder thread.

The only time we make a big change is if the robot gets too close to something 10 inches or less, or one or both motors stalls while it should be running.

A stall is the next thing we check for - if the flag is set, we unset it (return it to zero), and call the stall function.

The stall function:

Set isRunning flag to zero, stop motors, move both motors backwards at maxspeed (for a short period of time), stop motors, turn the robot a (turning is done by having one set of wheels moving backwards, and the other set of wheels moving forward at the same PWM rate, and for the same amount of time). reset pingAvg to zero, reset pingcount to zero, set PWML and PWMR to maxspeed, delay to get a new pingAvg.

A lot is going on in this function, but it happens pretty quickly.

in the loopMotor() function again - we now check to see if we are close to something, and deal with that condition if it's meet.

we are looking at an avg ping distance - why? The ultrasonic does a good job for such a cheap sensor, but errors do creep in sometimes, noise or other factors will sometimes cause these to go out of range, or read too close.

Doing a rolling avg over time does seem to weed out most of those error conditions.

The original idea (you can still see the code) was to start to have the robot slow down as it got closer to an object, unfortunately it didn't work quite the way I wanted it too, and I abandoned that idea for the more simple.

10 inches or less, stop and turn method used now. So if the 10 inches or less condition is meet, here is what happens:

stop motors, isRunning set to zero, encoder count (left/right) set to zero, turn robot, stop motors, pingavg set to zero, pingcount set to zero, left/right PWM set to max, delay to get a new avg.

The loop goes again. The idea is to keep the robot moving, but also if you turn make sure you aren't going to hit something, so turn again if you are (hopefully before you move to hit it) I have noticed however (it doesn't happen every time either) that it will move forward after a turn, and then stop quickly and turn again, causing little jumps.

I think my checks need to be moved to the top of the loop, and the forward motion of the motors moved to the bottom.

*** A Couple of notes about the motor drive functions: You'll see there are a lot of function that I have not used in anyway here. The idea was for future expansion, or a easy way to change what the robot does. And it was much easier to write the code now while it is fresh in my mind, than to go back later and figure out what I was doing :-)

* Having better timings here may be a beneficial for some advanced projects using this platform. Adding another millis counter and a millis check to the loopMotor() function wouldn't be too hard to do.

* the moveForward and moveBackward functions both caused problems with the encoder counting - I think because of the delay in them. which goes back to better timings would fix the problem.

* my temporary fix to the above problem was adding rightForward, rightBackward, leftForward, leftBackward with no delays at all (thou for some reason, I still have a length in the function call - don't know why or what I was thinking.... or was I thinking).

IF any of the threads needs some help, it's probably this one - the good news is it works.

**** We will be making some changes here for testing your motors and encoders too, so stay tune ***

Step 14: Ping Tab

In this thread we are getting an average for distance from the ultra sonic sensor.

for whatever reason (probably because I copied this from another sketch I made), I have the pinMode in the setupPing1() function.

loopPing1() function: this is pretty straight forward, each loop adds to the counter, and triggers the ping sensor, a little math is done to get distance in cm, and if that distance is too close or too far away an out of range condition is in play - (Which in this case resets both the ping average and the ping counter). if the distance is in range, it's added to pingavg.

ping1 a distance in inches is then calculated, and this (ping1) is used by the motor thread.

A small delay is used before the loop starts over again.

The original idea was to keep a running average and only reset when the robot turned, it would also not add the out of range value to pingavg. While I believe this was working, it appeared that it was not working, and was changed. The method I use now does appear to work.

pingavg and pingcount are both displayed on the LCD for troubleshooting reasons.

Step 15: LCD Tab

(The LCD is optional, but for completeness I'll explain this tab too)

I pretty much copied what the example for the Nokia 5110 was doing, and changed things a bit to display what I wanted.

***The library was developed with embedXcode for a TI Boosterpack by VILO in 2012, it was ported to another board (LM4F120) by Bryan Schremp also in 2012, found by me after a while looking (it was on github the whole time by the way) - I couldn't have used this display without it thou, and no changes were made by me it just worked with v17 of the IDE and the MSP432 board.***

For some reason, unknown to me I have to start the screen again here in this routines setupLCD() function.

The loopLCD() is fairly straight forward.

myScreen.clear() clears the display

myScreen.setFont(0) uses a small but readable font

myScreen.text(c,r,string) displays the string at location c, r (c is the column, and r is the row)

any variables that need displayed also need to be strings - so we have to convert all the integers to strings with

the String command.

We are going to display,

Count, Avg, Left, Right - Count is the ping counter, avg is the average distance in inches, left is the count of the left encoder, right is the count of the right encoder.

This takes care of what each tab does, let's get to testing.....

Step 16: Testing...

I'm mostly worried about testing the motors at this stage.

Remember in the main tab (bittybot_quad_rover_project) we setup some variables for the motor pins.

It looks something like this:

//Motor variable setup

int leftMotorPin1 =  40; //Left Int1   
int leftMotorPin2 =  39; //Left Int2
int rightMotorPin1 = 38; //Right Int3
int rightMotorPin2 = 37; //Right Int4

For now we are going to leave that alone, and hope you have the motors hooked up the same as I did! :-) But if we need to make changes to the motors this is were we would do it.

What we need to change is in the motor tab You will want to comment out everything in the loopMotor() function.

The easiest way is to put a /* at the begining of the loop, and a */ at the end of the loop - like this:

void loopMotor()                     <br>{</p><p>/*
//attempt to keep bittybot rover going straight, unless ping sensor says it's too close to an object.
//then turn to the left apx 90 degrees, and continue forward, continue forever.</p><p>isRunning = 1;
leftForward(pwmL, 0);
rightForward(pwmR, 0);</p><p>if (isStalled == 1) {
    isStalled = 0;
    stalled();
}
//if (ping1 > 29 && ping1 <= 39) {pwmR = pwmR-25; pwmL = pwmL-25;}
if (ping1 <= 10 && ping1 >=0) {
      stop();
      isRunning = 0;
      countl = 0;
      countr = 0;
      rotateRightBack(200, 300);
      rotateLeftForward(200, 300);
      stop();
      pingavg = 0;
      pingcount = 0;
      pwmL = maxspeed; //leftSetSpeed;
      pwmR = maxspeed; //rightSetSpeed;
      delay(500);
}
//if (pwmR > maxspeed) {pwmR = maxspeed;}
//if (pwmR < minspeed) {pwmR = minspeed;}
//rotateRightForward(pwmR, 1);
//rotateLeftForward(pwmL, 1);
*/</p><p>}</p>

Next in motor setup, we are going to un-comment the leftForward(70, 0); statement - because there is no delay in this function the motor should just start to run.

Hook the battery up to the motors, upload the code to the board, after it's done upload about 5 seconds later you should see the left motor start to run. (I was holding my robot so it couldn't go too far or fall off my table) - what you are looking for is to see if the robot moves in the forward direction, and if the wheels I am calling left are also moving.

IF the none of the motors move, try to increase the PWM signal to the motors change the 70 to something like 125 (remember 255 is the max), we don't need it to move fast, we just need to see that the direction is correct.

**** NOTE: You can also open the serial monitor up at this time, and see if you are getting reading from the left encoder, you should see it counting up. ****

IF you get movement but it's on the wrong set of motors - goto the main tab, and change the

Pin for the leftMotor to match the rightMotor, and change the rightMotor to what the leftMotor was.

IF the left motors spin, but spin in the wrong direction, swap the left motor pin numbers with each other.

Upload your code to the board and test again.

If everything looks good, comment out the leftForward(70, 0) command, and uncomment the rightForward(70,0) command. upload the code and test to see if your right motor comes on and if it's moving in the correct direct.

*** NOTE: you can also use the serial monitor to check the right encoder is counting ***

Again, if the right motor spins, but spins in the wrong direction swap the pin numbers for the rightMotor in the main tab.

upload the code and test again.

You can also test both motors together, or you can test the leftBackward(70, 0) or rightBackward(70, 0) or any combination.

** We also need to find the stall speed of the motors, typically this is around 50, but each motor is a little different. to do this we change the 70 to a lower number until the motor doesn't spin. Whatever number you end up with is your stall speed for that set of motors. In the main tab you'll see something like this:

int rightStallSpeed = 60;  //Wheels stop moving if PWM is 50 or less - I've added 10 to this vaule for a stall safty margin<br> int leftStallSpeed = 60;

I would recommend adding at least 10 to the stall speed, gives a little room for movement, but you can change your stall speed here. (In this project I didn't use the stall speed at all, so this is less important here, but it is something you should know for your motors)

Once you are happy with how it's working, comment the leftForward(70,0) and rightForward(70,0) in the motor tab, and take the /* and */ out of the loop.

* Encoder testing, the encoders can be a little tricky, the need to be pretty low (but not too low) on the encoder disc, really just enough to "see" the changes - as the motors are spinning you should see a green led on each of the encoders flash as the state changes, if you don't see the led flashing, your encoders are either too high or too low to read.

If the "right" encoder reads on the left wheel - then swap the pins around and that should fix it.

<em>int encoder0PinA = 29; //right encoder<br> int encoder0PinB = 30; //left encoder</em>

That should take care of testing the motors, you are of course free to test the other functions and tabs out as well.

* Ping tab I commented out the serial print from this tab, because it seemed to slow down the ping too much.

That being said, it is a good way to at least see if the sensor is hooked up correctly, but you'll want to make sure to re-comment them out.

* LCD - if you are using it, you should see information being displayed, if you don't check all your wires.

Really that should do it......

Step 17: Enjoy One More Video!

This is my 4th instructable, it's a project I wasn't planning on making into an instructable. But I think it's the best one I've done so far, even if I do say so myself!

Thanks for reading, and I hope you enjoyed the build, and the project.

Comments

About This Instructable

1,565views

17favorites

License:

Bio: I am a Ham Radio operator, computer geek, currently a service tech, robotic hobbyist. I've been &quot;playing&quot; with microcontrolers for the last several years ... More »
More by kd8bxp:2017 Halloween Cheerlights Ghost (Simple Hardware, Simple Software) & SpookyRobotsESP32/ESP8266 WIFI Display Using MQTT Protocol
Add instructable to: