-->
Page 2 of 3

Re: Esp8266 Multiple i2c buses with wire or other soft i2c

PostPosted: Sun Jan 29, 2017 1:53 pm
by martinayotte
I've look deeper at the core files, and now I understand about this behaviour :

The Wire class is using lower level twi function from core_esp8266_si2c.c, which has the pins variables as global static :
Code: Select allstatic unsigned char twi_sda, twi_scl;

So, it only remember the last value given to the last twi_init() call.

To fix that and having the possibilties to have multiple Wire object, it requires first to remove the static or create a new function twi_setpins(), and then in every Wire methods add code to set those pins number using the values stored in the Write object.

Probably a PR should be submitted for having this fixed forever...

Re: Esp8266 Multiple i2c buses with wire or other soft i2c

PostPosted: Sun Jan 29, 2017 2:03 pm
by GengusKahn
Hi there, I have been using multiple busses with some success...

The call to Wire.Begin(4,5), then init device MySHT.begin(), then Wire.begin(12,13)) init etc...


This is using 2 I2C buses with 2 Arduinos on bus 0 and SHT21 on bus 1...

Code: Select allvoid GetNano(){
int lOop=0;
    New1="";
    hostStringC="";
  delay(50);
  Wire.begin(4,5);            // I2C Bus 0
  delay(20);
  digitalWrite(2, LOW);       // When Set Request To Send Active Slave will refresh data....
  delay(RTSDelay);            // This will make sure the Arduino is in the for loop refreshing data......     
  Wire.beginTransmission(8);
 // yield();
  Wire.requestFrom(8, 6);     // request 6 bytes from slave device #8 bus 0 (Arduino Mini Pro costs £8 for 5 from China)
   while (Wire.available()) { // slave may send more Bytes than requested, embedded Respose Bytes - 8:15
    if(lOop>=2){
    one1 = Wire.read();       // receive a raw byte
    two1 = Wire.read();;
    three1 = Wire.read();
    four1 = Wire.read();
     if(Wire.available()>0){
     char c =  Wire.read();
     hostStringC += c;
     }
    }
  lOop++;
  char c = Wire.read();       // receive a byte as character
  New1+=c;
  }
 Wire.endTransmission();
  delay(25);
  lOop=0;
    New2="";
  hostString2C="";
  Wire.beginTransmission(6);
  Wire.requestFrom(6, 6);     // request 6 bytes from slave device #6 bus 0 (Arduino Mini Pro costs £8 for 5 from China)
   while (Wire.available()) { // slave may send more Bytes than requested, embedded Respose Bytes - 8:15
    if(lOop>=2){
    one12 = Wire.read();        // receive a raw byte
    two12 = Wire.read();;
    three12 = Wire.read();
    four12 = Wire.read();
     if(Wire.available()>0){
     char c =  Wire.read();
     hostString2C += c;
     }
    }
  lOop++;
  char c = Wire.read();       // receive a byte as character
  New2+=c;
  }
 Wire.endTransmission();
  delay(100);


New2=New2.substring(0,2);
if(New2=="A2"){// Very Simple error checking - ignored if missing.........
    four2=four12;
    three2=three12;
    two2=two12;
    one2=one12;
}
 delay(75);
 Wire.begin(12,13);           // I2C Bus 1
 delay(75);
 myHTU21D.begin();
 delay(50);
   Hum = myHTU21D.readCompensatedHumidity();
   Temp = myHTU21D.readTemperature();
   CoUnt++;
   ulMeasCount++;
    if(ulMeasCount>300){ulMeasCount=1;}
   pfTemp[ulMeasCount] = Temp;
   New1=New1.substring(0,2);  // Simple error checking.........
if(New1=="A1" && one1!=255 && four1!=255 ){
   pfVcC =  ESP.getVcc();
   duration1 = "";
   int hr,mn,st;
   st = millis() / 1000;
   mn = st / 60;
   hr = st / 3600;
   st = st - mn * 60;
   mn = mn - hr * 60;
   if (hr<10) {duration1 += ("0");}
   duration1 += (hr);
   duration1 += (":");
   if (mn<10) {duration1 += ("0");}
   duration1 += (mn);
   duration1 += (":");
   if (st<10) {duration1 += ("0");}
   duration1 += (st);
   four=four1;
   three=three1;
   two=two1;
   one=one1;
if(one>=12){SmAlrm=1;sAcnt++;}
if(two>=200){COAlrm=1;cAcnt++;}
/*
Serial.println("|_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_¬");
Serial.print("\r\n0  Device ID Value : ");
Serial.println(New1);
Serial.print("\r\n1 Arduino A0 Value  ");
Serial.print((float(one*20)));
Serial.print(" MilliVolts\r\n2 Arduino A1 Value  ");
Serial.print((float(two*2)/100)); 
Serial.print(" Volts\r\n3 Arduino A2 Value  ");
Serial.print((float(three*2)/100));
Serial.print(" Volts\r\n4 Arduino A3 Value  ");
Serial.print((float(four*2)/100));
Serial.print(" Volts\r\n5 ESPVcc ADC Value  ");
Serial.print(pfVcC/1000, 2);
Serial.print(" Volts\r\n6    SHT21 Humidity ");
Serial.print(Hum);
Serial.print(" RH %\r\n7 SHT21 Temperature ");
Serial.print(Temp);
Serial.print(" Deg C\r\n     Running Time : ");
Serial.print(duration1);
Serial.print("\r\nLoops ");
Serial.print(CoUnt);
Serial.print("\r\nSingle Errors ");
Serial.print(FCoUnt);
Serial.print("\r\nArduino Resets(+2 errors) ");
Serial.println(ReSet);
*/
}else{
    /*
    Serial.println("\r\nError in IIC Retrying.... ");
    Serial.print("\r\nLoops ");
    Serial.println(CoUnt);
    Serial.print("\r\nSingle Errors ");
    Serial.println(FCoUnt);
    Serial.print("\r\nArduino Resets(+2 errors) ");
    Serial.println(ReSet);
    */
    FCoUnt++;
  }
digitalWrite(2, HIGH);      // Set Request idle
}

Re: Esp8266 Multiple i2c buses with wire or other soft i2c

PostPosted: Wed May 31, 2017 1:31 pm
by Vanelo
Hello, try this..

TwoWire Wire1 = TwoWire();
TwoWire Wire2 = TwoWire();

On setup..
Wire1.begin(4,5);
Wire2.begin(12,13);

Re: Esp8266 Multiple i2c buses with wire or other soft i2c

PostPosted: Thu Jun 01, 2017 1:45 pm
by Pablo2048
What @Vanelo suggest will not work. Wire.cpp relies on SDK I2C implementation which uses SDA and SCL lines as static variables, filled in .begin() so it always uses the last ones defined. I'm using this approach:
every time when I need to access (or switch) between wire1 and wire2 I call wireX.begin(y,z); so this local variables are correctly set.