Author Topic: I²C issue on Raspberry Pi  (Read 2113 times)

0 Members and 1 Guest are viewing this topic.

Offline BlaffetuurTopic starter

  • Regular Contributor
  • *
  • Posts: 65
  • Country: be
I²C issue on Raspberry Pi
« on: January 06, 2018, 09:14:44 am »
Hi all,

I'm trying to get I²C communication going between a Raspberry Pi (master) and Arduino Uno (slave). Have a look at the PDF in the attachment, there I descirbe the problem in more detail.

I have 3 python scripts:
1. Request data from the slave: works fine
2. Send data to slave: works fine
3. Send data to slave and then read data from slave: gives me troubles.

Any help would be appreciated, Thanks  ;D !

-Robin
 

Offline frozenfrogz

  • Frequent Contributor
  • **
  • Posts: 936
  • Country: de
  • Having fun with Arduino and Raspberry Pi
Re: I²C issue on Raspberry Pi
« Reply #1 on: January 06, 2018, 10:10:00 am »
Might very well be a stretching issue, you can read more about it here: http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
There are also some suggested workarounds.
Maybe, you could dump I2C in favor of SPI?

Edit:
Here is also an informative write-up for the I2C interface.
https://aticleworld.com/i2c-bus-protocol-and-interface/
« Last Edit: January 06, 2018, 10:13:14 am by frozenfrogz »
He’s like a trained ape. Without the training.
 
The following users thanked this post: Blaffetuur

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4247
  • Country: gb
Re: I²C issue on Raspberry Pi
« Reply #2 on: January 06, 2018, 01:13:07 pm »
This is usually an anti-pattern that will burn you.

Code: [Select]
void receiveEvent(int howMany){
 while (Wire.available()){
 data = Wire.read();
 }
 rec = true;
}

Typically available() methods on streams or sockets tells you if there is something available to read "right now", ie. sitting in the read buffer.  available() returning 0 does not mean the transmission has finished.  I see people making this mistake quite a lot and in 99% of cases it will work fine, but when it doesn't it will be a pig to find out why.

It is better to communicate how the long the message is in the first few bytes, message header, and then wait on that many bytes arriving or timeout.  Or if you know how many bytes you are going to receive then check you have received that many.  Timeouts and blocking versus non blocking IO stuff would go here.

You appear to be only reading/writing one byte though, so it's academic.  However, you are depending on the Wire event model to know there is a byte available.  If available returns 0 your code will exit that function without actually reading a byte.

Don't run python as root.  Ignore what the idiots at Adafruit etc. tell you.  Add yourself to the relevant groups, logout and in again.  If you find a library which outputs "Expecting to run as root", edit it, delete that code.  It's dumb.  There are VERY few circumstances were you 'need' to run basic user scripts as root.  Those would include system administration or access system files... which is why you don't run scripts that don't need to do those things as root, because if they go wrong they can trash your system.  The reason why Adafruit et al suggest it is laziness and not bothering newbies with groups and chmod/chown etc.

https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=88718

And don't set files to 777 ever.

The only potentially relevant exception to this is if you need near-realtime priority for timing.  I do not believe this is require for I2C as the PI is more than fast enough.

As to your actual problem.  The clock pulse on the start of the data word appears mangled on the scope. That is the bit the PI is reading wrong which suggests it's being intercepted incorrectly, potentially due to the mangled clock pulse.
« Last Edit: January 06, 2018, 01:18:33 pm by paulca »
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4247
  • Country: gb
Re: I²C issue on Raspberry Pi
« Reply #3 on: January 06, 2018, 01:52:41 pm »
So I did a bit of digging and that mangled clock pulse is almost certainly the ATMega trying to slow the master down because the Wire library has not responded yet by setting a flag that it received the data.

See:
https://www.reddit.com/r/arduino/comments/2jip7s/are_there_ways_to_disable_clock_stretching_for/

The only viable options seem to be:
Slow the I2C clock down.
Make the Arduino master
Bit bang the hardware I2C yourself to set the TWINT flag as fast as possible.
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 
The following users thanked this post: Blaffetuur

Offline BlaffetuurTopic starter

  • Regular Contributor
  • *
  • Posts: 65
  • Country: be
Re: I²C issue on Raspberry Pi
« Reply #4 on: January 07, 2018, 08:49:04 am »
So I did a bit of digging and that mangled clock pulse is almost certainly the ATMega trying to slow the master down because the Wire library has not responded yet by setting a flag that it received the data.

See:
https://www.reddit.com/r/arduino/comments/2jip7s/are_there_ways_to_disable_clock_stretching_for/

The only viable options seem to be:
Slow the I2C clock down.
Make the Arduino master
Bit bang the hardware I2C yourself to set the TWINT flag as fast as possible.

Thanks for the tips ! I'm definitely going to look into the wire library some more and I never gave a second tought about running my scripts as root  :P. Two thing added to my to do list  ;D

Quote
The clock pulse on the start of the data word appears mangled on the scope.
Man I saw this too  |O I was so focused on the aknowledging part that I didn't added this to my list of possible causes.

As for the posibble solutions, I chose to slowing the clock down first:

Tried this http://www.mindsensors.com/blog/how-to/change-i2c-speed-with-raspberry-pi site first without much succes. The instructions used the don't appear to be effective in Raspbian Jessee.

By adding the folowing line to /boot/config.txt I was able to change the baud rate of the I²C bus  :D
Code: [Select]
dtparam=i2c_arm_baudrate=10000
I arbitrarily chose 10kpbs and it seems to be working fine. Did not yet tried at which speed it stops working.
 

Offline BlaffetuurTopic starter

  • Regular Contributor
  • *
  • Posts: 65
  • Country: be
Re: I²C issue on Raspberry Pi
« Reply #5 on: January 07, 2018, 09:36:06 am »
Might very well be a stretching issue, you can read more about it here: http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
There are also some suggested workarounds.
Maybe, you could dump I2C in favor of SPI?

Edit:
Here is also an informative write-up for the I2C interface.
https://aticleworld.com/i2c-bus-protocol-and-interface/

Yeah I see it now, thanks for the great article  :-+ it gives a really good explenation of what's happening. One of the suggestions is slowing down the I²C clock and thats exactly what I've done to solve it.
 

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4247
  • Country: gb
Re: I²C issue on Raspberry Pi
« Reply #6 on: January 07, 2018, 10:01:53 am »
I never gave a second tought about running my scripts as root  :P. Two thing added to my to do list  ;D

I recall that some of the Adafruit python libraries attempt to do a "modprobe", for example, "modprobe i2c-dev".  They need root for that to work.

However, again, it's a bit dumb doing this in a user script which shouldn't be changing kernel modules.  They tend to run the python script as root so it can do this.

The correct way is to set those up with either raspb-config or /boot/config.txt or the traditional /etc/modprobe.d/ entries.
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf