Pages: [1]   Go Down
Author Topic: Joystick controlled car, sensor time problem?  (Read 303 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I'm working on a project for a class and I'm very confused. I built a joystick controlled car that uses xbees to enable the conection between the controller and the car. I'm adding additional features to the car, and one of them is a proximity sensor that will make the car stop when it gets too close to a wall/obstacle. Since the code for the proximity code (ping)))) has a delay of 100 milliseconds, it interferes with the signal the car receives from the controller and the wheels don't turn when I unplug the car to let it run on the battery. I thought it was a power problem since I only had a small one, but my teacher told me that the delay messes up my code and that I need to add a timer (using millis to do so) I tried using millis in various ways but I had no results, I need some help please.

Here is my car's code.

Code:
#include <SoftwareSerial.h>
SoftwareSerial ss(2,3); //xbee is on pins 2 and 3 (these cannot be used for anything else)
 
//the Personal area network id, should be the same for all xbees that want to form a network
char panId[] = "7063520935";
 
// Destination HIGH and LOW
char destHi[] = "0013A200"; //same for every xbee
char destLo[] = "408CD712"; //different for every xbee
const int pingPin = 11;
const int  buttonPin = 10;    
int buttonState = 0;        
int pin = 2;
int power = 0;
int x = 0;
float differential = 0;
float drivea= 0;
float driveb = 0;
int AIN1 = 6;
int AIN2 = 7;
int BIN1 = 5;
int BIN2 = 4;
int PWMA = 8;
int PWMB = 13;
 
 
void setup(){
  
  ss.begin(9600); //setup software serial
  Serial.begin(9600); //setup hardware serial
  modifyXbee(); //force xbee to take on the desired panID and destination address
pinMode(PWMA, OUTPUT);
pinMode(PWMB, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);

}
 
void loop(){
  
   long duration, inches, cm;
 
 
   pinMode(pingPin, OUTPUT);
   digitalWrite(pingPin, LOW);
   delayMicroseconds(2);
   digitalWrite(pingPin, HIGH);
   delayMicroseconds(5);
   digitalWrite(pingPin, LOW);
 
   pinMode(pingPin, INPUT);
   duration = pulseIn(pingPin, HIGH);
 
  
   inches = microsecondsToInches(duration);
   cm = microsecondsToCentimeters(duration);
  
 /** Serial.print(inches);
   Serial.print("in, ");
   Serial.print(cm);
   Serial.print("cm");
   Serial.println();
  
 // delay(100);
  
    
  **/

  while(ss.available() > 0){
      char c = (char) ss.read(); //read a byte, and convert it to a character
      if(c == 'S'){ //only do something once we get the start byte
        int a = ss.parseInt(); //read the first int
        int b = ss.parseInt(); //read the second int
       power = map ( a , 0, 1023, -255, 255);
        x = map ( b, 0, 1023, -255, 255);

  
   if (power > 4 && x == 0){
digitalWrite(AIN2,HIGH);
 digitalWrite(AIN1,LOW);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
       analogWrite(PWMA, abs(power));
       analogWrite(PWMB, abs(power));
        }
 if( power == 4 && x<0){
 digitalWrite(AIN2,HIGH);
 digitalWrite(AIN1,LOW);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMA, abs(x/2));
analogWrite(PWMB, abs(x));
 }
        
  if( power == 4 && x>0){
 digitalWrite(AIN2,HIGH);
 digitalWrite(AIN1,LOW);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMA, abs(x));
analogWrite(PWMB, abs(x/2));
 }
 
  if (power > 4 && (x > 0)){ //go LEFT
digitalWrite(AIN2,HIGH);
digitalWrite(AIN1,LOW);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMA,abs(power-x)); //variable
analogWrite(PWMB,abs(power));
   }    
  
  
     if (power > 4 && (x < 0)){
      
digitalWrite(AIN2,HIGH);
 digitalWrite(AIN1,LOW);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
       analogWrite(PWMA,abs(power)); //variable
       analogWrite(PWMB,abs(power-x));
   }  
  
 
 if (power < 4 && x == 0) { //run CCW
digitalWrite(AIN2,LOW);
digitalWrite(AIN1,HIGH);
digitalWrite(BIN1,LOW);
digitalWrite(BIN2,HIGH);
       analogWrite(PWMA,abs(power)); //variable
       analogWrite(PWMB,abs(power)); //variable
       //Serial.print ("ccw");
      // Serial.println ( zooma );
         }
        
     if (power < 4 && (x > 0)){
digitalWrite(AIN2,LOW);
digitalWrite(AIN1,HIGH);
digitalWrite(BIN1,LOW);
digitalWrite(BIN2,HIGH);
       analogWrite(PWMA,abs(power - x)); //variable
       analogWrite(PWMB,abs(power));
   }  
  
    if (power < 4 && (x < 0)){
digitalWrite(AIN2,LOW);
digitalWrite(AIN1,HIGH);
digitalWrite(BIN1,LOW);
digitalWrite(BIN2,HIGH);
       analogWrite(PWMA,abs(power)); //variable by zoom
       analogWrite(PWMB,abs(power - x));
   }  
 
  if(cm < 20) {
    
    digitalWrite(AIN2, HIGH);
 digitalWrite(AIN1, HIGH);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,HIGH);
 analogWrite(PWMA, 255);
 analogWrite(PWMB, 255);
  }
  
      }
  }

}
 long microsecondsToInches(long microseconds)
 {
 
   return microseconds / 74 / 2;
 }
 
