sparkfun / SparkFun_u-blox_GNSS_Arduino_Library

An Arduino library which allows you to communicate seamlessly with the full range of u-blox GNSS modules
Other
227 stars 100 forks source link

problems with BLE on Arduino GIGA #210

Closed Nocentinia closed 1 year ago

Nocentinia commented 1 year ago

Hello, I'm having a problem that's driving me crazy! I use Arduino GIGA and the MKR GPS Shield (m8q) interfaced via serial port. basically when I use your library the BLE (I use the official Arduino library) stops working! my goal is to take the gps data and a BLE peripheral and then process it. I leave you the code to help you understand better.


void setup() {
  // put your setup code here, to run once:
 Serial.begin(115200);
  while (!Serial)
    ;  //Wait for user to open terminal

      if (!BLE.begin()) {
    Serial.println("starting Bluetooth® Low Energy failed!");
    while (1)
      ;
  }
BLE.scanForAddress("d3:82:53:e0:a9:72");

  Serial.println("SparkFun u-blox Example");
  do {
    Serial.println("GNSS: trying 38400 baud");
    mySerial.begin(38400);
    if (myGNSS.begin(mySerial) == true) break;

    delay(100);
    Serial.println("GNSS: trying 9600 baud");
    mySerial.begin(9600);
    if (myGNSS.begin(mySerial) == true) {
      Serial.println("GNSS: connected at 9600 baud, switching to 38400");
      myGNSS.setSerialRate(38400);
      delay(100);
    } else {
      //myGNSS.factoryReset();
      delay(2000);  //Wait a bit before trying again to limit the Serial output
    }
  } while (1);
  Serial.println("GNSS serial connected");

  myGNSS.setUART1Output(COM_TYPE_UBX);  //Set the UART port to output UBX only
  myGNSS.setI2COutput(COM_TYPE_UBX);    //Set the I2C port to output UBX only (turn off NMEA noise)
  myGNSS.setNavigationFrequency(1);
  myGNSS.setAutoPVT(true);
  myGNSS.saveConfiguration();  //Save the current settings to flash and BBR
  //myGNSS.powerSaveMode();

    pinMode(86, OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:

   BLEDevice peripheral = BLE.available();

  if (peripheral) {
    // discovered a peripheral, print out address, local name, and advertised service
    Serial.print("Found ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();

    if (peripheral.localName() != "ULTRASONIC") {
      return;
    }
    Serial.println("ciao");

    BLE.stopScan();
    Ble(peripheral);
    BLE.scanForAddress("d3:82:53:e0:a9:72");
  }
  Main();
}

void Ble(BLEDevice peripheral) {
  // connect to the peripheral
  Serial.println("Connecting ...");

  if (peripheral.connect()) {
    Serial.println("Connected");
  } else {
    Serial.println("Failed to connect!");
    return;
  }
  digitalWrite(87, LOW);
  // discover peripheral attributes
  Serial.println("Discovering attributes ...");
  if (peripheral.discoverAttributes()) {
    Serial.println("Attributes discovered");
  } else {
    Serial.println("Attribute discovery failed!");
    peripheral.disconnect();
    return;
  }

  BLECharacteristic A_W_I_Caratteristic = peripheral.characteristic("2A72");
  BLECharacteristic A_W_D_Caratteristic = peripheral.characteristic("2A73");
  A_W_I_Caratteristic.subscribe();
  A_W_D_Caratteristic.subscribe();

  if (!A_W_I_Caratteristic) {
    peripheral.disconnect();
    return;
  } else if (!A_W_I_Caratteristic.canRead()) {
    peripheral.disconnect();
    return;
  }

  Serial.println("stazione meteo OK");

  while (peripheral.connected()) {

    if (A_W_I_Caratteristic.valueUpdated()) {
      A_W_I_Caratteristic.readValue(W_Intensity_raw);
      W_Intensity = W_Intensity_raw / 100.0;
    }
    if (A_W_D_Caratteristic.valueUpdated()) {
      A_W_D_Caratteristic.readValue(W_Dir_raw);
      W_Dir = W_Dir_raw / 100;
      Wind = true;
    }
    Main();
  }
}

void Main() {

  if (myGNSS.getPVT()) {
    latitudine = myGNSS.getLatitude();
    longitudine = myGNSS.getLongitude();
    altitudine = myGNSS.getAltitude();
    velocita = myGNSS.getGroundSpeed();
    anno = myGNSS.getYear();
    mese = myGNSS.getMonth();
    giorno = myGNSS.getDay();
    ore = myGNSS.getHour();
    minuti = myGNSS.getMinute();
    secondi = myGNSS.getSecond();
    milli = myGNSS.getMillisecond();
    SIV = myGNSS.getSIV();
    rottaGps = myGNSS.getHeading();
    //Serial.println(rottaGps*0.00001);
    latitudine1 = latitudine * 0.0000001;
    longitudine1 = longitudine * 0.0000001;
    velocita = velocita / 1000;
    rottaGps1 = rottaGps * 0.00001;
    seriale();
    fixType = myGNSS.getFixType();
  }
}

void seriale() {
  Serial.print("rotta gps:");
  Serial.println(rottaGps1);
  Serial.print("velocità");
  Serial.println(velocita);
  Serial.print("direzione vento apparente:");
  Serial.println(AWA);
  Serial.print("intensità vento apparente:");
  Serial.println(AWS);
  Serial.print("direzione vento reale:");
  Serial.println(TWA);
  Serial.print("intensità vento reale:");
  Serial.println(TWS);

  Serial.println(Wind);
}

I also tried to simply detect peripherals without connecting to anything but it detects 2-3 instead of the 15 that are present (tried with the example provided by Arduino called "scan"). in my project there are also other components and other libraries, I tried to test each library individually but the only one that plays this "joke" on me is this one

PaulZC commented 1 year ago

Hi @Nocentinia ,

I don't think I can help you. I don't have a GIGA board to test. And it looks as if the root cause could be the BLE library and perhaps the way it interacts with Serial (UART)? I have seen your other posts and I understand your frustration, but I don't think I can help.

I suggest publishing your full code in your own repo and adding a link to it here. Then anyone wanting to see the full code can find it. Your code snippet above does not show how mySerial is defined for example. Please do not post your full code here, it needs to be in its own repo.

Try removing this library from your code and test it using some very simple Serial (UART) send and receive code. Do you see the same issue?

The MKR Shield supports I2C. Do you see the same issue with I2C?

I will leave this issue open for a while just in case anyone else can help.

Best wishes, Paul

Nocentinia commented 1 year ago

HI, then, mySerial is defined on Serial1 and if I try to read the raw data directly from the serial, without using your library everything works. unfortunately the Arduino shield only allows I2C via ELOV cable which I don't have available, I'll try to connect somehow... I'm sorry, I'm not very familiar with using GitHub, how can I publish my code?

PaulZC commented 1 year ago

Sparkfun has a GitHub Tutorial, but it is very old. 10 years!

Try searching for "GitHub Beginner Tutorial" and "GitHub Desktop Beginner Tutorial".

Best wishes, Paul

Nocentinia commented 1 year ago

this is my code: https://github.com/Nocentinia/Arduino-GIGA-BLE-SparkFun-LIB I fear that the problem will never be solved to my great regret...

Nocentinia commented 1 year ago

It seems like a dream to me, now everything works! both via UART and via I2C. instead of using BLE.scanForAddress("d3:82:53:e0:a9:72") I used BLE.scan(TRUE) and for each cycle of the loop I use BLE.poll(100)

I leave you the complete code so that you can understand better. Sooner or later we will need to calmly investigate what is happening in that black hole of the BLE library.

#include <SparkFun_u-blox_GNSS_Arduino_Library.h>
#include <ArduinoBLE.h>
#define mySerial Serial1

long lat, lon, alti, courseGps;
int day, month, year,SIV, milli, second, minutes, hours,TWA, TWS;
float lat1, lon1, courseGps1, speed,W_Intensity, W_Dir, AWA, AWS;
byte fixType;
uint16_t W_Intensity_raw, W_Dir_raw;
bool Wind;

SFE_UBLOX_GNSS myGNSS;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial)
    ;  //Wait for user to open terminal

  if (!BLE.begin()) {
    Serial.println("starting Bluetooth® Low Energy failed!");
    while (1)
      ;
  }
  BLE.scan(true);

  Serial.println("SparkFun u-blox Example");
  do {
    Serial.println("GNSS: trying 38400 baud");
    mySerial.begin(38400);
    if (myGNSS.begin(mySerial) == true) break;

    delay(100);
    Serial.println("GNSS: trying 9600 baud");
    mySerial.begin(9600);
    if (myGNSS.begin(mySerial) == true) {
      Serial.println("GNSS: connected at 9600 baud, switching to 38400");
      myGNSS.setSerialRate(38400);
      delay(100);
    } else {
      delay(2000);  //Wait a bit before trying again to limit the Serial output
    }
  } while (1);
  Serial.println("GNSS serial connected");

  myGNSS.setUART1Output(COM_TYPE_UBX);  //Set the UART port to output UBX only
  myGNSS.setI2COutput(COM_TYPE_UBX);    //Set the I2C port to output UBX only (turn off NMEA noise)
  myGNSS.setNavigationFrequency(1);
  myGNSS.setAutoPVT(true);
  myGNSS.saveConfiguration();  

  myGNSS.enableDebugging();

  pinMode(86, OUTPUT);
}

