I2C Kommunikation mit ESP2688

Guten Tag zusammen,

ich versuche zurzeit eine I2C Kommunikation zwischen einem ESP2688 mit Lua Firmenware und einem Arduino Uno hinzubekommen. Der Uno soll am Ende durch einen Attiny ersetzt werden, daher kann ich den Seriellen Port nicht benutzen.

Habe den Uno mit dem ESP also wie folgt verbunden:

ESP → Uno

GPIO 0 → A4
GPIO 2 → A5
GND → GND

In der Lua Konsole habe ich folgendes eingeben:

> i2c.setup(0, 3, 4, i2c.SLOW)
> i2c.start(0)
> i2c.write(0, "hello")

und auf den Uno habe ich folgenden Sketch aufgespielt:

#include  <Wire.h>

void setup()
{
  Serial.begin(9600);
  
  Wire.begin();
}

void loop()
{
  while(Wire.available())
  { 
    char c = Wire.read();
    Serial.print(c);
  }
  
  delay(500); 
  
}

Allerdings kommt beim Arduino Augenscheinlich nichts an. Er gibt zumindest nichts aus.
Ist es ein Problem, dass der ESP auf 3,3V arbeitet und der Arduino auf 5V oder habe ich einen anderen Denkfehler?

Mit Wire.begin() bist du ein Master. Du musst dich als Slave anmelden wenn du das so machst:

Und dann die Daten explizit an diese Slave Adresse senden!

Ist es ein Problem, dass der ESP auf 3,3V arbeitet und der Arduino auf 5V oder habe ich einen anderen Denkfehler?

Besser einen Pegelwandler dazwischen setzen.

Allerdings kommt beim Arduino Augenscheinlich nichts an.

Kein Wunder!
(Das Programm ist unvollständig)

// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop()
{
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

aus: https://www.arduino.cc/en/Tutorial/MasterWriter

Alles klar. Danke schon mal an beide.
Habe nun beide Scripts "überarbeitet":

Lua Script:

> i2c.setup(0, 3, 4, i2c.SLOW)
> i2c.address(0, 4, i2c.TRANSMITTER)
> i2c.start(0)
> num = i2c.write(0, "Hello")
> print(num)
0
> i2c.stop(0)

und der Arduino Sketch von @combie bzw. https://www.arduino.cc/en/Tutorial/MasterWriter .
Allerdings gibt der ESP auch an, dass er gar nichts auf die Leitung geschrieben hat. Eine Fehlermeldung gibt es leider nicht.

i2c.setup(0, 3, 4, i2c.SLOW)
i2c.start(0)
i2c.address(0, 4, i2c.TRANSMITTER)
inum = i2c.write(0, "Hello")
i2c.stop(0)
print(num)

ungetestet

Prüfe ob i2c.address() glücklich ist.

audacity363:
Ist es ein Problem, dass der ESP auf 3,3V arbeitet und der Arduino auf 5V ... ?

Serenifly:
Besser einen Pegelwandler dazwischen setzen.

Ein Pegelwandler ist die bessere Variante!

Allerdings ist hier dargelegt, daß es auch anders funktionieren kann. Der Mega2560 hat eingebaute 10k Pullup, UNO, ATtiny85 und ATtiny4313 haben meines Wissens keine. Im Zweifel messen, ob an SDA/SCL 5V anliegt.

OK nun funktioniert es mit dem Uno. Die Spannungwandler und die Pullups haben geholfen.
Danke schon einmal dafür.

Allerdings gibt es nun das nächste Problem: Der Attiny85.
Habe mir bereits die Library “TinyWireS” heruntergeladen und den Code dementsprechend angepasst.
Außerdem benutze ich den Leightweight Serial Output auf Pin 3.

Hier also der Code für den Attiny 85:

#include <TinyWireS.h>

int old_val = 0;
void setup()
{
  TinyWireS.begin(4);
  TinyWireS.onReceive(receiveEvent);
  Serial.begin(9600);
  pinMode(4, OUTPUT);
  Serial.println("Los gehts");
}

void loop()
{
  delay(100);
}

void receiveEvent(uint8_t howMany)
{
  int x = TinyWireS.receive();
  Serial.println("Habe etwas");
}

Compilieren und Uploaden tut er auch ohne Probleme und auch das “Los gehts” sehe ich nur dann war’s es das schon wieder.
Hat jemand eine Idee woran es liegen könnte?

Problem 1:

irgendwo im Internet:
remember to call TinyWireS_stop_check(); on the slave mainloop.

Problem 2:
(welches auf dem Fuße folgen wird)
Was meinst du, wofür hier in "void receiveEvent(uint8_t howMany)" das howMany steht?

Problem 3:
Ist ein Puffer angelegt? Groß genug?

Wenn Du die LCD-Sachen durch Serial ersetzt, sollte es bei Dir laufen:

// ATMEL ATtiny4313 (pins_arduino.c)
//
//                   +-\/-+
//      (D 17) PA2  1|    |20  VCC
// RX   (D  0) PD0  2|    |19  PB7 (D  16)  SCL
// TX   (D  1) PD1  3|    |18  PB6 (D  15)
//      (D  2) PA1  4|    |17  PB5 (D  14)  SDA
//      (D  3) PA0  5|    |16  PB4 (D  13)*
// INT0 (D  4) PD2  6|    |15  PB3 (D  12)*
// INT1 (D  5) PD3  7|    |14  PB2 (D  11)*
//      (D  6) PD4  8|    |13  PB1 (D  10)
//     *(D  7) PD5  9|    |12  PB0 (D  9)
//             GND 10|    |11  PD6 (D  8)
//                   +----+
//
// * indicates PWM port

// LCD -
//  1  - GND
//  2  - +5V
//  3  - Poti
//  4  - D0
//  5  - GND
//  6  - D1
//  7  - NC
//  8  - NC
//  9  - NC
// 10  - NC
// 11  - D2
// 12  - D3
// 13  - D4
// 14  - D5
// 15  - +5V
// 16  - GND

#include <LiquidCrystal.h>

//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // Arduino UNO
LiquidCrystal lcd(0, 1, 2, 3, 4, 5);  // ATtiny4313

#define I2C_SLAVE_ADDRESS 0x03 // the 7-bit address (remember to change this when adapting this example)
// Get this from https://github.com/rambo/TinyWire
#include <TinyWireS.h>
// in TinyWireS\usiTwiSlave.h auf 64 Byte geaendert
#ifndef TWI_RX_BUFFER_SIZE
#define TWI_RX_BUFFER_SIZE ( 64 )  // (original 16)
#endif

unsigned int e = 0;  // Eventzaehler

/**
 * The I2C data received -handler
 *
 * This needs to complete before the next incoming transaction (start, data, restart/stop) on the bus does
 * so be quick, set flags for long running tasks to be called from the mainloop instead of running them directly,
 */
void receiveEvent(uint8_t howMany) {
  if (TinyWireS.available() > 0) {                         // returns the number of bytes in the received buffer
    byte a = TinyWireS.receive();      // returns the next byte in the received buffer
    if (a < 16) {
      lcd.setCursor(a, 0);
    } else if (a < 32) {
      lcd.setCursor(a - 16, 1);
    } else {
      lcd.print(a);
    }
  }
}

void setup()
{
  lcd.begin(16, 2);
  lcd.setCursor(3, 1);
  lcd.print("LCD Bereit");
  lcd.setCursor(0, 0);

  TinyWireS.begin(I2C_SLAVE_ADDRESS);
  TinyWireS.onReceive(receiveEvent);
}

void loop()
{
  /**
   * This is the only way we can detect stop condition (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=984716&sid=82e9dc7299a8243b86cf7969dd41b5b5#984716)
   * it needs to be called in a very tight loop in order not to miss any (REMINDER: Do *not* use delay() anywhere, use tws_delay() instead).
   * It will call the function registered via TinyWireS.onReceive(); if there is data in the buffer on stop.
   */
  TinyWireS_stop_check();
}

Danke an euch beiden. Es hat auch funktioniert.
Hatte folgenden Code aufgespielt:

#include <TinyWireS.h>
// in TinyWireS\usiTwiSlave.h auf 64 Byte geaendert
#ifndef TWI_RX_BUFFER_SIZE
#define TWI_RX_BUFFER_SIZE ( 64 )  // (original 16)
#endif

#define I2C_SLAVE_ADDRESS 4

void receiveEvent(uint8_t howMany) 
{
  if (TinyWireS.available() > 0) 
  {
    byte a = TinyWireS.receive();
    Serial.println(a);
  }
}

void setup()
{
  serial.begin(9600);
  TinyWireS.begin(I2C_SLAVE_ADDRESS);
  TinyWireS.onReceive(receiveEvent);
}

void loop()
{
  TinyWireS_stop_check();
}

Es hat auch funktioniert, nur um weiter zu arbeiten hatte ich einige Änderungen gemacht und wollte die neue Version mit dem USBtinyISP aufspielen.
Aber hier: Fehlanzeige. Nach dem Upload bekomme ich nun immer den Fehler:

avrdude: verification error, first mismatch at byte 0x0040
0xcd != 0xde
avrdude: verification error; content mismatch

Am Code kann es nicht liegen, da auch ein einfaches Blink Beispiel sich nicht mehr aufspielen lässt.
Lösungsversuche:

1.) Alle Kabel abgemacht und nur den Attiny versuche zu programmieren.
2.) Einen anderen Attiny probiert.
3.) Rechner neugestartet
4.) Treiber für USBtinyISp neuinstalliert

Es funktioniert nicht mehr. Habe ich mir nun den Programmer zerschossen? Allerdings wüsste ich dann gerne warum. Sehe keinen Grund dafür.

Versorgungsspannung und USBtinyISP gleichzeitig angestöpselt?

Benutze die 5V des USBtiny als Spannungsversorgung.
Also im Grunde Ja.