long microsecondsToCentimeters(long microseconds)
 {
  
   return microseconds / 29 / 2;
 }    

/*************XBEE configuration stuff************/
/*do not change any of the code below unless you are trying to learn xbee configuration*/
void modifyXbee()
{
  startConfigurationMode();
  sendAtCommand("SH"); //print this xbee's 64 bit address (high)
  sendAtCommand("SL"); //print this xbee's 64 bit address (low)
  sendAtCommand("ID", panId); //set the pan id
  sendAtCommand("DH", destHi);  //set the other xbee's 64 bit address (high)
  sendAtCommand("DL", destLo); //set the other xbee's 64 bit address (low)
  sendAtCommand("RO", "3");  //3 serial characters of silence before transmit an xbee packet
  sendAtCommand("WR"); //write to flash memory (save)
  sendAtCommand("CN"); //exit command mode
} // end modifyXBee
 
void startConfigurationMode()
{ // Wait a second, send +++, then wait another second
  // to enter configuration mode
  delay(1000);
  ss.print("+++");
  Serial.print("+++");
  delay(2000);
  getXbeeResponse();
} // end startConfigurationMode
 
void sendAtCommand(char command[], char newValue[])
{
  // This version of the function takes a second parameter
  // that alters the value of the given command to the value
  // of that second parameter
  ss.write("AT");
  ss.write(command);
  ss.write(newValue);
  ss.write("\r");
  Serial.print("AT");
  Serial.print(command);
  Serial.print(" ");
  Serial.print(newValue);
  delay(100); // let XBee process information...
  getXbeeResponse();
}
 
void getXbeeResponse()
{
  // Get XBee Response
  Serial.print(" Response: ");
  while(ss.available()){
    Serial.write(ss.read()); //pass bytes through the serial port
  }
  Serial.println();
}
 
void sendAtCommand(char command[])
{
  // Sends an AT command with the proper delay
  // based on which AT command is sent.
  int responseDelay = 100; // default
 
  if (command == "WR"){
    responseDelay = 2000; // time to write to flash memory
  }
  ss.write("AT");
  ss.write(command);
  ss.write("\r");
  Serial.print("AT");
  Serial.print(command);
  Serial.print(" ");
  delay(responseDelay); // let XBee process information...
  getXbeeResponse();
}

« Last Edit: November 16, 2012, 11:18:41 am by Sandoval » Logged

Austin, TX
Offline Offline
Full Member
***
Karma: 1
Posts: 182
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
   Aside from some minor coding style issues, the only problems I can see with this code is the call to pulseIn().  I suggest you read the reference for it carefully: http://arduino.cc/en/Reference/PulseIn
  First, You did not specify a timeout, in which case it defaults to 1 second. That means the pulseIn function could take up to 1 second to return, which is a very long time.  During that time it won't respond to the controller, nor will it stop if it gets close to a wall.  I suggest using a much smaller timeout.
  Second problem: in the event that pulseIn times out, it returns 0. You need to detect that and write code to handle it. Currently, it will calculate the distance as 0, which is just about opposite of what you want.
  Third problem, the code block where you check the distance is inside the loop that reads the xbee serial input.  So you only do the stop check if you are also working the controller.  Move it to just after the calls to calculate the distance.

With those changes you might get away with not using millis(), which would require re-writing all of your code.

Have fun,
Logged

Chris J. Kiick
Robot builder and all around geek.

Pages: [1]   Go Up
Jump to: