Arduino communication using I2C

I m new to work with arduino.
In my experiment master and slave arduino use I2C for communication. Slave arduino reads temperature from temperature sensor,and writes to Master. But the temperature is not getting displayed on master arduino serial monitor. i used Wire.write(value),hope it writes int value.

I have checked with the temperature sensor,it reads and result is getting displyed on slaves serial monitor.

Master:

#include<Wire.h>
int temp;

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

void loop()
{
Wire.requestFrom(9,2);

while(Wire.available()==0);
{
temp=Wire.read();
Serial.print(temp);
}
delay(100);
}

Slave:

#define ONE_IRE_BUS 2
#include<Wire.h>
#include<DallaTemperature.h>
#include<OneWire.h>

int temp;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup()
{
Serial.begin(9600);
sensors.begin();
Wire.begin(9);
Wire.onRequest(requestEvent);
}

void loop()
{
delay(100);

}

void requestEvent()
{

sensors.requestTemperature();
temp=sensors.getTempCByIndex(0);
Wire.write(temp);
}

please help me, thanks in advance.

A 1 wire bus is not fast. I would recommend you read the temperature continuously and then respond to the request with the last completed value. Otherwise you could get a timeout.
Don’t try and do too much at once, just start by returning a fixed value first.

If you are a beginner why are you using two Arduino anyway. It is a common beginner’s mistake to think you need to use more than one Arduino. Most of the time this is due to not knowing the proper way to do things. You rarely need to use more than one processor.

hi...
I m doing an experiment in which two arduino uno's communicate using I2C protocol. Slave arduino reads temperature from sensor and writes to master arduino. slave uses Wire.write(value).But result is not getting displayed on master's serial monitor.

Checked with temperature sensor,it is reading temperature properly.

Attaching the code,please help.

master code:

#include<Wire.h>
int temp;


void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
Wire.begin(); //activate I2C link

}

void loop() {
  // put your main code here, to run repeatedly:
Wire.requestFrom(9,2); //requesting from slave at address 9

while(Wire.available()==0);
{
temp=Wire.read();
Serial.println(temp);
}
delay(1000);
}

Slave code

#include<Wire.h>
#include<DallasTemperature.h>
#define ONE_WIRE_BUS 2
#include<OneWire.h>

int temp;

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
Wire.begin(9); //activate I2C link
sensors.begin();
Wire.onRequest(requestEvent); //on request from master

}

void loop() {
  
delay(1000);
}


void requestEvent()
{

sensors.requestTemperature():
temp=sensors.getTempCByIndex(0);
Wire.write(temp);
}

Thank u so much sir for your reply.

yes,as you said ,i m new to arduino. i tried using single arduino with different sensors.Now i am doing device to device communication,i have done with master writer/slave receiver(sending integer value).

please tell me how to respond with the last completed value.(if possible coding help)

Please suggest me forums,blogs and other reading materials to acquire more knowledge in this field.

thank u sir

please tell me how to respond with the last completed value

When each sample is compleated you put the reading in a variable. Then when you get the request for data you just send that variable.

assuming you are using the DS18B20

as suggested, move

sensors.requestTemperature();
temp=sensors.getTempCByIndex(0);

into loop()
make temp a global
I would note that you did not alter the resolution and the default is 12bit and takes 750ms
if you review blink without delay, you can let your program run and get the temperature once a second.
as Grumpy_Mike suggested, if you put a fixed value
int testTemp = 562 ; //or some such
can you then get that value to be read on Master ?

as a note, I often use

int testValue = millis() ;

it gives me a reading that will change, but required no external sensors.

Nice write-up. You can also just look at the examples in the IDE

File->Examples-Wire->master reader
File->Examples->Wire->slave sender

to get working code

Thank you Grumpy_Mike and dave-in-nj.

I will try considering your suggestions.

Thank you very much sir for your time.
I am very new to this, definitely I will try considering your suggestions.

@OP
The codes that you have posted are not prepared correctly to keep conformity with the principles of I2C Bus operation. I am writing below these principles which, I hope, you will follow to correct/adjust your codes. Hopefully, you will be able to see correct temperature reading of the DS18B20 sensor on the Serial Monitor of Master (UNO).

1. Check that the setup among UNO, NANO, and DS18B20 is similar to the following diagram.
i2cBusDS18B20.png
Figure-1: Connection diagram among UNO, NANO using I2C Bus

2. We have to create the I2C Bus by including the following lines in the sketch,

#include<Wire.h>
Wire.begin();
//Wire.begin(slaveAddress); for slave

3. Check from Master side that the slave is present by executing the following codes:

Wire.beginTransmission(slaveAddress);
byte busStatus = Wire.endTransmission();
if(busStatus !=0x00)
{
   Serial.print("Slave is absent...!");
   while(1);  //wait for ever
}

4. Master makes request to the Slave to send temperature data which is float data (like 24.75). In response, how many data bytes will the Slave be sending to Master? Is it 2-byte (that's what you have entered in you sketch) or 4-byte. It is 4-byte - why and how? We see later. Let us execute the following code:

Wire.requestFrom(slaveAddress, 4);

After the execution of the above code, the Master waits until all the requested data bytes have arrived into the FIFO of the Master.

5. After the reception of the command of Step-4, the Slave goes out of its loop() function and then enters into the following sub-program (an interrupt context).

void sendEvent(int howMany)
{

}

Let us note down that the above sub-program must be declared in the setup() function by the following

Wire.onRequest(sendEvent();

6. The Slave executes the following codes in the sendEvent() sub-program to place the 4-byte temperature data into its FIFO for onward transmission to the Master.

Wire.write(dataByte0);
Wire.write(dataByte1);
Wire.write(dataByte2);
Wire.write(dataByte3);

7. In the meantime, the data bytes of Step-6 has arrived to the Master. Now, the Master executes the following codes to collect the data bytes from its FIFO into an array named byte dsArray[4];.

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

8. Let us include following codes in the sketch of the Slave to convert the float type temperature data into 4-byte data. I2C Bus is a byte oriented transmission link which demands that we must convert the float number into separate 4-byte data before transmission.

union
{
   float dsTemp;
   byte dsArray[4];

}data;

dataByte0 = data.dsArray[0];
......................................
.....................................
dataByte3 = ds.dsArray[3];

data.dsTemp = temp;    //temp is the float value that you have already acquired

9. At the Master side, carry out the reverse process of Step-8 to get the float value of temperature from the received bytes.

If the adjusted program works, it is fine; else, post them to undergo corrections as needed.

i2cBusDS18B20.png

GolamMostafa:
The codes that you have posted are not prepared correctly to keep conformity with the principles of I2C Bus operation. I am writing below these principles which, I hope, you will follow to correct/adjust your codes. Hopefully, you will be able to see correct temperature reading of the DS18B20 sensor on the Serial Monitor of Master (UNO).

1. Check that the setup among UNO, NANO, and DS18B20 is similar to the following diagram.
i2cBusDS18B20.png
Figure-1: Connection diagram among UNO, NANO using I2C Bus

why resistor is needed between SDA and SCL?

9. At the Master side, carry out the reverse process of Step-8 to get the float value of temperature from the received bytes.

If the adjusted program works, it is fine; else, post them to undergo corrections as needed.

i should declare an array dsArray[4] at master . right?

i will try, if any doubts i will get back to you.
thank you.

blh64:
Nice write-up.

I think it got deleted, it was there a minute ago I'm sure.

neiklot:
I think it got deleted, it was there a minute ago I'm sure.

i about to take print,how it got deleted?

is there any other way to get that information?

yashmb:
i about to take print,how it got deleted?

is there any other way to get that information?

Maybe GolamMostafa deleted it and then posted same or similar in your other thread. You have confused things by running two similar / related threads, I think.

GolamMostafa:
1. Check that the setup among UNO, NANO, and DS18B20 is similar to the following diagram.
i2cBusDS18B20.png
Figure-1: Connection diagram among UNO, NANO using I2C Bus

why resistor between SDA and SCL?

9. At the Master side, carry out the reverse process of Step-8 to get the float value of temperature from the received bytes.

I should declare an array dsArray[4] at master right?

thank u so much.

@GolamMostafa - You've done it again, casting unnecessary confusion and incorrect information here.

Master makes request to the Slave to send temperature data which is float data (like 24.75).

No it is not.
The dta sheet says:-

The temperature data is stored as a 16-bit sign-extended two’s complement number in the temperature register

The Slave executes the following codes in the sendEvent() sub-program to place the 4-byte temperature data into its FIFO for onward transmission to the Master.

While the unique ID from this chip is indeed a 64 bit quantity the temperature measurement is only a 2 byte quantity, see above, so only needs two bytes to send. The data sheet says:-

The resolution of the temperature sensor is user-configurable to 9, 10, 11, or 12 bits, corresponding to increments of 0.5°C,
0.25°C, 0.125°C, and 0.0625°C, respectively. The default resolution at power-up is 12-bit.

Let us include following codes in the sketch of the Slave to convert the float type temperature data into 4-byte data. I2C Bus is a byte oriented transmission link which demands that we must convert the float number into separate 4-byte data before transmission.

Very true but there are no floating point numbers produced by this chip and there is no need to do any floating point arithmetic, even for a Celsius to Fahrenheit conversion. See https://www.youtube.com/watch?v=nROK4cjQVXM for a monologue on the meeting of Celsius with Fahrenheit.

Let us note down that the above sub-program must be declared in the setup() function by the following

You are missing a closing bracket before the ;

why resistor between SDA and SCL?

No these are pull up resistors on each pin to 5V. These are needed for I2C communications.

I should declare an array dsArray[4] at master right?

No, even if he was right about sending 4 bytes, which he is not, then just no.

GolamMostafa:
8. Let us include following codes in the sketch of the Slave to convert the float type temperature data into 4-byte data. I2C Bus is a byte oriented transmission link which demands that we must convert the float number into separate 4-byte data before transmission.

union

{
  float dsTemp;
  byte dsArray[4];

}data;

dataByte0 = data.dsArray[0];
......................................
.....................................
dataByte3 = ds.dsArray[3];

data.dsTemp = temp;    //temp is the float value that you have already acquired

At slave side ,read temperature is stored in dsTemp.
what is there in dsArray[4]?

code writes dataByte[0] to dataByte[3] not dsTemp

getting so many doubts,please help.

@yashmb, do not cross-post. Threads merged.

Note the diagram that GolamMostafa posted is incorrect regarding the series resistor in the data line of the DS18B20. This is not needed and may even stop correct operation of the device. A 1 Wire bus needs a 4K7 pull up resistor on the signal line. That is a resistor between the signal line and +5V.

neiklot:
Maybe GolamMostafa deleted it and then posted same or similar in your other thread. You have confused things by running two similar / related threads, I think.

Yes! I did that, and I am sorry for the inconvenience. However, I reported to the Moderator about the cross-postings of the OP, who had kindly merged the posts; now, we are back together.