Home › Forums › Forums › Technical Support for BerryGPS and BerryGPS-IMU › BerryGPS-IMU v3 loses customized settings
- This topic has 4 replies, 3 voices, and was last updated 2 years, 11 months ago by ahogrelius.
- AuthorPosts
- June 23, 2020 at 9:59 am #15928ahogreliusParticipant
I have an application that requires a higher refresh rate than standard. I can change the settings with u-center but the customized settings are lost when the supercap is discharged. Is there a way to make the changes permanent? I considered using ubxtool to change the settings on startup but it seems the CAM-M8 isn’t fully supported even in the latest version of gpsd.
The second question is regarding the IMU. I have not been able to get stable readings from the IMU. They are stable for a few minutes after a calibration but after a few minutes the bearing is off by up to 30 degrees.
June 23, 2020 at 12:32 pm #15930PeterPParticipantThe CAM-M8 hasn’t got anywhere to store the custom config. You would need to set it every time you boot your Pi and you know there is no power in the superCap.
e.g. change to 2Hz(twice a second)
echo -e -n "\B5\x62\x06\x08\x06\x00\xF4\x01\x01\x00\x01\x00\x0B\x77" > /dev/serial0
Regarding the IMU, Which code are you using and is it unmodified (except for calibration values)?
Peter --OzzMaker.com --
June 24, 2020 at 4:24 am #15937ahogreliusParticipantI will try adding the shell code snippet to update the refresh every time I boot the Raspberry.
Regarding the second question. I’m using the “compass_tutorial02_tilt_compensation” example.
I was able to get stable and reliable readings by adding code to do an Exponential Moving Average of the heading. I also added code to allow calibration which improved things even more. With the changes I get stable readings that only is off by a degree or so compared to the compass app on my cellphone.
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include “IMU.c”//Defines for calibration from the calibration application
#define magXmax 1177
#define magYmax 993
#define magZmax 839
#define magXmin -692
#define magYmin -945
#define magZmin -1335//Defines for static offsets
#define heading_offset 0
#define heading_compensated_offset 0//Calculate Exponential Moving Average
float calc_ema(float in, float average, float alpha);
float calc_ema(float in, float average, float alpha)
{return ((alpha * in) + (1.0 – alpha) * average);
}int main(int argc, char *argv[])
{
int magRaw[3];
int accRaw[3];
float scaledMag[3];float accXnorm,accYnorm,pitch,roll,magXcomp,magYcomp;
float heading;
float heading2;
float average1 = 0;
float average2 = 0;
float average1disp = 0;
float average2disp = 0;
int32_t adc_value1;
int32_t adc_value2;detectIMU();
enableIMU();while(1)
{
readMAG(magRaw);
readACC(accRaw);//Apply hard iron calibration
magRaw[0] -= (magXmin + magXmax) /2 ;
magRaw[1] -= (magYmin + magYmax) /2 ;
magRaw[2] -= (magZmin + magZmax) /2 ;//Apply soft iron calibration
scaledMag[0] = (float)(magRaw[0] – magXmin) / (magXmax – magXmin) * 2 – 1;
scaledMag[1] = (float)(magRaw[1] – magYmin) / (magYmax – magYmin) * 2 – 1;
scaledMag[2] = (float)(magRaw[2] – magZmin) / (magZmax – magZmin) * 2 – 1;//If your IMU is upside down(Skull logo facing up), comment out the two lines below which will correct the tilt calculation
//accRaw[0] = -accRaw[0];
//accRaw[1] = -accRaw[1];//Compute heading
heading = 180 * atan2(scaledMag[1],scaledMag[0])/M_PI;
//float heading = 180 * atan2(magRaw[1],magRaw[0])/M_PI;
heading = heading – heading_offset;adc_value1 = (float)heading;
average1 = calc_ema(adc_value1, average1, 0.1);//Necessary with separate variable for display of the averaged heading as the function below creates problems with the averaging
average1disp = average1;//Convert heading to 0 – 360
if(heading < 0)
heading += 360;if(average1disp < 0)
average1disp += 360;printf(“Heading %7.3f \t “, heading);
printf(“Averaged Heading %7.0f \t “, average1disp);//Normalize accelerometer raw values.
accXnorm = accRaw[0]/sqrt(accRaw[0] * accRaw[0] + accRaw[1] * accRaw[1] + accRaw[2] * accRaw[2]);
accYnorm = accRaw[1]/sqrt(accRaw[0] * accRaw[0] + accRaw[1] * accRaw[1] + accRaw[2] * accRaw[2]);//Calculate pitch and roll
pitch = asin(accXnorm);
roll = -asin(accYnorm/cos(pitch));//Calculate the new tilt compensated values
magXcomp = magRaw[0]*cos(pitch)+magRaw[2]*sin(pitch);
if(LSM9DS0)
magYcomp = magRaw[0]*sin(roll)*sin(pitch)+magRaw[1]*cos(roll)-magRaw[2]*sin(roll)*cos(pitch); // LSM9DS0
else
magYcomp = magRaw[0]*sin(roll)*sin(pitch)+magRaw[1]*cos(roll)+magRaw[2]*sin(roll)*cos(pitch); // LSM9DS1//Calculate heading
heading2 = (180*atan2(magYcomp,magXcomp)/M_PI)-heading_compensated_offset;adc_value2 = (float)heading2;
average2 = calc_ema(adc_value2, average2, 0.1);
//Necessary with separate variable for display of the averaged heading as the function below creates problems with the averaging
average2disp = average2;//Convert heading to 0 – 360
if(heading < 0)
heading += 360;if(average2disp < 0)
average2disp += 360;printf(“Compensated Heading %7.3f\t”, heading);
printf(“Averaged Compensated Heading %7.0f\n”, average2disp);
//Sleep for 25ms
usleep(25000);}
}
June 24, 2020 at 11:43 am #15941Mark WilliamsKeymasterokay.. i see.
When doing a large average, this would result in a delay to the output. Or a phase shift if you were to graph out the two values.If you want to “smooth” the output more, you can also look at a low pass filter. Example here https://github.com/ozzmaker/BerryIMU/tree/master/python-BerryIMU-gryo-accel-compass-filters
Mark --OzzMaker.com --
June 24, 2020 at 1:35 pm #15943ahogreliusParticipantI hacked the old version of berryIMU.py (Used in Raspberry Pi Embedded Cap With GPS) to work with the new version of BerryGPS-IMU and it gives pretty much the same result as the code above.
- AuthorPosts
- You must be logged in to reply to this topic.