update: 2016/03/03
reference:
1.Raspberry Pi and Arduino Connected Using I2C - OscarLiang.net
2. [I2C] onRequest and onReceive as slave with Raspberry Pi Master
A. 檢查 Raspberry Pi:
1. Linux 版本
$ uname -a
Linux raspberrypi 4.1.17-v7+ #843 SMP Mon Feb 15 23:35:33 GMT 2016 armv7l GNU/Linux
2. python 版本
$ python -V
Python 2.7.9
-----------------------------------------------------------------------------------------------
B. 安裝 I2C 與 python相關套件:
$ sudo apt-get install python-smbus
$ sudo apt-get install python3-smbus // for python3
$ sudo apt-get install i2c-tools
// check
$ sudo aptitude search smbus
p pypy-smbus-cffi - This Python module allows SMBus access through the I2C /dev
i python-smbus - Python bindings for Linux SMBus access through i2c-dev
v python2.7-smbus -
i python3-smbus - Python 3 bindings for Linux SMBus access through i2c-dev
-----------------------------------------------------------------------------------------------
C. 安裝 I2C 的 Kernel Support:
$ sudo raspi-config
> 9 Advanced Options
> A7 I2C
....
> YesD. 檢查設定(選擇性)
$ cat /etc/modules
....
i2c-dev
$ cat /etc/modprobe.d/raspi-blacklist.conf
# ...
# ...
$ cat /boot/config.txt
....
dtparam=i2c_arm=on
$ cat /etc/group | grep i2c
i2c:x:998:pi
// $ sudo adduser pi i2c
-----------------------------------------------------------------------------------------------
E. I2C 測試:
$ 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: -- -- -- -- -- -- -- --
$ ls /dev/i2c*
/dev/i2c-1
-----------------------------------------------------------------------------------------------
F. Arduino Code:
#include <Wire.h>
#define SLAVE_ADDRESS 0x04
int number = 0;
int state = 0;
void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600); // start serial for output
// initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
//Serial.println(“Ready!”);
}
void loop() {
delay(100);
}
// callback for received data
void receiveData(int byteCount){
while(Wire.available()) {
number = Wire.read();
//Serial.print(“data received: “);
//Serial.println(number);
if (number == 1){
if (state == 0){
digitalWrite(13, HIGH); // set the LED on
state = 1;
}
else{
digitalWrite(13, LOW); // set the LED off
state = 0;
}
}
}
}
// callback for sending data
void sendData(){
Wire.write(number);
}
-----------------------------------------------------------------------------------------------
G. Raspberry Pi's Python Code:
#!/usr/bin/python
#encoding: utf-8
import smbus
import time
# for RPI version 1, use "bus = smbus.SMBus(0)"
bus = smbus.SMBus(1)
# This is the address we setup in the Arduino Program
address = 0x04
def writeNumber(value):
bus.write_byte(address, value)
# bus.write_byte_data(address, 0, value)
return -1
def readNumber():
number = bus.read_byte(address)
# number = bus.read_byte_data(address, 1)
return number
while True:
var = input("Enter 1 – 9:")
if not var:
continue
writeNumber(var)
print "RPI: Hi Arduino, I sent you ", var
# sleep one second
time.sleep(1)
number = readNumber()
print "Arduino: Hey RPI, I received a digit ", number
-----------------------------------------------------------------------------------------------
H. 備註:
When we use read_i2c_block_data(), It was too fast to write a command byte and read the data.
In that time, if we use Serial.println() to print log to serial. Arduino will can not follow the speed. and it missing the i2c read flag.
So, the dataReceive() funtion will not be run at all.
The solution is simple: just do not use Serial library until the i2c is free.
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。