esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
16.01k stars 13.33k forks source link

Support for I2C slave mode #1330

Closed kdsoo closed 5 years ago

kdsoo commented 8 years ago

I'm trying to run Adafruit esp8266 breakout as i2c slave using gpio 13 as scl and 14 as sda. Going through the Wire library code, I found it inapplicable to run esp as i2c slave with changed pin configuration. For ordinary use of Wire library for i2c slave configuration, we put slave address as Wire.begin() argument like "Wire.begin(address)" But considering Wire.pins() deprecated, there is no way to change i2c pin configuration. Am I getting right? So, how could I use esp as i2c slave with changed pin configuration? Any pointer will be appreciated.

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Links2004 commented 8 years ago

the ESP currently only support I2C master mode you can not run it in slave mode.

kdsoo commented 8 years ago

@Links2004 Thanks. I'll look for alternative interface to give commands to ESP.

isparkes commented 8 years ago

Is there an underlying reason not to implement slave mode, or is it just a "didn't get round to it yet" situation? If it's just a matter of priorities, I'd have a go at implementing slave mode...

Links2004 commented 8 years ago

there is no technical limitation, simple no one has done it yet.

isparkes commented 8 years ago

OK, great. I need it for a project I am doing. If I can get it to work reliably, I'll make a pull request for it.

francox-sg commented 8 years ago

yes!!! i need this library for my proyect, esp i2c slave is a priority for the community, if not, i2c can´t be implemmented completely (sorry for my english)

francox-sg commented 8 years ago

and... i can´t install the new library version of esp arduino ide....

isparkes commented 8 years ago

I looked into this, and I don't see an easy way to do this at the moment. The SDK does not provide support for interrupts, and therefore the interrupt driven slave mode which requires this is not an easy implementation at the moment.

Links2004 commented 8 years ago

there are interrupts, only for GPIO16 not. we use them for attachInterrupt for example. https://github.com/esp8266/Arduino/blob/master/cores/esp8266/core_esp8266_wiring_digital.c#L112 https://github.com/esp8266/Arduino/blob/master/cores/esp8266/core_esp8266_wiring_digital.c#L137 how fast you can go with simple use attachInterrupt needs to be tested. but default I2C run at 100kHz or for high speed 400kHz, I think this is reachable.

isparkes commented 8 years ago

Yes, I see that now. I was kind of hoping that the SDK would bring support for Slave Mode, but it doesn't. However with the point you bring, I agree, it should be possible to implement it outside of the SDK.

chrischsc commented 8 years ago

I would be really interested in this. Any progress or investigations so far?

Seriga commented 8 years ago

Can anyone have some developments for the implementation of the slave mode?

ESP32DE commented 8 years ago

http://bbs.espressif.com/download/file.php?id=1396&mode=view http://bbs.espressif.com/viewtopic.php?f=49&t=2092

judge2005 commented 7 years ago

Hi,

Well I've read through the espressiff topic listed above, and Am still not sure what the status is. There are a lot of code snippets, but there doesn't seem to be a complete posted solution, and it seems like there are still open questions. I don't have the time or the equipment to try and mold it all into a library, or even a chunk of code that I could just use. Do other people agree with my assessment of that thread? If you don't, could you post a complete, self contained solution?

Thanks - Paul

bjoham commented 7 years ago

I have done it. See http://www.esp8266.com/viewtopic.php?f=33&t=13546&p=0&e=0&sid=7f3455a872dbecf1ef55add30b106aae

jhonoryza commented 7 years ago

@bjoham can u push the implementation i2c-slave to the master branch? :)

bjoham commented 7 years ago

Done! (???)

Testato commented 7 years ago

@bjoham are you pushed a PR for your work ? It is very interesting merge it to master branch

mfatiga commented 7 years ago

What's going on with this issue? Is there any reason this is not merged to master yet? https://github.com/esp8266/Arduino/pull/3287

newbee42 commented 7 years ago

Hello all,

i am not very familiar with the concepts of git/github. However i ask myself, when the corrected Version including i2c slave support is available for regular arduino style programmer. I need this possibility to set esp8266 into the slave mode. So far i could see, a merge was done of the correct code with the main source code, so what are the next steps?

At all developpers of this code: thank you for the support of the ESP8266 platform, and go further, especially with i2c slave mode :o)

newbee42

bjoham commented 7 years ago

