12月 07

raspberry pi连接摄像头

  安装pygame产生窗口用,cv获取摄像头图像
$ sudo easy_install pygame
$ sudo apt-get install -y python-opencv

代码如下:

#!/bin/env python
# -*- coding:utf-8 -*-
# -------------------------------
# Filename:   
# Revision:
# Date:        2012-12-7
# Author:      simonzhang
# Email:       simon-zzm@163.com
# Web:         www.simonzhang.net
# -------------------------------
import pygame
import cv

pygame.init()
size = width, height = 640, 480
speed = [1, 1]  
black = 0, 0, 0  
  
pygame.display.set_caption('simonzhag.net')
screen = pygame.display.set_mode(size)

cam = cv.CreateCameraCapture(0)
cv.SetCaptureProperty(cam,cv.CV_CAP_PROP_FRAME_WIDTH, 640)
cv.SetCaptureProperty(cam,cv.CV_CAP_PROP_FRAME_HEIGHT, 480);

while 1:
    try:
        cv.GrabFrame(cam)
        img = cv.RetrieveFrame(cam)
        cv.SaveImage('/tmp/test.jpg', img)
    except:
        pass
    cv.WaitKey(1500)
    image = pygame.image.load('/tmp/test.jpg')
    screen.blit(image, speed)
    pygame.display.flip()

image

  如果cv.WaitKey过小或者请求太多会报select timeout。还不知道是摄像头问题、还是我的存储开始class2的问题。图像也经常获取不全,问题还未处理。
  也不是所有设想头都可以用。可以使用lsusb查看系统是否识别出usb设备,并且有/dev/video0文件。如果有就应该可以获取。

12月 06

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

  安装好USB的wifi模块,自动获取IP地址。获取到IP后邮件通知。这样每次重启就不用再连显示器了。

以下几个的安装是为了方便使用与本次无关。
安装vim
$ sudo apt-get install vim
将时区改为上海
$ sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
安装校时工具
$ sudo apt-get install ntpdate
通过网络同步时间
$ /usr/sbin/ntpdate stdtime.gov.hk

  把USB的wifi接口接好。
  我接了一个腾达W311M的wifi无线,用命令看到无线网卡已经加载。如下:
$ lsusb
Bus 001 Device 004: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter
image

  然后可以在图形化界面中wpa_gui配置。如果使用命令行可以用wpa_cli。我是直接修改配置文件。我的配置文件如下:

无线配置文件位置/etc/wpa_supplicant/wpa_supplicant.conf
文件内容如下:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=0

network={
ssid=”simonzhang”
psk=”xxxxxxx”
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
}

网络部分配置/etc/network/interface
文件内容如下:
auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

  配置完毕,将启动后发送邮件的脚本放到家目录中,脚本如下,如果邮件服务器认证不严的话用sendmail会更简单:

#!/bin/env python
# -*- coding:utf-8 -*-
# -------------------------------
# Filename:   
# Revision:
# Date:        2012-12-5
# Author:      simonzhang
# Email:       simon-zzm@163.com
# Web:         www.simonzhang.net
# -------------------------------
import os
import time
import socket
import fcntl
import struct
import smtplib
from email.mime.text import MIMEText


mail_host = 'smtp.exmail.qq.com'
mail_user = 'xxxxxxx'
mail_pwd = 'xxxxxxx'

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15])
         )[20:24])
    except IOError, e:
        return e

 
def mail_send(content, mailto, get_sub):
    msg = MIMEText(content.encode('utf8'), _subtype='html',  _charset='utf8')
    msg['From'] = mail_user
    msg['Subject'] = u'%s' % get_sub
    msg['To'] = mailto
    try:
        s = smtplib.SMTP()
        s.connect(mail_host)
        s.login(mail_user,mail_pwd)
        s.sendmail(mail_user,[mailto],msg.as_string())
        s.close()
        send = "OK"
    except Exception ,e:
        send = "ERROR! %s" % e
    return send


def main():
    _count_loop = 0
    while 1:
        ip_list = []
        if _count_loop == 0:
            os.system('sudo wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf')
            time.sleep(0.5)
            os.system('sudo dhclient wlan0')
        try:
            ip_list.append(get_ip_address('eth0'))
        except:
            pass
        try:
            ip_list.append(get_ip_address('wlan0'))
        except Except,e:
            pass
        _get_send_status =  mail_send('my pi ip', 'simon-zzm@163.com', '%s' % ip_list)
        _count_loop +=1
        if (_get_send_status == "OK") or (_count_loop == 3):
            break
        time.sleep(3)

if __name__ == "__main__":
    main()

NotificationIP脚本

  脚本测试通过,配置开机启动。

$ sudo vim /etc/rc.local

# Print the IP address
_IP=$(hostname -I) || true
if [ “$_IP” ]; then
printf “My IP address is %s\n” “$_IP”
fi
# start wifi
echo “Starting WiFi…”
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
sleep .5s
dhclient wlan0
echo “WiFi should be started”

# notification my ip
python /home/pi/script/NotificationIP.py

exit 0

失败经验总结:
1)之前是用的下面代码,但是在除掉网线后路由里的默认网关没有,用“sudo route add default gw 192.168.1.1”添加,如果有网线只是报有一个ip。
def get_local_ip_address():
ipaddr = ”
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((‘1.1.1.1’, 8000))
ipaddr = s.getsockname()[0]
s.close()
except:
ipaddr = “ERROR”
return ipaddr

