U-blox NEO-M8P I2C on atmega328p

I'm trying to design a board with atmega328p in order to integrate multiple sensors like gyros and accelerometers which provide a I2C interface.

I would like to add also a GPS module from U-blox and, in particular, the module NEO-M8P.
By reading its datasheet, it seems that it can work also on I2C but I wasn't able to find any sample on how to use it on Arduino.

I've seen that there is a Ublox Arduino Library, but I think it supports only UART communication.

Can you give me any suggestions on how to communicate between the GPS module and atmega, please?

I think it supports only UART communication

Well, according to the front page, it supports "any kind of input stream". Just read the bytes from I2C and pass them to the handle routine. Or, if you have an I2C class derived from Stream, you can pass it to the available() method.

Be sure to try this with a standard 328-based Arduino, first.

BTW, you probably don't need to use the binary UBX protocol. Try the standard NMEA text messages first.

Cheers,
/dev

Wrong Ublox manual.

Read the 'protocol specification' manual here;

The I2C interfaxce (DCC in UBLOX mythology) works in much the same way as a UART\Serial interface.

Thank you for your suggestions!

I only need to read NMEA strings and I do not need anything else.

From the "protocol specification" manual, I can read the receiver address:

Unlike all other interfaces, the DDC is not able to communicate in full-duplex mode, i.e. TX and RX are mutually
exclusive. u-blox receivers act as a slave in the communication setup, therefore they cannot initiate data
transfers on their own. The host, which is always master, provides the data clock (SCL), and the clock frequency
is therefore not configurable on the slave.
The receiver's DDC address is set to 0x42 by default. This address can be changed by setting the
mode
field in
CFG-PRT for DDC
accordingly.

So, from this, I can understand that I should use 0x42 as address for the Wire library.

The problem is that I can't find a way on how to use the Ublox Arduino Library to read the module by using the I2C protocol.
For example, this example only tries to read from Serial.

Since the M8P is in SMD technology, I can't test it with an Arduino board and I can only test it with a standalone arduino.
I would like to be sure if I can successfully use the I2C protocol in order to connect the SDA and SCL pins or if it is better to use the RX and TX pins.

Since the M8P is in SMD technology, I can't test it with an Arduino board and I can only test it with a standalone arduino.

I'm not sure what you mean... You can test the I2C interface by connecting the M8P evaluation board to "an Arduino". Aren't you going to prototype something?

I would like to be sure if I can successfully use the I2C protocol in order to connect the SDA and SCL pins or if it is better to use the RX and TX pins.

The M8P can only act as an I2C slave. This means the master must constantly check for available bytes at address 0xFF (device address defaults to 0x42).

Alternatively, you could configure the TXD pin (normally the UART TX pin) to signal that bytes are available (TX READY). You would watch for that signal and then start reading bytes.

I can't find a way on how to use the Ublox Arduino NeoGPS Library to read the module by using the I2C protocol.

Because Wire is derived from Stream, you can use it in with NeoGPS:

#include <NMEAGPS.h>
#include <Wire.h>

#define gpsPort Wire
const uint8_t NEO_M8P_ADDR = 0x42;
const uint8_t NEO_M8P_DATA = 0xFF;

NMEAGPS  gps;

//--------------------------

void setup()
{
  Serial.begin(9600);

  Serial.print( F("NEO-M8P test started\n") );
  Serial.flush();

  gpsPort.begin( NEO_M8P_ADDR );
  
  // Configure TXREADY pin and threshold...
}

//--------------------------

void loop()
{
  if (digitalRead( TXREADY )) {
    // "Some" data bytes are ready
    gpsPort.requestFrom( NEO_M8P_DATA, TXTHRESHOLD );
  }

  while (gps.available( gpsPort )) {
    gps_fix fix = gps.read();

    if (fix.valid.location)
      Serial.print( fix.latitude(), 6 ); // floating-point display
    Serial.print( ',' );
    if (fix.valid.location)
      Serial.print( fix.longitude(), 6 ); // floating-point display

    Serial.println();
  }
}

You just need to "request" the data so it becomes "available" for reading.

You should be aware that requestFrom is a blocking routine. Nothing else will happen until all 8 bytes have been received by the Arduino. At 400KHz, that's only 250us, but that's a lot longer than reading a byte from the HardwareSerial input buffer.

It seems kind of silly to check the pin and request the bytes, but that's how master/slave works. You could skip using the TXREADY pin and just keep asking for bytes. When no bytes are ready, the M8P returns 0xFF bytes, which are ignored by the NeoGPS parser.

Using AltSoftSerial on pins 8 & 9 is more CPU intensive than I2C, so the I2C is probably faster in the long run. My NeoSWSerial is almost is good. Don't even think about using SoftwareSerial. Could you use Serial for the M8P?

Cheers,
/dev,
author of NeoGPS

You can use either I2C, Softserial, or Hardware serial with the Ubloxes and GPS Libraries such as TinyGPS++.

However if you want to be 'sure' it works, only you can do that.

Never found the need for a seperate Ublox library.

Thanks again for your tips!

I would prefer to do not buy the evaluation board, but directly the NEO-M8P module in order to add it on my SMD board.

I will need to use the TX and RX pins available on atmega328p in order to send all the collected data to a pc.
These data are collected from GPS, accelerometer, magnetometer and other sensors.

I was thinking to use SoftwareSerial to fake another serial port via software and use it to connect to the GPS module. What do you think about this?

Will it slow down the whole system?

I would prefer to do not buy the evaluation board, but directly the NEO-M8P module in order to add it on my SMD board.

o_O

I was thinking to use SoftwareSerial to fake another serial port via software and use it to connect to the GPS module. What do you think about this?

I think I already wrote a paragraph about that.

/dev:
o_O

why?

why?

because its always best practice to mock-up or 'prototype' your circuits using a breadboard or something.. to ensure things work before jumping into the SMD version of the chip prior to testing.... ANYTHING?

I'd also say... if using an UNO or similar... DO NOT USE the hardware RX/TX pins.... (how are you going to upload new code then if those pins are taken?)

So either use I2C..or set up some software serial pins/output..

I was thinking to use as reference the Arduino Due board since it has a faster microcontroller and it provides up to 4 serial interfaces.

My whole system will include a ITG-3200 gyro, a ADXL345 accelerometer, a HMC5883L magnetometer and the U-blox GPS; I want to read from these sensors and output a text string on the Serial port which will include all the information.

The frequency of the syste should be 20Hz.

May be, the AT91SAM3X8E can be a better solution than the atmega328p.

What do you think about it?