Beaglebone-Arduino I2C communication

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
baronep
 
Posts: 10
Joined: Sun Jun 21, 2015 4:24 pm

Beaglebone-Arduino I2C communication

Post by baronep »

I am attempting to communicate between my Beaglebone Black and Arduino using i2c. Here is what I have so far

Arduino code:

Code: Select all

// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup()
{
  Serial.begin(9600);
  delay(1000);
  Serial.println("Startup");
  Wire.begin(0x60);                // join i2c bus with address #2
  Wire.onRequest(requestEvent); // register event
}

void loop()
{
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
  Serial.println("Wrote hello");
  float a = 3.14159;
      
  Wire.write((byte *) &a,4); // respond with message of 6 bytes
  Serial.println('%f',(byte *) &a);
  // as expected by master
}
void float2Bytes(float val,byte* bytes_array){
  // Create union of shared memory space
  union {
    float float_variable;
    byte temp_array[4];
  } u;
  // Overite bytes of union with float variable
  u.float_variable = val;
  // Assign bytes to input array
  memcpy(bytes_array, u.temp_array, 4);
}

Code: Select all


>> i2cdetect -y -r 1

 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

>> i2cdump -y 1 0x60

No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
10: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
20: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
30: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
50: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
80: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
a0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
b0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
c0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
d0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
e0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED
f0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    BANNED

>> i2cget -y 1 0x60

0xd0

(The 0xd0 is the last byte of 3.14159)
I can't however seem to submit a valid read request from the adafruit beaglebone i2c library. I want to read the 4 bytes from the arduino, but I cant seem to figure out how to do the equivalent of arduino's requestFrom function.

User avatar
baronep
 
Posts: 10
Joined: Sun Jun 21, 2015 4:24 pm

Re: Beaglebone-Arduino I2C communication

Post by baronep »

After a bit more research I think that it is because the Arduino wire library does not support repeated starts. Is there a way to disable repeated starts so that the stop byte is sent in between the register byte and the start byte?

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Beaglebone-Arduino I2C communication

Post by adafruit_support_mike »

Could you post the Python code you're using on the BBB please?

User avatar
baronep
 
Posts: 10
Joined: Sun Jun 21, 2015 4:24 pm

Re: Beaglebone-Arduino I2C communication

Post by baronep »

Python code

Code: Select all

import time
from Adafruit_I2C import Adafruit_I2C
i2c = Adafruit_I2C(0x60,busnum=1)
s = i2c.bus
print i2c.readList(0x00,6)
Newer simplified Arduino code
This is essentially the slave sender example but I changed the address

Code: Select all

// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup()
{
  Wire.begin(0x60);                // join i2c bus with address #2
  Wire.onRequest(requestEvent); // register event
}

void loop()
{
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
  Wire.write("hello "); // respond with message of 6 bytes
  // as expected by master
}
I can still use i2cget to get the first byte 0x68 or 'h', but I can't figure out how to get all of the bytes. Is there any way to forgo the Adafruit macros and use python-smbus directly to get around this problem?

User avatar
baronep
 
Posts: 10
Joined: Sun Jun 21, 2015 4:24 pm

Re: Beaglebone-Arduino I2C communication

Post by baronep »

So even after another few hours of hacking I'm still not able to get this to work. I tried this (https://gist.github.com/gileri/5a9285d6a1cfde142260) which I modified below changing the addresses and initializing with the adafruit library but still nothing. I can still get a single byte, but I don't get anything if I request an address or block using either i2cget or smbus. Is there any other diagnostic information that I can post?

Arduino:

Code: Select all

#include <Wire.h>
 
#define SLAVE_ADDRESS 0x60
 
#define FLOATS_SENT 2
 
float temperature = 10.5;
float luminosity = 5.2;
float data[FLOATS_SENT];
 
void setup() {
    pinMode(13, OUTPUT);
    Serial.begin(9600);
    
    data[0] = temperature;
    data[1] = luminosity;
    
    // initialize i2c as slave
    Wire.begin(SLAVE_ADDRESS);
 
    // define callbacks for i2c communication  
    Wire.onRequest(sendData);
}
 
void loop() {
    delay(100);
}
 
void sendData(){
  Wire.write((byte*) &temperature, FLOATS_SENT*sizeof(float));
}
BBB:

Code: Select all

import time
from Adafruit_I2C import Adafruit_I2C
import struct

address = 0x60

def get_data():
    return bus.read_i2c_block_data(address, 0);

def get_float(data, index):
    bytes = data[4*index:(index+1)*4]
    return struct.unpack('f', "".join(map(chr, bytes)))[0]

i2c = Adafruit_I2C(0x60,busnum=1)
bus = i2c.bus

while True:
    try:
        data = get_data()
        print(get_float(data, 0))
        print(get_float(data, 1))
    except:
        continue
time.sleep(1);

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Beaglebone-Arduino I2C communication

Post by adafruit_support_mike »

Mostly I needed to see the name of the module you were importing. Looks like you're using Adafruit_Python_GPIO.

Not only does that code not provide a way to disable repeated starts, it has a workaround to guarantee repeated starts on versions of the RasPi with a known bug that fails to do them.

The biggest problem is that repeated starts are the correct-according-to-spec behavior. The BBB is doing what it's supposed to, and the Arduino library is noncompliant.

The readRaw8 and writeRaw8 methods don't use a register, so you might try using those.

User avatar
baronep
 
Posts: 10
Joined: Sun Jun 21, 2015 4:24 pm

Re: Beaglebone-Arduino I2C communication

Post by baronep »

Right you were mike. It looks like the BBB is operating according to i2c spec and the arduino isn't.

The bug fix is simple and involves deleting or commenting one line in the TWI code: https://github.com/helenarobotics/Ardui ... 2b39b0fbca.

It is surprising that arduino has failed to remedy this (or even support a config option) to actually FOLLOW the I2C spec after 3 years. If there is a techinical reason that prevents implementing this fix then I am all ears but this caused a lot of pain on my end. Come on guys

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Beaglebone-Arduino I2C communication

Post by adafruit_support_mike »

It's probably a combination of inertia and obscurity. Not many people use the Arduino as an I2C client, and of those who do, not many will probably need correct repeated-start behavior.

Constructive feedback is the way to solve Open Source problems though.. post a description of the problem, the solution, and a measured dose of irritation over in the Arduino forums: http://forum.arduino.cc/

The IDE is getting a lot of work right now, so it shouldn't be hard to work that fix into an update once the developers know where to look.

Locked
Please be positive and constructive with your questions and comments.

Return to “Beagle Bone & Adafruit Beagle Bone products”