Getting I2C on ESP8266 to work

Posted on
Page
of 2
/ 2
Next
  • I am trying to get i2c to work on my ESP8266, but don't have much luck.
    I must be missing something.
    Maybe someone here can help me.

    I tried

    I2C1.setup({ sda: D12, scl: D14 });
    I2C.find(I2C1);
    =undefined
    

    I put 10k pull-ups on both GPIO12 and GPIO14

    Correct me if i am wrong but I was assuming that the I2C.find command is similar to i2cdetect and should return a list of I2C compatible devices/addresses on the I2C bus.

    If I specify a bitrate, like

    I2C1.setup({ sda: D12, scl: D14, bitrate: 100000 });
    

    my ESP8266 will crash/reset.

    When I try to read from an valid device address (checked with my Raspberry pi) I get

    I2C1.readFrom(0x11, 2);
    ERROR: No ACK
    =new Uint8Array([50, 41])
    

    But the returned data is invalid and a similar result is returned when reading from an invalid device address (just with different data).

    I am running this version of the firmware :
    s3.voneicken.com/espruino/espruino_1v85.­tve_master_66fde09_esp8266.tgz

    @MaBe tested this build to have working support for I2C as mentioned in the
    Latest Espruino build for Esp8266 topic.

    I am trying to communicate with an rrd-102v2.0 (FM radio (RDA5807)).

  • The I2C test with an oled is only using i2c.writeTo().

    Will do some tests with a I2C device that use i2c.readFrom().

  • I2C.find() doesn't do what you think it does. See the reference
    http://www.espruino.com/Reference#l_I2C_­find

    If you need to search the I2C bus for devices, it's just a for loop and I2C1.readFrom() to implement it yourself... Or you could just consult the datasheet and find out what the address is that way.

    This works... (as of a few weeks ago, I've been swamped lately, no time to do anything on my project, but unless something got broken, this works).

    
    I2C1.setup({scl:5,sda:4});
    var eeprom=require("AT24").connect(I2C1, 128, 512); //default address, ie, all address pins low. 
    
    //oodles of eeprom.read() and eeprom.write() 
    // full code: https://github.com/SpenceKonde/AzzyProje­cts/blob/master/Animate/Version6.js
    
    

    I don't think bitrate/baudrate works on the ESP8266.

  • Tried i2cdetect code with a OLED attached at address 0x3c and limit scan to 0x30-0x3f

    Get fussy read results for adr <> 0x3c and lots of ERROR: No ACK

    o no error for 0x3c - read value 65
    o no catch was triggered

    >echo(0);
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:
    10:
    20:
    ERROR: No ACK
    30:136
    ERROR: No ACK
    31:168
    ERROR: No ACK
    32:248
    ERROR: No ACK
    33:24
    ERROR: No ACK
    34:184
    ERROR: No ACK
    35:56
    ERROR: No ACK
    36:72
    ERROR: No ACK
    37:56
    ERROR: No ACK
    38:248
    ERROR: No ACK
    39:72
    ERROR: No ACK
    3a:40
    ERROR: No ACK
    3b:200
    3c:65
    ERROR: No ACK
    3d:88
    ERROR: No ACK
    3e:136
    ERROR: No ACK
    3f:24
    30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
    40:
    50:
    60:
    70:
    =undefined
    
  • start investigating the source code

  • There is a section on I2C on the esp8266 page: http://www.espruino.com/EspruinoESP8266

  • @tve - thanks
    ....

    • does not support clock stretching (a method by which slaves can slow down the master)

    ....

    will check this with a logic analyzer

  • I ran into similar issue trying to get I2C working with the Wii Nunchuck.

    • works fine with Pico, but not at all on ESP8266.
  • There are some implementation for clock stretching, eg: core_esp8266_si2c.c

    and Frida posted, that she has implemented clock stretching http://forum.espruino.com/comments/12973­407/

  • I am still trying to make it work with my FM radio module.

    The wiring should be correct because when I flashed Mongoose IoT (formerly smart.js)
    I could use the following code :

    var i2c = new I2C(4, 5);
    i2c.do(0x11, [I2C.WRITE, 0], [I2C.READ, 2]);
    

    And have it work perfectly.

    On Espruino I used the following (hopefully) equivalent code :

    I2C1.setup({ sda: D4, SCL: D5 });
    I2C1.writeTo(0x11, 0);
    I2C1.readFrom(0x11, 2)
    

    Which results in

    ERROR: No ACK
    ERROR: No ACK
    

    Can this have something to do with the lack of clock stretching ??

  • I guess you use the WEBIDE and upload your code, so the time between writeTo and readFrom is different.

    To make it equivalent put your code in a function and use setTimeout() to call it.

    eg:

    I2C1.setup({ sda: D4, SCL: D5 });
    
    function i2c_do(i2c,addr, w,r){
        i2c.writeTo(addr, w);
        i2c.readFrom(addr,r);
    }
    
    setTimeout(function(){i2c_do(I2C1,0x11,0­,2);},1000);
    
    
  • Are the 4,5 above the same - does it refer to gpio # or PIN number, or board label?

    Perhaps try NodeMCU:D4 and NodeMCU:D5 as these map the board labeling to pin numbering... http://www.espruino.com/Reference#l_Node­MCU_D0

  • @tve recommends these pins for the esp8266

    https://gitter.im/espruino/Espruino?at=5­72c3c4612cceadb7b1b25db

    Just realised you are part of this thread....

    Have you any other i2c device you can try other than the wii controller....

  • Looks like the I2C problem is specific to the radio module.

    A MCP23017 port expander that I connected to the same bus is recognized and works without problem.

    It is not a problem with the esp8266 because flashing different firmware makes it work.
    It should also mean that the circuit is wired up correctly.

    I will check the difference between the two firmwares next using a logic analyzer

  • Looks like espruinos I2C is almost 10x faster than mongoose, maybe it is too fast for this module. Would now be nice if I could set the bitrate lower.

  • Looks like espruinos I2C is almost 10x faster than mongoose

    This could be the issue? AFAIK I2C devices generally don't mind going slow, but some of them really don't like higher clock speeds.

  • Ok back to the drawing board, I slowed Espruino down to the same speed and even slower, but it made no difference.
    So the exact timing is the next thing to check out.
    For some reason the working version results in 001000100 while the espruino version results in 001000101.
    I am assuming that the slave is the one producing the last 0 in the working version and
    produces a 1 (or does nothing resulting in an automatic 1) in the not working version.

    Hopefully I am learning something here ;-)

  • If my comment is correct, it's running at approx 250khz. I didn't see any device that could not run at 400Mhz and this is the fastest I could make it go without making weird waveforms.

  • The code was indeed running at around 250kHz, according to the data sheet of the radio module it supports up to 400 kHz so it should have worked, but for some reason it doesn't.
    The I2C signals look correct, except for the following artifacts.

    The espruino version has these artifacts on the signal that don't exist on the mongoose version.

    I cannot get higher resolution out of my logic analyzer but
    the peak and dip coincide with the clock signal. In the code it seems to reapply the value of sda at each scl change :

    i2c_master_writeByte(uint8 wrdata)
    {
        uint8 dat;
        sint8 i;
    
        i2c_master_wait(2);
        i2c_master_setDC(m_nLastSDA, 0);
        i2c_master_wait(4);
    
        for (i = 7; i >= 0; i--) {
            dat = wrdata >> i;
            i2c_master_setDC(dat, 0); // << set sda when clock still low
            i2c_master_wait(1);
            i2c_master_setDC(dat, 1); // << set sda to same value but now with clock high
            i2c_master_wait(5);
            i2c_master_setDC(dat, 0); // << set sda to same value but with clock low again
            i2c_master_wait(2);
        }
    }
    

    I wonder if setting sda to 1 actually pulls it to 0 first before reapplying the 1.
    I cannot see any other problems when comparing the signals generated by espruino with the ones generated by mongoose :

    Note that the following images are using a lower sample rate so that is why the rise times look slow and it doesn't show the artifacts.
    Things to note: In this version of espruino I slowed down the I2C speed to match the mongoose speed, it is using the clock stretching version of i2c_master.c. Besides some slight timing differences to better match mongoose this should otherwise be the same as the version of this file in the master espruino branch.


    Espruino signal, notice it doesn't get ack.


    Mongoose signal, notice it does get ack (and does so consistently) .

    It looks like mongoose allows clock stretching also, but that happens after ack so should not be the cause of the difference.

    You can imagine that I am positively stumped why mongoose works consistently correct while Espruino consistently fails.

  • What is the exact device you're trying to get to work?
    I don't like the glitch you see, I'll have to check what my scope says. I just looked at the code and it should be fine. Mhhh...

  • The device is a RRD-102V2.0 module that has a RDA5807M Fm radio chip.

    According to the specs, It should be capable of 400kHz I2C communication speeds.
    Google for RDA5807M will bring up the data sheet.

    I managed to get slightly higher resolution that shows the glitch even better

    The glitch shows up even if not connected to the radio module and rda and scl just connected to the two pullup resistors.

  • Here is the mongoose IoT output on the same exact hardware for comparison. just to rule out any hardware or measuring errors.

  • hi, did anyone solve how to connect OLED into ESP8266 on Espruino?

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Getting I2C on ESP8266 to work

Posted by Avatar for virtualcodewarrior @virtualcodewarrior

Actions