8月 16

raspberry pi 使用mpu 6050三轴加速度 陀螺仪模块

连接线图。

raspberry pi 使用mpu 6050三轴加速度 陀螺仪模块

raspberry pi 使用mpu 6050三轴加速度 陀螺仪模块


raspberry pi 使用mpu 6050三轴加速度 陀螺仪模块

raspberry pi 使用mpu 6050三轴加速度 陀螺仪模块


  安装工具
sudo apt-get install -y python-smbus i2c-tools

编辑文件
$sudo vim /etc/modules
内容如下
i2c-bcm2708
i2c-dev

$vim /etc/modprobe.d/raspi-blacklist.conf
内容如下,直接注释掉
#blacklist spi-bcm2708
#blacklist i2c-bcm2708

测试一下
512M Pi’s use i2c port 1, 256M ones use i2c port 0!

pi@raspberrypi ~ $ 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: — — — — — — — — 68 — — — — — — —
70: — — — — — — — —

  一切正常。地址68在代码中会用到。源码如下。

#! /usr/bin/python
# -*- coding:utf-8 -*-
# Revision:
# Date:        2013-08-16
# Author:      simonzhang
# Email:       simon-zzm@163.com
# Web:         www.simonzhang.net
# -------------------------------

from time import sleep
from math import sqrt, atan

class i2c(object):
    # MPU6050内部地址,需查手册获得
    def __init__(self):
        # raspberry pi A is 0,B is 1
        self.pi = 1
        # iic address of MCP23017
        # 上面测试时候的地址
        self.address = 0x68
        # 
        import smbus
        self.bus = smbus.SMBus(self.pi)
        # 电源管理,正常启动接触休眠值0x00
        self.bus.write_byte_data(self.address, 0x6B, 0x00)
        # 陀螺仪采样率,典型值:0x07(125Hz)
        self.bus.write_byte_data(self.address, 0x19, 0x07)
        # 低通滤波频率,典型值:0x06(5Hz)
        self.bus.write_byte_data(self.address, 0x1A, 0x06)
        # 陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
        self.bus.write_byte_data(self.address, 0x1B, 0x18)
        # 加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
        self.bus.write_byte_data(self.address, 0x1C, 0x01)
    # 3轴的加速度
    def read_accel(self):
        # x轴 
        self.accel_x_h = self.bus.read_byte_data(self.address, 0x3B)
        self.accel_x_l = self.bus.read_byte_data(self.address, 0x3C)
        # y轴
        self.accel_y_h = self.bus.read_byte_data(self.address, 0x3D)
        self.accel_y_l = self.bus.read_byte_data(self.address, 0x3E)
        # z轴
        self.accel_z_h = self.bus.read_byte_data(self.address, 0x3E)
        self.accel_z_l = self.bus.read_byte_data(self.address, 0x3F)
        return self.accel_x_h, self.accel_x_l, \
               self.accel_y_h, self.accel_y_l, \
               self.accel_z_h, self.accel_z_l, \
    # 陀螺仪3轴角加速度,每秒多少度
    def read_gyro(self):
        # x轴角速度
        self.gyro_x_h = self.bus.read_byte_data(self.address, 0x43)
        self.gyro_x_l = self.bus.read_byte_data(self.address, 0x44)
        # y轴角速度
        self.gyro_y_h = self.bus.read_byte_data(self.address, 0x45)
        self.gyro_y_l = self.bus.read_byte_data(self.address, 0x46)
        # z轴角速度
        self.gyro_z_h = self.bus.read_byte_data(self.address, 0x47)
        self.gyro_z_l = self.bus.read_byte_data(self.address, 0x48)
        return self.gyro_x_h, self.gyro_x_l, \
               self.gyro_y_h, self.gyro_y_l, \
               self.gyro_z_h, self.gyro_z_l, \
    # 3轴与自然轴角度,参考他人的算法,也不是很明白
    def read_nature_axle_angle(self):
        # 先开方,然后在算出弧度,最后把弧度转换为角度
        # 使用try 防止分母为0
        # x轴
        tmp = self.accel_x_h/int(sqrt((self.accel_y_h*self.accel_y_h+self.accel_z_h*self.accel_z_h)))
        self.x_nature_axle_angle = int(atan(tmp)*1800/3.14)
        # y轴
        tmp = self.accel_y_h/int(sqrt((self.accel_x_h*self.accel_x_h+self.accel_z_h*self.accel_z_h)))
        self.y_nature_axle_angle = int(atan(tmp)*1800/3.14)
        # z轴
        try:
            tmp = int(sqrt((self.accel_x_h*self.accel_x_h+self.accel_y_h*self.accel_y_h)))/self.accel_z_h
        except:
            pass
        self.z_nature_axle_angle = int(atan(tmp)*1800/3.14)
        return self.x_nature_axle_angle,self.y_nature_axle_angle, self.z_nature_axle_angle
    # 芯片温度
    def read_temp(self):
        self.temp_out_h = self.bus.read_byte_data(self.address, 0x41)
        self.temp_out_l = self.bus.read_byte_data(self.address, 0x42)
        return self.temp_out_h, self.temp_out_l
        
