I2C - Combining bytes into another variable - Trying to use union but failing

Hello Everyone

First time dealing with I2C so please bear with me. I was trying to send a long over the I2C but then realized that the I2C only sends byte variables and not a long as a variable.

So this lead me to the following posts:

http://forum.arduino.cc/index.php/topic,160623.0.html
http://forum.arduino.cc/index.php/topic,109335.0.html

So in my slave sender sketch I've coded the following to split the long variable into 4 bytes and to transmit the 4 bytes then over the I2C bus:

      data[0] = distance;          // Split long distance into 4 bytes.
      data[1] = distance>>8;
      data[2] = distance>>16;
      data[3] = distance>>24;
      Wire.write(data,4);          // Write the 4 bytes over the I2C line.

On the master receiver side I need to add these bytes together to form a new long. I searched the forum a bit and came upon the first linked post and decided to use the union that is described by PaulS. I've declared my union as:

    union Distance
    {
      long Distance;
      byte Received_Byte_Array[4];
    };

and my void loop looks as follows:

    void loop()
    {
      Wire.requestFrom(2, 6);    // request 5 bytes from slave device #2
    
        if (Wire.available())    // slave may send less than requested
        {
          for ( int i; i <= 4; i++)
          {
            Received_Byte_Array[i] = Wire.read;
          }
        }

But now when compiling my master receiver sketch I get the following errors:

I2C_RX_Disp_Master_Reader.ino: In function 'void loop()':
I2C_RX_Disp_Master_Reader:43: error: 'Received_Byte_Array' was not declared in this scope
I2C_RX_Disp_Master_Reader:51: error: expected primary-expression before ')' token

I think that I'm not coding the union correct in the for loop but I don't know how to implement it. Can someone possibly point me in the right direction please.

Thank you
Dirk

Distance.Received_Byte_Array[i] = Wire.read ();

(It's better if you post all your code)

Hello AWOL

Below is my Slave Sender sketch. It is an Arduino Nano with the HC-SR04 ultrasonic sensor connected to it:

    #include <Wire.h>

//******************************************************************************************************************************************************************************
//**************************************                           Declaring Global Variables                          *********************************************************
//******************************************************************************************************************************************************************************

    #define echoPin 13               // Echo Pin
    #define trigPin 12               // Trigger Pin
    
    long duration; 
    long distance;         // Duration used to calculate distance 

    unsigned char data[4];

//******************************************************************************************************************************************************************************
//**************************************                                   Void Setup                                  *********************************************************
//******************************************************************************************************************************************************************************
   
    void setup()
    {
      Wire.begin(2);                // join i2c bus with address #2
      Wire.onRequest(requestEvent); // register event                
    }

//******************************************************************************************************************************************************************************
//**************************************                                   Void loop                                   *********************************************************
//******************************************************************************************************************************************************************************
    
    void loop()
    {

    }
    
//******************************************************************************************************************************************************************************
//**************************************                           Request data function                               *********************************************************
//******************************************************************************************************************************************************************************

    void requestEvent()
    {
      Ultrasonic_Measurement();    // Get the distance measurement.

      data[0] = distance;          // Split long distance into 4 bytes.
      data[1] = distance>>8;
      data[2] = distance>>16;
      data[3] = distance>>24;
      Wire.write(data,4);          // Write the 4 bytes over the I2C line.
      
    }
    
  //****************************************************************************************************************************************************************************
  //**************************************************                    Ultasonic measurement fucntion                ********************************************************
  //**************************************************************************************************************************************************************************** 
    
  void Ultrasonic_Measurement()
  {     
    /* The following trigPin/echoPin cycle is used to determine the
     distance of the nearest object by bouncing soundwaves off of it. */ 
     digitalWrite(trigPin, LOW); 
     delayMicroseconds(2); 
    
     digitalWrite(trigPin, HIGH);
     delayMicroseconds(10); 
     
     digitalWrite(trigPin, LOW);
     duration = pulseIn(echoPin, HIGH);
     
     //Calculate the distance (mm) based on the speed of sound.
     distance = duration/5.82;     
     
     //Delay 50ms before next reading.
     delay(50);
  } 

  //****************************************************************************************************************************************************************************

Here is the Master Receiver part of the code which I'm not sure how to implement. I've got everything hooked up to a GLCD so I'm printing the received variable on the GLCD and I'm not making use of serial.print because of this.

    #include <openGLCD.h>
    #include <include/openGLCD_GLCDv3.h> // GLCDv3 compatibilty mode  
    #include <Wire.h>

//******************************************************************************************************************************************************************************
//**************************************                           Declaring Global Variables                          *********************************************************
//******************************************************************************************************************************************************************************

    union Distance
    {
      long Distance;
      byte Received_Byte_Array[4];
    };  
   
//******************************************************************************************************************************************************************************
//**************************************                                   Void Setup                                  *********************************************************
//******************************************************************************************************************************************************************************
    
    void setup()
    {
      // Initialize the GLCD 
      GLCD.Init();

      // Start I²C bus as master
      Wire.begin();
    }

//******************************************************************************************************************************************************************************
//**************************************                                   Void loop                                   *********************************************************
//******************************************************************************************************************************************************************************
    
    void loop()
    {
      Wire.requestFrom(2, 6);    // request 5 bytes from slave device #2
    
        if (Wire.available())    // slave may send less than requested
        {
          for ( int i; i <= 4; i++)
          {
            Received_Byte_Array[i] = Wire.read;
          }         
        }
      
      GLCD.SelectFont(System5x7, BLACK); 
      GLCD.CursorToXY(10, 10);
      GLCD.print(Distance);   
      delay(100);
    }
for ( int i; i <= 4; i++)
          {
            Received_Byte_Array[i] = Wire.read;

"i" is not intitialised, your array doesn't have five elements, and Wire.read is a function that need to be called.

Updated it to:

          for ( int i = 0; i < 3; i++)
          {
            Received_Byte_Array[i] = Wire.read();
          }

Is this correct? Still getting the error: Recevied_Byte_Array was not declared in this scope

Thanks AWOL

Your array has four elements, not three.
You still haven't fully referenced the array, which is why you're getting the error message.

Hello AWOL

I changed the 3 to a 4 in the for statement. Thank you for pointing that out to me. Your stating that I'm not fully reference the array. I'm not sure how to accomplish this, could you instruct me possibly please. Thank you.

Remember that Received_Byte_Array forms part of the Distance union. Never worked with unions before so I'm not sure how to accomplish this. Thanks again

Dirk

  union Distance
    {
      long Distance;
      byte Received_Byte_Array[4];
    } Distance;

Hello AWOL

Apologies for the spoon-fed session but I'm just not getting any joy. I've referenced the union as you've stated:

    union Distance
    {
      long Distance;
      byte Received_Byte_Array[4];
    } Distance;

Then I tried to compile but I'm still getting the issue of Received_Byte_Array not declared. I then looked at the post from the first link again and tried to accomplish it as PaulS said in that post:

stuff sensorData;
sensorData.bytes[0] = firstValue;
sensorData.bytes[1] = secondValue;
sensorData.bytes[2] = thirdValue;
sensorData.bytes[3] = fourthValue;

My version being:

        if (Wire.available())    // slave may send less than requested
        {
            Distance; 
            Received_Byte_Array[0] = Wire.read();
            Received_Byte_Array[1] = Wire.read();
            Received_Byte_Array[2] = Wire.read();
            Received_Byte_Array[3] = Wire.read();                        
        }

I also tried:

            for ( int i = 0; i < 4; i++)
            {
              Distance Received_Byte_Array[i] = Wire.read();
            }

as well as:

            for ( int i = 0; i < 4; i++)
            {
              Distance; Received_Byte_Array[i] = Wire.read();
            }

Still nothing, apologies if I'm being a nuisance but I'm not finding any examples of this.

Distance Received_Byte_Array[i] = Wire.read();``Distance; Received_Byte_Array[i] = Wire.read();
Yes, just trying random punctuation is not a great approach to programming.

Distance.Received_Byte_Array[i] = Wire.read();

Yes, just trying random punctuation is not a great approach to programming.

So true

Thank you for the assistance as well as your patience. Much appreciated. It is compiling now without an issue.
Dirk