-->
Page 1 of 4

Demo sketch esp8266->I2C>Arduino

PostPosted: Thu Sep 17, 2015 11:22 am
by Erni
Hi,
I have been trying to make ESP-01 talk to an Arduino via I2C, and it is almost succesfull.
The reason why this could be a good idea is that you get 6 analog inputs and a lot of digital pin's
In this webserver there are two functions.
One toggles the Led on pin 13 and the other reads the analog value on A1.
It works almost, but for some reason if you click the pin toogle you get the analog value, but only the first time.
The next click gives the right value.

Maybe someone can see the error ?

Code: Select all//I2c code from: http://www.berryjam.eu/2014/07/advanced-arduino-i2c-communication/
// (c) 2014 Ignas Gramba
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <Wire.h>

ESP8266WebServer webserver(80);

#define SlaveDeviceId 9
int value;
int pinValue;

void handleRoot() {
  String arg0 = String(webserver.arg(0));
  String arg1 = String(webserver.arg(1));
  if (webserver.arg(0) == "1") {
    pinValue = setPin(); // slave toggles led
  }

  if (webserver.arg(0) == "2") {
    value = getValue(); // slave reads analog
  }
  String val = String(value);
  String pin = String(pinValue);
  String htmlDoc = "<!DOCTYPE html>";
  htmlDoc += "<html>";
  htmlDoc += "<head>";
  htmlDoc += "<title>TWI . Demo</title>";
  htmlDoc += "</head>";
  htmlDoc += "<body>";
  htmlDoc += "<br>Toggle led <a href='/?led=1'>click</a><br>";
  htmlDoc += "<br>Raed analog value <a href='/?led=2'>click</a><br>";
  htmlDoc += "<br>";
  htmlDoc += "pinStatus=" + pin + "  Analog value=" + val;
  htmlDoc += "<br>";
  htmlDoc += "</body>";
  htmlDoc += "</html>";
  webserver.send(200, "text/html", htmlDoc);
}

void handleNotFound() {
  webserver.send(404, "text/plain", "Page not found ...");
}

void setup() {
  Serial.begin(115200);
  Wire.begin(0, 2);       // join i2c bus sda,scl
  delay(10);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  WiFi.begin("xxx", "yyyyy");
  delay(100);
  webserver.on("/", handleRoot);
  webserver.onNotFound(handleNotFound);
  webserver.begin();
  Serial.println("Web server has started on: ");
  Serial.print(WiFi.localIP());
}

void loop() {
  webserver.handleClient();
}

int setPin() {
  Wire.beginTransmission(SlaveDeviceId);
  Wire.write(8); // Transfer command ("8") to set pin command
  delay(100);
  // GET RESPONSE
  int receivedValue = 0;
  Wire.requestFrom(SlaveDeviceId, 2);
  receivedValue =  Wire.read() << 8 | Wire.read(); // combine two bytes into integer
  int error = Wire.endTransmission();
  Serial.println(error);
 // Serial.print(" Setpin= ");
 // Serial.println(receivedValue);
  return receivedValue;
}

int getValue() {
  Wire.beginTransmission(SlaveDeviceId);
  Wire.write(1); // Transfer command ("1") to get X sensor value;
  delay(100);
  // GET RESPONSE
  int receivedValue1 = 0;
  Wire.requestFrom(SlaveDeviceId, 2);
  receivedValue1 = Wire.read() << 8 | Wire.read(); // combine two bytes into integer
  int error = Wire.endTransmission();
  //Serial.println(error);
 // Serial.print(" Analog= ");
 // Serial.println(receivedValue1);
  return receivedValue1;
}


Edit:
And this is the sketch for the slave running on a 3.3V Arduino

Code: Select all//http://www.berryjam.eu/2014/07/advanced-arduino-i2c-communication/
// (c) 2014 Ignas Gramba
//
#include <Wire.h>

#define SensorPin 1
#define ledPin 13

const byte SlaveDeviceId = 9;
byte LastMasterCommand = 0;
byte state = 0;

