sparkfun / SparkFun_Ublox_Arduino_Library

Library to control UBX binary protocol and NMEA over I2C on Ublox GPS modules
Other
141 stars 85 forks source link

NEO-M8U on I2C behavior is erratic with ESP-12F #121

Closed Daedaliss10 closed 3 years ago

Daedaliss10 commented 4 years ago

Subject of the issue

NEO-M8U module causes bus issues with other I2C devices, causes resets and general instability.

Your workbench

What development board or microcontroller are you using - ESP-12F ( Wemos D1 Mini) What version of hardware or breakout board are you using - Sparkfun GPS Board (NEO-M8U) How is the breakout board wired to your microcontroller - I2C lines, 3.3v supply capable of 800mA, hardwired via wirewrap pins & hookup wire for 3.3V, GND, SCL, SDA How is everything being powered - USB 5V to onboard LDO (3.3v 800mA) Are there any additional details that may help us help you - Will be using 3 devices on I2C bus.

Steps to reproduce

SETUP:

Install 3 I2C devices on Wemos D1 Mini; Sparkfun NEO-M8U, Sparkfun MAX30105 & Sparkfun BME680. Install libraries to connect and communicate with the devices. Remove jumper connections for I2C bus pull ups on two of three devices. Set up basic sketch to connect and poll sensors. Connect Serial monitor for output messages. (sketch to follow)

ISSUE:

Device behavior is erratic. Sometimes GPS module successfully connects, sometimes doesn't. (sometimes fresh boot works, resetting device via RESET pin does not). On reset, sometimes other I2C devices have connection issues. When GPS module removed, leaving 2 I2C devices connected, system initializes fine, and operates and resets as expected.

Sketch:

include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS

include "heartRate.h"

include

include "MAX30105.h"

include "spo2_algorithm.h"

include "Zanshin_BME680.h"

include

include

include

BME680_Class BME680; ///< Create an instance of the BME680 class //BME60 I2C address = 0x77 (0x76 if jumper closed on bottom)

MAX30105 particleSensor; //MAX30105 I2C address = 0xAF (read), 0xAE (write)? .h file says 0x57

SFE_UBLOX_GPS myGPS; //GPS I2C address = 0x42

static int32_t temp, humidity, pressure, gas; bool gpsEnabled, bme680Enabled, max30105Enabled = false;