2)系统应该不支持热插拔,每次查usb wifi时都会重启。

3)不知道是电力原因,还是USB wifi原因,连接质量很不好,容易断开。

参考文档:
http://stinebaugh.info/auto-start-your-wifi-on-raspberry-pi/

12月 05

go语言跑在Raspberry pi 上

  之前go语言在HTC的android手机上运行正常,所以在raspberry pi上也应该没有问题。所以测试一下,如果可以又多了一种开发方法。下载go1.0.3.

安装需要的包
$ sudo apt-get install mercurial bison gcc libc6-dev ed gawk make git

配置环境变量,将以下配置放在profile文件的最底部,为了方便直接用go源码编译,直接放在家目录里。
$ sudo vi /etc/profile
export GOARM=5
export GOROOT=/home/pi/go
export GOARCH=arm
export GOOS=linux
export PATH=$PATH;/home/pi/go/bin/

开始编译
$ cd go/src/
$ time ./all.bash

经过漫长的等待终于编译完了,耗时如下。
real 49m48.591s
user 44m33.760s
sys 2m7.540s

直接用之前的代码测试http://www.simonzhang.net/?p=1346。运行成功。

12月 04

python 源码删除注释并编译成字节码

  上线需要,将py的源码中注释删掉,然后编译成字节码,这样加载速度会比较快。写此脚本主要是为了删除注释。当然如果上线不想放py源码,则在最后增加删除源码即可。我把这个代码起名为咕噜咕噜。python 源码删除注释并编译。

#!/bin/env python
# -*- coding:utf-8 -*-
# -------------------------------
# Filename:    
# Revision:
# Date:        2012-12-3
# Author:      simonzhang
# Email:       simon-zzm@163.com
# Web:         www.simonzhang.net 
# -------------------------------
import os
import re
import sys
import shutil
import compileall


def delete_Notes(py_file):
    # 原始文件只读打开,处理文件追加打开
    _tmp_sr_file = open(py_file, "rb").readlines()
    _tmp_de_file = open("%s.swp" % py_file, "ab")
    _skip_status = 0
    _now_line = 0
    _multi_count = 0 
    # 循环处理
    for line in _tmp_sr_file:
        # 跳过前10行,因为我的开头注释有10行
        if _now_line > 10:
            # 获取开头一位和三位
            try:
                _single_row_notes = line.strip()[0]
            except:
                _single_row_notes = ""
            try: 
                _multi_row_notes = line.strip()[0:3]
            except:
                _multi_row_notes = ""
            # 获取行是否为注释
            if _single_row_notes == "#":
                _skip_status = 1
            elif _multi_row_notes == "'''":
                if _multi_count == 0:
                    _skip_status = 1
                    _multi_count = 1
                else:
                    _skip_status = 1
                    _multi_count = 0
            elif _multi_count == 1:
                _skip_status = 1
            else:
                _skip_status = 0
        else:
            _skip_status = 0
        # 判断是否跳过写入
        if _skip_status == 0:
            _tmp_de_file.write(line)
        _now_line += 1
    _tmp_de_file.close()
    # 处理完毕将临时文件处理为原始文件
    shutil.move("%s.swp" % py_file, py_file)
        

def main():
    _get_src_path = sys.argv[1]
    _get_dec_path = sys.argv[2]
    if os.path.exists(_get_src_path):
        # 拷贝原始文件夹
        shutil.copytree(_get_src_path, _get_dec_path)
        # 删除原始文件中的注释
        find_py_file = re.compile(r"^.*\.py$")
        find_walk = os.walk(_get_dec_path)
        for path,dirs,files in find_walk:
            for f in files:
                if find_py_file.search(f):
                    delete_Notes("%s/%s" % (path, f))
        # 编译成字节码
        compileall.compile_dir(_get_dec_path)
    else:
        print "Path Error!"

if __name__ == "__main__":
    main()

使用方法,
gulugulu.py 源码路径 目标路径

python 源码删除注释并编译

12月 03

raspberry pi 初步和远程配置

  买raspberry pi主要因为推荐使用python。今天的板子总算到了,先照几张照片。
  主板的样子。
image
  外壳都是散的自己安装。
image
  组装完成。大小和鼠标差不多。
image

  系统安装和初步配置网上资料很多,就不重复了。直接来调试连接远程,方便将来开发。
首先升级一下系统,测试了一下远程连接ssh没有问题
$ sudo apt-get update
开始安装vnc,方便远程桌面开发
$ sudo apt-get install tightvncserver
启动服务
$ vncserver
查看监听端口
$ netstat -atnp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:5901 0.0.0.0:* LISTEN 2795/Xtightvnc
tcp 0 0 0.0.0.0:6001 0.0.0.0:* LISTEN 2795/Xtightvnc
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN –
tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN –
tcp 0 52 192.168.1.128:22 192.168.1.73:4958 ESTABLISHED –

从图中看到vnc有两个进程,两个监控端口,端口5901是RFB协议的VNC客户端连接,端口6001是X应用程,也序可以连接到VNC服务器。因为没有5801所以不能通过浏览器访问。直接下个windows下的客户端tightvnc客户端,连接成功。下一步可以开发了。系统上安装的是python2.7 和python3
image