Jump to content


Photo

Trouble with Robotics kit

kit robotics funduino how to make your first robot

  • Please log in to reply
82 replies to this topic

#21 Nathan House

Nathan House

    Administrator

  • Administrators
  • 122 posts
  • LocationLynchburg, VA

Posted 26 January 2014 - 01:36 AM

Oops, you're right! I didn't realize it was too narrow to go across the gap in the breadboard the right way -- the only way it fits across the gap is the wrong way (for the way it was wired).

 

Here's a revised diagram:

 

j9y9.png

 

Now it should work :)

 

The pins closer together (in the above diagram, the two bottom ones) aren't connected until the switch is pressed. So when the switch is open, pin 2 will be LOW and when it's closed (pressed), pin 2 will be pulled HIGH.


  • 0

#22 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 27 January 2014 - 07:50 PM

Yay!!! I have the button being recognized! Hallelujah! And the motors stop! There is a slight purr coming from the motors, like it's trying to move, but doesn't have the power to do so. Is this the configuring/tuning you were talking about?

 

Turns out that it was a bad jumper cable :P Good grief. However it is, I can now get down to business and move on with the development on the other features!

 

This is the wiring I ended up using:

 

aware_killbutton_works1.png


  • 0

#23 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 27 January 2014 - 08:52 PM

Question regarding the code.

 

With the #define statement, does the value that comes after it mean much, other than the fact that it sets the state apart from other states?

 

I'm working on writing code that when an object is detected, instead of turning left it takes measurements from both sides and follows the longer path. Also, and suggestions for this would be appreciated, as I'm new to C/Arduino.


  • 0

#24 Nathan House

Nathan House

    Administrator

  • Administrators
  • 122 posts
  • LocationLynchburg, VA

Posted 28 January 2014 - 02:58 AM

Great, glad to hear you got it working!

 