void loop() {
BLE.poll(100);
  BLEDevice peripheral = BLE.available();
  if (peripheral) {
    Serial.print("Found ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();

    if (peripheral.localName() != "ULTRASONIC") {
      return;
    }

    BLE.stopScan();
    Ble(peripheral);
    BLE.scan(true);
  }
  Main();
}

void Ble(BLEDevice peripheral) {
  // connect to the peripheral
  Serial.println("Connecting ...");

  if (peripheral.connect()) {
    Serial.println("Connected");
  } else {
    Serial.println("Failed to connect!");
    return;
  }
  digitalWrite(87, LOW);
  // discover peripheral attributes
  Serial.println("Discovering attributes ...");
  if (peripheral.discoverAttributes()) {
    Serial.println("Attributes discovered");
  } else {
    Serial.println("Attribute discovery failed!");
    peripheral.disconnect();
    return;
  }

  BLECharacteristic A_W_I_Caratteristic = peripheral.characteristic("2A72");
  BLECharacteristic A_W_D_Caratteristic = peripheral.characteristic("2A73");
  A_W_I_Caratteristic.subscribe();
  A_W_D_Caratteristic.subscribe();

  if (!A_W_I_Caratteristic) {
    peripheral.disconnect();
    return;
  } else if (!A_W_I_Caratteristic.canRead()) {
    peripheral.disconnect();
    return;
  }

  while (peripheral.connected()) {

    if (A_W_I_Caratteristic.valueUpdated()) {
      A_W_I_Caratteristic.readValue(W_Intensity_raw);
      W_Intensity = W_Intensity_raw / 100.0;
    }
    if (A_W_D_Caratteristic.valueUpdated()) {
      A_W_D_Caratteristic.readValue(W_Dir_raw);
      W_Dir = W_Dir_raw / 100;
      Wind = true;
    }
    Main();
  }
}

void Main() {

  if (myGNSS.getPVT()) {
    lat = myGNSS.getLatitude();
    lon = myGNSS.getLongitude();
    alti = myGNSS.getAltitude();
    speed = myGNSS.getGroundSpeed();
    year = myGNSS.getYear();
    month = myGNSS.getMonth();
    day = myGNSS.getDay();
    hours = myGNSS.getHour();
    minutes= myGNSS.getMinute();
    second = myGNSS.getSecond();
    milli = myGNSS.getMillisecond();
    SIV = myGNSS.getSIV();
    courseGps = myGNSS.getHeading();
    //Serial.println(rottaGps*0.00001);
    lat1 = lat * 0.0000001;
    lon1 = lon * 0.0000001;
    speed = speed / 1000;
    courseGps1 = courseGps * 0.00001;
    serial();
    fixType = myGNSS.getFixType();
  }
}

void serial() {
  Serial.print("GPS Course:");
  Serial.println(courseGps1);
  Serial.print("speed:");
  Serial.println(speed);
  Serial.print("AWA:");
  Serial.println(AWA);
  Serial.print("AWS:");
  Serial.println(AWS);
  Serial.print("TWA:");
  Serial.println(TWA);
  Serial.print("TWS:");
  Serial.println(TWS);
  Serial.print("Wind station");
  Serial.println(Wind);
}
PaulZC commented 1 year ago

Hi @Nocentinia ,

Many thanks for the update. I am very glad your code is working!

Very best wishes, Paul