Using ESP8266-01 to communicate to an Arduino (I2C Master-Slave)

Hi,
I used to use AT firmware on the ESP8266 to grab and post data using ThingSpeak. But because of their instability, I'm developping my own firmware, which will send back to the Arduino Strings if the Arduino requests it. In this case, the Arduino Uno is the Master and the ESP the slave.

The problem is that I don't know how to get SCL and SDA pins (I2C) on the ESP8266-01:

Using Rx and Tx pins doesn't seems to work.

There is a similar post here about using ESP as a master and Arduino as a slave: [Solved] ESP8266 to Nano I2C Problems. - Networking, Protocols, and Devices - Arduino Forum

But the guy actually used this line to set the SCL and SDA pins because the ESP is the master:
Wire.begin(0,2);//Change to Wire.begin() for non ESP.

And as my ESP is not the master, I must use this line:
Wire.begin(8); // join i2c bus with address #8

Here is the slave_sender and master_reader examples code in the Wire.h library:

Slave:

#include <Wire.h>

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

void loop()
{
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
  Wire.write("hello "); // respond with message of 6 bytes
  // as expected by master
}

Master:

#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop()
{
  Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

  while (Wire.available())   // slave may send less than requested
  {
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}

I tried to use this line to set SCL and SDA to pin GPIO-0 and GPIO-2:
Wire.pins(0,2);
Wire.begin(8); // join i2c bus with address #8

But I didn't get any response from the ESP.

Do you guys have any suggestion? Thank you.

VindicteN:
Hi,
I used to use AT firmware on the ESP8266 to grab and post data using ThingSpeak. But because of their instability, I'm developping my own firmware, which will send back to the Arduino Strings if the Arduino requests it. In this case, the Arduino Uno is the Master and the ESP the slave.

The problem is that I don't know how to get SCL and SDA pins (I2C) on the ESP8266-01:

Using Rx and Tx pins doesn't seems to work.

There is a similar post here about using ESP as a master and Arduino as a slave: [Solved] ESP8266 to Nano I2C Problems. - Networking, Protocols, and Devices - Arduino Forum

But the guy actually used this line to set the SCL and SDA pins because the ESP is the master:
Wire.begin(0,2);//Change to Wire.begin() for non ESP.

And as my ESP is not the master, I must use this line:
Wire.begin(8); // join i2c bus with address #8

Here is the slave_sender and master_reader examples code in the Wire.h library:

Slave:

#include <Wire.h>

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

void loop()
{
 delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
 Wire.write("hello "); // respond with message of 6 bytes
 // as expected by master
}




Master:


#include <Wire.h>

void setup()
{
 Wire.begin();        // join i2c bus (address optional for master)
 Serial.begin(9600);  // start serial for output
}

void loop()
{
 Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

while (Wire.available())   // slave may send less than requested
 {
   char c = Wire.read(); // receive a byte as character
   Serial.print(c);         // print the character
 }

delay(500);
}




I tried to use this line to set SCL and SDA to pin GPIO-0 and GPIO-2:
**Wire.pins(0,2);**
**Wire.begin(8); // join i2c bus with address #8**

But I didn't get any response from the ESP.

Do you guys have any suggestion? Thank you.

To my Knowledge (I could be ignorant), the Arduino version of the ESP8266 series (GitHub) does not support the ESP as a slave.

What environment are you using on the ESP?

Chuck.

What environment are you using on the ESP?

I'm using the Arduino IDE for the ESP and the Arduino Uno.

chucktodd:
To my Knowledge (I could be ignorant), the Arduino version of the [GitHub - esp8266/Arduino: ESP8266 core for Arduino]ESP8266 series (GitHub)](http://) does not support the ESP as a slave.

Damn, you're right: https://github.com/esp8266/Arduino/issues/1330
I didn't have the idea to look there. Thanks.

Is there another way to communicate between this 2 things?
A guy is working on I2C as a slave but he hasn't finished it yet: http://bbs.espressif.com/viewtopic.php?f=49&t=2092

VindicteN:
I'm using the Arduino IDE for the ESP and the Arduino Uno.

Damn, you're right: https://github.com/esp8266/Arduino/issues/1330
I didn't have the idea to look there. Thanks.

Is there another way to communicate between this 2 things?
A guy is working on I2C as a slave but he hasn't finished it yet: http://bbs.espressif.com/viewtopic.php?f=49&t=2092

Use the ESP as the master, poll the UNO on a regular basis to ask if it wants something. The UNO's OnRequest() event would be waiting with a request. The answer would be in OnReceive().

Chuck.

Thanks, I started to work on that. I just have a last question about it:

void setup() {
  // put your setup code here, to run once:
  // ESP
  Wire.begin(I2CAddressESPWifi);
  Wire.onReceive(readData); //Call a function when Arduino Master send data. 
  Wire.onRequest(sendDataBack); //Call a function when Arduino Master ask for data
}

void loop() {
  // put your main code here, to run repeatedly:
  // Stuff to do with delay(), like displaying on LCD screen, or measuring temperature.
}

What happens if the Arduino Master (ESP here) ask or send data while the loop is running stuff, like displaying or measuring a sensor? There might be a risk of interference?
I see on the slave exemples of the Wire.h library that the void loop is empty (only a delay instruction).

Thank you

VindicteN:
Thanks, I started to work on that. I just have a last question about it:

void setup() {

// put your setup code here, to run once:
 // ESP
 Wire.begin(I2CAddressESPWifi);
 Wire.onReceive(readData); //Call a function when Arduino Master send data.
 Wire.onRequest(sendDataBack); //Call a function when Arduino Master ask for data
}

void loop() {
 // put your main code here, to run repeatedly:
 // Stuff to do with delay(), like displaying on LCD screen, or measuring temperature.
}




What happens if the Arduino Master (ESP here) ask or send data while the loop is running stuff, like displaying or measuring a sensor? There might be a risk of interference? 
I see on the slave exemples of the Wire.h library that the void loop is empty (only a delay instruction).

Thank you

The I2C protocol is designed to handle bus collisions, you just have to check the return codes.

char char cmd[]="CMD:7";
Wire.beginTransmission(slaveid);
Wire.write(cmd);
uint8_t err=Wire.endTransmission();

/*
err will be one of:
 0: success
 2: address NAK, No slave answered
 3: data NAK, Slave returned NAK, did not acknowledge reception of a byte
 4: other error, here is were The Arduino Library sticks any other error.
     like bus_arbitration_lost,
The actual error codes that the TWI hardware can express is found here
C:\Program Files\Arduino\hardware\tools\avr\avr\include\util\twi.h

They are not returned to the user, all are lumped into err=4.  I modified my Wire.h to
return them with a Wire.lastError() call
 
*/
//so better coding would be


char char cmd[]="CMD:7";
uint8_t retryCount=4;
bool success=false;
while(!success&&(retryCount)){
  Wire.beginTransmission(slaveid); 
  Wire.write(cmd);
  uint8_t err=Wire.endTransmission();
  success=(err==0);
  retryCount--;
  if(!success){ 
    delay(1);
    //wait a tiny bit for the 'other' master to complete
    }
  }

if(!success){
  //have a heart attack and Die
  }

Chuck.

That's all I need to know, thank you!

I have done it. See Login