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

Moderator: igrr

User avatar
By bjoham
#62808 You can use the RX pin as debug output to the scope/logic analyzer and set its level at strategic points in the code. Emensely valuable when debugging!

A 1-byte request packet is 18 clocks and 6 bytes 63 clocks. When the slave receives the request, it uses clock stretching while calling the callback. The callback fills the buffer and releases the clock. The bytes are sent back to back and the master calls its callback when all data have been received.

Does the level shifter work without power?
User avatar
By Barfoos
#62810 The level shifter is conmnected to the 5V supply and I have connected the GND on both the high- and low-voltage side. I just didn't connect the 3.3V output of the level-shifter to the ESP. Instead, I generate the 3.3 V with a 5V/3.3V breadboard-PSU-thingie.

I have included a picture of my setup. On the left hand side, you can see the Arduino UNO and a display with I2C-adapter on the 5V side of the level shifter. On the right hand side you can see the ESP-01 (I2C disconnected) and the Arduino Nano, which runs as a slave-sender with a different address.
Image

I didn't have a chance to check the other things yet, but I wanted to reply as quickly as possible because it takes quite some time before the posts get approved by the moderators.
/e: cool, this post showed up instantly.
User avatar
By Barfoos
#63044 Hi. I have switched from the ESP-01 to a NodeMCU v3 (D1 SCL, D2 SDA) and finally got the Raspberry to work as a logic level capture-device*.

This should be a fail: http://i.imgur.com/XhHSBsy.png
And this should show a successful transmission: http://i.imgur.com/awGkCHK.png

I wanted to mention that (for some unknown reason) the communication started to randomly succeeded evey 10th or 20th time, and is currently working every 2nd time.

Current setup: Arduino Nano as master, Arduino Uno and NodeMCU as slaves and a Display. The NodeMCU is on the 3V3-side of a level-shifter. And to make sure that it's not the level-shifters fault, the signal from the Nano to the Uno (and the display) goes from the 5V-side of the level-shifter to the 3V3 side and then back again to the 5V side before it reaches the Uno.

The master (nano) requests a byte from each slave (esp, uno) and then writes the char to the first (esp) and second (uno) line of the Display.
The code on the slaves returns a character, that is incremented by 1 every time requestEvent(); is called.

chars sent by ESP
Code: Select alltry1: 1 345 7 9 ; = ?
try2: 1 3 5 7 9 ; = ?
try3: 1 3 5 7 9 ; = ?
try4: 1 3 5 7 9 ; = ?
try5: 1 3 5 7 9 ; = ?

the Uno works perfectly every time:
Code: Select allUno: 123456789:;<=>?@


As you can see, the ESP doesn't just work 50% of the time, but (apart from the "glitch" in the first try) it works every 2nd time.
Tthe ESPs requestEvent() routine is called (the char is incremented) every time, but the communication from the ESP to the master isn't reliable yet.

Code running on the slaves:
Code: Select all#include <Wire.h>
uint8_t i='1';
void setup() {
  delay(3000);
  Serial.begin(9600);  // start serial for output
  Wire.begin(8);        // join i2c bus (address optional for master)
  Wire.onRequest(requestEvent); // register event
  Serial.print("blobb");
}

void loop() {
  delay(100);
}

void requestEvent() {
  Wire.write(i);
  i++;
  if(i=='z'+1) {
    i='1';
  }
}


code running on the master:
Code: Select all#include <Wire.h>
#include <LiquidCrystal_I2C.h>

char c,d;
int i=0;

LiquidCrystal_I2C lcd(0x3F, 16,2);  // Set the LCD I2C address

void setup() {
  delay(2000);
  lcd.begin(16,2); lcd.init(); lcd.backlight(); lcd.home (); //lcd.print("Hello, ARDUINO "); 
  Serial.begin(9600); Serial.println("hallo");
  Wire.begin();
  //Wire.setClock(31000L);
  TWSR |= 3;
}

void loop() {
//  while(!Serial.available()) {
//  }
//  Serial.read(); 

  while(i<16) {
    c = ' ';
    Wire.requestFrom(8, 1);    // request 6 bytes from slave device
    if(Wire.available()) { // slave may send less than requested
      c = Wire.read(); // receive a byte as character
      Serial.println(c);         // print the character
    }
   
    delay(100);
    d = ' ';
    Wire.requestFrom(6, 1);    // request 6 bytes from slave device
    if(Wire.available()) { // slave may send less than requested
      d = Wire.read(); // receive a byte as character
      Serial.println(d);         // print the character
    }

    delay(300);
      lcd.setCursor(i,0);
      lcd.print(c);
      lcd.setCursor(i,1);
      lcd.print(d);
    delay(300);
    i++;
  }
}


/edit: I have included traces of the i2c transmission: http://imgur.com/a/DXa8b
The upper image (~8.5e5 should show a successful transmission, ~4.3e5 should be a fail)


*I had a look at a few different software solutions, but most were complicated and outdated. I now use http://abyz.co.uk/rpi/pigpio/piscope.html
User avatar
By bjoham
#63050 Great pics!
As far as I understand, the transmission is terminated prematurely after 7 clocks in the data transfer. It should be 9 as in the successful transfer.

The transfer is initiated with ADDR 8 (0001000) + R (1) + ACK (0) as it should. Next, the slave takes control of the SDA pin (after the spike). The successful case sends 0x33 (00110011) + NAK (1, end of buffer) whereas the failure is 0x3? (0011001?).

As I don't think a slave can send a STOP signal, my belief is that the master is the origin...

As a side note, you can't expect 100% success on the ESP. Every now and then, it gets busy with other stuff and the slave will mess up the transfer. In the worst case, it happens when SDA or SCL is low which will affect all devices on the bus. The timeout is intended to clean this up but the bus will be "locked" until then. I am not sure whether it's foolproof but my system has been running like a charm.