If there are steps missing for others to try this out, please let me know. I have not fully grasped how to do these things yet.

On my list, there are still the action points on testing (and fixing) the functional issues reported earlier.

bjoham commented 7 years ago

My setup still works without (noticable) issues on the I2C side.

From the temperature graph from the last few weeks, however, it is apparent that painting the temperature sensor's housing with a non-white color was not a good idea. Perhaps it could be used as a good-weather detector... (The sensor is on the north side of the house and since we have long nights during the summer, there are two temperature spikes every day with clear skies.)

thermiq

newts commented 7 years ago

Thanks for the i2c slave stuff. I am looking into it now for a project. What did you do for your weather data? I am looking at something similar maybe I want to simulate a SHT-3X chip to display outdoor weather data on a cheap temperature/humidity display like this: https://www.amazon.com/gp/product/B000XTJRRA/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1

The idea is I have wunderground station and can get the temperature and humidity via wifi and provide it to the display device as if I was a SHT-3X.

jv

devyte commented 6 years ago

It seems that the referenced PR is still not merged.

pdewilde commented 6 years ago

Bump

cmoine commented 6 years ago

Instead of a PR which seems complicated, could we have a snippet/source code instead ?

palto42 commented 6 years ago

You can find the code in the pull request #3287 (see commits) There seems to several open comments in the pull request for I2C slave support, guess that's why it's not accepted in current format. To me it looks that mainly some code clean-up is requested.

devyte commented 5 years ago

Fixed in #5226 .

dav1d-wright commented 5 years ago

Hello,

I have Version 2.5.2 installed but I can't get the I2C slave mode to work. Even with the Arduino slave_receiver example it does not work. Can someone help me on this? Here is my code:

// Wire Slave Receiver
// by devyte
// based on the example 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

// This example code is in the public domain.

#include <Wire.h>

#define SDA_PIN 12
#define SCL_PIN 13

const int16_t I2C_SLAVE = 0x12;

void setup() {
  Serial.begin(115200);           // start serial for output

  Wire.begin(SDA_PIN, SCL_PIN, I2C_SLAVE); // new syntax: join i2c bus (address required for slave)
  Wire.onReceive(receiveEvent); // register event
}

void loop() {
  delay(1000);
  Serial.println("Loop");
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(size_t howMany) {

  (void) 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
}

I am displaying the communication lines on a scope and don't see the slave ACKs

earlephilhower commented 5 years ago

@wrd90, I'm doing a big rewrite on the I2C code to reduce the memory footprint in #6326. Unfortunately, for me it's been an exercise in hand optimization as I'm not actively using anything over an I2C now. That said, though, I've gone over the FSMs a few times (they're hairier than I would have thought) and might be able to work through some cases by hand and see what's going on.

Can you provide some full logic analyzer traces of SCA/SDL over the entire communications that are failing? A picture is worth a thousand words, as they say...

earlephilhower commented 5 years ago

Oh yeah, if you could capture at a 10x+ multiple of SCLK since there are dependencies on the order of signals changing that would be most useful. (i.e. if SCLK comes in 10ns before a SDA transition vs. 10ns after a SDA change then things could follow a different path)

dav1d-wright commented 5 years ago

Hi @earlephilhower and thanks for the quick reply! That sounds great already thank you! I can certainly provide some scope screenshots by tomorrow. Have you already been able to pin point the rough arwa where this issue might be located? Maybe I could be of some assistance. Do you maybe have an intermediate copy of the code that might provide some fixes?

earlephilhower commented 5 years ago

No fixes yet, sorry. I've just been trying to make sure the slimmed-down version has only the same bugs as the original code. :)

With a waveform where you can tell which xisition precedes another, though, it's simple enough to trace the logic. It looks like basically slave I2C is straightforward (again, famous last words), if it detects its address (which it seems to be, since you're seeing returned data), with it just having to ship in/out the data bits and the nack flag...

dav1d-wright commented 5 years ago

Hello @earlephilhower,

I'm sorry I didn't have enough time yesterday after all. I am attaching the screenshots, and I uploaded CSV files to my Dropbox, since I can't share upload them here. I hope they are what you need!

Best, David

https://www.dropbox.com/s/eihh534q58dmu1p/scope_1_SBUS1_I2C.csv?dl=0 https://www.dropbox.com/s/3ktnc7mamqqro5i/scope_1_SCL1.csv?dl=0 https://www.dropbox.com/s/lopkz5s3fsmtdou/scope_1_SDA1.csv?dl=0

scope_0

scope_2

earlephilhower commented 5 years ago

I'm traveling for a few days but will give these a look when I get back. The CSVs looks like they have good sampling rates so edge ordering should be easy to catch.

earlephilhower commented 5 years ago

Scratch my last comment, on further inspection I see it trying to generate ACK in the prior state: https://github.com/esp8266/Arduino/blob/19d09eae2b5ff9ed7cc48b5fa2c912d1297462b9/cores/esp8266/core_esp8266_si2c.cpp#L562-L580

My guess, then, is that the address is not matching the expected value. Adding in some printfs when it hits the TWI_SEND_ACK state of the current twi_data that it's captured would be instructive. Either it's not getting to this state at all, in which case there'd be no printouts, or it's getting there but with maybe an extra or missing shift so it's out-of-sync.

Git-Bruno commented 5 years ago

Hi, I am seeing the same behavior that David reported with all bytes sent from a I2C master device to a WEMOS Mini Pro board beiing NACK'ed. I run SDK 2.5.2 too. The I2C master clock is around 180kHz. I have added code in the onSclChange function in core_esp8266_si2c.cpp to toggle a GPIO pin to get the SCL value echoed to a test pin :

// GPIO15 is D8 on WEMOS Mini

define GPIO15_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1<<15))

define GPIO15_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1<<15))

define GPIO15(x) ((x)?GPIO15_H:GPIO15_L)

void ICACHE_RAM_ATTR onSclChange(void) { static uint8_t sda; static uint8_t scl; sda = SDA_READ(); scl = SCL_READ();
GPIO15(scl); .....

The screenshot attached shows that there is a significant delay in toggling the test pin on SCL changes and that some SCL changes are not echoed to the test pin. The more changes on SDA the worst the situation gets. I presume this is because calls to the onSclChange() SCL_echo get more delayed by calls to onSdaChange(). Setting the WEMOS clock to 160MHz (default is 80MHz) helps a little bit but not all SCL changes are echoed. No sure why there is this 6µs between a SCL change front and the pin toggling as the test is done witn the slave_receiver.ino sketch with on I2C slave code running.

Best, Bruno

bjoham commented 5 years ago

Since I haven't had the time to follow this in detail, I might be dead wrong. In my perspective, clock speeds in the MHz range do not work.

When running this on a ESP 8266 at least, the interrupt latency was too high to cope with anything around even 100 kHz.

But maybe some updates have been done to improve upon the original slave-mode implementation.

/Björn

Git-Bruno notifications@github.com skrev: (1 augusti 2019 12:19:12 CEST)

Hi, I am seeing the same behavior that David reported with all bytes sent from a I2C master device to a WEMOS Mini Pro board beiing NACK'ed.

I run SDK 2.5.2 too. The I2C master clock is around 180kHz. > I have added code in the onSclChange function in core_esp8266_si2c.cpp to toggle a GPIO pin to get the SCL value echoed to a test pin :>

// GPIO15 is D8 on WEMOS Mini>

define GPIO15_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS,

1<<15))>

define GPIO15_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS,

1<<15))>

define GPIO15(x) ((x)?GPIO15_H:GPIO15_L)>

void ICACHE_RAM_ATTR onSclChange(void)> {> static uint8_t sda;> static uint8_t scl;> sda = SDA_READ();> scl = SCL_READ(); > GPIO15(scl);> .....>

The screenshot attached shows that there is a significant delay in toggling the test pin on SCL changes and that some SCL changes are not echoed to the test pin.> The more changes on SDA the worst the situation gets. I presume this is because calls to the onSclChange()> SCL_echo> get more delayed by calls to onSdaChange().> Setting the WEMOS clock to 160MHz (default is 80MHz) helps a little bit but not all SCL changes are echoed.> No sure why there is this 6µs between a SCL change front and the pin toggling as the test is done witn the slave_receiver.ino sketch with on I2C slave code running.>

Best,> Bruno>

-- > You are receiving this because you were mentioned.> Reply to this email directly or view it on GitHub:> https://github.com/esp8266/Arduino/issues/1330#issuecomment-517222843

-- Skickat från min Android-enhet med K-9 Mail. Ursäkta min fåordighet.