void setup() { pinMode(MUX_SELECT, OUTPUT); pinMode(A0, INPUT); digitalWrite(MUX_SELECT, LOW);

Serial.begin(UART_SPD); Wire.begin();

if(!BME680.begin(I2C_STANDARD_MODE)) // Start BME680 using I2C, use first device found { Serial.print(F("BME680 was not found. Please check wiring/power. ")); delay(1000); bme680Enabled = false; } else { Serial.println("BME680 initialized successfully. "); Serial.println("BME680 I2C address = 0x" + String(BME680.getI2CAddress(), HEX)); BME680.setOversampling(TemperatureSensor,Oversample16); // Use enumerated type values BME680.setOversampling(HumiditySensor, Oversample16); // Use enumerated type values BME680.setOversampling(PressureSensor, Oversample16); // Use enumerated type values BME680.setIIRFilter(IIR4); // Use enumerated type values BME680.setGas(320,150); // for 150 milliseconds bme680Enabled = true; }

if(particleSensor.begin() == false) { Serial.println("MAX30105 was not found. Please check wiring/power. "); delay(1000); max30105Enabled = false; } else { particleSensor.setup(); //Configure sensor. Use 6.4mA for LED drive Serial.println("MAX30105 initialized successfully. "); Serial.println("MAX30105 getRevisionID() = " + String(particleSensor.getRevisionID()) + ", getPartID() = " + String(particleSensor.readPartID())); max30105Enabled = true; }

if(myGPS.begin() == false) //Connect to the Ublox module using Wire port { Serial.println("u-blox NEO-M8U not found. Please check wiring/power"); delay(1000); gpsEnabled = false; } else { Serial.println("u-blox NEO-M8U initialzied successfully."); myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise) Serial.println("u-blox.IsConnected() = " + String(myGPS.isConnected(100))); Serial.println("u-blox version = " + String(myGPS.getProtocolVersionHigh()) + "." + String(myGPS.getProtocolVersionLow())); gpsEnabled = true; } } }

void loop() { temp = 0; humidity = 0; pressure = 0; gas = 0; if(bme680Enabled) { BME680.getSensorData(temp,humidity,pressure,gas); Serial.println("BME680 output: temp = " + String(temp) + ", humidity = " + String(humidity) + ", pressure = " + String(pressure) + ", gas + " + String(gas)); }

if(max30105Enabled) { Serial.println("MAX30105 R = " + String(particleSensor.getRed()) + ", G = " + String(particleSensor.getGreen()) + ", IR = " + String(particleSensor.getIR())); }

if(gpsEnabled) { Serial.println("Latitude = " + String(myGPS.getLatitude()) + ", Longitude = " + String(myGPS.getLongitude()) + ", Altitude = " + String(myGPS.getAltitude())); }

Serial.println("Analog Reading = " + String(analogRead(A0))); digitalWrite(MUX_SELECT, !digitalRead(MUX_SELECT)); delay(5000); } }

2ND TEST

SETUP:

Removed all but the the GPS module from I2C bus on Wemos D1 Mini. Run Example3_GetPosition from Sparkfun u-blox Arduino library. No I2C pull up resistors on GPS module OR Wemos D1 Mini (as per Wemos schematic)

ISSUE:

Similiar behavior as before. Sometimes resets once or two on startup, then gets into loop and correctly functions. On system reset, never re-establishes connection.

3RD TEST

Same test as 2ND TEST, this time including an I2C device with pull ups, but not configured in firmware. Run Example3_GetPosition again. Similar behavior as 2ND TEST.

Expected behavior

Stable and reliable device operation when used on I2C bus with other devices installed.

Actual behavior

System operation is unstable and unreliable. Not usable in current form.

PaulZC commented 4 years ago

Hi @Daedaliss10 , Thank you for reporting this issue. Unfortunately I don't have any ESP hardware available and so I cannot replicate the problems you are seeing. I do have some suggestions though: When we connect u-blox breakouts to Artemis boards, we do see occasional I2C problems which we don't as yet fully understand. These things help:

Please let us know if this fixes or reduces your issues. Best wishes, Paul

CptHolzschnauz commented 4 years ago

I have a similar problem with a MKR1400 and MKR 1500 Board. The compiler throws out:

SparkFun_Ublox_Arduino_Library.cpp: In member function 'sfe_ublox_status_e SFE_UBLOX_GPS::sendI2cCommand(ubxPacket*, uint16_t)':

samd/1.8.8/cores/arduino/RingBuffer.h:31:28: warning: large integer implicitly truncated to unsigned type [-Woverflow]

define SERIAL_BUFFER_SIZE 256

SparkFun_Ublox_Arduino_Library.h:64:27: note: in expansion of macro 'SERIAL_BUFFER_SIZE'

define I2C_BUFFER_LENGTH SERIAL_BUFFER_SIZE

SparkFun_Ublox_Arduino_Library.cpp:1097:13: note: in expansion of macro 'I2C_BUFFER_LENGTH' len = I2C_BUFFER_LENGTH;

May there be some incompatibility with the new SAMD21 core software? I have also no pull ups and reduced speed to 100. The behaviour is described by Daedaliss10 in perfection. Thx R

CptHolzschnauz commented 3 years ago

I tried several configurations and i came to the conclusion that SAM-M8Q causes a fatal error on the I2C bus with a Arduino MKR 1400 sooner or later. For the frist 30 min to 24 hours everything looks fine, the signal on the oszi is perfect. When the error occurs, the board comes to a complete halt, even the internal hardware SAMD21 watchdog freezes, sometimes the battery charger which is also connected to the I2C can blink out his panic state. Even the reset button is not working anymore then, the board needs to be unpowered.

The good news: With UART connected everything works perfect. For those with the same ublox SAM-M8Q IC2 problems: Check the sparkfun example 12 UseUart, you can also switch the unit to ubx only, you can use the lib and instances the same way.

Daedaliss10 commented 3 years ago

Hi @Daedaliss10 , Thank you for reporting this issue. Unfortunately I don't have any ESP hardware available and so I cannot replicate the problems you are seeing. I do have some suggestions though: When we connect u-blox breakouts to Artemis boards, we do see occasional I2C problems which we don't as yet fully understand. These things help:

  • Remove all pull-ups from the I2C bus. The u-blox modules have internal ones, so we cut the jumpers to disconnect the resistor pull-ups on the u-blox breakout board too.
  • I'm not familiar with the ESP. Does it have configurable pull-ups internal to the ESP? If it does, please disable those too. (We do the same thing on Artemis).
  • Please drop the bus speed to 100kHz. We see fewer issues at 100kHz compared to 400kHz.
  • Please give the u-blox a full second to power-up before you attempt to communicate with it. You may need to add an extra delay to your code to give it time to start up.

Please let us know if this fixes or reduces your issues. Best wishes, Paul

Thank you Paul for the feedback. We did try all these recommendations, but it didn't seem to resolve the issue. We did test against a regular Arduino Uno, and the u-blox module worked as expected, robustly.

Upon further investigation, we had team members whom their setups did not exhibit these same issues, despite being the same hardware setup. Root cause ended up being board files. The problematic setups were using esp8266 by ESP8266 Community version 2.5.2. Success was had with board files from versions 2.7.1 and 2.7.4 (currently newest release).

Please consider this issue resolved for us.

PaulZC commented 3 years ago

Hi @Daedaliss10 & @CptHolzschnauz ,

Many thanks for the feedback. Glad you figured out the issue and got it working.

Hope the rest of your project goes well!

All the best,

Paul