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

I2C Slave not implemented #118

Closed
Curclamas opened this issue Jan 5, 2017 · 58 comments · Fixed by #5746
Closed

I2C Slave not implemented #118

Curclamas opened this issue Jan 5, 2017 · 58 comments · Fixed by #5746
Assignees
Labels
Area: Peripherals API Relates to peripheral's APIs. Status: Solved
Milestone

Comments

@Curclamas
Copy link
Contributor

Curclamas commented Jan 5, 2017

Description

It seams that the I2C slave functionality from the Arduino Wire Lib is not implemented.

Code example

#include <Wire.h> 

void setup() 
{ 
 Wire.begin(0x03);
 Wire.onRequest(requestEvent);
} 

void loop() 
{ 
 delay(10); 
} 

void requestEvent() 
{
 Wire.send(0x13);
}

Error occured during compilation

exit status 1
'class TwoWire' has no member named 'onRequest'

EDIT: Fixed errror message.

@Curclamas Curclamas changed the title I2C Slave implementation I2C Slave not implemented Jan 11, 2017
@gryzli133
Copy link

did you find a solution for that issue?

@copercini copercini added the Status: To be implemented Selected for Development label Aug 27, 2017
@marcolettieri
Copy link

no news? i've done with esp-idf but arduino way is simpler and clearer

@lbernstone
Copy link
Contributor

@stickbreaker is working on slave I2C (https://github.com/stickbreaker/arduino-esp32/tree/master/libraries/Wire). Not sure where he is at with it, but development is active.

@marcolettieri
Copy link

marcolettieri commented May 14, 2018 via email

@Nightreaver
Copy link

Updates?

@stickbreaker
Copy link
Contributor

I've got a working Slave mode, but I am still working through coexistence with Master mode. Slave mode on ESP32 has to call onRequest() before the Slave is addressed. So the outbound data is always stale. Currently Slave mode exists in a separate task, and I haven't decide on the 'correct' design to refresh this data:

  • never
  • every time onReceive() activates
  • manually controlled by application
  • every time a Master transactions supplant Slave mode.
  • so some combination of all of these.

It is base on a re-implementation of Wire() that is designed for multi-tasking support Multiple Wire() objects are create, each Object is designed as single threaded, The multiple Wire() Objects are safely multi-threaded and share the hardware. But, the Application must transactionalize their access if necessary. The transaction locking with MUTEX's can be abused to cause deadlocks. The 'simple' Arduino 'it just work' philosophy is tough to implement with complex interactions.

Chuck.

@Zhairgling
Copy link

Hi @stickbreaker , Any news ?
Can you share code ?
Thanks

@canDry
Copy link

canDry commented Jul 25, 2019

BUMP! Anyone have a slave receive solution/fix/workaround?

@nockieboy
Copy link

BUMP! Surely there must be enough demand for this feature to warrant some serious development from those that know how?

@dpharris
Copy link

Update? How can we help?

@JAICHANGPARK
Copy link

Any Update This issues?
I'd like to use I2C Slave mode with arduino uno

@ameer1234567890
Copy link

@JAICHANGPARK i2c slave does work on the Arduino Uno. This issue is for ESP32.

@JAICHANGPARK
Copy link

@ameer1234567890 I already know.
I mean that I hope to use Esp 32 Slave Mode using arduino IDE

@yeckel
Copy link

yeckel commented Nov 6, 2019

Any updates? Or example how to workaround that issue?

@Tom5051
Copy link

Tom5051 commented Nov 21, 2019

Please help, I also need to use an ESP32 in slave mode but get this error:
(.literal._Z5setupv+0x8): undefined reference to `TwoWire::onReceive(void (*)(int))'

@stickbreaker
Copy link
Contributor

@Tom5051 @yeckel No updates yet, I have a proof of concept, but it is not ready for prime time, (It requires a major change of existing code). Possibly Spring 2020 I might have code is releasable.

Chuck.

@netkruzer
Copy link

Thanks for your efforts Chuck. Another bump for i2c as a slave mode when you have a chance. Would be really useful.

@stickbreaker
Copy link
Contributor

@netkruzer Not ready yet. It's not yet code that I want my name attached to. And, I do not want to even think of supporting it as is.

Chuck.

@ellensp
Copy link

ellensp commented Mar 16, 2020

Darn, I'm also wanting this feature..

@zamorae
Copy link

zamorae commented Apr 21, 2020

@stickbreaker Hi Chuck. Any date in the foreseeable future that you can provide to have a release of the I2C solution for ESP32? I have been dreaming for a while to use it for some projects I have. Let us know!

Thanks
-zamorae

@ameer1234567890
Copy link

It was reported on #1697 by @laercionit that "Someone had succeeded in putting as SLAVE?" Any details on this?

@laercionit
Copy link

I couldn't ... I don't think TwoWire is ready for that.

@gutierrezps
Copy link

gutierrezps commented Jun 17, 2020

I have made a workaround library not based on interrupts, but based on the only two slave methods currently available from ESP-IDF.

https://github.com/gutierrezps/ESP32_I2C_Slave

@me-no-dev me-no-dev moved this from Assigned to Seeking Contributors in (Archived) Arduino Core ESP32 RoadMap Jul 16, 2021
@VojtechBartoska VojtechBartoska added this to the 2.0.1 milestone Jul 29, 2021
@VojtechBartoska VojtechBartoska moved this from To-Do (Seeking Contributors) to 2.0.1 release in (Archived) Arduino Core ESP32 RoadMap Jul 29, 2021
@SuGlider SuGlider assigned SuGlider and unassigned SuGlider Aug 18, 2021
@SuGlider SuGlider self-assigned this Aug 28, 2021
@VojtechBartoska VojtechBartoska moved this from 2.0.1 release to To-Do (Seeking Contributors) in (Archived) Arduino Core ESP32 RoadMap Sep 8, 2021
@me-no-dev me-no-dev assigned me-no-dev and unassigned SuGlider Sep 20, 2021
@me-no-dev
Copy link
Member

If you are still interested, I2C Slave is on the way: #5746

@JAICHANGPARK
Copy link

@me-no-dev awesome

@zalexua
Copy link

zalexua commented Oct 11, 2021

Interesting - will it be proper implementation using ESP32 hardware or some workaround on software level?

@ianr34
Copy link

ianr34 commented Oct 11, 2021

Yep - still very interested in having the esp32 as a slave - and it to be able to get a read request, then live get data and send it back - without polling etc etc. ie what the 328P can easily do.. It really should have been able to do it on the first release - as I said above, at least the serial port guys did it right...

OK, it is calling i2c_slave_attach_callbacks - which sounds promising.

It's in esp32-hal-i2c-slave.h

esp_err_t i2c_slave_attach_callbacks(uint8_t num, i2c_slave_request_cb_t request_callback, i2c_slave_receive_cb_t receive_callback, void * arg);

Which goes to https://github.com/espressif/arduino-esp32/blob/951c32056a562b08da956503db186fd4bd2f019c/cores/esp32/esp32-hal-i2c-slave.c

Which looks like it is doing something similar to the uarts - ie interrupts and queues, using some things I didn't know existed to do some of the i2c stuff ie
https://esp-idf-lib.readthedocs.io/en/latest/groups/i2cdev.html

This call looks interesting too i2c_ll_write_txfifo (out of components/soc/src/esp32/include/hal/i2c_ll.h)

So prob my fault, but I hadn't know some of these calls existed.. But using what's about to be committed as an example it looks like we might be able to write what is needed!
It will be interesting to see the speed it goes at given a fair bit is in software.

@me-no-dev
Copy link
Member

So... the ESP32 I2C peripheral does not support clock stretching when in Slave Mode. Therefore, by the time that you get the event and fill the fifo, transaction has already been started and if there were bytes in the FIFO, those would have started sending, else NACK has been sent.

What you ask for DOES work on ESP32-S2 and onward, but not on ESP32.

@ianr34
Copy link

ianr34 commented Oct 11, 2021

OK, so you are saying that the esp32 won't be supporting the full i2c slave model - but the s2 onwards will. That's grreat, as I could move to the s2 for the slave, and will prob be going to the s3 generally anyway (more pins!) - price willing.

Of course, I could just write a bit banging slave for the esp32 - looking at the above code late last night I was assuming that was what you had half done, otherwise you can't support Wire.onRequest(requestEvent); - as it of course generates the bytes to be returned to the master..

So is the above code only for the -s2 and onwards?

@me-no-dev
Copy link
Member

it work on all chips, but on ESP32 it just behaves a bit differently. You need to pre-load the data that the master will be able to read. ESP32 as master is also not liking having the clock stretched for too long. Let's say you use S2 as Slave and ESP32 as Master. The slave needs to handle the onRequest as fast as possible to ensure that the ESP32 will not give up waiting for the clock to stop stretching.

@ianr34
Copy link

ianr34 commented Oct 12, 2021

yes, so it doesn't work on the esp32.

Preloading the data IS the core issue and has been since the esp32 was released - preloading is no good for many many many things. No point the master getting data that might be very old..

And yes, onRequest (or whatever it is called as I don't use the ardunio wire library) is always done fast. Typically you just copy the data from somewhere safe, and then exit. You never do any work in it...

@me-no-dev
Copy link
Member

I would not call it that big of an issue really... you can use one GPIO on the Slave to signal that there is new data (like many sensors work) and then release the IO in onRequest

@ianr34
Copy link

ianr34 commented Oct 12, 2021

you're making a lot of assumptions with that ie 1) that there is a pin free (A real big problem..), 2) that you want the master interrupt driven (I agree sometimes useful), and 3) it might be the master knows when it wants a value, not the slave, and then (of course) it wants the most recent one. ie at times you want the master to be the master..

I'm putting another device into a product now that has interrupt pins, and I can i2c read it. I'm not using the interrupt pins.

@me-no-dev
Copy link
Member

I'm giving you options. not making assumptions :D
ESP32 will not be able to magically start stretching out of this conversation. This is what the hardware can offer. There are other peripherals as well ;) and other chips that can do it. Even with this limitation, you can do almost anything.

@ianr34
Copy link

ianr34 commented Oct 12, 2021

I'm just glad you fixed the hardware with the later versions - as it was a mistake with the esp32.

I could still do a software one for the esp32 - I just haven't had time. The esp32 is easily fast enough.

@VojtechBartoska VojtechBartoska moved this from To-Do (Seeking Contributors) to Development Complete in (Archived) Arduino Core ESP32 RoadMap Oct 14, 2021
@VojtechBartoska VojtechBartoska added the Area: Peripherals API Relates to peripheral's APIs. label Dec 13, 2021
@VojtechBartoska VojtechBartoska added Status: Solved and removed Status: To be implemented Selected for Development labels Apr 6, 2022
Lzw655 pushed a commit to Lzw655/arduino-esp32 that referenced this issue Oct 12, 2023
* Rework the lib-builder for ESP-IDF v5.1

* Update package json with tolls matching the ESP-IDF version

* fix: rainmaker examples crashing on s3 due to low stack memory. (espressif#106) (espressif#107)

* Update scripts with the latest requirements

* Update configs + SR Support

* Add esp-elf-gdp to the list of packages

* Fix RainMaker builds and new sr models path

* Temporary force arduino branch for CI to work

* fix target branch

* Delete esp-dl component manifest for requiring IDF 4.4.x

* Temporary changes to allow Cron CI to run

* Support builds based on ESP-IDF tag

* Push to esp32-arduino-libs

* Update repository_dispatch.sh

* Rework scripts to allow build when either dst needs it

* Github complains when pushing to the libs repo

* Authenticate to the libs repo

* Attempt at splitting SDK from Arduino

* Archive only the result and reorder deploy commands

* Update cron.sh

* Fix script and zip paths

* Fix download URL and json merger

* Change sdk folder structure and fix json generation

* Switch output folder from sdk to esp32-arduino-libs

* arduino_tinyusb: compile support for DFU mode (espressif#116)

* Update PlatformIO build script templates (espressif#118)

Adds support for new package with precompiled SDK libraries

* Autogenerate PlatformIO manifest file for prebuilt SDK libs (espressif#119)

* Autogenerate PlatformIO manifest file for prebuilt SDK libs

- Add a special Python script that generates "package.json" with IDF revision from the "version.txt" according to SemVer

* Tidy up

* Refactor manifest generator

Now IDF version and commit hash are passed directly from Git client instead of reading from a pregenerated "version.txt" file

* Move IDF definitions to be available with any build

* Use more components from registry and add mp3 decoder

* esp-sr component requires clearing before each build

* revert ESP_SR from component manager

* Build ESP_SR only for ESP32-S3 for now

* [TinyUSB] Update esp32sx dcd and add dwc2 option

* Workaround for recent change in ESP-Insights

* Add initial support for ESP32-C6

* Run build tests on ESP32-C6

* Remove -mlongcalls for non-xtensa chips

* Temp fix for ESP-Insights on C6

* Add support for ESP32H2

* Added tflite-micro component (espressif#128)

* Update build badge in README.md

* Added tflite-micro component

---------

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>

* Make cron rebuild the libs if they need to be pushed to Arduino

For when we change something in the lib-builder, but no new updates are available in ESP-IDF

* Update build actions

* Fix permissions

* Do not build for obsolete Flash modes

* Try separate detect for cron builds

* Add permissions to github api

* Try more basic commit detection

* another try to pass vars and get commit

* Update push.yml

* Update config.sh

* Enable builds again

* Update build.sh

* Combine the artifacts from all jobs

* fix and test deploy check

* Update push.yml

* Disable Memprot to allow loading external elfs

* Fix archive name

* Disable coredump to flash

* Enable SPI ETH KSZ8851SNL

* Add temporary support for Arduino SPI Ethernet

* Add a temporary fix for relative include in BT lib

* Enable Classic BT HID Host and Device for ESP32

* Revert "Enable Classic BT HID Host and Device for ESP32"

This reverts commit aa0040ad271d00ac507fd2b478ee143b6c118615.

* C6 was added to ESP-SR

* Update Ethernet and remove SR workaround

* Pin RainMaker version

* Update target branch

* Add back cron.sh

---------

Co-authored-by: Sanket Wadekar <67091512+sanketwadekar@users.noreply.github.com>
Co-authored-by: Luca Burelli <pil@iol.it>
Co-authored-by: Valerii Koval <valeros@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Peripherals API Relates to peripheral's APIs. Status: Solved
Projects
No open projects
Development

Successfully merging a pull request may close this issue.