Im working on a flight computer that uses the SAM-M10Q GPS and i cant seem to get a FIX with the code i made to work with the other chips on the board. When i run the SparkFun NMEAparsing code it gets a FIX just fine. I have tried a bit of trouble shooting but nothing has worked, i suspect another chip is interfering but i'm not sure.
Here is the code that doesn't work:
#include <Wire.h>
#include <Adafruit_LIS3MDL.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include "SparkFun_BMI270_Arduino_Library.h"
#include <SparkFun_u-blox_GNSS_v3.h>
#include "SdFat.h"
#include <SPI.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#include <Adafruit_MS8607.h>
#include <Adafruit_LSM6DSO32.h>
#include <Adafruit_INA260.h>
#include "Adafruit_BMP3XX.h"
#include <Arduino.h>
#include <Adafruit_BNO08x.h>
#include <MicroNMEA.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BMP3XX bmp;
Adafruit_INA260 ina260 = Adafruit_INA260();
Adafruit_MS8607 ms8607;
#define PIN 4
SdFat sd;
// Log file.
SdFile dataFile;
SdFile dataFile2;
SdFile dataFile3;
const uint8_t chipSelect = BUILTIN_SDCARD;
#define NUMPIXELS 3
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
SFE_UBLOX_GNSS myGPS;
Adafruit_LSM6DSO32 dso32;
BMI270 imu;
char nmeaBuffer[100];
MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer));
// I2C address selection
uint8_t i2cAddress = BMI2_I2C_PRIM_ADDR; // 0x68
//uint8_t i2cAddress = BMI2_I2C_SEC_ADDR; // 0x69
Adafruit_LIS3MDL lis3mdl;
boolean onetime = false;
boolean onetime1 = false;
boolean onetime2 = false;
boolean onetime3 = false;
boolean onetime4 = false;
boolean onetime5 = false;
boolean onetime6 = false;
boolean onetime7 = false;
boolean onetime8 = false;
boolean onetime9 = false;
boolean onetime10 = false;
boolean onetime11 = false;
boolean onetime12 = false;
boolean onetime13 = false;
boolean onetime14 = false;
boolean onetime15 = false;
boolean onetime16 = false;
boolean onetime17 = false;
boolean overdd = false;
boolean atdd = false;
boolean timelockout = true;
boolean atdr = false;
const int buzzer = 8;
int alt = 0.00;
boolean ready = false;
boolean launch = false;
boolean apogge = false;
boolean inflight = false;
boolean land = false;
int Speed = 0.00;
int ms1 = 0.00;
int ms2 = 0.00;
int x, y, z;
int x2, y2, z2;
double roll = 0.00, pitch = 0.00;
double roll2 = 0.00, pitch2 = 0.00;
int average_roll = 0.00;
int average_pitch = 0.00;
int average_x = 0.00;
int average_y = 0.00;
int average_z = 0.00;
int motorburntime = 4.00; //------------------------------------- motor burn time lockout
int mainstate = 0;
int dstate = 0;
int subaltest = 0;
int average_x_gyro = 0.00;
int average_y_gyro = 0.00;
int average_z_gyro = 0.00;
int launchlook = 0;
int landlook = 0;
int apogeelook = 0;
int readylook = 0;
int readingone = 0;
int readingtwo = 0;
unsigned long timenow = 0;
unsigned long timenow1 = 0;
unsigned long timenow2 = 0;
unsigned long timenow3 = 0;
unsigned long timenow4 = 0;
unsigned long timenow5 = 0;
unsigned long timenow6 = 0;
struct euler_t {
float yaw;
float pitch;
float roll;
} ypr;
#define BNO08X_RESET -1
Adafruit_BNO08x bno08x(BNO08X_RESET);
sh2_SensorValue_t sensorValue;
#ifdef FAST_MODE
// Top frequency is reported to be 1000Hz (but freq is somewhat variable)
sh2_SensorId_t reportType = SH2_GYRO_INTEGRATED_RV;
long reportIntervalUs = 2000;
#else
// Top frequency is about 250Hz but this report is more accurate
sh2_SensorId_t reportType = SH2_ARVR_STABILIZED_RV;
long reportIntervalUs = 5000;
#endif
void setup(){
while(!Serial) delay(10);
Serial.begin(115200);
Serial.println("Start up....");
pinMode(buzzer, OUTPUT);
// tone(buzzer, 1000);
Wire.begin(); // Start I2C
pixels.begin();
pinMode(9, OUTPUT);
pinMode(7, OUTPUT);
while (myGPS.begin() == false) //Connect to the u-blox module using Wire port
{
Serial.println("u-blox GNSS not detected at default I2C address. Retrying...");
delay (1000);
}
#ifdef SERIAL_OUTPUT
// If our board supports it, we can output the NMEA data automatically on (e.g.) Serial1
Serial1.begin(115200);
myGNSS.setNMEAOutputPort(Serial1);
#endif
myGPS.setI2COutput(COM_TYPE_UBX | COM_TYPE_NMEA); //Set the I2C port to output both NMEA and UBX messages
myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save (only) the communications port settings to flash and BBR
myGPS.setProcessNMEAMask(SFE_UBLOX_FILTER_NMEA_ALL); // Make sure the library is passing all NMEA messages to processNMEA
myGPS.setProcessNMEAMask(SFE_UBLOX_FILTER_NMEA_GGA); // Or, we can be kind to MicroNMEA and _only_ pass the GGA messages to it
if (! lis3mdl.begin_I2C()) {
Serial.print("LIS3MDL start up not good");
while(1);
}else{
Serial.print("LIS3MDL start up good....");
}
lis3mdl.setPerformanceMode(LIS3MDL_MEDIUMMODE);
Serial.print("Performance mode set to: ");
switch (lis3mdl.getPerformanceMode()) {
case LIS3MDL_ULTRAHIGHMODE: Serial.println("Ultra-High"); break;
}
lis3mdl.setOperationMode(LIS3MDL_CONTINUOUSMODE);
Serial.print("Operation mode set to: ");
// Single shot mode will complete conversion and go into power down
switch (lis3mdl.getOperationMode()) {
case LIS3MDL_CONTINUOUSMODE: Serial.println("Continuous"); break;
case LIS3MDL_SINGLEMODE: Serial.println("Single mode"); break;
case LIS3MDL_POWERDOWNMODE: Serial.println("Power-down"); break;
}
lis3mdl.setDataRate(LIS3MDL_DATARATE_155_HZ);
Serial.print("Data rate set to: ");
switch (lis3mdl.getDataRate()) {
case LIS3MDL_DATARATE_0_625_HZ: Serial.println("0.625 Hz"); break;
case LIS3MDL_DATARATE_1_25_HZ: Serial.println("1.25 Hz"); break;
case LIS3MDL_DATARATE_2_5_HZ: Serial.println("2.5 Hz"); break;
case LIS3MDL_DATARATE_5_HZ: Serial.println("5 Hz"); break;
case LIS3MDL_DATARATE_10_HZ: Serial.println("10 Hz"); break;
case LIS3MDL_DATARATE_20_HZ: Serial.println("20 Hz"); break;
case LIS3MDL_DATARATE_40_HZ: Serial.println("40 Hz"); break;
case LIS3MDL_DATARATE_80_HZ: Serial.println("80 Hz"); break;
case LIS3MDL_DATARATE_155_HZ: Serial.println("155 Hz"); break;
case LIS3MDL_DATARATE_300_HZ: Serial.println("300 Hz"); break;
case LIS3MDL_DATARATE_560_HZ: Serial.println("560 Hz"); break;
case LIS3MDL_DATARATE_1000_HZ: Serial.println("1000 Hz"); break;
}
lis3mdl.setRange(LIS3MDL_RANGE_4_GAUSS);
Serial.print("Range set to: ");
switch (lis3mdl.getRange()) {
case LIS3MDL_RANGE_16_GAUSS: Serial.println("+-16 gauss"); break;
}
lis3mdl.setIntThreshold(500);
lis3mdl.configInterrupt(false, false, true, // enable z axis
true, // polarity
false, // don't latch
true); // enabled!
while(imu.beginI2C(i2cAddress) != BMI2_OK){
Serial.print("BMI270 start up bad");
while(1);
}
Serial.print("BMI270 start up good....");
if (!dso32.begin_I2C()) {
Serial.print("LSM6DOS32 start not good");
while(1);
}else{
Serial.print("LSM6DOS32 start up good....");
}
if (!ms8607.begin()) {
Serial.print("MS8607 start up not good");
while(1);
}else{
Serial.print("MS8607 start up good....");
}
ms8607.setHumidityResolution(MS8607_HUMIDITY_RESOLUTION_OSR_8b);
if (!bmp.begin_I2C()) {
Serial.print("BMP390 start up not good");
while (1);
}else{
Serial.print("BMP390 start up good....");
}
bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp.setOutputDataRate(BMP3_ODR_50_HZ);
if (!ina260.begin(0x45)) {
Serial.println("Couldn't find INA260 chip");
while (1);
}
Serial.println("Found INA260 chip");
if (!sd.begin(chipSelect)) {
Serial.println("Card failed, or not present");
while (1) {
// No SD card, so don't do anything more - stay stuck here
}
}
Serial.println("card initialized.");
if (!bno08x.begin_I2C(0x4B)) {
//if (!bno08x.begin_UART(&Serial1)) { // Requires a device with > 300 byte UART buffer!
//if (!bno08x.begin_SPI(BNO08X_CS, BNO08X_INT)) {
Serial.println("Failed to find BNO08x chip");
while (1) { delay(10); }
}
Serial.println("BNO08x Found!");
//setReports(reportType, reportIntervalUs);
dataFile.open("FlightData.csv", FILE_WRITE);
dataFile2.open("GPSData.csv", FILE_WRITE);
dataFile3.open("EventData.csv", FILE_WRITE);
dataFile.println("Started up");
dataFile.println(" ___ .______ ______");
dataFile.println(" / \ | _ \ / |");
dataFile.println(" / ^ \ | |_) | | ,----'");
dataFile.println(" / /_\ \ | / | |");
dataFile.println(" / _____ \ | |\ \----.| `----.");
dataFile.println("/__/ \__\ | _| `._____| \______|");
dataFile2.println(" ___ .______ ______");
dataFile2.println(" / \ | _ \ / |");
dataFile2.println(" / ^ \ | |_) | | ,----'");
dataFile2.println(" / /_\ \ | / | |");
dataFile2.println(" / _____ \ | |\ \----.| `----.");
dataFile2.println("/__/ \__\ | _| `._____| \______|");
dataFile3.println("___ .______ ______");
dataFile3.println("/ \ | _ \ / |");
dataFile3.println("/ ^ \ | |_) | | ,----'");
dataFile3.println("/ /_\ \ | / | |");
dataFile3.println("/ _____ \ | |\ \----.| `----.");
dataFile3.println("/__/ \__\ | _| `._____| \______|");
noTone(buzzer);
}
void setReports(void) {
Serial.println("Setting desired reports");
if (!bno08x.enableReport(SH2_ACCELEROMETER)) {
Serial.println("Could not enable accelerometer");
}
if (!bno08x.enableReport(SH2_GYROSCOPE_CALIBRATED)) {
Serial.println("Could not enable gyroscope");
}
if (!bno08x.enableReport(SH2_MAGNETIC_FIELD_CALIBRATED)) {
Serial.println("Could not enable magnetic field calibrated");
}
if (!bno08x.enableReport(SH2_LINEAR_ACCELERATION)) {
Serial.println("Could not enable linear acceleration");
}
if (!bno08x.enableReport(SH2_GRAVITY)) {
Serial.println("Could not enable gravity vector");
}
if (!bno08x.enableReport(SH2_ROTATION_VECTOR)) {
Serial.println("Could not enable rotation vector");
}
if (!bno08x.enableReport(SH2_GEOMAGNETIC_ROTATION_VECTOR)) {
Serial.println("Could not enable geomagnetic rotation vector");
}
if (!bno08x.enableReport(SH2_GAME_ROTATION_VECTOR)) {
Serial.println("Could not enable game rotation vector");
}
if (!bno08x.enableReport(SH2_STEP_COUNTER)) {
Serial.println("Could not enable step counter");
}
if (!bno08x.enableReport(SH2_STABILITY_CLASSIFIER)) {
Serial.println("Could not enable stability classifier");
}
if (!bno08x.enableReport(SH2_RAW_ACCELEROMETER)) {
Serial.println("Could not enable raw accelerometer");
}
if (!bno08x.enableReport(SH2_RAW_GYROSCOPE)) {
Serial.println("Could not enable raw gyroscope");
}
if (!bno08x.enableReport(SH2_RAW_MAGNETOMETER)) {
Serial.println("Could not enable raw magnetometer");
}
if (!bno08x.enableReport(SH2_SHAKE_DETECTOR)) {
Serial.println("Could not enable shake detector");
}
if (!bno08x.enableReport(SH2_PERSONAL_ACTIVITY_CLASSIFIER)) {
Serial.println("Could not enable personal activity classifier");
}
}
void quaternionToEuler(float qr, float qi, float qj, float qk, euler_t* ypr, bool degrees = false) {
float sqr = sq(qr);
float sqi = sq(qi);
float sqj = sq(qj);
float sqk = sq(qk);
ypr->yaw = atan2(2.0 * (qi * qj + qk * qr), (sqi - sqj - sqk + sqr));
ypr->pitch = asin(-2.0 * (qi * qk - qj * qr) / (sqi + sqj + sqk + sqr));
ypr->roll = atan2(2.0 * (qj * qk + qi * qr), (-sqi - sqj + sqk + sqr));
if (degrees) {
ypr->yaw *= RAD_TO_DEG;
ypr->pitch *= RAD_TO_DEG;
ypr->roll *= RAD_TO_DEG;
}
}
void quaternionToEulerRV(sh2_RotationVectorWAcc_t* rotational_vector, euler_t* ypr, bool degrees = false) {
quaternionToEuler(rotational_vector->real, rotational_vector->i, rotational_vector->j, rotational_vector->k, ypr, degrees);
}
void quaternionToEulerGI(sh2_GyroIntegratedRV_t* rotational_vector, euler_t* ypr, bool degrees = false) {
quaternionToEuler(rotational_vector->real, rotational_vector->i, rotational_vector->j, rotational_vector->k, ypr, degrees);
}
void setReports(sh2_SensorId_t reportType, long report_interval) {
Serial.println("Setting desired reports");
if (! bno08x.enableReport(reportType, report_interval)) {
Serial.println("Could not enable stabilized remote vector");
}
}
void loop(){
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t temp;
if (bno08x.wasReset()) {
Serial.print("sensor was reset ");
//setReports(reportType, reportIntervalUs);
}
if (bno08x.getSensorEvent(&sensorValue)) {
// in this demo only one report type will be received depending on FAST_MODE define (above)
switch (sensorValue.sensorId) {
case SH2_ARVR_STABILIZED_RV:
quaternionToEulerRV(&sensorValue.un.arvrStabilizedRV, &ypr, true);
case SH2_GYRO_INTEGRATED_RV:
// faster (more noise?)
quaternionToEulerGI(&sensorValue.un.gyroIntegratedRV, &ypr, true);
break;
}
static long last = 0;
long now = micros();
last = now;
}
dso32.getEvent(&accel, &gyro, &temp);
imu.getSensorData();
lis3mdl.read();
sensors_event_t event;
lis3mdl.getEvent(&event);
sensors_event_t pressure, humidity;
ms8607.getEvent(&pressure, &temp, &humidity);
double x_Buff = float(imu.data.accelX);
double y_Buff = float(imu.data.accelY);
double z_Buff = float(imu.data.accelZ);
roll = atan2(y_Buff, z_Buff) * 57.3;
pitch = atan2((- x_Buff), sqrt(y_Buff * y_Buff + z_Buff * z_Buff)) * 57.3;
double x_Buff2 = float(accel.acceleration.x);
double y_Buff2 = float(accel.acceleration.y);
double z_Buff2 = float(accel.acceleration.z);
roll2 = atan2(y_Buff2, z_Buff2) * 57.3;
pitch2 = atan2((- x_Buff2), sqrt(y_Buff2 * y_Buff2 + z_Buff2 * z_Buff2)) * 57.3;
average_roll = roll + roll2 / 2;
average_x = imu.data.accelX + accel.acceleration.x / 2;
average_y = imu.data.accelY + accel.acceleration.y / 2;
average_z = imu.data.accelZ + accel.acceleration.z / 2;
average_x_gyro = imu.data.gyroX, 3 + gyro.gyro.x / 2;
average_y_gyro = imu.data.gyroY, 3 + gyro.gyro.y / 2;
average_z_gyro = imu.data.gyroZ, 3 + gyro.gyro.z / 2;
if(ready == true){ // ------------------ ready for launch
if(onetime1 == false){
tone(buzzer, 1000);
delay(100);
noTone(buzzer);
tone(buzzer, 1000);
delay(100);
noTone(buzzer);
tone(buzzer, 1000);
delay(100);
noTone(buzzer);
onetime1 = true;
}
pixels.setPixelColor(1, pixels.Color(20, 255, 1));
pixels.show();
//-------------------------------------------------
if(onetime == false){
ms1 = bmp.readAltitude(1013.25) - alt;
onetime = true;
}
if(millis() >= timenow + 1000){ //speed caculation m/s
ms2 = bmp.readAltitude(1013.25) - alt;
Speed = ms2 - ms1;
onetime = false;
timenow += 1000;
}
//----------------------------------------------------
if(launch == true){ // -------------------------------- launch stuff starts here
if(onetime3 == false){
launchlook += 1;
onetime3 = true;
}
launch = true;
pixels.setPixelColor(1, pixels.Color(255, 0, 228 ));
pixels.show();
if(millis() >= timenow2 + 3000){
tone(buzzer, 1000);
timenow2 += 3000;
}else{ // buzz
noTone(buzzer);
}
//-----------------------------------------------
if(bmp.readAltitude(1013.25) - alt >= 233){
overdd = true;
}
if(overdd == true){
if(bmp.readAltitude(1013.25) - alt <= 233){//------------------ main chute 233
atdd = true;
}
}
if(atdd == true){
if(millis() >= timenow3 + 5000){
if(onetime16 == false){
digitalWrite(9, HIGH);
mainstate += 1;
onetime16 = true;
}
timenow3 += 5000;
}else{
digitalWrite(9, LOW);
}
}
//-----------------------------------------------------
if(timelockout == true){
if(millis() >= timenow5 + motorburntime){
timelockout = false;
timenow5 += 5000;
} // motor burn lock out
Serial.print("Lockout on");
}else{
Serial.print("Lockout off");
}
//-----------------------------------------------------
if(timelockout == false){
readingone = bmp.readAltitude(1013.25) - alt;
if(millis() >= timenow4 + 500){
readingtwo = bmp.readAltitude(1013.25) - alt;
timenow4 += 500;
}
subaltest = readingtwo - readingone;
if(subaltest <= 1){
digitalWrite(7, HIGH);
if(onetime17 == false){
onetime17 = true;
}
}
}
//---------------------------------------------------
if(Speed >= 20){
onetime5 = true;
}
if(onetime5 == true){
if(Speed <= 5){
apogge = true;
if(onetime6 == false){ // apogee calc 1
apogeelook += 1;
onetime6 = true;
}
}
}
//------------------------------------------------------
if(bmp.readAltitude(1013.25) - alt <= 4.00){
land = true; // look for landing
if(onetime4 == false){
landlook += 1;
onetime4 = true;
}
}
//----------------
//----------------
}// -------------------------------- launch stuff ends here
if(bmp.readAltitude(1013.25) - alt >= 5.00){
launch = true;
}else{
if(millis() >= timenow1 + 7000){
tone(buzzer, 1000);
timenow1 += 7000;
}else{ // buzz
noTone(buzzer);
}
}
}else{
pixels.setPixelColor(1, pixels.Color(1, 96, 255));
pixels.show();
if(bmp.readAltitude(1013.25) >= alt){
alt++;
}
if(bmp.readAltitude(1013.25) <= alt){
alt--;
}
if(bmp.readAltitude(1013.25) - alt <= 0.40){
ready = true;
readylook += 1;
}
}
Serial.print(bmp.readAltitude(1013.25) - alt);
Serial.print(" Pitch1 ");
Serial.print(pitch2);
Serial.print(sensorValue.status);
Serial.print(ypr.yaw);
Serial.print(" Pitch2 ");
Serial.print(ypr.pitch);
Serial.println(ypr.roll);
dataFile.open("FlightData.csv", FILE_WRITE);
dataFile.print(millis());
dataFile.print(",");
dataFile.print("BMP390: ");
dataFile.print(",");
dataFile.print(". Alt ");
dataFile.print(bmp.readAltitude(1013.25) - alt);
dataFile.print(",");
dataFile.print(". temp ");
dataFile.print(bmp.temperature);
dataFile.print(",");
dataFile.print(". Pressure ");
dataFile.print(bmp.pressure / 100.0 );
dataFile.print(",");
dataFile.print(". Speed:");
dataFile.print(Speed);
dataFile.print(",");
dataFile.print(". Pitch: ");
dataFile.print(pitch2);
dataFile.print(",");
dataFile.print(". Roll: ");
dataFile.print(roll2);
dataFile.print(",");
dataFile.print(". Acc X: ");
dataFile.print(average_x);
dataFile.print(",");
dataFile.print(". Acc Y: ");
dataFile.print(average_y);
dataFile.print(",");
dataFile.print(". Acc Z: ");
dataFile.print(average_z);
dataFile.print(",");
dataFile.print(". Gyro X: ");
dataFile.print(average_x_gyro);
dataFile.print(",");
dataFile.print(". Gyro Y: ");
dataFile.print(average_y_gyro);
dataFile.print(",");
dataFile.print(". Gyro Z: ");
dataFile.print(average_z_gyro);
dataFile.print(",");
dataFile.print(". MAg: ");
dataFile.print(",");
dataFile.print(". \tX: ");
dataFile.print(lis3mdl.x);
dataFile.print(",");
dataFile.print(". \tY: ");
dataFile.print(lis3mdl.y);
dataFile.print(",");
dataFile.print(". \tZ ");
dataFile.print(lis3mdl.z);
dataFile.print(",");
dataFile.print(". uTesla \tX: ");
dataFile.print(event.magnetic.x);
dataFile.print(",");
dataFile.print(". uTesla \tY: ");
dataFile.print(event.magnetic.y);
dataFile.print(",");
dataFile.print(". uTesla \tZ: ");
dataFile.print(event.magnetic.z);
dataFile.print(",");
dataFile.print(". Heading: ");
dataFile.print(event.magnetic.heading);
dataFile.print(",");
dataFile.print(". Pitch: ");
dataFile.print(event.magnetic.pitch);
dataFile.print(",");
dataFile.print(". Roll: ");
dataFile.print(event.magnetic.roll);
dataFile.print(",");
dataFile.print(". Status: ");
dataFile.print(event.magnetic.status);
dataFile.print(",");
dataFile.print(". LSM6: ");
dataFile.print(",");
dataFile.print(". Temp ");
dataFile.print(temp.temperature);
dataFile.print(",");
dataFile.print(". Accel X: ");
dataFile.print(accel.acceleration.x);
dataFile.print(",");
dataFile.print(". Accel Y: ");
dataFile.print(accel.acceleration.y);
dataFile.print(",");
dataFile.print(". Accel Z: ");
dataFile.print(accel.acceleration.z);
dataFile.print(",");
dataFile.print(". Gyro X: ");
dataFile.print(gyro.gyro.x);
dataFile.print(",");
dataFile.print(". Gyro Y: ");
dataFile.print(gyro.gyro.y);
dataFile.print(",");
dataFile.print(". Gyro Z: ");
dataFile.print(gyro.gyro.z);
dataFile.print(",");
dataFile.print(". BMI270: ");
dataFile.print(",");
dataFile.print(". Accel X: ");
dataFile.print(imu.data.accelX);
dataFile.print(",");
dataFile.print(". Accel Y: ");
dataFile.print(imu.data.accelY);
dataFile.print(",");
dataFile.print(". Accel Z: ");
dataFile.print(imu.data.accelZ);
dataFile.print(",");
dataFile.print(". Gyro X ");
dataFile.print(imu.data.gyroX);
dataFile.print(",");
dataFile.print(". Gyro Y: ");
dataFile.print(imu.data.gyroY);
dataFile.print(",");
dataFile.print(". Gyro Z: ");
dataFile.print(imu.data.gyroZ);
dataFile.print(",");
dataFile.print(" BNO085 ");
dataFile.print(",");
dataFile.print(" Yaw: ");
dataFile.print(ypr.yaw);
dataFile.print(",");
dataFile.print(" Pitch: ");
dataFile.print(ypr.pitch);
dataFile.print(",");
dataFile.print(" Roll: ");
dataFile.print(ypr.roll);
dataFile.print(",");
dataFile.print(" Raw Accelerometer: ");
dataFile.print(",");
dataFile.print(" X: ");
dataFile.print(sensorValue.un.rawAccelerometer.x);
dataFile.print(",");
dataFile.print(" Y: ");
dataFile.print(sensorValue.un.rawAccelerometer.y);
dataFile.print(",");
dataFile.print(" Z: ");
dataFile.print(sensorValue.un.rawAccelerometer.z);
dataFile.print(",");
dataFile.print(" Raw Gyro: ");
dataFile.print(",");
dataFile.print(" X: ");
dataFile.print(sensorValue.un.rawGyroscope.x);
dataFile.print(",");
dataFile.print(" Y: ");
dataFile.print(sensorValue.un.rawGyroscope.y);
dataFile.print(",");
dataFile.print(" Z: ");
dataFile.print(sensorValue.un.rawGyroscope.z);
dataFile.print(",");
dataFile.print(" Raw Magnetometer: ");
dataFile.print(",");
dataFile.print(" X: ");
dataFile.print(sensorValue.un.rawMagnetometer.x);
dataFile.print(",");
dataFile.print(" Y: ");
dataFile.print(sensorValue.un.rawMagnetometer.y);
dataFile.print(",");
dataFile.print(" Z: ");
dataFile.print(sensorValue.un.rawMagnetometer.z);
dataFile.print(",");
dataFile.print(" Accelerometer: ");
dataFile.print(",");
dataFile.print(" X: ");
dataFile.print(sensorValue.un.accelerometer.x);
dataFile.print(",");
dataFile.print(" Y: ");
dataFile.print(sensorValue.un.accelerometer.y);
dataFile.print(",");
dataFile.print(" Z: ");
dataFile.print(sensorValue.un.accelerometer.z);
dataFile.print(",");
dataFile.print(" Gyro: ");
dataFile.print(",");
dataFile.print(" X: ");
dataFile.print(sensorValue.un.gyroscope.x);
dataFile.print(",");
dataFile.print(" Y: ");
dataFile.print(sensorValue.un.gyroscope.y);
dataFile.print(",");
dataFile.print(" Z: ");
dataFile.print(sensorValue.un.gyroscope.z);
dataFile.print(",");
dataFile.print(" Magnetic Field: ");
dataFile.print(",");
dataFile.print(" X: ");
dataFile.print(sensorValue.un.magneticField.x);
dataFile.print(",");
dataFile.print(" Y: ");
dataFile.print(sensorValue.un.magneticField.y);
dataFile.print(",");
dataFile.print(" Z: ");
dataFile.print(sensorValue.un.magneticField.z);
dataFile.print(",");
dataFile.print(" Linear Acceleration: ");
dataFile.print(",");
dataFile.print(" X: ");
dataFile.print(sensorValue.un.linearAcceleration.x);
dataFile.print(",");
dataFile.print(" Y: ");
dataFile.print(sensorValue.un.linearAcceleration.y);
dataFile.print(",");
dataFile.print(" Z: ");
dataFile.print(sensorValue.un.linearAcceleration.z);
dataFile.print(" Rotation Vector: ");
dataFile.print(",");
dataFile.print(" R: ");
dataFile.print(sensorValue.un.rotationVector.real);
dataFile.print(",");
dataFile.print(" I: ");
dataFile.print(sensorValue.un.rotationVector.i);
dataFile.print(",");
dataFile.print(" J: ");
dataFile.print(sensorValue.un.rotationVector.j);
dataFile.print(",");
dataFile.print(" K: ");
dataFile.print(sensorValue.un.rotationVector.k);
dataFile.print(",");
dataFile.print(" Geo-Magnetic Rotation Vector: ");
dataFile.print(",");
dataFile.print(" R: ");
dataFile.print(sensorValue.un.geoMagRotationVector.real);
dataFile.print(",");
dataFile.print(" I: ");
dataFile.print(sensorValue.un.geoMagRotationVector.i);
dataFile.print(",");
dataFile.print(" J: ");
dataFile.print(sensorValue.un.geoMagRotationVector.j);
dataFile.print(",");
dataFile.print(" K: ");
dataFile.print(sensorValue.un.geoMagRotationVector.k);
dataFile.print(",");
dataFile.print(" Game Rotation Vector: ");
dataFile.print(",");
dataFile.print(" R: ");
dataFile.print(sensorValue.un.gameRotationVector.real);
dataFile.print(",");
dataFile.print(" I: ");
dataFile.print(sensorValue.un.gameRotationVector.i);
dataFile.print(",");
dataFile.print(" J: ");
dataFile.print(sensorValue.un.gameRotationVector.j);
dataFile.print(",");
dataFile.print(" K: ");
dataFile.print(sensorValue.un.gameRotationVector.real);
dataFile.print(",");
dataFile.print(" INA260: ");
dataFile.print(",");
dataFile.print(" Voltage ");
dataFile.print(ina260.readBusVoltage() / 1000);
dataFile.print(",");
dataFile.print(" Current ");
dataFile.print(ina260.readCurrent());
dataFile.print(",");
dataFile.print(" Power ");
dataFile.print(ina260.readPower());
dataFile.print(",");
dataFile.print(" MS8607: ");
dataFile.print(",");
dataFile.print(" Temp ");
dataFile.print(temp.temperature);
dataFile.print(",");
dataFile.print(" Pressure ");
dataFile.print(pressure.pressure);
dataFile.print(",");
dataFile.print(" Humidity ");
dataFile.print(humidity.relative_humidity);
dataFile.print(",");
dataFile.print(" Launched: ");
dataFile.print(launchlook);
dataFile.print(",");
dataFile.print(" Landed: ");
dataFile.print(landlook);
dataFile.print(",");
dataFile.print(" Apogee: ");
dataFile.print(apogeelook);
dataFile.print(",");
dataFile.print(" Ready for launch: ");
dataFile.print(readylook);
dataFile.print(",");
dataFile.print(" drouge: ");
dataFile.print(dstate);
dataFile.print(",");
dataFile.print(" main: ");
dataFile.print(mainstate);
dataFile.println(",");
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
if(nmea.isValid() == true)
{
long latitude_mdeg = nmea.getLatitude();
long longitude_mdeg = nmea.getLongitude();
Serial.print("Latitude (deg): ");
Serial.println(latitude_mdeg / 1000000., 6);
Serial.print("Longitude (deg): ");
Serial.println(longitude_mdeg / 1000000., 6);
nmea.clear(); // Clear the MicroNMEA storage to make sure we are getting fresh data
}
else
{
Serial.println("Waiting for fresh data");
}
delay(250); //Don't pound too hard on the I2C bus
}
void DevUBLOXGNSS::processNMEA(char incoming)
{
//Take the incoming char from the u-blox I2C port and pass it on to the MicroNMEA lib
//for sentence cracking
nmea.process(incoming);
}
And the code that does:
/*
Read NMEA sentences over I2C using u-blox module
By: Nathan Seidle
SparkFun Electronics
Date: August 22nd, 2018
License: MIT. See license file for more information.
This example reads the NMEA characters over I2C and pipes them to MicroNMEA
This example will output your current long/lat and satellites in view
Feel like supporting open source hardware?
Buy a board from SparkFun!
SparkFun GPS-RTK2 - ZED-F9P (GPS-15136) https://www.sparkfun.com/products/15136
SparkFun GPS-RTK-SMA - ZED-F9P (GPS-16481) https://www.sparkfun.com/products/16481
SparkFun MAX-M10S Breakout (GPS-18037) https://www.sparkfun.com/products/18037
SparkFun ZED-F9K Breakout (GPS-18719) https://www.sparkfun.com/products/18719
SparkFun ZED-F9R Breakout (GPS-16344) https://www.sparkfun.com/products/16344
For more MicroNMEA info see https://github.com/stevemarple/MicroNMEA
Hardware Connections:
Plug a Qwiic cable into the GNSS and a BlackBoard
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
Open the serial monitor at 115200 baud to see the output
Go outside! Wait ~25 seconds and you should see your lat/long
*/
#include <Wire.h> //Needed for I2C to GNSS
#include <SparkFun_u-blox_GNSS_v3.h> //http://librarymanager/All#SparkFun_u-blox_GNSS_v3
SFE_UBLOX_GNSS myGNSS;
#include <MicroNMEA.h> //http://librarymanager/All#MicroNMEA
char nmeaBuffer[100];
MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer));
//#define SERIAL_OUTPUT // Uncomment this line to push the NMEA data automatically to a Serial port
void setup()
{
Serial.begin(115200);
Serial.println("SparkFun u-blox Example");
#ifdef SERIAL_OUTPUT
// If our board supports it, we can output the NMEA data automatically on (e.g.) Serial1
Serial1.begin(115200);
myGNSS.setNMEAOutputPort(Serial1);
#endif
Wire.begin();
if (myGNSS.begin() == false)
{
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
while (1);
}
myGNSS.setI2COutput(COM_TYPE_UBX | COM_TYPE_NMEA); //Set the I2C port to output both NMEA and UBX messages
myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save (only) the communications port settings to flash and BBR
myGNSS.setProcessNMEAMask(SFE_UBLOX_FILTER_NMEA_ALL); // Make sure the library is passing all NMEA messages to processNMEA
myGNSS.setProcessNMEAMask(SFE_UBLOX_FILTER_NMEA_GGA); // Or, we can be kind to MicroNMEA and _only_ pass the GGA messages to it
}
void loop()
{
myGNSS.checkUblox(); //See if new data is available. Process bytes as they come in.
if(nmea.isValid() == true)
{
long latitude_mdeg = nmea.getLatitude();
long longitude_mdeg = nmea.getLongitude();
Serial.print("Latitude (deg): ");
Serial.println(latitude_mdeg / 1000000., 6);
Serial.print("Longitude (deg): ");
Serial.println(longitude_mdeg / 1000000., 6);
nmea.clear(); // Clear the MicroNMEA storage to make sure we are getting fresh data
}
else
{
Serial.println("Waiting for fresh data");
}
delay(250); //Don't pound too hard on the I2C bus
}
//This function gets called from the SparkFun u-blox Arduino Library
//As each NMEA character comes in you can specify what to do with it
//Useful for passing to other libraries like tinyGPS, MicroNMEA, or even
//a buffer, radio, etc.
void DevUBLOXGNSS::processNMEA(char incoming)
{
//Take the incoming char from the u-blox I2C port and pass it on to the MicroNMEA lib
//for sentence cracking
nmea.process(incoming);
}
