Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP8266 as a I2C slave #5762

Open
6 tasks done
gotfredsen opened this issue Feb 15, 2019 · 34 comments
Open
6 tasks done

ESP8266 as a I2C slave #5762

gotfredsen opened this issue Feb 15, 2019 · 34 comments

Comments

@gotfredsen
Copy link

gotfredsen commented Feb 15, 2019

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: [ESP-12F] XinaBox CW01
  • Core Version: [2.5.0] Latest board file in Arduino
  • Development Env: [Arduino IDE 1.8.8]
  • Operating System: [MacOS ver 12.0.3]

Settings in IDE

  • Module: [Generic ESP8266 Module]
  • Flash Mode: [DOUT]
  • Flash Size: [4MB]
  • lwip Variant: [v2 Lower Memory]
  • Reset Method: [ck]
  • Flash Frequency: [26Mhz]
  • CPU Frequency: [80Mhz]
  • Upload Using: [SERIAL]
  • Upload Speed: [115200] (serial upload only)

Problem Description

While ESP8266(I2C Master) to ESP8266(I2C Slave) works, with a pinch†, I cannot get ESP8266 to work as an I2C Slave towards Raspberry Pi, Micro:Bit and others.

The sketch below works perfectly as an ESP8266 I2C slave used with a ESP8266 I2C Master, but not otherwise.

I can detect‡, the slave on a RPi using i2cdetect -y 1, but can't communicate with the slave. I have tried frequency change, clock stretching in Arduino, 3 different libraries on the RPi, and I have tried in MicroPython on a Micro:Bit to no avail.

† In order to have the ESP8266 Master to work, I have to call the Wire.begin() with an address, like a Master address, that is not standard, but otherwise it won't work for me.
i2cdetect -y 1 only works 80% of the time, and while seemingly high, it is not 100% of the time like with all other I2C slaves.

MCVE Sketch

#include <Wire.h>
void requestEvent() {
  Wire.write("At your service!");
}
void setup() {
  Wire.begin(2,14,0x08);           
  Wire.onRequest(requestEvent);
}
void loop() {
}

Debug Messages

Debug messages go here

More attempts: Just to make sure I haven't lost it, I tried with another WiFi board, the Arduino MKR1000, and the above code (except for the pin allocations), and it worked perfectly.

Here is the RPi code, btw:

import pigpio
pi = pigpio.pi()
handle = pi.i2c_open(1,8,0)
(count, data) = pi.i2c_read_device(handle, 16)
print(data)
pi.i2c_close(handle)
pi.stop()
@pat1
Copy link

pat1 commented Mar 10, 2019

Do you use in your circuit two pull-up resistors?

@gotfredsen
Copy link
Author

I have external pull-up resistors (on SDA and SLC), which in any case I don't believe I need since there is only 2 devices on the bus, 1 master and 1 slave.

@r3na
Copy link

r3na commented Mar 25, 2019

Hi @gotfredsen I have the same issue here. This driver works well between two ESP8266 (e.g. Adafruit HUZZAH ESP8266 Breakout - one being master and the other slave). But it does not work using one ESP8266 and another board (w/ different driver - e.g. Teensy 3.x). Anyone had success using 2 different boards/drivers ? I tried without pull-up resistors, then with (4k7, 2k2, 2k7, 10k) and also with different clocks... No success in any of these cases.

@rousir
Copy link

rousir commented Apr 4, 2019

Hi, Is the problem solved?I have the same issue here. This driver works well between two ESP8266,But it does not work using one ESP8266 and arduino uno

@d-a-v
Copy link
Collaborator

d-a-v commented Apr 4, 2019

per #5226 (comment)

This driver works well between two ESP8266

What is the maximum reachable & sustainable clock frequency between esp8266 hardware i2c master and software i2c slave ?

@jasondickert
Copy link

jasondickert commented Apr 17, 2019

Hi, Is the problem solved?I have the same issue here. This driver works well between two ESP8266,But it does not work using one ESP8266 and arduino uno

I have the same issue. I can get the ESP8266 to work as a master with my Mega2560, but when I flip the roles where the ESP8266 is in slave mode it doesn't appear to respond to either request or receive event. Tried setClock at 50000, 100000, 200000, and 400000. Also, on the same bus I have a PCA9685 that responds to the mega when it's the master with no problem. Using a 5v/3.3v level shifter between the two sides (also skipped that and ran the mega at 3.3v too with no luck).

