Having doubt in I2C

@golam

The receiver code is not robust. You declare the array with 4 bytes and you store bytes in there starting at howMany-1 without ensuring that it is 3 or less

There is no need to do the hacked union approach (you are relying on a compiler dependent, unspecified behavior even if that works), just doing

float v = 263.30;
Wire.beginTransmission(8);
Wire.write(&v, sizeof(v));
Wire.endTransmission();

is enough to send the 4 bytes (little endian) as demonstrated in my code above.

@GolamMostafa, Thanks for your response.

I executed your code mentioned in #19 it will display master code output but it will not display slave output. I connected 4.7K ohm resistor instead of 2.2K ohm resistor.
Hardware Setup:
Master MEGA Slave UNO
GND ----------------------> GND
SDA (20) ----------------------> SDA (A4)
SCL (21) ----------------------> SCL (A5)

**STEP 1:**I first open Master serial monitor, I set serial port as Mega It display the output.

STEP 2: I close the master serial monitor.

STEP 3: I choose serial port as Arduino Uno in the slave File. Once I compiled the program, I could open
the serial monitor of Slave arduino. But it will not display nay output.

The above procedure only I follow for executing this program. I think I made a mistake in the proclariody clarify my doubt.

@Ganesh2807, it seems that the I2C bus is not connected, or one of the boards is broken. In my opinion, the examples by the others are too complicated.

Did you know that you can have two Arduino IDE running at the same time ?

Connect both Arduino boards to the computer.
Start an Arduino IDE and carefully select the serial port of one Arduino board. Move the Arduino IDE window to one side of the screen.
Start the Arduino IDE once more, and carefully select the serial port of the other Arduino board.
Then you have two Arduino IDE running, each one connected to an Arduino board and each one with its own serial monitor.

When the Arduino Uno does not display any output, you make it display output. For example in setup():

void setup()
{
  Serial.begin(9600);
  Serial.println( "The Slave sketch has started");
  Wire.begin(8);
  Wire.onReceive(receiveEvent);
}

Do you see that on the serial monitor ?

Run the I2C Scanner on the Arduino Mega.
Can you confirm that the Slave is detected ?
When nothing is detected, then you don't have to try something else because the I2C bus is not working. Can you try to fix that ? If you use a breadboard, try an other location on the breadboard or try to avoid using a breadboard. Use other wires. Check the pin numbers.

It is useless to try to transfer data as long as the I2C Scanner does not detect the Slave Arduino board (the Slave Arduino board must be in Slave mode).

@Koepel,

I used I2C scanner program, but my slave arduino uno will not be connected. I am getting this output.

I2C Scanner
Scanning...
No I2C devices found

Run the I2C Scanner on the Arduino Mega.

This will suitable for detecting arduino slave device also huh. I cannot run the two COM3 & COM4 port at the same time. Anybody know reference for this.

Then your I2C bus is not working. There is no I2C connection between the Arduino Mega and the Arduino Uno. Can you make a photo of it, so we can check the wires ? Do you have another Arduino board ? Did you try other wires ?

The COM3 and COM4 didn't work at the same time ? I don't know why. I'm using linux and I can run two (or more) at the same time.

J-M-L:
@golam

The receiver code is not robust. You declare the array with 4 bytes and you store bytes in there starting at howMany-1 without ensuring that it is 3 or less

The float is always 4-byte long. I have no idea if it's length changes with computing platform. If so, sizeof(float) style is appropriate.

When howmany is always equal to the number of times the Wire.write() instruction has been executed by the Master, there is no need to check its numerical value?

I’m just saying don’t hardcode 4 when what you mean is sizeof float

Also trying to write in an array without checking bounds and is a programming risk

To OP - if the code I published for you does not work with just three short wires as documented then you have a hardware issue. (Of course make sure you don’t use the Arduino’s Built in serial console (unless you launch 2 instances you can’t have 2 serial monitors)

@Koepel
Thank you for putting the idea of checking the presence of an active slave (MCU based I2C device) in the I2C Bus. I have experimented your idea and it works well.

Ganesh2807:
@Koepel,

I used I2C scanner program, but my slave arduino uno will not be connected. I am getting this output.

I2C Scanner
Scanning...
No I2C devices found

1. You must have loaded the following codes as minimum in the Slave Arduino (UNO).

#include<Wire.h>

void setup() 
{
 Wire.begin(0x08); 
}

void loop() 
{

}

2. Now, load the following program in the MEGA. If your I2C Bus wiring connection is correct (as pointed out by @Koepel), the UNO shud be found at address 8.

#include <Wire.h>

// setup
void setup() 
{
  Serial.begin(9600);
  Serial.println("Address search");
  Serial.println("-------------------------");
  
  Wire.begin();
  int i2c = 0x00;
  for (int i=0; i<32; i++) {
    Serial.print("Search at [");
    Serial.print(i2c, HEX);
    Serial.print("]: ");
    Wire.beginTransmission(i2c);
    int result = Wire.endTransmission();
    if (result==0)
      Serial.println("FOUND!");
    else
      Serial.println("not found");
    i2c++;
  }

}

// main loop
void loop() 
{

}
  1. You must have loaded the following codes as minimum in the Slave Arduino (UNO).
void setup() 

{
Wire.begin(0x08);
}

void loop()
{

}

@GolamMostafa, Thank you for providing this program. Now my slave Arduino board had found.

@Koepel, Thank you for providing a I2C Scanner program.

I dug an old program for you... I just added the array management to match your case. See if you get what it does:

@J-M-L, Thanks for your kind response.

Master Codes for MEGA

#include <Wire.h>
union
{
  float v;
  uint32_t as_int;
  byte b[4];
} myData;


void setup()
{
  Wire.begin();
  Serial.begin(9600);
  myData.v = 263.30;//floatValue.v = 263.30;
  Wire.beginTransmission(8);
[b]  delay(15000);[/b]
  Wire.write(myData.b[3]);//(floatValue.b[3]);  //0x43
  Wire.write(myData.b[2]);//floatValue.b[2]);   //0x83
  Wire.write(myData.b[1]);//floatValue.b[1]);   //0xA6
  Wire.write(myData.b[0]);//(floatValue.b[0]);  //0x66
  Wire.endTransmission();

  Serial.println("Transmission Done!");

}

void loop() {


}

Slave UNO Codes:

#include <Wire.h>

byte dataArray[4];
int j;
void setup()
{
  Wire.begin(8);
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);

}

void loop() 
{
 
}

void receiveEvent(int howmany) 
{
  
    for (j = howmany - 1; j >= 0; j--) 
    {
      dataArray[j] = Wire.read();
      Serial.println(dataArray[j], HEX);
    }
 
}

I got results for this program, I add a delay() after the Wire.beginTransmission() of data. It works fine.
I have a doubt in I2C still,

  1. I need a clarification between connecting Arduino and I2C devices with two resistor and without this
    resistor ?

  2. Is there any possibility to use Serial.begin() in Arduino Mega board ?

  3. How to write a array of data using loop from master to slave.

  4. What are all things to know about I2C, SPI, UART & RS232 to become well versed in this protocol.

Can anybody providing a guidance for me

@OP

Tell us the reason for inserting 1500 ms time delay after the Wire.beginTransmission(8); command. Having heard your answer, we hope to explain to you if this delay is needed or not.

While compile my Arduino master and slave program, it will not show any error. Open my Master Serial monitor, it show information what is expected then I open my Slave Serial Monitor it will not display any data.

I think it transmitting the data very quickly before opening the Slave Serial Monitor. So I add delay() after Wire.beginTransmission(). It will display the data in Slave Serial Monitor.

But there will be a trouble in this adding delay() because within the delay() is complete I want to open a Slave Serial Monitor then only I get a result otherwise I didn't get the result.

So that only I added delay().

The I2C Bus transaction is on handshaking scheme; therefore, there is no chance for the missing of any data item. There is no need to insert time delay. You may follow these steps:

1. Upload Slave sketch and open the Serial Monitor-2 (SM2). There is nothing on the SM-2.
2. Upload Master sketch and open SM-1.
3. Observe that SM-1 shows the message: Transmission Done!
4. Observe that the data bytes transmitted from the Master have appeared on SM-2.
5. Press RESET switch of the Master. Observe that events of Step-3 and 4 have happened.

Why don't you evaluate the return code of the function endTransmission?

Having doubts is so much better than knowing?

If there is no error on the master, the data was sent.

Wire.endTransmission()
Description

Ends a transmission to a slave device that was begun by beginTransmission() and transmits the bytes that were queued by write().

As of Arduino 1.0.1, endTransmission() accepts a boolean argument changing its behavior for compatibility with certain I2C devices.

If true, endTransmission() sends a stop message after transmission, releasing the I2C bus.

If false, endTransmission() sends a restart message after transmission. The bus will not be released, which prevents another master device from transmitting between messages. This allows one master device to send multiple transmissions while in control.

The default value is true.
Syntax

Wire.endTransmission()
Wire.endTransmission(stop)
Parameters

stop : boolean. true will send a stop message, releasing the bus after transmission. false will send a restart, keeping the connection active.
Returns

byte, which indicates the status of the transmission:

0:success
** 1:data too long to fit in transmit buffer**
** 2:received NACK on transmit of address**
** 3:received NACK on transmit of data**
** 4:other error**

he I2C Bus transaction is on handshaking scheme; therefore, there is no chance for the missing of any data item. There is no need to insert time delay. You may follow these steps:

  1. Upload Slave sketch and open the Serial Monitor-2 (SM2). There is nothing on the SM-2.
  2. Upload Master sketch and open SM-1.
  3. Observe that SM-1 shows the message: Transmission Done!
  4. Observe that the data bytes transmitted from the Master have appeared on SM-2.
  5. Press RESET switch of the Master. Observe that events of Step-3 and 4 have happened.

@GolamMostafa, I experimented this instruction as you mentioned, while executing this STEP 4 there is nothing on SM -2, but once Press RESET switch of master without opening SM -1 observe on SM - 2 it display the result.

NOTE: Sometimes my SM - 1 and SM - 2, I can open at same time. But sometimes only one SM can
run at a time. SM-1 and SM-2 are at different COM port. I am using Windows 8, Arduino
Version 1.8.5.

NOTE: Sometimes my SM - 1 and SM - 2, I can open at same time. But sometimes only one SM can
run at a time. SM-1 and SM-2 are at different COM port. I am using Windows 8, Arduino
Version 1.8.5.

Are you following the procedure given in reply #22 about how to get two different instances of the ide running to display two independent monitors?

Are you following the procedure given in reply #22 about how to get two different instances of the IDE running to display two independent monitors?

I follow this procedure given in reply #22. I select COM Port 10 for SM-1 it display the MASTER command while Selecting the COM Port 9 for SM-2 the previous serial monitor closes and open recent COM Port 9, It will not display the result.

while Press the reset button on MASTER board (Arduino Mega) without opening and selecting the SM-1 & COM PORT 10. It display the output SLAVE output in COM PORT 9 slave.

When two instances of the Arduino IDE are started, they work independent of each other. Opening a serial monitor with the second one will not close the serial monitor of the first one.

Could you tell us, how do you start a second Arduino IDE ?

Alternatively use a different Serial terminal - there are a few available