SBAS and ZOE-M8Q

Hey,

I’m wondering if anybody’s played with SBAS on the M8Q receiver. Trying to get better accuracy and that might help :slight_smile:

Good morning,

Here, in this U-blox Youtube video (Brazilian portuguese), you will see a lot of information about many different ways to get GNSS precision. You will need to thing about at least: When, What and How.

Regards,

Claudio

I’ve been linked this youtube video before, but i can’t understand it. Slides are useful though!

Take a look in the slides and If you have any question, call me

Thanks @crmrosa for the help so far.

i’ve added this bit of code to the sparksfun GNSS library:



bool SFE_UBLOX_GNSS::getSBASConfig(UBX_CFG_SBAS_t *data, uint16_t maxWait) {
  packetCfg.cls = UBX_CLASS_CFG;
  packetCfg.id = UBX_CFG_SBAS;
  packetCfg.len = 0;
  packetCfg.startingSpot = 0;

  if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) {
    return (false);
  }

  uint8_t tmp = extractByte(&packetCfg, 0);
  data->modeTest = (tmp & 0b00000010) != 0;
  data->modeEnabled = (tmp & 0b00000001) != 0;

  tmp = extractByte(&packetCfg, 1);
  data->usageRange = (tmp & 0b00000001) != 0;
  data->usageDiffCorr = (tmp & 0b00000010) != 0;
  data->usageIntegrity = (tmp & 0b00000100) != 0;
  
  data->maxSBAS = extractByte(&packetCfg, 2);
  

  tmp = extractLong(&packetCfg, 3);  
  for (int i = 0; i < 8; i++) {
    uint32_t mask = 1 << i; // Create a mask for bit at position i
    data->scanmode[i] = (tmp & mask) != 0; // Check if the bit is set and assign to the array
  }

  uint32_t tmp2 = extractLong(&packetCfg, 4);  
  for (int i = 8; i < 39; i++) {
    uint32_t mask = 1 << i; // Create a mask for bit at position i
    data->scanmode[i] = (tmp2 & mask) != 0; // Check if the bit is set and assign to the array
  }
  return true;
}