The ESP8266 in my case is Adafruit's HUZZAH.

Edit: after trolling through the related issue threads here on this topic I'll just stick with using this device and my mega as multi-masters where the esp can spam the mega as needed. Where the mega needs to get something to the esp it can do so when the esp asks (on some polling interval).

@nedoskiv
Copy link

nedoskiv commented Apr 22, 2019

I'm testing esp8266 (wemos DI mini) as slave with esp32 (micropython) as master, as far I can tell, esp8266 receive from ESP32 but cannot sent any data back. Micropython error is:

>>> i2c.readfrom_mem_into(48, 0x14, data)

OSError: [Errno 19] ENODEV
It is I2C timeout/IO error

>> > i2c.writeto_mem(48, 0x04, b'\x00\x00\x01')

execute without problem and my debug on esp8266 slave reports all correctly:

loop1
processevent: 4,0,0,1,

my ESP32 communicate with attiny without any problems.

@schliepi
Copy link

schliepi commented Sep 1, 2019

I have exactly the same issue like thread opener @gotfredsen.

I further investigated with a logic analyzer and sigrok's pulseview app.

From what I see is: esp8266 has - running at 80MHz - not enough performance for receiving at 100kHz with the current implementation.
Even at 160MHz there was no success at 100kHz.
atmega328p works like a charm - it encodes/decodes i2c in hardware. esp8266 does not.

For research I used master_writer and slave_receiver.
I tried two different Wire.begin() followed by Wire.setClock() for master_writer.
Of course for each test case only one steClock-line active

Block A withAddress
Wire.begin(SDA_PIN, SCL_PIN, I2C_MASTER);
//Wire.setClock(50000L); // this results in 30.8kHz - success
//Wire.setClock(100000L); // this results in 40.8kHz - success
//Wire.setClock(400000L); // this results in 58.8kHz - success

Block B noAddress
// patched core_esp8266_sic.cpp to accept setClock(25000L)
Wire.begin(SDA_PIN, SCL_PIN); // join i2c bus (address optional for master)
//Wire.setClock(25000L); // this results in 28.6kHz - success
//Wire.setClock(50000L); // this results in 54.1kHz - no success
//Wire.setClock(100000L); // this results in 90.9kHz - no success
//Wire.setClock(200000L); // this results in 166.7kHz - no success

Hopefully @pasko-zh finds time to finish #2055.

I could attach some screenshots of pulseview for the test cases above, if this is of any interest.

@devyte
Copy link
Collaborator

devyte commented Sep 1, 2019

Unfortunately, @pasko-zh's code is licensed under GPL3, which is incompatible with our repo license. Unless that very nice implementation changes licensing, or we get an explicit exception, we can't integrate it directly here.

@earlephilhower
Copy link
Collaborator