def main():
    i = i2c()
    while 1:
        print i.read_accel()
        print i.read_gyro()
        print i.read_temp()
        print i.read_nature_axle_angle()
        print "=" * 20
        sleep(0.5)
   
if __name__ == "__main__":
   main()

  因为要在管理员环境下运行。命令如下
sudo python iic_python.py

开始收集测试数据。
测试源码

参考
http://wiki.erazor-zone.de/wiki:linux:python:smbus:doc
http://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/configuring-i2c
http://blog.sina.com.cn/s/blog_8240cbef01018i10.html
http://www.geek-workshop.com/thread-2328-1-1.html

5月 09

raspberry pi 测试pypy 切割图片效率

为了方便安装pypy的第三方库,首先安装pip。
$ curl -O http://python-distribute.org/distribute_setup.py
$ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py
$ sudo pypy distribute_setup.py
$ sudo pypy get-pip.py

首先找了一个3M(3072×2304)的图片,缩小为300×300的大小
脚本:

# -*- coding:utf-8 -*-
# -------------------------------
# Filename:    .py
# Revision:    1.0
# Date:        2013-05-08
# Author:      simonzhang
# Web:         www.simonzhang.net
# Email:       simon-zzm@163.com
# -------------------------------


from PIL import Image


def main():
    get_data = Image.open('test.jpg')
    tmp = get_data.resize((300, 300),)
    tmp.save('test1.jpg', 'JPEG', quality=75)


if __name__ == '__main__':
    main()

在pypy上装PIL
$ sudo /usr/lib/pypy-upstream/bin/pip install PIL

运行脚本报错如下:

File “/usr/lib/pypy-upstream/site-packages/PIL/Image.py”, line 1290, in resize
self.load()
File “/usr/lib/pypy-upstream/site-packages/PIL/ImageFile.py”, line 189, in load
d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
File “/usr/lib/pypy-upstream/site-packages/PIL/Image.py”, line 385, in _getdecoder
raise IOError(“decoder %s not available” % decoder_name)
IOError: decoder jpeg not available

不能调用系统库,之前在处理过这种问题http://www.simonzhang.net/?p=435
但是pypy比较复杂,兼容有问题。直接删除PIL,使用pillow。Pillow基础就是PIL只是兼容性强,更利于推广。
$ sudo /usr/lib/pypy-upstream/bin/pip uninstall PIL

$ sudo /usr/lib/pypy-upstream/bin/pip install pillow

注意必须使用
from PIL import Image

否则会报错
File “/usr/lib/pypy-upstream/site-packages/PIL/Image.py”, line 2020, in open
raise IOError(“cannot identify image file”)
IOError: cannot identify image file

在安装完pillow后没有产生PIL.pth文件,直接手动写一个。
$ sudo vim /usr/lib/pypy-upstream/site-packages/PIL.pth
内容是:PIL。

开始测试

time python cut_pic.py

real 0m2.841s
user 0m2.630s
sys 0m0.200s

time pypy cut_pic.py

real 0m5.144s
user 0m4.870s
sys 0m0.230s

