we first were using the course to technique but it gave us the fluctuated heading towards destination why dont know?
AWOL:
is there a particular reason you didn't use the "course_to" method?
The GPS-determined heading fluctuated too much at low speeds because it depends on motion to determine heading. The compass measures absolute heading against an external reference (Earth's magnetic field).
how about using modifying Calc bearing code i got it from my friend i think there is something wrong with this code
#include <math.h>
#include <nmea.h>
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal myLCD(42, 40, 38, 36, 34, 32);
float lat;
float lon;
NMEA myGPS(GPRMC);
float dest_latitude = 25.37104;//the destination Latitude
float dest_longitude = 68.35567;//the destination Longitude
int HMC6352SlaveAddress = 0x42;
int HMC6352ReadAddress = 0x41;
const int potPin = A8; //Analog pin A8 for reading Potientiometer that drives the Servo steering
const int leftMotor = 27; //Pin connected to the Relay pin for moving the steering to left
const int rightMotor = 26;//Pin connected to the Relay pin for moving the steering to right
int motorA1=22; //Pin connected to the Relay pin for moving the car forward
int motorA2=23; //Pin connected to the Relay pin for moving the car backward
//below code describes the Steering ranges for left right and center
char Dir;
bool isLeft() {
return (analogRead(potPin)/4) <65;
}
bool isLeftOfCenter() {
return (analogRead(potPin)/4) < 108;
}
bool isRightOfCenter() {
return (analogRead(potPin)/4) > 118;
}
bool isRight() {
return (analogRead(potPin)/4) > 128;
}
int beeperpin=44;//the following pin is connected to the buzzer pin
void setup() {
Serial1.begin(4800);//Start the serial communication of GPS from the Mega Board
//PIN DESCRIPTION
pinMode(leftMotor,OUTPUT);
pinMode(rightMotor,OUTPUT);
pinMode(motorA1,OUTPUT);
pinMode(motorA2,OUTPUT);
myLCD.begin(16,2);//starting the LCD
myLCD.print("GPS BASED");//Printing on LCD
delay(3000);
myLCD.clear();//Clearing the LCD
myLCD.home();
Wire.begin();
HMC6352SlaveAddress = HMC6352SlaveAddress >> 1;
pinMode(beeperpin,OUTPUT);
pinMode(13,OUTPUT);
}
void loop(){
if (Serial1.available() > 0 ) {
// read incoming character from GPS
if (myGPS.decode(Serial1.read())) {
// check if the character completes a valid GPS sentence
// check if GPS positioning was unactive
myLCD.setCursor(15,1);
myLCD.print('V');
// check if GPS positioning was active
if (myGPS.gprmc_status() == 'A') {
myLCD.setCursor(15,1);
myLCD.print('A');
lat=myGPS.gprmc_latitude();//Current latitude
lon = myGPS.gprmc_longitude();//Current longitude
int d=(round(myGPS.gprmc_distance_to(dest_latitude, dest_longitude, MTR)));
//calculate the distance by rounding the GPS data from the current latitude,longitude to the desired Longitude
myLCD.setCursor(0,0);
myLCD.print('D:');
myLCD.setCursor(3, 0);
myLCD.print(d);//Print the Distnace on LCD
myLCD.setCursor(7, 0);
myLCD.print('m');
//if the distance is less than 6 than it should stop the car
if (d < 6){
myLCD.clear();
myLCD.home();
myLCD.setCursor(0,0);
myLCD.print("Destinat");//Print destination
digitalWrite(13, HIGH);//Put the LED high
digitalWrite(beeperpin, HIGH);//On the Buzzer pin
carbreak();//apply car breaks
}
//if the distnace is not greater than 6 then move towards the waypoint
if (d > 6){
myLCD.clear();
myLCD.home();
myLCD.setCursor(0,0);
myLCD.print('D:');
myLCD.setCursor(3, 0);
myLCD.print(d);//Print the Distnace on LCD
myLCD.setCursor(7, 0);
myLCD.print('m');
digitalWrite(beeperpin, LOW);
digitalWrite(13, LOW);
//average the down the direction from current latitude,longitude to destination latitude,longitude
float mydir= 0;
for (int x = 0; x<20; x=x+1){
mydir=mydir + myGPS.gprmc_course_to(dest_latitude, dest_longitude);
}
mydir=mydir/20;
if (mydir < 0) {//thats what i not understand
mydir += 360; //thats what i not understand
}
if (mydir > 180) { //thats what i not understand
mydir -= 360; //thats what i not understand
}
float currentdir = compassvalue();//its the compass value
float finaldir =currentdir - mydir;//subtract the compass value form the GPS beairng
myLCD.setCursor(2,1);
if ( abs (finaldir) < 20)//if the final direction is +20 or -20 it should go straight
{
myLCD.print ('Go Straight');
motorForward();//car Forward
steering('C');//Steering Centered
while(finaldir < 0)//if the Final direction is less than zero than goto LEFT
{
myLCD.print ("L");
motorForward();
steering('L');
}
while(finaldir > 0)//if the Final direction is greater than zero than goto RIGHT
{
myLCD.print ("R");
motorForward();
steering('R');
}
myLCD.print(abs(finaldir), DEC);//print the Direction
myLCD.print(223, BYTE); // print °-character
}
}
}
}
}
}
int compassvalue(){
//"Get Data. Compensate and Calculate New Heading"
Wire.beginTransmission(HMC6352SlaveAddress);
Wire.send(HMC6352ReadAddress); // The "Get Data" command
Wire.endTransmission();
//time delays required by HMC6352 upon receipt of the command
//Get Data. Compensate and Calculate New Heading : 6ms
delay(6);
Wire.requestFrom(HMC6352SlaveAddress, 2); //get the two data bytes, MSB and LSB
//"The heading output data will be the value in tenths of degrees
//from zero to 3599 and provided in binary format over the two bytes."
byte MSB = Wire.receive();
byte LSB = Wire.receive();
float headingSum = (MSB << 8) + LSB; //(MSB / LSB sum)
float headingInt = headingSum / 10;
//Serial.print(headingInt);
//Serial.println(" degrees");
return headingInt;
}
//Motor commands Description
void motorStop() {
digitalWrite(leftMotor, LOW);
digitalWrite(rightMotor, LOW);
}
void motorLeft() {
digitalWrite(leftMotor, HIGH);
}
void motorRight() {
digitalWrite(rightMotor, HIGH);
}
//back wheels
void motorForward()
{
digitalWrite(motorA1,HIGH);
digitalWrite(motorA2,LOW);
}
void motorBackward()
{
digitalWrite(motorA1,LOW);
digitalWrite(motorA2,HIGH);
}
void carbreak()
{
digitalWrite(motorA1,LOW);
digitalWrite(motorA2,LOW);
}
void steering(char Dir)
{
//if (Serial.available() == 0)
//return;
//Dir=toupper(Serial.read());
switch (Dir)
{
case 'L':
//Serial.println("New command: L");
if (isLeft())
{
}//Serial.println("Already Left");
else
{
//Serial.println("Heading Left");
motorLeft();
while (!isLeft()) /* JUST WAITING */;
motorStop();
//Serial.println("Is now Left");
}
break;
case 'C':
//Serial.println("New command: C");
if (isRightOfCenter())
{
//Serial.println("Heading Left toward Center");
motorLeft();
while (isRightOfCenter()) /* JUST WAITING */;
motorStop();
//Serial.println("Is now Centered");
}
else
if (isLeftOfCenter())
{
//Serial.println("Heading Right toward Center");
motorRight();
while (isLeftOfCenter()) /* JUST WAITING */;
motorStop();
//Serial.println("Is now Centered");
}
else
{
}
//Serial.println("Already Centered");
break;
case 'R':
//Serial.println("New command: R");
if (isRight())
{
}//Serial.println("Already Right");
else
{
//Serial.println("Heading Right");
motorRight();
while (!isRight()) /* JUST WAITING */;
motorStop();
//Serial.println("Is now Right");
}
break;
} // end of switch on direction
}
should i try this one
should i try this one
Try it by all means, and when you have done, if you still have problems, post the debug output and your observations.
If you don't have problems, pat yourself on the back, and post in the "Exhibitions" section.
This:
//average the down the direction from current latitude,longitude to destination latitude,longitude
float mydir= 0;
for (int x = 0; x<20; x=x+1){
mydir=mydir + myGPS.gprmc_course_to(dest_latitude, dest_longitude);
}
mydir=mydir/20;
seems a bit of a waste of time, if I'm understanding how the library works with the current NMEA sentence. A running average over several sentences would be more sensible.
myLCD.print ('Go Straight');
Can you see what you did wrong there?
while(finaldir < 0) {
while(finaldir > 0) {
Uh-oh!
the above code did not worked for me so i modified it
#include <math.h>
#include <nmea.h>
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal myLCD(42, 40, 38, 36, 34, 32);
float lat;
float lon;
NMEA myGPS(GPRMC);
float dest_latitude = 25.37104;//the destination Latitude
float dest_longitude = 68.35567;//the destination Longitude
int HMC6352SlaveAddress = 0x42;
int HMC6352ReadAddress = 0x41;
const int potPin = A8; //Analog pin A8 for reading Potientiometer that drives the Servo steering
const int leftMotor = 27; //Pin connected to the Relay pin for moving the steering to left
const int rightMotor = 26;//Pin connected to the Relay pin for moving the steering to right
int motorA1=22; //Pin connected to the Relay pin for moving the car forward
int motorA2=23; //Pin connected to the Relay pin for moving the car backward
//below code describes the Steering ranges for left right and center
char Dir;
bool isLeft() {
return (analogRead(potPin)/4) <65;
}
bool isLeftOfCenter() {
return (analogRead(potPin)/4) < 108;
}
bool isRightOfCenter() {
return (analogRead(potPin)/4) > 118;
}
bool isRight() {
return (analogRead(potPin)/4) > 128;
}
int beeperpin=44;//the following pin is connected to the buzzer pin
void setup() {
Serial.begin(9600);
Serial1.begin(4800);//Start the serial communication of GPS from the Mega Board
//PIN DESCRIPTION
pinMode(leftMotor,OUTPUT);
pinMode(rightMotor,OUTPUT);
pinMode(motorA1,OUTPUT);
pinMode(motorA2,OUTPUT);
myLCD.begin(16,2);//starting the LCD
Serial.print("GPS BASED");
myLCD.print("GPS BASED");//Printing on LCD
delay(1000);
myLCD.clear();//Clearing the LCD
myLCD.home();
Wire.begin();
HMC6352SlaveAddress = HMC6352SlaveAddress >> 1;
pinMode(beeperpin,OUTPUT);
pinMode(13,OUTPUT);
}
void loop(){
if (Serial1.available() > 0 ) {
// read incoming character from GPS
if (myGPS.decode(Serial1.read())) {
// check if the character completes a valid GPS sentence
// check if GPS positioning was unactive
Serial.println("V");
myLCD.setCursor(15,1);
myLCD.print("V");
// check if GPS positioning was active
if (myGPS.gprmc_status() == 'A') {
Serial.println("A");
myLCD.setCursor(15,1);
myLCD.print("A");
lat=myGPS.gprmc_latitude();//Current latitude
lon = myGPS.gprmc_longitude();//Current longitude
int d=(round(myGPS.gprmc_distance_to(dest_latitude, dest_longitude, MTR)));
//calculate the distance by rounding the GPS data from the current latitude,longitude to the desired Longitude
Serial.println("D:");
Serial.print(d);
Serial.print("m");
Serial.print("\n");
myLCD.setCursor(0,0);
myLCD.print("D:");
myLCD.setCursor(3, 0);
myLCD.print(d);//Print the Distnace on LCD
myLCD.setCursor(7, 0);
myLCD.print("m");
//if the distance is less than 6 than it should stop the car
if (d < 6){
myLCD.clear();
myLCD.home();
Serial.println("Destination");
Serial.println("CarbreaK");
myLCD.setCursor(0,0);
myLCD.print("Destinat");//Print destination
digitalWrite(13, HIGH);//Put the LED high
digitalWrite(beeperpin, HIGH);//On the Buzzer pin
carbreak();//apply car breaks
}
//if the distnace is not greater than 6 then move towards the waypoint
if (d > 6){
Serial.println("D:");
Serial.print(d);
Serial.print("m");
Serial.print("\n");
myLCD.clear();
myLCD.home();
myLCD.setCursor(0,0);
myLCD.print("D:");
myLCD.setCursor(3, 0);
myLCD.print(d);//Print the Distnace on LCD
myLCD.setCursor(7, 0);
myLCD.print("m");
digitalWrite(beeperpin, LOW);
digitalWrite(13, LOW);
//average the down the direction from current latitude,longitude to destination latitude,longitude
float mydir= 0;
for (int x = 0; x<20; x=x+1){
mydir=mydir + myGPS.gprmc_course_to(dest_latitude, dest_longitude);
}
mydir=mydir/20;
if (mydir < 0) {//thats what i not understand
mydir += 360; //thats what i not understand
}
if (mydir > 180) { //thats what i not understand
mydir -= 360; //thats what i not understand
}
Serial.println("GPS degree:");
Serial.print(mydir);
Serial.print("deg");
Serial.print("\n");
float currentdir = compassvalue();//its the compass value
Serial.println("Compass Degree");
Serial.print(currentdir);
Serial.print("deg");
Serial.print("\n");
float finaldir =currentdir - mydir;//subtract the compass value form the GPS beairng
Serial.println(finaldir);
Serial.print("\n");
Serial.println("Straight");
myLCD.setCursor(2,1);
if ( finaldir < 20 && finaldir > 340 )//if the final direction is +20 or -20 it should go straight
{
Serial.println("Straight");
myLCD.print ("Go Straight");
//motorForward();//car Forward
//steering('C');//Steering Centered
}
if(finaldir >180 && finaldir < 339)
{
Serial.print("Straight");
Serial.println("Left");
myLCD.print ("L");
//motorForward();
//steering('L');
}
if(finaldir > 20 && finaldir < 179)
{
Serial.print("Straight");
Serial.println("Right");
myLCD.print ("R");
//motorForward();
//steering('R');
}
myLCD.print(abs(finaldir), DEC);//print the Direction
myLCD.print(223, BYTE); // print °-character
}
}
}
}
}
int compassvalue(){
//"Get Data. Compensate and Calculate New Heading"
Wire.beginTransmission(HMC6352SlaveAddress);
Wire.send(HMC6352ReadAddress); // The "Get Data" command
Wire.endTransmission();
//time delays required by HMC6352 upon receipt of the command
//Get Data. Compensate and Calculate New Heading : 6ms
delay(6);
Wire.requestFrom(HMC6352SlaveAddress, 2); //get the two data bytes, MSB and LSB
//"The heading output data will be the value in tenths of degrees
//from zero to 3599 and provided in binary format over the two bytes."
byte MSB = Wire.receive();
byte LSB = Wire.receive();
float headingSum = (MSB << 8) + LSB; //(MSB / LSB sum)
float headingInt = headingSum / 10;
//Serial.print(headingInt);
//Serial.println(" degrees");
return headingInt;
}
//Motor commands Description
void motorStop() {
digitalWrite(leftMotor, LOW);
digitalWrite(rightMotor, LOW);
}
void motorLeft() {
digitalWrite(leftMotor, HIGH);
}
void motorRight() {
digitalWrite(rightMotor, HIGH);
}
//back wheels
void motorForward()
{
digitalWrite(motorA1,HIGH);
digitalWrite(motorA2,LOW);
}
void motorBackward()
{
digitalWrite(motorA1,LOW);
digitalWrite(motorA2,HIGH);
}
void carbreak()
{
digitalWrite(motorA1,LOW);
digitalWrite(motorA2,LOW);
}
void steering(char Dir)
{
//if (Serial.available() == 0)
//return;
//Dir=toupper(Serial.read());
switch (Dir)
{
case 'L':
//Serial.println("New command: L");
if (isLeft())
{
}//Serial.println("Already Left");
else
{
//Serial.println("Heading Left");
motorLeft();
while (!isLeft()) /* JUST WAITING */;
motorStop();
//Serial.println("Is now Left");
}
break;
case 'C':
//Serial.println("New command: C");
if (isRightOfCenter())
{
//Serial.println("Heading Left toward Center");
motorLeft();
while (isRightOfCenter()) /* JUST WAITING */;
motorStop();
//Serial.println("Is now Centered");
}
else
if (isLeftOfCenter())
{
//Serial.println("Heading Right toward Center");
motorRight();
while (isLeftOfCenter()) /* JUST WAITING */;
motorStop();
//Serial.println("Is now Centered");
}
else
{
}
//Serial.println("Already Centered");
break;
case 'R':
//Serial.println("New command: R");
if (isRight())
{
}//Serial.println("Already Right");
else
{
//Serial.println("Heading Right");
motorRight();
while (!isRight()) /* JUST WAITING */;
motorStop();
//Serial.println("Is now Right");
}
break;
} // end of switch on direction
}
and the output is here
output.txt (8.89 KB)
What is the point of this:
float mydir= 0;
for (int x = 0; x<20; x=x+1){
mydir=mydir + myGPS.gprmc_course_to(dest_latitude, dest_longitude);
}
mydir=mydir/20;
?
its used for averaging the 20 readings from the GPS
I thought you might say that.
Think of a number, but don't tell me what it is.
Double it.
Multiply that number by five.
Double that number.
Divide the number you have now by twenty.
You have the number you started with.
Amazing, or what?
I'm available for weddings and bar mitzvahs, my rate-sheet is online.
I think I pointed this out earlier.
ok then but it still does not work good from my side
Think of a number, but don't tell me what it is.
Add it to itself twenty times.
Divide the number you have now by twenty.You have the number you started with.
Amazing, or what?I'm available for weddings and bar mitzvahs, my rate-sheet is online.
I think I pointed this out earlier.
Well, your debug trace doesn't give any indication of how long it took (hint), but I'd probably go for continuous (1Hz) updates from the GPS, and do a rolling average of lat/long.
it still does not work good from my side
I'm sorry to hear that.
i am just working on the ranges but not able to define it properly so i need help in defining the ranges if you can do me a favour
You can't define the range; the range is simply the distance from where you are to where you want to be, and will obviously vary.
only worried about the direction
if ( finaldir < 20 && finaldir > 340 )//if the final direction is +20 or -20 it should go straight
{
Serial.println("Straight");
myLCD.print ("Go Straight");
//motorForward();//car Forward
//steering('C');//Steering Centered
}
if(finaldir >180 && finaldir < 339)
{
Serial.print("Straight");
Serial.println("Left");myLCD.print ("L");
//motorForward();
//steering('L');
}
if(finaldir > 20 && finaldir < 179)
{
Serial.print("Straight");
Serial.println("Right");myLCD.print ("R");
//motorForward();
//steering('R');
}
if ( finaldir < 20 && finaldir > 340 )/
Doesn't seem very likely, does it?
AWOL:
if ( finaldir < 20 && finaldir > 340 )/Doesn't seem very likely, does it?
Also you have some gaps where if the value is 179 through 180, 339 through 340, or exactly 20 (as examples) there's no result as you've not tested for >= or <=.
tell me the mistakes if any
uncheck_asad_test_new_2.pde (10.2 KB)
Well, as usual, you're ignoring what you're being told.
How many times do you need to be told that adding the same number twenty times and then dividing by twenty is a waste of time?
How many times have I told you that static analysis of software is about the least productive way of debugging?
Again if ( finaldir < 20 && finaldir > 340 )//
Can you list all the values of "finaldir" which are going to trigger this condition?
(Hint: It's a very short list)