I've looked at @pasko-zh's code, and while it looks really nicely built and organized (best comments in ASM I've seen in a long time), I don't think it really solves the problems here.

From what I read, brzo-i2c is a master-mode only implementation, and it's fully busy-waiting (i.e. 100% of CPU while running). For master transactions, that's probably fine and the most direct way to make it happen. His scope traces look really gorgeous this way!

But on a slave, you need to do IRQ triggered operations or else you can't use the 8266 to do anything else besides busy-waiting (i.e. no wifi, no anything).

The current slave code is slow because it probably spends >50% of its active CPU time in OS IRQ handling code before the ROM calls our IRQ handler (saving processor state, etc.) So it loses edges easily and that limits the slave clock rate it can work at. It also is going to be hit by IRQ disable windows when doing WiFi operations, increasing the required clock cycle for stable operation.

Something that short-circuits the OS IRQ handling and does the slave FSM immediately, with minimal register usage, and which makes the IRQs NMI if possible, might be able to move the needle. Or, a creative (ab)use of the I2S port might be able to do it.

There is a PR #6326 which focused on reducing IRAM usage, but which should also (because of using fewer instructions) run at slightly higher frequencies. @schliepi, would you be able to give it a try and see if it helps in any way (or if it busts slave mode completely)?

@schliepi
Copy link

schliepi commented Sep 3, 2019

Some further investigation later. Is it really OS IRQ handling that slows slave mode down?
Simple test setup how long it takes after input pin signal change until IRQ handler runs:
D1 directly connected to D2. Interrupt attached to D2. When called set lines D5 and D6 low.
So when I set D1 low, I expect some delay, an then D5 and D6 get pulled low.

This is the simple Arduino sketch:

#include <PolledTimeout.h>

#define D1_LOW()   (GPES = (1 << D1)) //Enable D1 (becomes output and since GPO is 0 for the pin, it will pull the line low)
#define D1_HIGH()  (GPEC = (1 << D1)) //Disable D1 (becomes input and since it has pullup it will go high)
#define D1_READ()  ((GPI & (1 << D1)) != 0)
#define D2_READ()  ((GPI & (1 << D2)) != 0)
#define D5_LOW()   (GPES = (1 << D5)) //Enable D5 (becomes output and since GPO is 0 for the pin, it will pull the line low)
#define D5_HIGH()  (GPEC = (1 << D5)) //Disable D5 (becomes input and since it has pullup it will go high)
#define D6_LOW()   (GPES = (1 << D6)) //Enable D6 (becomes output and since GPO is 0 for the pin, it will pull the line low)
#define D6_HIGH()  (GPEC = (1 << D6)) //Disable D6 (becomes input and since it has pullup it will go high)

void ICACHE_RAM_ATTR onD2Change();

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);           // start serial for output
  Serial.println();
  Serial.printf("getChipId     = %08X\n", ESP.getChipId());
  Serial.printf("getCpuFreqMHz = %8d\n", ESP.getCpuFreqMHz());

  pinMode(D1, INPUT_PULLUP);
  pinMode(D2, INPUT_PULLUP);
  pinMode(D5, INPUT_PULLUP);
  pinMode(D6, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(D2), onD2Change, CHANGE);
}

void onD2Change() {
  D5_LOW();
  D6_LOW();
  D5_HIGH();
  D6_HIGH();
}

void loop() {
  // put your main code here, to run repeatedly:
  using periodic = esp8266::polledTimeout::periodicFastMs;
  static periodic nextPing(5);

  if (nextPing) {
    if (D1_READ() == 1) {
      D1_LOW();
    } else {
      D1_HIGH();
    }
  }
}

Measuring with logic analyzer at 24MHz:
Time for D5 going low after D1/D2 going high: 4us.
Time for D6 going low after D5 going low: 80ns.
5762-intr-speed

4us until my code executes in iterrupt?
Am I measuring wrong?
Running at 160MHz the times getting halved.

I read this over at espressif
https://bbs.espressif.com/viewtopic.php?t=360#p1358

We test the normal latency is about 1~1.2us

@earlephilhower
Copy link
Collaborator

IIRC, there's not a separate IRQ vector for each pin change, only one general GPIO IRQ. That pin change IRQ then needs to figure out which callback to call, so I am pretty sure there's a reasonable amount of code being executed before the first insn of our callback gets executed. I would be happy to be proven otherwise, because if it's in our code we can try and do something about it!

A test you can automate would be to use ESP.getCycleCount(). That's an internal 80MHz counter (even when core is at 160) and you can copy it just before writing to GPIO-Set and grab it again right at the top of your callback. Then in the main routine after some hardcoded delay you can do a delta from end-start and get the "speed of light" for IRQs...

@d-a-v d-a-v added this to the 2.6.0 milestone Sep 10, 2019
@Jason2866
Copy link
Contributor

Jason2866 commented Sep 12, 2019

@gemu2015 had problems with i2c too. He found a solution for his driver (for Tasmota)
arendst/Tasmota#6360 (comment)
EDIT: Ignore. Not related!

@devyte
Copy link
Collaborator

devyte commented Oct 29, 2019

CC @Tech-TX
There are some known issues with I2C. I think stability should be improved first before this goes further.
Pushing back.

@devyte devyte modified the milestones: 2.6.0, 2.7.0 Oct 29, 2019
@Tech-TX
Copy link
Contributor

Tech-TX commented Nov 13, 2019

I'll look into it, but if the IRQ response time is 4us then the slave code won't work with most masters. In the spec there's a zero minimum hold time requirement on SDA after SCL falls from the master. That needs a latch to catch reliably. The data won't be there when we eventually read it, if the read is delayed by 4us. I can check it on a 'scope to see what it's doing and get better resolution.