Yes, if you have the motors set to neutral and they are still moving (or trying to move), then you can use a screwdriver to turn the potentiometer in them to tune them (there's a little hole on either the side or back).

 

The wiring looks good, nice work!

 

Question regarding the code.

 

With the #define statement, does the value that comes after it mean much, other than the fact that it sets the state apart from other states?

 

The syntax for the #define statement is:

#define token value

Where "token" is the alias you want to use for "value." All it means is that you can use "token" instead of "value" in your program. So, for example, suppose that you have a function call like this in your program:

setMotor(180);

You could make a define like this:

#define FULL_SPEED 180

And use it like this:

setMotor(FULL_SPEED);

So when you run the program, the compiler just replaces the "token" with the "value" everywhere in your program.

 

However, important note: I've noticed that the Arduino compiler doesn't allow defines to be used in some functions. That's why in the program in the tutorial I declared the pin numbers as "const int," like this:

const int ultrasonic2TrigPin = 9;
I initially tried using #define statements, but the compiler wouldn't let me for some reason (a const int is a variable of type integer that remains constant throughout the program).
 

 

I'm working on writing code that when an object is detected, instead of turning left it takes measurements from both sides and follows the longer path. Also, and suggestions for this would be appreciated, as I'm new to C/Arduino.

 

Great idea! So do you have three ultrasonic sensors hooked up, one on the front and one on each side?

 

 

To know when to turn, and what way to turn, you'll need to measure the distance in front of the robot and check if it's less than some amount that you define (which means there's something in front of it), then you can check the distances on the left and right and based on which has a larger value, turn that direction and then drive straight again.

 

The best way to implement this would be using something called a finite state machine, but that's kind of challenging to learn, so I'd suggest getting something like the following pseudocode working first:

// get distances from all three ultrasonics

if(front ultrasonic < some distance) // if there's an object in front of the robot
{
    if(left ultrasonic > right ultrasonic) // if the path on the left is larger than on the right
    {
        // set the motors to turn left
        // use delay() to keep the robot turning for however many milliseconds it takes it to turn 90 degrees 
    }
    else  // if the path on the right is larger than on the left
    {
        // set the motors to turn right
        // use delay() to keep the robot turning for however many milliseconds it takes it to turn 90 degrees 
    }
}      
else
{
    // set the motors to drive forward
}

  • 0

#25 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 28 January 2014 - 05:55 PM

Yeah, sorta. I only have one ultrasonic sensor. I'm planning on buying a breadboard and two more sensors, as I think that will be easier than trying to work out this, but for now I'll keep working at it. This is my code so far, but it isn't working:

// define the states
#define DRIVE_FORWARD            0
#define TURN_LEFT                1
#define TURN_RIGHT               2
#define SCAN                     3
...
// set times for turning
unsigned long timeToTurn90 = 1100;                // it takes about 1.1 seconds to turn 90 degrees
unsigned long timeToTurn180 = 2200;               // it takes about 2.2 seconds to turn 180 degrees
...

void stateMachine()
{
  if(state == DRIVE_FORWARD) // no obstacles detected
  {
    if(ultrasonic2Distance > 6 || ultrasonic2Distance < 0) // if there's nothing in front of us
    {
      // drive forward
      rightMotor.write(0);
      leftMotor.write(180);
    }
    else                                                  // there's an object in front of us
    {
      state = SCAN;
    }
  }
  else if(state == SCAN)       // obstacle detected - start scanning
  {
    
    scan();                    // go to the scanning function
    
  }

  else if(state == TURN_LEFT) // left is longer
  {
    
    unsigned long turnStartTime = millis();             // save the time that we started turning
    
    while((millis()-turnStartTime) < timeToTurn90)    // stay in this loop until timeToTurn90 (1.1 seconds) has elapsed
    {
      // turn left
      rightMotor.write(0);
      leftMotor.write(0);
    }
    
    state = DRIVE_FORWARD;
    
  }
 
  else if(state == TURN_RIGHT)
  {
    
    unsigned long turnStartTime = millis();
    
    while((millis() - turnStartTime) < timeToTurn180)
    {
      //turn right
      rightMotor.write(180);
      leftMotor.write(180);
    }
    
    state = DRIVE_FORWARD;
  }
    
}
...
void scan() {
    
  unsigned long turnStartTime = millis();             // save the time that we started turning
 
  while((millis()-turnStartTime) < timeToTurn90)    // stay in this loop until timeToTurnLeft (1.1 seconds) has elapsed
  {
    // turn left
    rightMotor.write(0);
    leftMotor.write(0);
  }
 
  readUltrasonicSensors();
 
  dist_left = ultrasonic2Distance;      // Assign the value of the left distance to dist_left
 
  Serial.print('dist_left');
  Serial.println(dist_left);
 
  state = DRIVE_FORWARD;
 
  Serial.print('dist_right');
  Serial.println(dist_right);
 
  if (dist_left > dist_right)         // Is the distance longer on the left?
  {
    state = TURN_LEFT;                // Turn left   
}  
 
  else if (dist_left < dist_right)    // Is the distance shorter on the left?
  {
    state == TURN_RIGHT;
  }
 
  else if (dist_left == dist_right)   // Are they equal?
  {
   state == TURN_LEFT;               // Turn left if they are equal
  }
 
  else                                // Something weird happened
  {
    Serial.println('Distance comparison failed for unknown reason');
    Serial.println("Here's dist_left & dist_right: ");
    Serial.print("dist_left: ");
    Serial.println(dist_left);
    Serial.print("dist_right: ");
    Serial.println(dist_right);
    Serial.println("Killing Robot for Safety");
    endProgram();
  }

}

Basically the reasoning behind the code is like you said:

// get distances from all three ultrasonics

if(front ultrasonic < some distance) // if there's an object in front of the robot
{
    if(left ultrasonic > right ultrasonic) // if the path on the left is larger than on the right
    {
        // set the motors to turn left
        // use delay() to keep the robot turning for however many milliseconds it takes it to turn 90 degrees 
    }
    else  // if the path on the right is larger than on the left
    {
        // set the motors to turn right
        // use delay() to keep the robot turning for however many milliseconds it takes it to turn 90 degrees 
    }
}      
else
{
    // set the motors to drive forward
}

 

Basic Reasoning/Plan:

 

1. Go until you see an object

2. When object is seen turn 90 degrees (1.1 seconds - I am going to have to work on timing those out myself) right

3. When done turning, get measurement and store in dist_right

4. Turn 180 degree (2.2 - double 90 degrees, it seems to go slower when turning this way)

5. When done turning, get measurement and store in dist_left

6. Compare the value of dist_right and dist_left

7. Whichever is longer, go that way


  • 0

#26 Nathan House

Nathan House

    Administrator

  • Administrators
  • 122 posts
  • LocationLynchburg, VA

Posted 28 January 2014 - 09:06 PM

Basic Reasoning/Plan:

 

1. Go until you see an object

2. When object is seen turn 90 degrees (1.1 seconds - I am going to have to work on timing those out myself) right

3. When done turning, get measurement and store in dist_right

4. Turn 180 degree (2.2 - double 90 degrees, it seems to go slower when turning this way)

5. When done turning, get measurement and store in dist_left

6. Compare the value of dist_right and dist_left

7. Whichever is longer, go that way

 

Your logic seems sound and that looks like a good plan. 

 

It looks like you have the robot turn left or right 90 degrees at the beginning of scan, read the ultrasonic, but then you don't have the code to make it turn 180 degrees so that you can measure the distance in the other direction. If after your call to readUltrasonicSensors() you make it turn 180 and read the sensor again, then it looks like it might work.

 

When trying to debug your code, make sure to keep the USB cable plugged into the computer (if you have one long enough) so that you can see the output of your program in the terminal while it's running. Getting feedback like that really helps when debugging.


  • 0

#27 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 29 January 2014 - 08:11 PM

That would explain the issue! I will try out this and get back to the forum.

The only thing with the USB cable is that it, for some reason, causes the right servo to not work, and the left only very slightly and it constricts movement. I do have a longer one, not sure what is causing the USB issue, as data comes and goes fine...


  • 0

#28 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 29 January 2014 - 09:01 PM

So, I changed the code, not really sure how I managed to write it the other way the first time :P. Anyways, this is the new version (important stuff anyways):

boolean doScan = false;           // Obviously, false = don't scan, true = scan
...
void stateMachine()
{
  if(state == DRIVE_FORWARD) // no obstacles detected
  {
    long distanceAhead = (ultrasonic2Distance > 6 || ultrasonic2Distance < 0);
    
    Serial.print("distanceAhead: ");
    Serial.println(distanceAhead);
    
    if(distanceAhead) // if there's nothing in front of us
    {
      // drive forward
      rightMotor.write(0);
      leftMotor.write(180);
    }
    else                                                  // there's an object in front of us
    {
      doScan = true;
    }
  }

  else if(state == TURN_LEFT) // left is longer
  {
    
    unsigned long turnStartTime = millis();             // save the time that we started turning
    
    while((millis()-turnStartTime) < timeToTurn90)    // stay in this loop until timeToTurn90 (1.1 seconds) has elapsed
    {
      // turn left
      rightMotor.write(180);
      leftMotor.write(180);
    }
    
    state = DRIVE_FORWARD;
    
    doScan = false;
    
  }
  
  else if(state == TURN_RIGHT) 
  {
    
    unsigned long turnStartTime = millis();
    
    while((millis() - turnStartTime) < timeToTurn180)
    {
      //turn right
      rightMotor.write(0);
      leftMotor.write(0);
    }
    
    state = DRIVE_FORWARD;
    
    doScan = false;
    
  }
  
  if (doScan == true)
  {
    scan();
  }
    
}
...
void scan() {
    
  unsigned long turnStartTime = millis();             // save the time that we started turning
  
  while((millis()-turnStartTime) < timeToTurn90)    // stay in this loop until timeToTurnLeft (1.1 seconds) has elapsed
  {
    // turn left
    rightMotor.write(180);
    leftMotor.write(180);
  }
  
  readUltrasonicSensors();
  
  dist_left = ultrasonic2Distance;      // Assign the value of the left distance to dist_left
  
  Serial.print("dist_left: ");
  Serial.println(dist_left);
  
  turnStartTime = millis();
  
  while((millis()-turnStartTime) < timeToTurn180)
  {
    //turn right
    rightMotor.write(0);
    leftMotor.write(0);
  }
  
  readUltrasonicSensors();
  
  dist_right = ultrasonic2Distance;
  
  Serial.print("dist_right: ");
  Serial.println(dist_right);
 
  if (dist_left > dist_right)         // Is the distance longer on the left?
  {
    Serial.println("Turning LEFT");
    state = TURN_LEFT;                // Turn left   
    doScan = false;
  }  
  
  else if (dist_left < dist_right)    // Is the distance shorter on the left?
  {
    Serial.println("Turning RIGHT");
    state == TURN_RIGHT;
    doScan = false;
  }
  
  else if (dist_left == dist_right)   // Are they equal?
  {
    state == TURN_LEFT;               // Turn left if they are equal
    doScan = false;
  }
  
  else                                // Something weird happened
  {
    Serial.println('Distance comparison failed for unknown reason');
    Serial.println("Here's dist_left & dist_right: ");
    Serial.print("dist_left: ");
    Serial.println(dist_left);
    Serial.print("dist_right: ");
    Serial.println(dist_right);
    Serial.println("Killing Robot for Safety");
    endProgram();
  }

}

Changed around the way I tell if the robot is scanning (swapped state = SCAN for boolean doScan) and worked on the timing a bit. While it is working better (not infinitely looping and the comparison is working) it isn't turning to the sides, just 180 deg. turns :P


  • 0

#29 Nathan House

Nathan House

    Administrator

  • Administrators
  • 122 posts
  • LocationLynchburg, VA

Posted 30 January 2014 - 01:12 AM

The only thing with the USB cable is that it, for some reason, causes the right servo to not work, and the left only very slightly and it constricts movement. I do have a longer one, not sure what is causing the USB issue, as data comes and goes fine...

 

It should work the same with or without the USB cable. Are you keeping the battery pack plugged in when you use the USB cable? If not, try keeping it plugged in and see if that works.

 

 

Changed around the way I tell if the robot is scanning (swapped state = SCAN for boolean doScan) and worked on the timing a bit. While it is working better (not infinitely looping and the comparison is working) it isn't turning to the sides, just 180 deg. turns  :P

 

According to your code, once the object is detected it should turn 90 degrees to the left, measure the distance, turn 180 degrees (now facing right), measure the distance, and then change the state based upon those measurements. The logic seems good.

 

So what exactly happens when the program runs?

 

Can you copy what prints out to the serial console here? (assuming you can get it to work with a USB cable plugged in).


  • 0

#30 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 31 January 2014 - 01:18 AM

This robot is beginning to get rather annoying... <_<

 

As for getting the ouput, that's basically impossible. The cord keeps messing with the servos (bumping into them, stopping them, all in all a real pain) so I have basically given up on getting the debug data. If I had a LCD I could display it that way, but I don't :mellow:.

 

As for what happens, I changed the code (again...sorry, though same logic) so that the robot is supposed to stop when the robot sees something and then goes from there, stopping every time it finishes turning.

 

However, I believe I'm having issues with the stop and the 90 degree turn, because the robot will go until it sees something, then sputters along and eventually stop. I also added some delays after the servo stops to emphasize the halt so the robot does actually stop, but it never completes the 90 degree turn, just the 180 degree turn. I'm going to try out just 90 degree turns, no 180 deg, as that looks like it could be part of the issue.

 

Never mind all that...my code is working exactly as I planned it, it just isn't working how I want it to. I think it's actually a servo calibration/timing issue.

 

Currently the robot goes until it sees an object (though the response time seems quite impaired. Could that be caused by the extra code looking for the kill switch?) and the stops. This is where the servo configuration really pops up, as the left servo (as I mentioned before, sputters quite a bit). I have to try tweaking that a bit more. I'm also not quite sure that the timing is quite right (with my robot that is) and I'm going to continue messing with those values. Here's hoping!


  • 0

#31 Nathan House

Nathan House

    Administrator

  • Administrators
  • 122 posts
  • LocationLynchburg, VA

Posted 31 January 2014 - 01:45 AM

This robot is beginning to get rather annoying... <_<

 

Stick with it, debugging is perhaps the most important programming skill. Anyone can write code, but it takes real effort to learn to debug a program :)

 

As for getting the ouput, that's basically impossible. The cord keeps messing with the servos (bumping into them, stopping them, all in all a real pain) so I have basically given up on getting the debug data. If I had a LCD I could display it that way, but I don't  :mellow:.

 
Getting output from the robot is crucial in order to debug the program. Trying to debug a program without getting any kind of feedback from it is tedious, frustrating, slow going, and often fruitless. Here are a few ideas:
  • Reposition the Ardunio on your robot so that the USB port is facing the rear (like in this picture)
  • Take the wheels off the robot, or put something under it to lift it off the ground, then use your hand to simulate an object appearing in front of it to trigger the state change

Somehow, you've got to figure out a way to keep the USB cable plugged in so that you can get feedback from it. You might also be able to buy some sort of wireless device to transmit data back to the computer, but I've never tried doing that..

 

As for what happens, I changed the code (again...sorry, though same logic) so that the robot is supposed to stop when the robot sees something and then goes from there, stopping every time it finishes turning.

 

However, I believe I'm having issues with the stop and the 90 degree turn, because the robot will go until it sees something, then sputters along and eventually stop. I also added some delays after the servo stops to emphasize the halt so the robot does actually stop, but it never completes the 90 degree turn, just the 180 degree turn. I'm going to try out just 90 degree turns, no 180 deg, as that looks like it could be part of the issue.

 

As I mentioned a while back when you were asking for advice on what approach to take with the programming, state machines can be tricky and are hard to learn to use at first. I've written tons of programs using state machines and I still often find it challenging and have trouble getting the logic working correctly. The key is to have a debugging statement (i.e. a command that prints text out to the serial console) inside of each state so that you can see what's happening with the program.

 

When debugging a program, you want to have some sort of debug output wherever something important happens, or whenever the program flow changes, so that you can look at the output and from that see exactly how the program executed. For example, you might make a state machine like this:

if(state == 1)
{
    println("inside of state 1");
    
    println("starting turn");
    while(time < turnTime)
    {
        // set motors to turn
    }
    println("turn finished!");
}
else if(state == 2)
{
    println("inside of state 2");
}
else
{
    println("error: invalid state!");
}

When you run the program, you might be expecting it to go into state 1, but looking at the output you might find that it goes into state 2. In that case, it's probably a bug and using more println statements and working your way backwards you can find out where the problem is. Or the state might not be set correctly (i.e. being an invalid state), causing nothing to happen when you turn the robot on, and you could be scratching your head for hours, but by having a debug statement in the last "else" statement, you would immediately know what the problem was.

 

Note how I put println statements around the while loop. If your program seems to freeze at some point, try putting debug statements before and after things like loops and function calls, then by looking at your debug output you can see if the program got hung up somewhere.

 

Moral of the story is, you've got to get debug output from your program in order to effectively debug it. I'm doing a lot of website programming right now in a language called PHP and there's a lot of debugging involved since it can get pretty complex. For many functions, I'll actually have a parameter called "debug" that, when set to true, enables debug output from the function. That way I can enable or disable debug output from the function just by changing the value of the parameter in the function call.

 

Debugging is a very important skill and is something of an art. Just stick with it and you'll make progress! Also, be sure to take breaks. If you're stuck on something for more then, say, an hour, you'll often make much better progress if you take a few short breaks now and then.

 


  • 0

#32 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 31 January 2014 - 02:04 AM

So I wrote a simple sketch that just turns the servos to 90 and tried to calibrate the servos and I believe I did, but there still is a deviation to the right. I will try propping it up on something so I can't move and simulate an object, though I believe part of my problem is in the movement phase, but as you said, getting debugging info is crucial.

 

I do have a habit of working for extended periods and I really should take breaks more often, and I usually do, but this project has been irking me cause I really would like a working bot, and thus I've been working non-stop :P

 

I got the debug info and it looks like the robot starts off with the distance in front of it as having an object there, so that throws it off (not exactly sure how to fix that - any hints?) towards the beginning. As for the comparison and the servo writes, I believe they are all in order. The robot "sees" the first object and goes through the steps I programmed, turning one way then the other, getting the distance both times. I'm pretty sure my issue is with the servos, not the code, which I think is going to make diagnosing this a lot harder. As I mentioned, the robot has a deviation to the right, even though they should be calibrated to each-other. Not exactly sure what is going on with the timing, as that isn't something that can be debugged. I believe the issues I am having are caused by the servos not being in sync, and possibly the fact that they aren't connected to the tape on the inside of the body (pulled away and won't go back on, I might get some stronger stuff from a craft store).

 

Kinda Off-topic, but I noticed you replied, but your user didn't pop up in the Online users thing-a-ma-bob. Is that because you are the Admin, you can sneak around? Just wondering, no need to answer :D


  • 0

#33 Nathan House

Nathan House

    Administrator

  • Administrators
  • 122 posts
  • LocationLynchburg, VA

Posted 31 January 2014 - 09:32 PM

So I wrote a simple sketch that just turns the servos to 90 and tried to calibrate the servos and I believe I did, but there still is a deviation to the right. I will try propping it up on something so I can't move and simulate an object, though I believe part of my problem is in the movement phase, but as you said, getting debugging info is crucial.

 

Setting the servos to neutral and then tuning them so that they don't move (or are barely moving, as it might be impossible to get them to stop completely) will get the robot driving mostly straight, but because no two servos are perfectly identical there will always be a bit of deviation between them. If after tuning the servos, the robot deviates to one side or the other, you can try adding an offset to it in your software. For example, if you're setting the right servo to 120, you can instead set it to 120+offset (where offset is a number you determine experimentally) to get it to drive straighter. 

 

Unfortunately, it's impossible to get a robot to drive perfectly straight -- no matter what motors or servos are being used -- without using some kind of sensor. The two most commonly used sensors for this purpose are gyroscopes and encoders. You should be able to get it driving fairly straight without resorting to using one of these sensors, but learning to use a sensor to make it drive straight would be a great future project for you (gyroscopes are really cool!).

 

