[SOLVED] I2C slow

Discussion in 'UDOO NEO' started by Gorgo, Jun 5, 2017.

  1. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    Board: Udoo Neo Full
    OS: Udoobuntu 2.1.2 + UART6 patch
    Kernel: Linux udooneo 3.14.56-udooneo-02053-gcf9f3ed-dirty #3 SMP PREEMPT Thu Apr 13 16:43:23 UTC 2017 armv7l armv7l armv7l GNU/Linux

    Hi everyone,
    I'm facing a very annoying and tricky bug related to I2C and M4.
    I'm building a wather station with UDOO and BMP180 and a RTC DS3231. Both of them use I2C.

    If I plug them directly with my Udoo, everything works.
    I tested them separately today but I already know that they work together with a breadboard.

    I usually check them with i2cdetect and this is the BMP

    Code:
    udooer@udooneo:~$ sudo i2cdetect -y 1
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- 77
    And this is the RCT:

    Code:
    udooer@udooneo:~$ sudo i2cdetect -y 1
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- 6f
    70: -- -- -- -- -- -- -- --                         
    udooer@udooneo:~$ sudo i2cdetect -y 1
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- --                         
    udooer@udooneo:~$ sudo i2cdetect -y 1
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- 6f
    70: -- -- -- -- -- -- -- --                         
    
    Every i2cdetect commands lasted <2sec.

    Actually I'm wondering why it has 3 interfaces. I knew about 0x68 but what about 0x57, but above all, 0x6f discussed in HERE too.
    Btw, this is merely curiosity...let's go back to the problem.

    We designed a PCB for the Udoo and this is the design:

    [​IMG]

    The pcb gets 12V from the right, UDOO boots and the sensors are off by default.
    We put a transistor linked to GPIO3 to turn the sensors power on by:
    Code:
    pinMode(3, OUTPUT);
    digitalWrite(3, HIGH); //SENSORS on
    in the setup().

    Everything works...but not always, and this is the tricky bug.
    Sometimes the sketch isn't able to get data from the I2C bus, so the RTC and BMP don't work.
    In this case I try to i2cdetect the bus, but this time, every 'i2cdetect -y 1' lasts 1sec per address.
    No problems with i2cdetect -y 0,2,3,4.

    Sometimes I get the sensors, sometimes not.

    Code:
    udooer@udooneo:~$ sudo i2cdetect -y 1
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- -- 
    Any idea why? Any test I can do?

    Thank you!
     
  2. waltervl

    waltervl UDOOer

    Joined:
    Dec 12, 2015
    Messages:
    2,314
    Likes Received:
    580
    From where are you normally monitoring the I2C, from Arduino side or Linux side? Did you switch off I2C from Linux side if monitored from Arduino?
    Didyou use wire or wire1 in Arduino sketch?
     
  3. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    So, I get sensors data from Arduino side that writes them on Serial and I read them from Linux side. Basically I'm monitoring them from Arduino side.

    How I switch I2C off from Linux side? Is it possible?

    About Wire and Wire1, I'm trying to understand which use.
    Before putting my UDOO on the pcb, I tried it with dupont directly.
    I'm using THIS library for BMP180 and THIS to read RTC.

    I tried the BMP085test that doesn't begin Wire or Wire1 in his setup() and I could get data from SDA/SCL from Arduino Side.
    In setup() the bmp.begin() calls Wire.begin();

    I also tried ds3231.ino from the RTC lib and this is its defines:

    Code:
    #include <Wire.h>
    #include "RTClib.h"
    #ifdef __AVR__
     #include <avr/pgmspace.h>
    #elif defined(ESP8266)
     #include <pgmspace.h>
    #elif defined(ARDUINO_ARCH_SAMD)
    // nothing special needed
    #elif defined(ARDUINO_SAM_DUE)
     #define PROGMEM
     #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
     #define Wire Wire1
    #endif
    
    #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
    
    #if (ARDUINO >= 100)
     #include <Arduino.h> // capital A so it is error prone on case-sensitive filesystems
     // Macro to deal with the difference in I2C write functions from old and new Arduino versions.
     #define _I2C_WRITE write
     #define _I2C_READ  read
    #else
     #include <WProgram.h>
     #define _I2C_WRITE send
     #define _I2C_READ  receive
    #endif
    They both worked.
    In my global sketch I usually use, I put Wire1.begin() before rtc.begin() or bmp.begin().

    Should I fix something?
     
    Last edited: Jun 5, 2017
  4. waltervl

    waltervl UDOOer

    Joined:
    Dec 12, 2015
    Messages:
    2,314
    Likes Received:
    580
  5. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    What about the Wire other functions?
    Should it call Wire1.{beginTransmission/requestFrom/write/send} or Wire.{beginTransmission/requestFrom/write/send}?
    Is it correct #define Wire Wire1?

    Shall I call Wire1.begin() in my setup() too?


    For example, I'm testing only the BMP library.
    I put:

    > In the .cpp file, the define.
    Code:
    #include "Adafruit_BMP085.h"
    #define Wire Wire1
    > In ino file this is new setup()
    Code:
    void setup() {
      Serial.begin(115200);
      pinMode(3, OUTPUT);
      digitalWrite(3, HIGH); //SENSORS on
      delay(10);
      if (!bmp.begin()) {
        Serial.println("Could not find a valid BMP085 sensor, check wiring!");
        while (1) {}
      }
    }
    With this configuration, my i2cdetect ends after 1sec and it finds the two sensors (bmp and rtc), BUT I cannot read values from the sketch (begin fails)

    Code:
    udooer@udooneo:~$ sudo i2cdetect -y 1
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- 77
     
    Last edited: Jun 7, 2017
  6. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    In details:
    SSH linux side
    Code:
    udooer@udooneo:~$ sudo i2cget -y 1 0x77 0xD0
    0x55
    In the sketch:
    Code:
    Wire1.begin();
    uint8_t res = read8(0xD0);
    
    [...]
    
    uint8_t Adafruit_BMP085::read8(uint8_t a) {
      uint8_t ret;
    
      Wire1.beginTransmission(BMP085_I2CADDR); // start transmission to device 
    #if (ARDUINO >= 100)
      Wire1.write(a); // sends register address to read from
    #else
      Wire1.send(a); // sends register address to read from
    #endif
      Wire1.endTransmission(); // end transmission
     
      Wire1.beginTransmission(BMP085_I2CADDR); // start transmission to device 
      Wire1.requestFrom(BMP085_I2CADDR, 1);// send data n-bytes read
    #if (ARDUINO >= 100)
      ret = Wire1.read(); // receive DATA
    #else
      ret = Wire1.receive(); // receive DATA
    #endif
      Wire1.endTransmission(); // end transmission
    
      return ret;
    }
    
    res is 0xFF :(
     
  7. Maurice

    Maurice Active Member

    Joined:
    Oct 13, 2015
    Messages:
    394
    Likes Received:
    87
    Cool!
    Just wondering, are you sure you are allowed to put UDOO's logo on a product not manufactured by them?
     
  8. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    Hmm Actually it's something I'll ask once I get my code working :) At the moment is a prototype PCB. I can remove it if it's a problem.
    But let come back to the topic :)
     
  9. waltervl

    waltervl UDOOer

    Joined:
    Dec 12, 2015
    Messages:
    2,314
    Likes Received:
    580
  10. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    Uhmm the define should do the same effect as change all of them even if fhe documentation is not clear about changing only the begin or everything and when call Wire1.
    Maybe @Laura or @Francesco knows it.
    Dont't worry about the println. They will be read by a python script in A9
     
    waltervl likes this.
  11. waltervl

    waltervl UDOOer

    Joined:
    Dec 12, 2015
    Messages:
    2,314
    Likes Received:
    580
    OK, they changed the documentation! It will soon say:

    I2C/Wire
    UDOO Neo M4 Processor has 2 I2C buses wired to the pinout headers and consequentially have 2 Wire objects:

    • Wire: for Brick Connector and SCL/SDA Pins [I2C-2]
    • Wire1: for Motion Sensors (Accelerometer,Magnetometer,Gyroscope) [I2C-4]
    Be careful and double check when calling Wire.begin() or Wire1.begin() in sketches or libraries. Also check out to have I2C-2 disabled on A9 if you use Wire, and I2C-4 disabled on A9 if you use Wire1.
     
  12. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    o_O Wat? It's the opposite from before!
    Ok so..since I'm using SDA/SCL from internal pins (M4) I set:
    Wire.begin() in my setup() and I removed it from the library setup. The Udoo devs confirm that Wire.begin() is needed only if there isn't in the library setup.

    The devs also said to remove i2c-2 from the device tree since I cannot use it from A9. So I removed it. Now I have only UART6 and UART1 set. I dunno if it's correct, but I still see my sensors with i2cdetect -y 1 on A9.

    Code:
    [sudo] password for udooer:
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- 77 
    Software-side should be okay now. Right?

    Despite of this "fix", the main problem doesn't seems fixed :mad:
    Sometimes the sketch detects the bmp and starts, sometimes it hangs on bmp.begin().
     
  13. waltervl

    waltervl UDOOer

    Joined:
    Dec 12, 2015
    Messages:
    2,314
    Likes Received:
    580
    Did you make a support call for this? It would be nice that you or the devs mentioned this as now everybodey can learn.
     
  14. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    Of course. I opened a support ticket and I will report any progress.
    Now they asked for my /boot/uEnv.txt to check if my device tree is correct and working.
     
  15. jas-mx

    jas-mx Active Member

    Joined:
    Dec 31, 2013
    Messages:
    407
    Likes Received:
    118
    You can verify if the kernel is still trying to register i2c-2 by seeing what i2c devices are registered:

    Code:
    dmesg | grep i2c 
     
  16. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    Yes it does.

    Code:
    [    0.107127] i2c i2c-0: IMX I2C adapter registered
    [    0.108873] i2c i2c-1: IMX I2C adapter registered
    [    0.109634] i2c i2c-2: IMX I2C adapter registered
    [    1.376943] i2c /dev entries driver
    
    But in my device editor I remove all I2C devices.

    My uEnv.txt is:

    Code:
    udooer@udooneo:~$ cat /boot/uEnv.txt
    #save this file with unix-like newlines! (\n, 0x0A)
    
    video_output=hdmi
    m4_enabled=true
    #m4last=/path/to/arduino/sketch.fw
    #fdt_file=/path/to/custom/devicetree.dtb
    use_custom_dtb=true
    
    Which files should I control?
     
  17. jas-mx

    jas-mx Active Member

    Joined:
    Dec 31, 2013
    Messages:
    407
    Likes Received:
    118
    To find which dtb file is being loaded you need to dump the serial console output of when the board boots (uboot +kernel).
     
  18. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    This is my boot output: https://pastebin.com/Ujs9uvZW
    I used another Udoo to read the boot.
    I supposed I'm using 'imx6sx-udoo-neo-full-hdmi-m4.dtb'. How to print it?

    I didn't use the pcb because I had some problems with minicom and dirty characters because I'm at home and I can't solder the pins properly.
     
    Last edited: Jun 13, 2017
  19. jas-mx

    jas-mx Active Member

    Joined:
    Dec 31, 2013
    Messages:
    407
    Likes Received:
    118
    You need to de-compile the dtb back to a dts file, to do this you need to checkout the kernel source to get the dtc tool. An example command of how to decompile the dtb :

    Code:
    $KERNEL/scripts/dtc/dtc -I dts -O dtb -o <dtb_file> <dts_file>
    
     
  20. Gorgo

    Gorgo UDOOer

    Joined:
    Nov 9, 2016
    Messages:
    159
    Likes Received:
    17
    In /boot/ there're only the .dtb files. Where are .dts?

    Shall I compile it locally to get .dts? (https://www.udoo.org/docs-neo/Advanced_Topics/Compile_Linux_Kernel.html)
     

Share This Page