The GPES = (1 << D1) pin wiggles above I already have the definitive timing for:
44ns @ 80MHz, 35.25ns @ 160 from iram, 88ns @ 80MHz, 74ns @ 160 from flash
so all I have to do is add a pin wiggle in the first line of Twi::onSclChange and I can subtract that and tell you exactly how long the response time is to within ~5ns. It's too late tonight, so I'll check it tomorrow.

@Tech-TX
Copy link
Contributor

Tech-TX commented Dec 6, 2019

BTW, the full comment on the Espressif BBS is this:

Re: ESP interrupt latency
Postby netlook » Thu Apr 16, 2015 1:43 pm

We test the normal latency is about 1~1.2us , Now the API "ETS_SPI_INTR_ATTACH(isr_handler, void *)" is directly attached on the interrupt vector.

Note the date. There have been significant changes to the core since 2015. The most recent (this week) test of GPIO interrupt latency with the current core is:

GPIO Interrupt latency at 80MHz, code supposedly in IRAM:
CHANGE = 3.880us, ~310 cycles @ 12.5ns/cycle
RISING = 3.921us, ~314 cycles
FALLING = 3.921us, ~314 cycles

GPIO Interrupt latency at 160MHz, code supposedly in IRAM:
CHANGE = 2.056us, ~329 cycles @ 6.25ns/cycle
RISING = 2.081us, ~333 cycles
FALLING = 2.081us, ~333 cycles

The times are exact +/- 5ns, the 'cycles' are a rough equivalent in machine cycles; the machine cycles aren't exact. Due to the difference @ 80/160, it looks like there's a cache miss somewhere, as that would show greater effect at 160MHz. I tried bumping my D1 Mini boards up to QIO 80MHz and couldn't see any difference, so I guess the core isn't executing that speed init for my flash chips.

@gotfredsen

I have external pull-up resistors (on SDA and SLC), which in any case I don't believe I need since there is only 2 devices on the bus, 1 master and 1 slave.

You always need external pull-up resistors on SDA and SCL if you expect it to run reliably or else you're driving the bus with a sawtooth. Using only the ~50K internal pull-ups in the chip violates the I2C spec on risetime. The only reason the internal pull-ups are even included in the library is because sooo many people don't know anything about I2C. Common values for external pull-up resistors is 4.7K to 10K, even lower if you're running at 400KHz or faster. Most modules include pull-up resistors in the 10K range, which is sufficient for 100KHz bus speeds, and usually works at 400KHz.

@devyte
Copy link
Collaborator

devyte commented Dec 18, 2019

Reducing 2.7.0 scope. This is to be handled as part of the ongoing Wire rework.

@devyte devyte removed this from the 2.7.0 milestone Dec 18, 2019
@Tech-TX
Copy link
Contributor

Tech-TX commented Dec 22, 2019

I have a Pi Zero W that's on it's first boot, and updates are taking forever. I think I can drive the I2C port a couple of different ways. There's some helpful hints regarding RPi and I2C here:
https://www.abelectronics.co.uk/kb/article/1089/i2c--smbus-and-raspbian-stretch-linux
notably that the clock wanders all over the place on the 3B, 3B+ and Zero W, and he has a fix to lock it down. The testing I just did with the slave side shows that the '8266 slave works from ~76KHz down to ~6.5KHz. Go faster and it NAKs, go slower and it looks like the event timer gets a timeout.

Sorry, never seen a Micro:Bit.

You have to compile @ 160MHz CPU speed to get the slave to talk at 50KHz. I haven't tried it yet with an 80MHz CPU compile and slower bus speeds. That's next on my list of Things To Test.
edit: at 80MHz, the slave operates solidly from 39KHz down to ~6.5KHz. It runs erratically from 40-43KHz, not recommended.