图片产生大小如下
-rw-r–r– 1 pi pi 3588203 5月 8 16:02 test.jpg
-rw-r–r– 1 pi pi 21907 5月 8 16:10 test_pypy.jpg
-rw-r–r– 1 pi pi 21907 5月 8 16:09 test_python.jpg

直接使用python的效果更佳,不清楚原因。之后有版本升级了再做测试。

5月 08

raspberry pi上测试pypy效果

PyPy 2.0 alpha for ARM 发布

官方网页
http://pypy.org/download.html

有专门针对raspberry pi的版本。来简单做个测试。
我这竟还要翻墙下回来。
安装很顺利。
$sudo dpkg -i pypy-upstream_2.0~alpha+arm_armhf.deb

开始测试一下效果,直接到oschina拷贝“ruby太慢的”python版测试一下。

import time
start=time.time()
all=xrange(1,10**7)
def check(num):
    a=list(str(num))
    b=a[::-1]
    if a==b:
        return True
    return False
for i in all:
    if check(i):
        if check(i**2):
            print i,i**2
 
end=time.time()
print end-start

开始测试
直接用python测试
time python test.py
。。。

real 8m13.570s
user 8m3.490s
sys 0m0.560s

使用pypy测试
time pypy test.py
。。。

real 1m45.521s
user 1m44.230s
sys 0m0.150s

结论使用pypy处理运算速度比python高出差不多7倍的效果。

2月 05

raspberry pi 串口控制51单片机

  制作小车都用raspberry pi上的口有些麻烦,所以把一些基础控制给51单片机解决,raspberry pi控制高层应用。所以测试一下raspberry pi串口连接调试51单片机。
  第一步: 
sudo apt-get install python-serial
sudo easy_install pyserial

  第二部接线部分图
  raspberry pi板子串口接线图

raspberry 串口接线图1

raspberry 串口接线图1


  杜邦线连接
IMAG1302-1 
raspberry 串口接线图3

raspberry 串口接线图3

 

  代码部分
  raspberry pi python串口控制代码

#!/bin/env python
# -*- coding:utf-8 -*-
# -------------------------------
# Filename:    
# Revision:    
# Date:        2013-02-5
# Author:      simonzhang
# Email:       simon-zzm@163.com
# WWW:         www.simonzhang.net
# -------------------------------
import serial
import time

#### 定义小灯亮灭初始值
i = 0 
#### 实例化串口
ser = serial.Serial('/dev/ttyAMA0', 9600, timeout = 0.5)
for j in range(10):
    if ser.isOpen() == False:
        ser.open()
    #### 每次循环对上值次取反
    if i == 0:
       i = 1
    else:
       i = 0
    #### 向串口发送字符
    ser.write(chr(i))
    #### 获取串口返回值
    #### linux为福阻塞模式,在阻塞模式下
    #### 会报错,所以抱起来就好了。
    try:
        re = ser.readlines()
    except:
        pass
    print re
    time.sleep(2)

  51单片机代码

#include 
#include 
typedef unsigned char uint8;
typedef unsigned int  uint16;


uint8 num;
sbit D0 = P0^0; 

void init()
{
	SCON = 0x50;
    TMOD = 0x20;

	TH1 = 0xFD;
	TL1 = 0xFD;
	TR1 = 1; //打开定时器
	ES  = 1;
	EA  = 1; //打开总开关
}

void interrupt_uart() interrupt 4
{
	if(TI)
	{
		TI = 0;
		REN = 1;
	}
	if(RI)
	{
		RI = 0;
		num = SBUF;	
		if (num == 1)
		{
			D0 = 0;
			SBUF = 0;
		}
		else
		{
			D0 = 1;
			SBUF =1;
		}
		REN = 0;
	}
}


main()
{
	init();
	while(1);
}

源码下载
raspberrypito51

2月 04

raspberry pi 开机wifi自动启动并发邮件通知(二)

比之前脚本添加了,测试公网IP的函数。
def get_global_ip():
get_html = urllib2.urlopen(‘http://iframe.ip138.com/ic.asp’).read()
_re_ip = re.compile(r’\d{2,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}’, re.DOTALL)
_global_ip = _re_ip.findall(get_html)[0]
return _global_ip

代码下载NotificationIP.py