I2C Master Slave GPS communication not receiving string

Greetings. I’ll make this short.

I would like to ask why my master(writer) and slave(receiver) cannot receive lat and lng. It is able to write in master but cannot display lat & lng in slave serial monitor. I presume something is not right in my slave code. Much help would be appreciated.

i2c Master code

// Include Arduino Wire library for I2C
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include “TinyGPS++.h”
#include “SoftwareSerial.h”

int lat;
int lng;
int pinCS = 53;

File myFile;
TinyGPSPlus gps;//This is the GPS object that will pretty much do all the grunt work with the NMEA data
SoftwareSerial serial_connection(62, 63);

#define SLAVE_ADDR 9 // Define Slave I2C Address

void setup() {

// Initialize I2C communications as Master
Wire.begin();
Serial.begin(9600);
serial_connection.begin(9600);//This opens up communications to the GPS
pinMode(pinCS, OUTPUT);
}

void loop()
{
while(serial_connection.available())//While there are characters to come from the GPS
{
gps.encode(serial_connection.read());//This feeds the serial NMEA data into the library one char at a time
}
if(gps.location.isUpdated())//This will pretty much be fired all the time anyway but will at least reduce it to only after a package of NMEA data comes in
{
myFile = SD.open(“xtracker.txt”, FILE_WRITE); // Create/Open file
myFile.print(“Latitude:”);
myFile.print(gps.location.lat(), 6);// Latitude in degrees (double)
myFile.print(",");
myFile.print(“Longitude:”);
myFile.print(gps.location.lng(), 6);// Longitude in degrees (double)
myFile.println();
myFile.close();
}

lat = (gps.location.lat(), 6);//defining variable lat for reading in slave
lng = (gps.location.lat(), 6);//defining variable lng for reading in slave

// Write a charatre to the Slave
Wire.beginTransmission(SLAVE_ADDR);
Wire.write(lat);
Wire.write(lng);
Wire.endTransmission();
delay(500);

}// end loop()

i2c Slave code

// Include Arduino Wire library for I2C
#include <Wire.h>

// Define Slave I2C Address
#define SLAVE_ADDR 9

// Variable for received data
int lat;
int lng;

void setup() {

// Initialize I2C communications as Slave
Wire.begin(SLAVE_ADDR);

// Function to run when data received from master
Wire.onReceive(receiveEvent);

// Setup Serial Monitor
Serial.begin(9600);
Serial.println(“I2C Slave Demonstration”);
}
String data = “”;

void receiveEvent() {
// Print value of incoming data
data = “”;
while( Wire.available()){
data += (char)Wire.read();
Serial.println(data);
}
}
void loop()
{
delay(50);
}

    lat = (gps.location.lat(), 6);//defining variable lat for reading in slave
    lng = (gps.location.lat(), 6);//defining variable lng for reading in slave

I'm not sure what you think this is doing but it almost certainly is not.

I see mr.john. I gave a variable to lat & lng so it can be printed in slave. I understand its a bit messy as i took from sources however could you guide me in correcting it. Thank you & have a blessed day.

It looks like you thought "Serial.print(gps.location.lat(), 6);" which displays "gps.location.lat()" with six decimal places on Serial Monitor could be changed to , "lat = (gps.location.lat(), 6);" to store "gps.location.lat()" into an integer variable. That is wrong for three reasons.

  • The ", 6" part of that expression only makes sense then "(gps.location.lat(), 6)" is used as function arguments. When not used as function arguments it becomes a "comma expression" where only the rightmost value is kept.
  • You can't store any decimal places in an integer variable.
  • Wire.write(value); only sends one byte so your integer value is limited to the range 0..255 or -128..127 neither will cover the 0..359 or E/W180 range of Longitude.

To get the value of type 'double' (same as 'float') to the slave you have to store the value in a variable of type 'double' and then pass ALL of the bytes of the variable to the slave:

  double lat = gps.location.lat();
  double lng = gps.location.lng();


  // Send the two 'double' values to the Slave
  Wire.beginTransmission(SLAVE_ADDR);
  Wire.write((byte *)&lat, sizeof lat);
  Wire.write((byte *)&lng, sizeof lng);
  Wire.endTransmission();

Now you will have to modify the slave to put the multiple bytes of the 'double' values back together into variables of type 'double'.

Appreciate the feedback sir. Well explained while giving me more insight on i2c. However i have done my research on this forum and stackoverflow on changing from bytes back to var but came up short as they are very different examples and hard to follow or gasp whats going on. Do you have any sites that a newbie can actually refer to?

If you have the extra time, could you guide me through it like you did with the master code. If its time consuming, i understand. Still appreciate your time.Thanks.