Hi guys !
I have a project to make tracking antenna for UAV. I want to use PID algorithm to rotate the servo.
Here, I use compass to give a feedback value of current heading of antenna, for feedback input PID.
Firstly, I did coding and configuring to show the degree of compass' current heading. Yeah, It worked, showed the right value of compass' heading in 0-360 degrees. But, in a some times, the proses stopped. I don't know how. Sometimes, in 10 seconds, 30 seconds, 1 minute, 5 minutes, it stopped, really random.
Does anybody here know the problem and the solution? I've shearched in the internet, but haven't found the solution. I attach the code bellow.
Need help Guys!
Thank you very much!
*FYI: I used Arduino Uno and Turnigy Neo-6M GPS with Compass as compass.
Cheers,
Ardian Umam
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
void setup() {
Serial.begin(9600); //baudrate serial monitor
mag.begin();
}
void loop() {
sensors_event_t event;
mag.getEvent(&event);
//calculate compass' degree
float heading = atan2(event.magnetic.y, event.magnetic.x);
float declinationAngle = 0;
heading += declinationAngle;
// Correct for when signs are reversed.
if(heading < 0)
heading += 2*22/7;
// Check for wrap due to addition of declination.
if(heading > 2*22/7)
heading -= 2*22/7;
// Convert radians to degrees for readability.
float headingDegrees = heading * 180/22*7;//value of compass' degree
}
What makes you think that something stopped?
Above sketch seems to be a very crippled version of your code, that cannot hang but in mag.getEvent(). Add some debug output to it, to find out more about the calculated values, which may make fail other (eliminated) code.
I don't know exactly. I think that there are two possibilities : fragile wiring or the library that I used.
That compass worked properly when I used in APM (Ardu Pilot Mega), so I tent to say that the cause is the library. I used Adafuit Libraries (#include <Adafruit_Sensor.h> & #include <Adafruit_HMC5883_U.h>). I've tried to trouble shoot in those library, but I haven't found the solution.
I've tried to give "mag.getEvent()" a comment, then there was an error when compiled the sketch..,
Thanks.,
heading += 2*22/7;
Since you are doing integer math you are using 3 for the value of pi. You could either use the pre-defined value 'PI':
heading += 2*PI;
or use floating-point constants:
heading += 2.0*22.0/7.0;
I'm having the same issue. Here's my code (basic sample code with debug added). I narrowed down the stopping point for my particular setup to this section in the start of the main loop:
sensors_event_t event;
Serial.print("stopping point 1 passed"); // gets past this point
mag.getEvent(&event);
Serial.print("stopping point 2 passed"); // never reaches this point
Full code:
/***************************************************************************
This is a library example for the HMC5883 magnentometer/compass
Designed specifically to work with the Adafruit HMC5883 Breakout
http://www.adafruit.com/products/1746
*** You will also need to install the Adafruit_Sensor library! ***
These displays use I2C to communicate, 2 pins are required to interface.
Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products
from Adafruit!
Written by Kevin Townsend for Adafruit Industries with some heading example from
Love Electronics (loveelectronics.co.uk)
This program is free software: you can redistribute it and/or modify
it under the terms of the version 3 GNU General Public License as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***************************************************************************/
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
void displaySensorDetails(void)
{
sensor_t sensor;
mag.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" uT");
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" uT");
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" uT");
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}
void setup(void)
{
Serial.begin(9600);
Serial.println("HMC5883 Magnetometer Test"); Serial.println("");
/* Initialise the sensor */
if(!mag.begin())
{
/* There was a problem detecting the HMC5883 ... check your connections */
Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
while(1);
}
/* Display some basic information on this sensor */
displaySensorDetails();
}
void loop(void)
{
/* Get a new sensor event */
sensors_event_t event;
Serial.print("stopping point 1 passed");
mag.getEvent(&event);
Serial.print("stopping point 2 passed"");
/* Display the results (magnetic vector values are in micro-Tesla (uT)) */
Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print(" ");
Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print(" ");
Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print(" ");Serial.println("uT");
// Hold the module so that Z is pointing 'up' and you can measure the heading with x&y
// Calculate heading when the magnetometer is level, then correct for signs of axis.
float heading = atan2(event.magnetic.y, event.magnetic.z);
// Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
// Find yours here: http://www.magnetic-declination.com/
// Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
// If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
float declinationAngle = 1.603;
heading += declinationAngle;
// Correct for when signs are reversed.
if(heading < 0)
heading += 2*PI;
// Check for wrap due to addition of declination.
if(heading > 2*PI)
heading -= 2*PI;
// Convert radians to degrees for readability.
float headingDegrees = (heading * 180/M_PI);
Serial.print("Heading (degrees): "); Serial.println(headingDegrees);
delay(500);
}
I reach the same stopping point in other sketches also. My sensor is working with another library however.
It seems that adding
Wire.begin();
in the setup may help. This library seems a bit...unreliable from my recent experiences.
johnwasser:
heading += 2*22/7;
Since you are doing integer math you are using 3 for the value of pi. You could either use the pre-defined value 'PI':
heading += 2*PI;
or use floating-point constants:
heading += 2.0*22.0/7.0;
I prefer 355.0/113.0 for pi.
odometer:
I prefer 355.0/113.0 for pi.
Seems a bit old school. They used something similar in ancient egypt. Not a very exact math.
their circle probably came out to be more this 0 than this o
mykiscool:
Seems a bit old school. They used something similar in ancient egypt. Not a very exact math.
their circle probably came out to be more this 0 than this o
I also don't see any advantage over using "PI". Why use something less accurate?
Just out of curiosity, is the pi function calculated each time or is it hard coded?
mykiscool:
Just out of curiosity, is the pi function calculated each time or is it hard coded?
I don't know for sure, but I imagine it's treated as a floating point constant. I would be very very amaze if it weren't treated as a floating point constant.
My guess is it's a 32-bit float.