I got the debug info and it looks like the robot starts off with the distance in front of it as having an object there, so that throws it off (not exactly sure how to fix that - any hints?) towards the beginning. As for the comparison and the servo writes, I believe they are all in order. The robot "sees" the first object and goes through the steps I programmed, turning one way then the other, getting the distance both times. I'm pretty sure my issue is with the servos, not the code, which I think is going to make diagnosing this a lot harder. As I mentioned, the robot has a deviation to the right, even though they should be calibrated to each-other. Not exactly sure what is going on with the timing, as that isn't something that can be debugged. I believe the issues I am having are caused by the servos not being in sync, and possibly the fact that they aren't connected to the tape on the inside of the body (pulled away and won't go back on, I might get some stronger stuff from a craft store).

 
Well it sounds like there might be a few problems with the program, so let's just start with the first one.. You said that it thinks it sees an object when there isn't one? Can you post your current code, along with the output from the serial terminal when the program runs (i.e. with the robot off, open the serial terminal, turn the robot on, let it run, then post the output here). 
 
We'll get 'er working :)
 

Kinda Off-topic, but I noticed you replied, but your user didn't pop up in the Online users thing-a-ma-bob. Is that because you are the Admin, you can sneak around? Just wondering, no need to answer  :D

 

Not a clue! I may have accidentally checked the "Sign in anonymously" box when I logged in -- that's the only thing I can think of, lol..


  • 0

#34 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 01 February 2014 - 12:44 AM

Okay, here's the code: http://wp.me/a2ZT4c-6j I just uploaded it to my blog so you could see all of the code without having to read through it on the forum (would be way too long). Only thing is that my blog doesn't support the upload of most files, so I just added the .pdf extension on the end. Just delete the .pdf extension and pop it into a folder of the same name.

 

Here's what the output is:

objectAhead: 0
Scanning
Turning Right 90 deg
Turning Right Complete
Motor stopped
dist_left: 28
Turning Left 180 deg
Turning Left 180 deg complete
Motor stopped
dist_right: 27
Turning Right 90 deg
Turning Right 90 deg complete
Motor stopped
Turning LEFT
TURN_LEFT
TURN_LEFT COMPLETE
... (bunch of measurements and objectAhead = 1) ...
objectAhead: 0
Scanning
Turning Right 90 deg
Turning Right Complete
Motor stopped
dist_left: 16
Turning Left 180 deg
Turning Left 180 deg complete
Motor stopped
dist_right: 4
Turning Right 90 deg
Turning Right 90 deg complete
Motor stopped
Turning LEFT
TURN_LEFT
TURN_LEFT Complete

The first part is what happens every time I start the robot, it says there is something is in front of me. Could I set that at the beginning (int  as nothing and then it would be set to something when there actually is something?


  • 0

#35 Nathan House

Nathan House

    Administrator

  • Administrators
  • 122 posts
  • LocationLynchburg, VA

Posted 03 February 2014 - 04:55 AM

In your code you have readUltrasonicSensors() inside of the following IF statement:

if(millis() - timeLoopDelay >= loopPeriod)

But call stateMachine() outside of that statement. I think what might be happening is that when the robot turns on, it doesn't go inside of the IF statement because not enough time has elapsed, but it still calls stateMachine() because it's outside of the IF statement.

 

Try putting debugOutput() and stateMachine() inside of the if statement and see if that fixes the problem!


  • 0

#36 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 04 February 2014 - 01:30 AM

I think I did what you said, but whatever I did didn't work. Here's that IF statement (changed):

  if(millis() - timeLoopDelay >= loopPeriod)
  {    
    stateMachine();
    
    debugOutput();

    readUltrasonicSensors();  // read and store the measured distances
    
    timeLoopDelay = millis();
  }

What should I do about getting this fixed?

 

I really want to get this project working, but the servos just aren't cooperating. The debug info seems very random and the servos seem to work only about 1/3 of the time how they are supposed to. They seem rather opinionated about how they are going to work and when. I'm going to see if I can't get permission to upload a video of how the robot is moving, as that would help (right?)


  • 0

#37 Nathan House

Nathan House

    Administrator

  • Administrators
  • 122 posts
  • LocationLynchburg, VA

Posted 04 February 2014 - 02:19 AM

Yep, that's what I was talking about.

 

A video won't really help with debugging the program.. The key to debugging a program is to capture the debug output in the serial terminal and then use that to figure out how the program executed. When you trace the flow of the program, you'll find where it went astray (assuming you have debug statements in all the right places).

 

This is a really big, complex program right now. Here's my suggestion: simplify it. Strip it down to a barebones program and then start adding things back piece by piece. For example, you could:

  • Get rid of everything except for setup(), loop() and killButton(). Inside of loop(), just have code to make the robot drive forward. This way, you can make sure that the servos are working, and you can make sure that your kill switch is working. Make sure to use print statements to print out debug information so that you know what's happening in the program.
  • Next, you can add the ultrasonic sensor code back. Make your call to readUltrasonicSensors() inside of loop() and use print statements to print the distance out to the console. You could also add an if() statement that stops the servos if there's an object in front.
  • Once that's all working, you can start adding the state machine back piece by piece, making sure to have lots of debug statements so that you can easily trace the flow of the program to figure out why it's not working.

The problem you're having right now is very common -- the program is too big and complex for you to debug easily. By simplifying the program and then slowly adding stuff back, you can debug it much more easily!


  • 0

#38 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 04 February 2014 - 04:43 PM

Exactly what I was thinking, I just have never got to doing it. I don't know why, it always works better to just re-write once you've learned what works and what doesn't instead of adapting.

I suggested the video in case that would help with getting the servos tuned, but I think this will work better sooner. I will do that and update this response as the features are added in and debugged.

Forward Eorlingas!

EDIT

Just noticed, the IF statement
if(millis() - timeLoopDelay >= loopPeriod)
runs the first time when timeLoopDelay is set to 0, as per this statement: unsigned long timeLoopDelay = 0;

Could that be causing an issue?

Also, I was wondering if you knew of any way to program/upload the code to the Arduino from another IDE, such as Geany (Ubuntu IDE/Text Editor), or any for that matter. The Arduino IDE is okay, but kind of ugly and a pain to use in some cases.

The code would be SO much simpler to write and understand if we could use multiple files, is this possible/would it even work? I read here http://www.arduino.c...cking/Libraries, but would I be able to, say, put the scan() function in another file and use it?
  • 0

#39 Nathan House

Nathan House

    Administrator

  • Administrators
  • 122 posts
  • LocationLynchburg, VA

Posted 07 February 2014 - 01:05 AM

Just noticed, the IF statement

if(millis() - timeLoopDelay >= loopPeriod)

runs the first time when timeLoopDelay is set to 0, as per this statement: unsigned long timeLoopDelay    = 0;

 

Could that be causing an issue?

 

I think the program needs to enter it on the first loop.. We want the code inside of the IF statement to execute as soon as the robot turns on and to keep executing for as long as it's on -- the only reason we use the IF statement is to limit how quickly the code inside it is executed (executing the code over and over too quickly is kind of wasteful as it's unnecessary and can cause issues when trying to implement more advanced things like PIDs).

 

Also, I was wondering if you knew of any way to program/upload the code to the Arduino from another IDE, such as Geany (Ubuntu IDE/Text Editor), or any for that matter. The Arduino IDE is okay, but kind of ugly and a pain to use in some cases.

 

I don't like the Arduino IDE that much, either, but I've never tried using another one. It's probably possible, but I'm really not sure how to do it..

 

 

The code would be SO much simpler to write and understand if we could use multiple files, is this possible/would it even work? I read here http://www.arduino.c...cking/Libraries, but would I be able to, say, put the scan() function in another file and use it?

 

Yep, you can do that! Click on the down arrow just below the serial terminal button (upper right hand corner in the IDE), click New Tab, type in a name for the tab and click OK. You can then cut and paste whatever code you want to move to the different file.

 

So, for example, you could create a new tab called state_machine and then put the state machine function in there! 


  • 0

#40 PatriotAce

PatriotAce

    Advanced Member

  • Members
  • PipPipPip
  • 47 posts
  • LocationLowell, MI, USA

Posted 24 February 2014 - 03:17 AM

Received the two supersonic sensors along with the soldering iron. Thanks for the help :D

However, I was wondering, how can I mount the sensors facing left and right. Don't breadboard tracks run A-E and F-J? Because, if I mount the sensors facing out, they all the power/signals will be running down one track, and I don't think that would be very good...
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users