Chat here about code rewrites, mods, etc... with respect to the github project https://github.com/esp8266/Arduino

Moderator: igrr

User avatar
By Barfoos
#62599 I haven't got it to work yet.
I'm using the example from https://www.arduino.cc/en/Tutorial/MasterReader with an Arduino Uno, but ultimately want to run the master directly on a 328p without the Arduino-stuff.

The ESP8266 and the Uno communicate via a level-shifter, with 4k7 pullup resistors on both lines, on both sides of the level shifter.
I tried lowering the clock rate, but that didn't help.

Current state:
Code: Select all// ESP8266
#include <Wire.h>

void setup() {
  Wire.pins(0, 2); // Select GPIO0 as SDA and GPIO2 as SCL
  Wire.begin(8);                // join i2c bus with address #8
  Wire.setClock(14000L);
  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
}

Code: Select all//Uno
#include <Wire.h>

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

void loop() {
  Serial.println("blobb");
  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);
}


Did I make any obvious mistakes?

/e: Since (at least on the arduino uno) Wire.setClock(); doesn't like values < 14k, I set it to 50k and then set the TWI-prescaler to 4 (TWSR |= 1;), so it should run @ 12.5 kHz. The handheld osciloscope says ~13 kHz, close enough.
I used another Arduino (Nano) instead of the ESP8266, and the data transfer works, even with the level shifter.
Sadly, connecting the ESP to the bus messes up the bus and neither the Nano, nor the ESP8266 respond the master (yes, the slaves have different IDs.)
Last edited by Barfoos on Sat Feb 18, 2017 8:38 am, edited 1 time in total.
User avatar
By bjoham
#62765 @Barfoos: As you have noted, setting the I2C clock through the Wire.setClock() call doesn't help for low frequencies. I did more or less like you did to make sure the Master was sending at low enough speed. (Setting prescaler bits, etc.)

What commit are you using? As I wrote above, only the first commit has been tried on the actual hardware. The other cleanups were made without actual HW trials (only compilation).

Also, I have just tried with one-byte data. Does it work better if you just request 1 byte? (Maybe not the thing, but Wire.write("hello "), isn't that 7 bytes?)

Since you have an oscilloscope, does the SCL line show a proper clock signal? Does the SDA line show the START + ADDR + ACK + DATA + STOP transients? If you have a two-channel scope, it should be easy to see it, but even a one-channel peace should be enough to detect a total failure. Please feel free to send pics showing your signals.

The bus-messup observation of yours could be a key perhaps. That should be easy to spot on a scope. A bus-messup issue should either be noticeable by periods with SCL low (clock stretching) or SDA low (synchronization errors).

In my case, I don't have any extra pullups. The ESP8266 has internal pullups and the equipment I connect to too (Arduino or heat pump). In your case, the pullups shouldn't be needed either and add extra load to the I2C components. What level shifter are you using?

What ESP8266 board are you using? Have you seen https://github.com/esp8266/Arduino/issues/584 where a NodeMCU board's D0 and D2 correspond to GPIO16 and GPIO4, respectively? Also, GPIO16 on the ESP8266 has issues for this use if I remember correctly. Does it work better if you use the default SDA = GPIO4 = D2 and SCL = GPIO5 = D1 pins?
If you're using the ESP8266-01 module, the GPIO0 pin must not be held low during boot to prevent the module from entering bootloader mode.
User avatar
By Barfoos
#62796 I manually copied the source from the first commit into the files created by the the arduino board-manager ( ESP8266 version 2.3.0), since cloning the git resulted in an error. I think it was missing the esptool binary. Come to think about it, this might not have been the best idea.

I have not tried to request only 1 byte. My limited understanding of the Arduino-implementation of I2C is, that requesting 6 bytes is just 6 times requesting one byte. In the code I use each byte should be printed directly after it has been received.
This might also be wrong, I'll have another look at the Arduino-libs.

I have an analog 2ch oscilloscope and a fairly simple handheld 1ch multimeter/DSO. But I have a raspberry that I will turn into a logic analyzer to sniff the bus.

I have tried different configurations of pull up resistors. I started without, then tried them on either and on both sides of the level shifter. The level shifter is a cheap 4 channel eBay thing, with integrated 3.3 V regulator (which I don't use, since it probably couldn't drive the ESP, and transistors makes as JIY, with the Y rotated 90 degrees. Google says this should be Fairchild/On Semi KS1298, IIRC.

I am using the ESP-01, so I am basically limited to the two GPIO-Pins. I might have to check if I could use the RXD and TXD pins while I am not flashing the chip.
And I guess that I can't just solder cables to some of the other pins of the ESP and use those. If I can't make it work, I'll order a bigger version of the ESP with more pins and try again.

Thank you very much for your answer, I'll try to use your advice later today and report back :)