I'll have some more info later on. Apparently the Pi hardware supports clock stretching, but the driver doesn't (or didn't). It's hard to tell for sure.

@Tech-TX
Copy link
Contributor

Tech-TX commented Dec 23, 2019

Update: success on the first try. I don't know what you folks are all doing wrong.
I have a fresh install of the bloated Raspbian w/ desktop running on a Pi Zero W. I opened /boot/config.txt and added:
dtparam=12c_arm=on
dtparam=i2c1_baudrate=50000
and then down at the bottom added
core_freq=250
as I didn't want the I2C bus clock wandering (see that link I posted just above)

I popped open a terminal window and ran sudo i2cdetect -y 1, and the Slave_Receiver was seen the first time and every time thereafter at address 0x08, no misses. Getting cocky, I next entered
i2ctransfer 1 w28@0x08 0x01 0x41+
and the slave printed ABCDEFGHIJKLMNOPQRSTUVWXYZ91 on it's terminal monitor on the other computer.
Hmmm. Looks like my Pi user already has i2c privileges, so I didn't need the sudo with i2cdetect.
For someone that hasn't turned on a Linux command prompt since the pre-1.0 Slackware days, it wasn't too hard. I don't know what problems you're having, but it's working for me. Here's screenshots for proof:
RPi
monitor

Hardware: Pi Zero W, and a Wemos D1 Mini connected appropriately with 10K pull-up resistors on SCL and SDA. Latest Raspbian on the Pi with just the distribution files. Arduino 1.8.10 with the git install for the ESP8266 (latest, of course) and the default slave_receiver example program. Nothing special.

@Tech-TX
Copy link
Contributor

Tech-TX commented Dec 24, 2019

I've been looking further, and here's a good breakdown on why people are having problems with the Pi:
http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
Compiling the slave side with a CPU Frequency of 160 MHz should minimize the slave clock stretches, but it won't eliminate them. The only stretches I see are on the ACK of the address, and they're around 150% the normal duration of SCL low. It stretches again about 170% width after the ACK for the address from a Repeated Start (if used). I can't do anything about that without a complete re-write of the slave, which I'm planning now. Don't hold your breath, as blue is probably not a good color for you. 😉

slave stretch

The ESP8266 I2C library is working within the I2C spec even now. The Ras Pi is violating the spec two different ways, and will have problems with numerous other devices that stretch. We can only go so far to fix someone else's broken hardware implementation.

@razzner
Copy link

razzner commented Apr 20, 2020

I trying to communicate through i2c from esp32 to esp8266.
esp32 as master and esp8266 slave.

Probably problem with esp8266, it doesn`t working as slave.

I have no success, maybe someone can help or tried to do that?

@oculos
Copy link

oculos commented Aug 4, 2020

Update: success on the first try. I don't know what you folks are all doing wrong.
I have a fresh install of the bloated Raspbian w/ desktop running on a Pi Zero W. I opened /boot/config.txt and added:
dtparam=12c_arm=on
dtparam=i2c1_baudrate=50000
and then down at the bottom added
core_freq=250
as I didn't want the I2C bus clock wandering (see that link I posted just above)

Hardware: Pi Zero W, and a Wemos D1 Mini connected appropriately with 10K pull-up resistors on SCL and SDA. Latest Raspbian on the Pi with just the distribution files. Arduino 1.8.10 with the git install for the ESP8266 (latest, of course) and the default slave_receiver example program. Nothing special.

Amazing. This works! A few things I also think people should know - hell, I wish I knew before:

  • the devices must be connected to the same ground - so I connected the WeMos D1 to the Pi's ground.
  • I didn't use a pull up resistor at first, and I could still see the slave on the Pi. I had some spare 22k resistors, plugged them, and they work just fine, though I'll buy some 10k resistors for that.

@oculos
Copy link

oculos commented Aug 5, 2020

Hardware: Pi Zero W, and a Wemos D1 Mini connected appropriately with 10K pull-up resistors on SCL and SDA. Latest Raspbian on the Pi with just the distribution files. Arduino 1.8.10 with the git install for the ESP8266 (latest, of course) and the default slave_receiver example program. Nothing special.

@Tech-TX Could you give a hint on what "connected appropriately"? So I imagine you put pull-up resistors on scl and sda, between them and 3.3V, I take it? I tried this, but I'm having lots of trouble to get data transferred. From the pi to the Wemos D1 Mini I get a few packets sent, then a 121 Remote I/O error. From the Wemos to the Pi I never get any data that makes sense.

@rajhlinux
Copy link

I have the same problem, I have a WeMos D1 Mini (ESP8266). In Arduino IDE I am unable to get it work in I2C slave mode. How did some people here made it work in slave mode?

@firtinahg
Copy link

I have also the same problem. I can't run the ESP8266(NodeMCU v3 - 1.0) with CC430 as slave. Reverse of it which CC430 as slave receiver and NodeMCU is master sender I can get all of the chars. However I can't get any character if I use NodemMCU as slave receiver.

@JiriBilek
Copy link
Contributor

JiriBilek commented Jan 5, 2021

Are you sending the right data to the ESP8266? Are you aware that there is a proprietary protocol running on the SPI layer the ESP only recognize?

Edit: Sorry, my answer was not relevant to the question.

@rajhlinux
Copy link

rajhlinux commented Jan 6, 2021 via email

@rajhlinux
Copy link

rajhlinux commented Jan 6, 2021 via email

@JiriBilek
Copy link
Contributor

@rajhlinux Sorry, I was mistaken, I have no experience in I2C slave communication in ESP8266. Please ignore my previous post.

@schliepi
Copy link

schliepi commented Jan 6, 2021

My research further up in this issue showed ESP8266 not being able to catch up to I2C speed 100kHz. When using an Arduino Uno as master and ESP8266 as slave, I had to slow down I2C speed to 25kHz to get it working.

But this resarch was before refactoring of I2C code happened. I cannot say how much better (or worse?) it got.

ESP8266 user interrupt response time to a changing input pin simply is too slow.

@rajhlinux
Copy link

rajhlinux commented Jan 6, 2021 via email

@jasondickert
Copy link

jasondickert commented Jan 6, 2021 via email

@rajhlinux
Copy link

rajhlinux commented Jan 6, 2021 via email

@jonasborn
Copy link

jonasborn commented Feb 15, 2023

For documentation, as I've got it hooked up at the moment:
D1 Mini as master, NodeMCU v2 as slave

`PLATFORM: Espressif 8266 (4.1.0) > NodeMCU 1.0 (ESP-12E Module)
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
PACKAGES: 
 - framework-arduinoespressif8266 @ 3.30101.0 (3.1.1) 
 - tool-esptool @ 1.413.0 (4.13) 
 - tool-esptoolpy @ 1.30000.201119 (3.0.0) 
 - tool-mklittlefs @ 1.203.210628 (2.3) 
 - tool-mkspiffs @ 1.200.0 (2.0) 
 - toolchain-xtensa @ 2.100300.220621 (10.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 37 compatible libraries
Scanning dependencies...
Dependency Graph
|-- Wire @ 1.0`

image

Master

#include <Arduino.h>
#include <Wire.h>
#include <PolledTimeout.h>

#define SDA_PIN D1
#define SCL_PIN D2
const int16_t I2C_MASTER = 0x42;
const int16_t I2C_SLAVE = 0x08;

void setup() {
  Wire.setClock(20000L);
  Serial.begin(9600);
  Serial.println("Master started");
  Wire.begin(SDA_PIN, SCL_PIN, I2C_MASTER);
}

byte x = 0;

void loop() {
  using periodic = esp8266::polledTimeout::periodicMs;
  static periodic nextPing(1000);

  if (nextPing) {
    Serial.println("Ping");
    Wire.beginTransmission(I2C_SLAVE);
    Wire.write("x is ");
    Wire.write(x);
    Wire.endTransmission();
    x++;
  }
  delay(100);
}

Slave

#include <Arduino.h>
#include <Wire.h>

#define SDA_PIN D1
#define SCL_PIN D2
const int16_t I2C_MASTER = 0x42;
const int16_t I2C_SLAVE = 0x08;

void requestEvent() {
  Serial.println("Req");
}

void receiveEvemt(int a) {
  Serial.println("Rec");
}

void setup() {
  Serial.begin(9600);
  Serial.println("Started");
  Wire.begin(SDA_PIN, SCL_PIN, I2C_SLAVE); 
  Wire.onRequest(requestEvent);
  Wire.onReceive(receiveEvemt);
}

void loop() {
  delay(100);
}

Setting down the clock using
Wire.setClock(20000L);
was needed to get it working. Other clock times were not tested.

Without setting the clock:
image

Build was done using PlatformIO 3.0.0 (2023-02-01) on Ubuntu KDE 20.04.5 LTS
Edit: Formatting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests