casanovg / nb-i2c-cmd

ESP8266-ATtiny85 I2C communication demo
MIT License
0 stars 0 forks source link

Problem with i2c Addresses > 0x3f #1

Open BlueFinBima opened 7 years ago

BlueFinBima commented 7 years ago

Hi Gustavo, firstly, I do not think think this problem is with your code, however I was able to refine the problem I am having using this project. The basic scenario is ESP8266 talking to ATTiny85 running rambo's usiTwiSlave. What your code allowed m to see was that when my ATTiny85's address > 0x3f, it did not show up in the i2c scan, and it would very rarely interact with with ESP8266. The code I was running in the ATTiny85 with address 0x45 continues to work happily with other i2c masters.
My question to you is - do you have the same problem when the slave's i2c address is 0x4f for example? My guess is that there is a timing issue being created on the ESP8266, and exposing a problem on the TinyWireS such that when the high order bit of the pre-shifted address is 1, the interrupt used to detect a start condition is not triggered (confirmed with a debugger). I do not have n oscilloscope so I am unable to explore this further.
I had been pulling my hair out over this problem until I stumbled into your code, which allowed me to refine the problem, to a big thank you for making this available. If you do not see this problem, it would be very helpful if you could tell me what library you are using for i2c on the ESP8266. Many thanks, Neil

casanovg commented 7 years ago

Hi Neil, Thanks for posting. I'm certainly not facing the problem you describe. Right now I'm testing 0x4F as the Tiny slave address, and it was correctly discovered by the ESP8266 master. I also tried 0x45 without trouble (see posted vid). I'm using a Lolin board (ESP-12E) and a Digispark to cut test times (only two cables, no pull-up resistors needed). On the ESP I'm running the standard Wire library v1.0.0 that comes with the Arduino v1.8.1 IDE. On the Tiny85 I'm using Rambo's TinyWireS. Hope you can solve it, let me know ... Gus

BlueFinBima commented 7 years ago

Hi Gustavo, thanks for the response. I'm aware of the 7-bit addressing and that isn't the problem. What I find interesting is that your libraries and set-up are quite similar to mine, but you do not see the problem. The two wire libraries should be the same, I am using a NodeMCU with a 12E. My understanding is that the wire library for the ESP8266 does not ship with the Arduino IDE and comes from the ESP8266 project but looking into those files I think says that most of the work is done in a n external library. Are you able to confirm that you are also using the 2.3.0 version of the ESP8266?

I have tried pull-up resistors from 0R to 10K and the problem remains. My ATTiny85 is running 5v and 8MHz internal clock. Does that match your setup?

I do have a level shifter (to 5v) on the I2C lines, but none of my other I2C devices (ie non ATTiny85) are showing a problem, and they all have addresses in the range 0x70 - 0x7F.

I did set a breakpoint in the ISR which is supposed to detect the start ( USI_START_VECTOR ) and it fires when the address is < 0x40 but not if the MSB of the address is 1 (ie the first bit after the START) and I am concluding that the issue is that the USI is not detecting the start in this situation when the first bit to arrive is 1 - most likely due to some timing issue. Finally, I have also tried with different setClockStretchLimit values and this has not helped the problem.

Unfortunately youtube is not allowing me to view your video, because that might have answered some questions, but I really do appreciate your response, and once again, having your tests to run was a great help, so thank you for making them available.

I think my next step is probably to run the ATTiny85 at 3v3 without the level shifter and see if this makes a difference. Thanks, Neil

casanovg commented 7 years ago

Hi Neil Yes, I realised that your problem had nothing to do with the 7-bit LSB addressing issue after doing the test with 0x45 / 4F. I guess that Wire libraries already handle these details. Today I tested a NodeMCU instead of the Lolin as master, just in case, and it is also OK with the slave detection at 0x4F. Regarding the Wire library, I don't remember exactly how I got it, I thought that came with the IDE, but now that you mentioned, perhaps It came with the ESP8266 board support package (I confirm that I have v2.3.0, see pics). I started with Arduino to work with the ESP SoC, so it happened at the same time, around four months ago. By the way, the Arduino IDE is so limited, that I switched to Visual Studio after a while using it. About the resistors, I completely understand you, I've struggled a lot at the beginning, that is why I fell in the "i2c address scan" path. There are moments when you doubt about everything, the code, voltage, resistors, magic, etc. After you overcome this, you realise that they're not that important (at least in development stage), it always works. As I mentioned, now I'm using just two wires with no resistors, plugged to USB outlets (5V) in two different PCs and it's OK. If you can get rid of the level shifter, I think it's a good idea. As a side comment, I consider this stage: "to have both SoCs chatting with certain reliability" closed. Now I've moved to my real problem: concurrency of ADC, I2C and PWM on the Tiny, but count on me If I can be helpful to solve your issue. I would also like to mention that to have I2C working between these two guys wasn't my original project, but I had to follow this hard path due to ESP8266 ADC instability when transmits WiFi packets, just if you plan to do something similar ... Question, have you tried to burn this code directly into the boards? I mean, without any other code running. Does it work? I posted the video again ... Regards, Gustavo wire esp8266 20170726_074923

casanovg commented 7 years ago

Issue abandoned by opener ...

BlueFinBima commented 7 years ago

Hello Gustavo,

apologies for not getting back to you on this but I was on vacation, and I had to wait for the Bus Pirate to arrive. Testing with the Bus Pirate in i2c mode indicated that there were still issues without the NodeMCU, but not address related, and I could not identify the real nature of the problem (it might have been my lack of understanding about how to operate the Bus Pirate).

I was able to confirm that the only issue was the addressing. All read and write operations worked as expected. Removing the signal buffer did not change the problem, and altering the pull up resistors from none down to 1K also did not change the symptoms. Changing the speed of the i2c bus also did not fix the problem. Using a better 5V supply also did not help.

In the end, I ran out of time and energy, and I just changed the addresses of all the AtTiny85 devices to below 0x40 and I have not had any issues since.

I am convinced that the issue must be related to the timing of the start and the first bit following it when that comes from the ESP8266, but until I invest in an oscilloscope, I will be unable to prove it.

Thank you for posting your video again, and for making your code available (which I did run unaltered but had the same problem).

Your project, your comments, and confirmation of software levels have been most helpful, so thank you for the assistance

Regards, Neil...

On 23 August 2017 at 00:12, Gustavo Casanova notifications@github.com wrote:

Closed #1 https://github.com/casanovg/nb-i2c-cmd/issues/1.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/casanovg/nb-i2c-cmd/issues/1#event-1216876185, or mute the thread https://github.com/notifications/unsubscribe-auth/ARqwGC3wMcs2dZ1xrKy9Np0oyaaQBnG7ks5sa2BNgaJpZM4Ohqzn .

casanovg commented 7 years ago

Thanks Neil, and you're welcome.

Unfortunately, I couldn't reproduce the problem by doing mixed tests of an ESP01-Attiny85, ESP01-Digispark, NodeMCU-Digispark and NodeMCU-Attiny85, most of the time without pull-ups, and a couple of tests with 10k. It always works well for me, at any address.

I can't help with the Bus Pirate since I do not have one, in fact, I didn't know it, but I see that it is an interesting and versatile tool, maybe I buy one.

It could be a timing problem as you mention. Just to try to avoid them is that I suggested running this project as is. Because, as you may have noticed, it does not initialize WiFi in the ESP8266, this is on purpose to separate the problem domains. I'm reserving the full integration for the end, including the Blynk library, but I wanted to make sure I2C is running free of locks from other functions.

I'm glad that, despite not finding the source of the problem, your application allows you to use lower addresses and move forward.

Good luck, and here I am if there is anything I can help you with! Gustavo

casanovg commented 7 years ago

Hi Neil,

I return to this topic to let you know that, trying to optimize the tiny85 power consumption, I met the problem exactly as you described it, the slave doesn't respond to the ESP8266 I2C scan when configured on addresses above 3F.

Maybe you already moved on to another topic, but I wouldn't want to let it pass without commenting it. In my case, the bug appeared after setting the tiny85 CPU clock at 8MHz.

I also confirm that, when the tiny85 is set to 16MHz, it responds perfectly across the full range of addresses. This was the configuration I've been using in our previous communications, that is why I wasn't being able to reproduce the problem.

In sum, these are the tiny85 fuse configurations I've been testing:

I do not have time now to investigate why this happens, it seems too accurate to be a hardware timing problem, maybe there is something in the TinyWireS library. Perhaps I will investigate more in-depth later on, for the moment, I will only follow this recipe: At 8MHz, addresses up to 0x3F.

I also tested that working at 1 MHz (Low = 0x62, High = 0xDD, Extended = 0xFE) the tiny85 responds to the scan in lower addresses, i.e. 0x09, 0x0A, but later communication is totally unreliable.

Well, that's all for now, regards and good luck! Gustavo

BlueFinBima commented 7 years ago

Hello Gustavo,

I really do appreciate that you contacted me about this. It confirms that I did not make a rookie error with my programs.

Unfortunately I ran out of time to get to the bottom of the problem and I moved all of my Tiny85's to addresses below 0x40 where they operate without problems. All of my devices are running 8MHz on internal oscillator.

I think that I decided that the problem was on the ESP8266 side, not necessarily a bug in the TinyWireS library per se, (I did look at the code and it seemed fine in isolation) but possibly some subtlety to do with the wider operation of the ESP8266. I had no problems when the i2c master was on an Atmel32U4. I did not get a chance to test with an ESP32 but I would guess is that the problem would not exist on this more capable device.

Hopefully my original notification to your projects saved you a little time when you did eventually encounter the problem.

If you ever do get an answer to this, I would certainly appreciate it if you could let me know.

Best wishes, Neil

On 17 September 2017 at 01:53, Gustavo Casanova notifications@github.com wrote:

Hi Neil,

I return to this topic to let you know that, trying to optimize the tiny85 power consumption, I met the problem exactly as you described it, the slave doesn't respond to the ESP8266 I2C scan when configured on addresses above 3F.

Maybe you already moved on to another topic, but I wouldn't want to let it pass without commenting it. In my case, the bug appeared after setting the tiny85 CPU clock at 8MHz.

I also confirm that, when the tiny85 is set to 16MHz, it responds perfectly across the full range of addresses. This was the configuration I've been using in our previous communications, that is why I wasn't being able to reproduce the problem.

In sum, these are the tiny85 fuse configurations I've been testing:

  • 8 MHz clock (RC): Low = 0xE2, High = 0xDD, Extended = 0xFE -> Responds only on addresses lower than 0x40.
  • 16 MHz clock (PLL): Low = 0xE1, High = 0xDD, Extended = 0xFE -> Responds over the full range of addresses

I do not have time now to investigate why this happens, it seems too accurate to be a hardware timing problem, maybe there is something in the TinyWireS library. Perhaps I will investigate more in-depth later on, for the moment, I will only follow this recipe: At 8MHz, addresses up to 0x3F.

I also tested that working at 1 MHz (Low = 0xE2, High = 0xDD, Extended = 0xFE) the tiny85 responds to the scan in low directions, but later communication is totally unreliable.

Well, that's all for now, regards and good luck! Gustavo

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/casanovg/nb-i2c-cmd/issues/1#issuecomment-330004783, or mute the thread https://github.com/notifications/unsubscribe-auth/ARqwGCjmPn2023mytjVE1KFaNMWLBVzGks5sjG2KgaJpZM4Ohqzn .

dlkeng commented 2 years ago

FYI I too ran into this problem when using an ESP8266 Wemos D1 clone to communicate with an ATtiny25 I2C slave device using the TinyWireS code for the I2C slave on the ATtiny25. I did not see this problem when using an Arduino Nano to communicate with the same ATtiny25 on the I2C bus.

In exploring the problem with a logic analyzer, the ESP8266 start condition timing is very tight (nanoseconds) with respect to asserting SDA high (on addresses > 0x3f) after the initial SCL low signal compared to the Arduino Nano (microseconds).

In the TinyWireS code for the USI_START_VECTOR interrupt service routine is a test for the state of the SDA pin at the I2C Start condition that assumes the SDA signal is low for a valid Start condition. Since the SDA is low for such a short time, at 8 Mhz, the ATtiny25 is missing this low state, but an ATtiny running at a faster rate (16 Mhz) might not miss it.

I changed the TinyWireS code in the USI_START_VECTOR interrupt service routine to no longer check for the state of the SDA signal (assuming it is low) and now the ESP8266 I2C communications work well with the ATtiny25 I2C slave device.

BlueFinBima commented 2 years ago

Dan, many thanks for the results of your investigation. Very enlightening, and makes perfect sense.

On Fri, 11 Feb 2022, 15:00 Dan, @.***> wrote:

FYI I too ran into this problem when using an ESP8266 Wemos D1 clone to communicate with an ATtiny25 I2C slave device using the TinyWireS code for the I2C slave on the ATtiny25. I did not see this problem when using an Arduino Nano to communicate with the same ATtiny25 on the I2C bus.

In exploring the problem with a logic analyzer, the ESP8266 start condition timing is very tight (nanoseconds) with respect to asserting SDA high (on addresses > 0x3f) after the initial SCL low signal compared to the Arduino Nano (microseconds).

In the TinyWireS code for the USI_START_VECTOR interrupt service routine is a test for the state of the SDA pin at the I2C Start condition that assumes the SDA signal is low for a valid Start condition. Since the SDA is low for such a short time, at 8 Mhz, the ATtiny25 is missing this low state, but an ATtiny running at a faster rate (16 Mhz) might not miss it.

I changed the TinyWireS code in the USI_START_VECTOR interrupt service routine to no longer check for the state of the SDA signal (assuming it is low) and now the ESP8266 I2C communications work well with the ATtiny25 I2C slave device.

— Reply to this email directly, view it on GitHub https://github.com/casanovg/nb-i2c-cmd/issues/1#issuecomment-1036302660, or unsubscribe https://github.com/notifications/unsubscribe-auth/AENLAGE3CTX656NJ2AHVTXDU2UQCBANCNFSM4DUGVTTQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

casanovg commented 2 years ago

FYI I too ran into this problem when using an ESP8266 Wemos D1 clone to communicate with an ATtiny25 I2C slave device using the TinyWireS code for the I2C slave on the ATtiny25. I did not see this problem when using an Arduino Nano to communicate with the same ATtiny25 on the I2C bus.

In exploring the problem with a logic analyzer, the ESP8266 start condition timing is very tight (nanoseconds) with respect to asserting SDA high (on addresses > 0x3f) after the initial SCL low signal compared to the Arduino Nano (microseconds).

In the TinyWireS code for the USI_START_VECTOR interrupt service routine is a test for the state of the SDA pin at the I2C Start condition that assumes the SDA signal is low for a valid Start condition. Since the SDA is low for such a short time, at 8 Mhz, the ATtiny25 is missing this low state, but an ATtiny running at a faster rate (16 Mhz) might not miss it.

I changed the TinyWireS code in the USI_START_VECTOR interrupt service routine to no longer check for the state of the SDA signal (assuming it is low) and now the ESP8266 I2C communications work well with the ATtiny25 I2C slave device.

Dan, I also appreciate your detailed follow-up on this topic. I'll test and use your proposed solution from now on ...