-->
Page 3 of 4

Re: Demo sketch esp8266->I2C>Arduino

PostPosted: Mon Oct 26, 2015 3:35 pm
by Erni
Let me know if you like me to post the hole code for esp and arduino.


That would be a good idea

Re: Demo sketch esp8266->I2C>Arduino

PostPosted: Tue Oct 27, 2015 3:44 am
by bogdanioanliviu
Here is the code for the master ESP-01
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>
#include <PubSubClient.h>


const char* ssid = "HouseNetwork";
const char* password = "password";
const char* mqtt_server = "192.168.1.39";
//ESP8266WebServer webserver(80);
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
char valoare[20];

//int value = 0;
#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
  setup_wifi();
  Serial.println("");
  Serial.println("WiFi connected");
  delay(100);
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  //webserver.on("/", handleRoot);
  //webserver.onNotFound(handleNotFound);
  //webserver.begin();
  //Serial.println("Web server has started on: ");
  Serial.print(WiFi.localIP());
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    setPin();
    //digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    getValue();
    //digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.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;
  String valprimit;
  Wire.requestFrom(SlaveDeviceId, 2);
  receivedValue =  Wire.read() << 8 | Wire.read();// combine two bytes into integer
  valprimit = String(receivedValue);
 
  valprimit.toCharArray(valoare, 20);
  client.publish("outTopic", valoare);
  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;
  String valprimit = "";
  //String c = "";
  Wire.requestFrom(SlaveDeviceId, 2);
  receivedValue1 = Wire.read() << 8 | Wire.read(); // combine two bytes into integer
  /*byte b[2];
  //if ( Wire.available()) {
    b[0] = Wire.read();
    b[1] = Wire.read();
    //receivedValue1 = Wire.read();
    //receivedValue1 = receivedValue1 << 8;
    //receivedValue1 |= Wire.read();
  }
  receivedValue1 = (b[0]);*/
  valprimit = String(receivedValue1);
  valprimit.toCharArray(valoare, 20);
  client.publish("outTopic", valoare);
  int error = Wire.endTransmission();
 
  return receivedValue1;
}



And this is the code for the arduino mini 5V Slave
Code: Select all//http://www.berryjam.eu/2014/07/advanced-arduino-i2c-communication/
// (c) 2014 Ignas Gramba
//
#include <Wire.h>
#include <SoftwareSerial.h>

#define SensorPin 0
#define ledPin 13
SoftwareSerial esp8266(2,3);
const byte SlaveDeviceId = 9;
byte LastMasterCommand = 0;
byte state = 0;

void setup() {
  Serial.begin(9600);
  esp8266.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);
  //if ( esp8266.available() )   
  //{ 
  //  Serial.write( esp8266.read() ); 
  //}
  //float temp = (analogRead(SensorPin)*5/1024.0) - 0.5;
  //temp = temp / 0.01;
  //Serial.println((int)temp);
}

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 = getValue();
      Serial.print("returnValue este:"); Serial.println(returnValue);
      byte b[2];
      b[0] = returnValue >> 8;
      Serial.println(b[0]);
      b[1] = returnValue & 0xFF;
      Serial.println(b[1]);
      Wire.write(b, 2);
      //Serial.print(b[0]);
      //Serial.print(b[1]);
      //Serial.print(b[2]);
      LastMasterCommand = 0;
      break;}

    case 8: {  // Return Y sensor value
      returnValue = setPin();
      byte buffer[2];
      buffer[0] = returnValue >> 8;
      buffer[1] = returnValue & 0xff;
      Wire.write(buffer, 2);
      Serial.print(buffer[0]);
                // null last Master's command
      break;}
  }
LastMasterCommand = 0;
 
}

int getValue() {
  float val1 = analogRead(SensorPin);
  val1 = (val1*5/1024.0) - 0.5;
  val1 = val1 / 0.01;
  int val = (int) val1;
  //int val = 22;
  //Serial.println((int)val);
  //val = (val - .5) * 100;
  //int val = analogRead(SensorPin);
  return val;
}

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


As it is it will return the correct value when i send a value of 1 and call getPin() but it is not returning correct value when i send value other values and call getValue()
On the arduino i use a fix value of 22 on the outTopic i see a value of 63 for example.
Thank you for you're help.

Re: Demo sketch esp8266->I2C>Arduino

PostPosted: Tue Oct 27, 2015 5:46 am
by Erni
First of all it is not a good idea to use serial.prints in ISR() routines
And the slavesRespond is such an ISR()
So If I remove the Serial.prints and the calculations from that routine it works, meaning that I get a result from case 1:
getValue(); between 0 and 1023 on the ESP8266 master.
I am using a potmeter on the slave arduino connected to pin A0.

I can't test the master code as I have no idea about MQTT

So I would recommend that you read the value from the slave and do the calculations on the master side.
Here is the code that works:

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

#define SensorPin 0
#define ledPin 13
SoftwareSerial esp8266(2,3);
const byte SlaveDeviceId = 9;
byte LastMasterCommand = 0;
byte state = 0;

void setup() {
  Serial.begin(9600);
  esp8266.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);
  //if ( esp8266.available() )   
  //{ 
  //  Serial.write( esp8266.read() ); 
  //}
  //float temp = (analogRead(SensorPin)*5/1024.0) - 0.5;
  //temp = temp / 0.01;
  //Serial.println((int)temp);
}

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 = getValue();
      break;

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

  byte buffer[2];
      buffer[0] = returnValue >> 8;
      buffer[1] = returnValue & 0xff;
      Wire.write(buffer, 2);
      Serial.print(buffer[0]);
             
LastMasterCommand = 0;
 
}

int getValue() {
  int val = analogRead(SensorPin);
 // val1 = (val1*5/1024.0) - 0.5;
 // val1 = val1 / 0.01;
 // int val = (int) val1;
  //int val = 22;
  //Serial.println((int)val);
  //val = (val - .5) * 100;
  //int val = analogRead(SensorPin);
  return val;
}

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

Re: Demo sketch esp8266->I2C>Arduino

PostPosted: Tue Oct 27, 2015 7:25 am
by bogdanioanliviu
Hy
Using the code you put i get this results :

i call getpin() from esp and returned value is correct 0 or 1
but Serial.print(buffer[0]); will always be 0 ????

if i call getvalue() from esp it will return 127 or 255 as value
again Serial.print(buffer[0]); will display 0

the read value from A0 it is somethig like this:
167
161
0185
0186
0173
0180
0188
0185
0174
0181
0175
0183
0184
The 0 it is from Serial.print(buffer[0]);
can it be that the buffer has to be bigger ?
why is Serial.print(buffer[0]); always 0