void setup() {
  //Serial.begin(115200);
  Wire.begin(SlaveDeviceId);      // join i2c bus with Slave ID
  Wire.onReceive(receiveCommand); // register talk event
  Wire.onRequest(slavesRespond);  // register callback event
  pinMode(SensorPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  delay(100);
}

void receiveCommand(int howMany) {
  LastMasterCommand = Wire.read(); // 1 byte (maximum 256 commands)
}

void slavesRespond() {
  int returnValue = 0;

  switch (LastMasterCommand) {
    case 0:   // No new command was received
      Wire.write("NA");
      break;

    case 1:   // Return X sensor value
      returnValue = GetXSensorValue();
      break;

    case 8:   // Return Y sensor value
      returnValue = setPin();
      break;
  }

  byte buffer[2];
  buffer[0] = returnValue >> 8;
  buffer[1] = returnValue & 255;
  Wire.write(buffer, 2);
  LastMasterCommand = 0;          // null last Master's command
}

int GetXSensorValue() {
  int val = analogRead(SensorPin);
  //int val = analogRead(SensorPin);
  return val;
}

int setPin() {
  state = !state;
  digitalWrite(ledPin, state);
  return state;
}

Re: Demo sketch esp8266->I2C>Arduino

PostPosted: Thu Oct 08, 2015 11:13 am
by frippe75
I THINK you need to end transmission in-between write and the receive part.

From the doc:
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.

Code: Select allint setPin() {
  Wire.beginTransmission(SlaveDeviceId);
  Wire.write(8); // Transfer command ("8") to set pin command
  Wire.endTransmission();  // Moved up here by frippe75
  delay(100);
  // GET RESPONSE
  int receivedValue = 0;
  Wire.requestFrom(SlaveDeviceId, 2);
  receivedValue =  Wire.read() << 8 | Wire.read(); // combine two bytes into integer
  Serial.println(error);
 // Serial.print(" Setpin= ");
 // Serial.println(receivedValue);
  return receivedValue;
}

Re: Demo sketch esp8266->I2C>Arduino

PostPosted: Thu Oct 08, 2015 12:17 pm
by Erni
That's it :D

Thank you very much frippe75
Now it works as expected.

Maybe it could be useful to others so here is the corrected sketch for the master ESP8266:

Code: Select all//I2c code from: http://www.berryjam.eu/2014/07/advanced-arduino-i2c-communication/
// (c) 2014 Ignas Gramba
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <Wire.h>

ESP8266WebServer webserver(80);

#define SlaveDeviceId 9
int value;
int pinValue;

void handleRoot() {
  String arg0 = String(webserver.arg(0));
  String arg1 = String(webserver.arg(1));
  if (webserver.arg(0) == "1") {
    pinValue = setPin(); // slave toggles led
  }

  if (webserver.arg(0) == "2") {
    value = getValue(); // slave reads analog
  }
  String val = String(value);
  String pin = String(pinValue);
  String htmlDoc = "<!DOCTYPE html>";
  htmlDoc += "<html>";
  htmlDoc += "<head>";
  htmlDoc += "<title>TWI . Demo</title>";
  htmlDoc += "</head>";
  htmlDoc += "<body>";
  htmlDoc += "<br>Toggle led <a href='/?led=1'>click</a><br>";
  htmlDoc += "<br>Raed analog value <a href='/?led=2'>click</a><br>";
  htmlDoc += "<br>";
  htmlDoc += "pinStatus=" + pin + "  Analog value=" + val;
  htmlDoc += "<br>";
  htmlDoc += "</body>";
  htmlDoc += "</html>";
  webserver.send(200, "text/html", htmlDoc);
}

void handleNotFound() {
  webserver.send(404, "text/plain", "Page not found ...");
}

void setup() {
  Serial.begin(115200);
  Wire.begin(0, 2);       // join i2c bus sda,scl
  WiFi.begin("xxx", "yyyyy");
  delay(10);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  delay(100);
  webserver.on("/", handleRoot);
  webserver.onNotFound(handleNotFound);
  webserver.begin();
  Serial.println("Web server has started on: ");
  Serial.print(WiFi.localIP());
}

void loop() {
  webserver.handleClient();
}

int setPin() {
  Wire.beginTransmission(SlaveDeviceId);
  Wire.write(8); // Transfer command ("8") to set pin command
  Wire.endTransmission();  // Moved up here by frippe75
  delay(100);
  // GET RESPONSE
  int receivedValue = 0;
  Wire.requestFrom(SlaveDeviceId, 2);
  receivedValue =  Wire.read() << 8 | Wire.read(); // combine two bytes into integer
  int error = Wire.endTransmission();
  Serial.println(error);
  return receivedValue;
}

int getValue() {
  Wire.beginTransmission(SlaveDeviceId);
  Wire.write(1); // Transfer command ("1") to get X sensor value;
  Wire.endTransmission();  // Moved up here by frippe75
  delay(100);
  // GET RESPONSE
  int receivedValue1 = 0;
  Wire.requestFrom(SlaveDeviceId, 2);
  receivedValue1 = Wire.read() << 8 | Wire.read(); // combine two bytes into integer
  int error = Wire.endTransmission();
 
  return receivedValue1;
}

Re: Demo sketch esp8266->I2C>Arduino

PostPosted: Thu Oct 22, 2015 10:59 pm
by Thomas14
Hi!
I just tried to implement this, but it didn't worked very well. Uploading on Arduino and ESP8266 wasn't a problem. I connected GPIO 0 to A5 and GPIO 2 to A4. But the ESP8266 didn't appear as an AP at all. That's the output of the Serial Monitor from the ESP8266:

Code: Select all.........................................................................................................
Exception (0):
epc1=0x40201540 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont
sp: 3ffeb030 end: 3ffeb210 offset: 01a0

>>>stack>>>
3ffeb1d0:  00000000 00000000 00000000 00000000 
3ffeb1e0:  00000000 00000000 00000000 3ffeb23c 
3ffeb1f0:  3fffdc20 00000000 3ffeb234 40201cbf 
3ffeb200:  00000000 00000000 3ffea1f0 40100378 
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,7)

load 0x4010f000, len 1264, room 16
tail 0
chksum 0x42
csum 0x42
~ld
................................................................................................................................................................
 ets Jan  8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x4010f000, len 1264, room 16
tail 0
chksum 0x42
csum 0x42
~ld


Do you have an idea what might be the problem?

Thanks!

Thomas