Using it like so:

  UBX_CFG_SBAS_t sbasData;
  if (g_GNSS.getSBASConfig(&sbasData) == false)
  {
    SERIAL_LOG("COULD NOT GET SBAS CONFIG");
    LedHelper::BlinkHalt(10);
  }

  SERIAL_LOG("SBAS - maxSBAS: %u", sbasData.maxSBAS);
  SERIAL_LOG("SBAS - modeEnabled: %u", sbasData.modeEnabled);
  SERIAL_LOG("SBAS - modeTest: %u", sbasData.modeTest);
  SERIAL_LOG("SBAS - usageDiffCorr: %u", sbasData.usageDiffCorr);
  SERIAL_LOG("SBAS - usageIntegrity: %u", sbasData.usageIntegrity);
  SERIAL_LOG("SBAS - usageRange: %u", sbasData.usageRange);

  for (int i = 0; i < 39; i++)
  {
    SERIAL_LOG("SCANMODE %d: %d", i, sbasData.scanmode[i]);
  }```


The output of that is:

SBAS - maxSBAS: 3
SBAS - modeEnabled: 1
SBAS - modeTest: 0
SBAS - usageDiffCorr: 1
SBAS - usageIntegrity: 0
SBAS - usageRange: 1
SCANMODE 0: 0
SCANMODE 1: 0
SCANMODE 2: 0
SCANMODE 3: 0
SCANMODE 4: 0
SCANMODE 5: 0
SCANMODE 6: 0
SCANMODE 7: 0
SCANMODE 8: 1
SCANMODE 9: 1
SCANMODE 10: 0
SCANMODE 11: 0
SCANMODE 12: 0
SCANMODE 13: 1
SCANMODE 14: 0
SCANMODE 15: 1
SCANMODE 16: 1
SCANMODE 17: 1
SCANMODE 18: 1
SCANMODE 19: 0
SCANMODE 20: 0
SCANMODE 21: 0
SCANMODE 22: 0
SCANMODE 23: 0
SCANMODE 24: 0
SCANMODE 25: 0
SCANMODE 26: 0
SCANMODE 27: 0
SCANMODE 28: 0
SCANMODE 29: 0
SCANMODE 30: 0
SCANMODE 31: 0
SCANMODE 32: 0
SCANMODE 33: 0
SCANMODE 34: 0
SCANMODE 35: 0
SCANMODE 36: 0
SCANMODE 37: 0
SCANMODE 38: 0


So, i think that means SBAS is enabled by default?

Well, I am using RAK12500, a ublox ZOE-M8. Some messages were written in Portuguese because my clients and I, we live in Brazil.

I am using VSCode/PlatformIO, then my configuration file for the libraries is?

[env:wiscore_rak4631]
platform = nordicnrf52
board = wiscore_rak4631
framework = arduino
; upload_port = COM7
monitor_speed = 115200
; monitor_dtr = 0
; monitor_rts = 0
lib_deps = 
	sparkfun/SparkFun LIS3DH Arduino Library @ ^1.0.3
	adafruit/Adafruit BME680 Library @ ^2.0.4
	sparkfun/SparkFun u-blox GNSS Arduino Library @ ^2.2.27
	beegee-tokyo/SX126x-Arduino @ ^2.0.26
	beegee-tokyo/RAK15007-CY15B108QN @ ^1.0.0
	bblanchon/ArduinoJson @ ^7.0.4
	sabas1080/CayenneLPP @ ^1.1.0

I have only two functions:

  1. void IniciaRAK12500(), to initialize the sensor and remember that the time for precision is important because entire the Almanac (list of satellite) can be need 12 minutes to be completed.
  2. vodi LeGNSS(), it read satellites values and to write all of them in variables to be packed in the another function and at the end to be sent by LoRa
void IniciaRAK12500()
{
   // Incia RAK12500 GNSS sensor
	pinMode(WB_IO2, OUTPUT);  
	digitalWrite(WB_IO2, 0);
	vTaskDelay(pdMS_TO_TICKS(1000));
	digitalWrite(WB_IO2, 1);
	vTaskDelay(pdMS_TO_TICKS(1000));

	if (CFG_DEBUG >= D_INFORMA) {
		Serial.println("============  Iniciando o RAK12500 via I2C ============");
		Serial.println("=======================================================");
		}
	do  //testa se o sensor está conectado
	{
		count2++;
		if (SensorGNSS.begin() == false)
			{
					if (CFG_DEBUG != 0) {
						Serial.print("Não detectado o u-blox GNSS no endereço padrão. Verifique as conexões. Tentativa ");
						Serial.print(String(count2));
						Serial.println(". Tentando outra vez!");
						Serial.println("=======================================================");
						}
			}
	} while(((SensorGNSS.begin()) == false) & (count2<11));
	if (CFG_DEBUG >= D_INFORMA) { 
		Serial.println("=========== RA12500 inciado com sucesso ===============");
		Serial.println("=======================================================");
		}
	SensorGNSS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
	SensorGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save (only) the communications port settings to flash and BBR
}



void LeGNSS()
	{
	if (CFG_DEBUG >= D_INFORMA) {
		// Le via GNSS a geo-localização
		Serial.println("=======================================================");
		Serial.println("============= Geo-localização =========================");
	}
	count2=0;
	do  //testa se o sensor está conectado
		{
			count2++;
			if (SensorGNSS.begin() == false)
				{
				if (CFG_DEBUG >= D_ERRO) {
					Serial.print("Não foi detectado o u-blox GNSS no endereço padrão. Verifique as conexões. Tentativa ");
					Serial.print(String(count2));
					Serial.println(". Tentando outra vez!");
					}
				}
		} while((SensorGNSS.begin() == false) & (count2<11)); 
	if (SensorGNSS.begin() != false) { //Connect to the u-blox module using Wire port
		if (millis() - g_lastTime > 1000)
			{
				g_lastTime = millis(); //Update the timer
				// Data e hora
				RAK12500.UNIXEpoch	 = SensorGNSS.getUnixEpoch(); // Recebe o horário no formato UNIX

				// Posição
				RAK12500.Latitude = SensorGNSS.getLatitude();
				RAK12500.Longitude = SensorGNSS.getLongitude();
				RAK12500.Altitude = SensorGNSS.getAltitude(); // Altitude em metros
				RAK12500.Acuracia = SensorGNSS.getHorizontalDOP() / 100.0;
				RAK12500.Velocidade = SensorGNSS.getGroundSpeed()/100.0;
				RAK12500.Direcao = SensorGNSS.getHeading()/100000.0;
				RAK12500.sats = SensorGNSS.getSIV();
				if (CFG_DEBUG >= D_INFORMA) {
					Serial.printf(" tamanho de UNIXEpoch: %d\n",sizeof(RAK12500.UNIXEpoch));
					Serial.printf(" tamanho de Lat: %d\n",sizeof(RAK12500.Latitude));
					Serial.printf(" tamanho de Long: %d\n",sizeof(RAK12500.Longitude));
					Serial.printf(" tamanho de Alt: %d\n",sizeof(RAK12500.Altitude));
					Serial.printf("Inteiros Lat: %d Lon: %d \n", RAK12500.Latitude, RAK12500.Longitude);
					Serial.printf("Inteira Alt: %d M \n", RAK12500.Altitude);
					Serial.printf(" UNIXEpoch: %d\n", RAK12500.UNIXEpoch);
					Serial.printf("Lat: %9.6f Lon: %9.6f", RAK12500.Latitude / 10000000.0, RAK12500.Longitude/ 10000000.0);
					Serial.printf(" Alt: %5.2f M \n", RAK12500.Altitude / 1000.0);
					Serial.printf(" Acuracia: %3.2f %%\n", RAK12500.Acuracia);
					Serial.printf(" Velocidade: %4.1f m/s \n", RAK12500.Velocidade);
					Serial.printf(" Direção: %4.1f graus \n", RAK12500.Direcao);
					Serial.printf(" Satélites: %3d\n", RAK12500.sats);
					Serial.println("=======================================================");
					vTaskDelay(pdMS_TO_TICKS(5000));
					}
			}
		}
	}

My code is roughtly the same, with the same GNSS library. That’s all fine.

At the moment i’m just wondering if we need to do something special to get SBAS to work, or if that works out of the box.