A20 and MOD-Wii-UEXT-NUNCHUCK: read_i2c_block_data [SOLVED]

Started by Tar, April 02, 2014, 10:22:05 PM

Previous topic - Next topic

Tar

Hi,

Inspired by http://olimex.wordpress.com/2013/01/11/raspberry-pi-project-interfacing-wii-nunchuk-with-rpi/ i want to use the Nunchuck controller with my A20 Olinuxino, but don`t have any success.

I tried the test-tool from https://github.com/OLIMEX/raspberrypi/blob/master/MOD-Wii-NUNCHUK/mod-nunchuck.py
changed it to use the right SMBus (2), but:

olimex@a20-OLinuXino:~/src/CamControl$ python mod-nunchuck.py
Traceback (most recent call last):
  File "mod-nunchuck.py", line 65, in <module>
    main()
  File "mod-nunchuck.py", line 29, in main
    buf = bus.read_i2c_block_data(address, command, 6)
IOError: [Errno 70] Communication error on send

I plugged it into UEXT2 and see it:
olimex@a20-OLinuXino:~/src/CamControl$ /usr/sbin/i2cdetect -y sunxi-i2c.2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- 52 -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --                         
olimex@a20-OLinuXino:~/src/CamControl$ /usr/sbin/i2cdump -y sunxi-i2c.2 0x52
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    XXXXXXXXXXXXXXXX
10: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
20: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
30: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
50: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
80: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
a0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
b0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
c0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
d0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
e0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
f0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX

Any Idea?

EDIT:

Well, finally i found a c version of the python code, which does not use read_i2c_block_data. Without this call, everything is fine.
read_i2c_block_data sends a byte and reads multiple data
i now write_byte_data and afterwards read 6 single bytes with read_byte_data. This works.

Maybe one of the i2c geeks may explain why the read_i2c_block data version works on RasPi but not on OLinuXino.
i
Regards,

Tar

to_m99

I have the same problem with read_i2c_block_data.

First I started with:

import smbus
import time
bus = smbus.SMBus(2)

bus.write_byte_data(0x52,0x40,0x00)
time.sleep(0.1)

while True:
  print '#',
  try:
    bus.write_byte(0x52,0x00)
    time.sleep(0.1)
   
    data0 =  bus.read_byte(0x52)
    data1 =  bus.read_byte(0x52)
    data2 =  bus.read_byte(0x52)
    data3 =  bus.read_byte(0x52)
    data4 =  bus.read_byte(0x52)
    data5 =  bus.read_byte(0x52)

    joy_x = data0
    joy_y = data1
    accel_x = (data2 << 2) + ((data5 & 0x0c) >> 2)
    accel_y = (data3 << 2) + ((data5 & 0x30) >> 4)
    accel_z = (data4 << 2) + ((data5 & 0xc0) >> 6)
    buttons = data5 & 0x03
    button_c = (buttons == 1) or (buttons == 2)
    button_z = (buttons == 0) or (buttons == 2)
    print 'Jx: %s Jy: %s Ax: %s Ay: %s Az: %s Bc: %s Bz: %s' % (joy_x, joy_y, accel_x, accel_y, accel_z, button_c, button_z)
   
  except IOError as e:
    print e
  time.sleep(0.1)


and it worked perfectly.
But reading was to slow for me. So I changed sleep time to 0.01 with the consequence that I got sometimes reading errors and values were jumping.
http://www.raspberrypi.org/forums/viewtopic.php?&t=28231
Additional CPU usage was to high.

Now I compared it with a C implementation to see if I have the same issues there.
Result when reading 6x(1 byte):
even with a delay of only 2ms, values where stable (+/- 1).
CPU usage: 20%  :(

Result when reading 1x(6 byte):
CPU usage dropped to 8%  :D

So I think read_i2c_block_data would help, if you need a higher refresh rate and/or less CPU usage.

Br,
Tom

Tar

Hi Tom,

in fact i did not search the raspi forum, it would also have saved some time for me.

The funny thing is - olimex demo code seems to run on a raspi. Just now, i don`t have one for comparison. Nevertheless, the read_byte version, as well as the c-code, which uses
num_bytes_read = 6;
if ((file = open(device, O_RDWR)) < 0)
exit(1);


if(ioctl(file, I2C_SLAVE, address) < 0)
exit(1);
if(read(file, buffer_in, num_bytes_read) != num_bytes_read)
exit(1);

show a result.

For the c-version, the CPU usage is about 4% at a delay of 10ms between the loops, if I go down to 1ms, it reaches 20%.