在上面的任务中可见,智能家居机器人系统分为两层结构:嵌入式控制板和底层控制板。嵌入式控制板是整个系统的中心,具有强大的嵌入式内核,负责强大的数据运算、智能分析和视觉处理显示控制等,基本上就是一台“迷你”型计算机;底层控制板属于单片机级别,主要负责传感器的数据采集、逻辑判断及机器人的电机驱动等,属于强大的机器人控制器(具有控制灵活、编程方便等特点)。
嵌入式控制板和底层控制系统板之间通过什么方式通信呢?这是本任务的主要目标。通过上一节的学习,可知嵌入式控制板用USB和底层控制板相连,这样在嵌入式控制板上可以直接对底层控制板编程和自动更新底层控制板中的程序,使用非常方便。但是嵌入式控制板上面的USB资源是有限的,如果需要扩展更多的USB设备,就会使得USB资源不够用,而且嵌入式控制板和底层控制板通过USB通信,其实是USB转串口的通信方式,串口端口容易发生变化,在嵌入式控制板上面的程序不能通用,而且通信的速度受限,不能进行高速传输,所以在这里主要是以I2C通信来对接两个控制板,而USB接口基本上负责下载程序用。
嵌入式控制板和底层控制板接线可以参考图2.5.3,嵌入式控制板GPIO PIN3连接底层板的PC4/SDA、PIN5连接底层板的PC5/SCL。
注意:这个接线图需要牢记,因为在后面的内容中会频繁使用它。
当硬件电路连接好之后,开始操作软件部分。嵌入式控制板自带的I2C为连接众多I2C的外部设备提供了方便。
首先,需要修改嵌入式控制板系统的配置文件,通过nano编辑器修改“raspi-blacklist.conf”文件的内容:
pi@raspberrypi ~ $ sudo nano /etc/modprobe.d/raspi-blacklist.conf
图2.5.3 嵌入式控制板和底层控制板通信接线
修改后的内容如下,开启I2C功能:
# blacklist spi and i2c by default (many users don't need them)
blacklist spi-bcm2708
blacklist i2c-bcm2708
打开“/etc/modules”文件,在文件结尾处加上“i2c-dev”:
pi@raspberrypi ~ $ sudo nano /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
# Parameters can be specified after the module name.
snd-bcm2835
i2c-bcm2708
i2c-dev
更新一次包列表:
pi@raspberrypi ~ $ sudo apt-get update
安装I2C-tools工具与Python-smbus:
pi@raspberrypi ~ $ sudo apt-get install i2c-tools python-smbus
设置允许Pi用户访问 I2C 设备:
$ sudo adduser pi i2c
重启嵌入式控制板系统,在这以后,应该可以看到I2C设备:
pi@raspberrypi ~ $ ll /dev/i2c*
crw-rw---T 1 root i2c 89, 0 May 25 11:56 /dev/i2c-0
crw-rw---T 1 root i2c 89, 1 May 25 11:56 /dev/i2c-1
现在运行一个简单的测试,扫描I2C总线:
pi@raspberrypi ~ $ 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: -- -- -- -- -- -- -- --
1. 把arduino设置为I2C通信的从设备
编写一个简单的程序,这里设置arduino I2C通信的从地址为“0×04”,通过获取在嵌入式系统板上面的蓝牙键盘中输入的数字“1”,然后利用I2C通信把数字“1”传递给arduino。当arduino接收到来自I2C总线上的数字“1”时,arduino控制器上面自带的LED灯即被控制。
这个程序在arduino IDE 1.0编程环境下经过了测试:
#include 〈Wire.h〉
#define SLAVE_ADDRESS 0x04
int number = 0;
int state = 0;void setup() {
pin Mode(13, OUTPUT);
Serial.begin(9600); // start serial for output
// initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);
// define callbacks for i2c communication
Wire.on Receive(receive Data);
Wire.on Request(send Data);
Serial.println("Ready!");
}
void loop() {
delay(100);
}
// callback for received data
void receive Data(int byte Count){
while(Wire.available()) {
number = Wire.read();
Serial.print("data received: ");
Serial.println(number);
if (number == 1){
if (state == 0){
digital Write(13, HIGH); // set the LED on
state = 1;
}
else{
digital Write(13, LOW); // set the LED off
state = 0;
}
}
}
}
// callback for sending data
void send Data(){
Wire.write(number);
}
2. 把嵌入式控制板设置为I2C通信的主设备
进行Python编程并利用arduino 建立I2C通信。嵌入式控制板需要获取在键盘输入的数字“1”,再把数字“1”通过I2C总线发送出来,让arduino接收到命令,进行对LED的控制。
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 write Number(value):
bus.write_byte(address, value)
# bus.write_byte_data(address, 0, value)
return -1
def read Number():
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
write Number(var)
print "RPI: Hi Arduino, I sent you ", var
# sleep one second
time.sleep(1)
number = read Number()
print "Arduino: Hey RPI, I received a digit ", number
如果要确保功能测试成功,那么在终端中再次运行I2cdetect-y 1,此应该得到这样的“04”地址,即与arduino建立了正常的通信。
pi@raspberrypi ~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
如果显示的数字就是“04”,则说明程序是正常的。可以试试按下键盘上面的数字键“1”,是不是看到arduino LED闪烁了呢?如果没有闪烁,请检查接线和编程是否有错误。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。