<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Python :: 标签 :: yafeng 的博客</title><link>http://yafengabc.github.io/tags/python/index.html</link><description/><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 19 Sep 2026 14:36:30 +0800</lastBuildDate><atom:link href="http://yafengabc.github.io/tags/python/index.xml" rel="self" type="application/rss+xml"/><item><title>Python64+win10_64+cython+msys2(ming64)踩坑记</title><link>http://yafengabc.github.io/cnblogs/p11399939/index.html</link><pubDate>Mon, 26 Aug 2019 15:56:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p11399939/index.html</guid><description>一直在linux下用python，一直妥妥的，从没想过在windows下编译cython模块，直到昨天……&#10;过程是曲折的，解决方法是简单的，时间不多，长话短说，直接先来个传送门：&#10;https://www.jianshu.com/p/50105307dea5&#10;这里的步骤是可以的，因为我用的msys2，所以过程有一点点曲折，下边补充说明一下：&#10;msys2算是个windows下的linux系统，里边一共包含了3套工具链，&#10;比如安装GCC，可以直接安装gcc这个包，也可以安装mingw-w64-i686-gcc或者mingw-w64-x86_64-gcc&#10;这三个包不同之处在于，gcc是属于msys2系统本身的工具链，如果编译软件，会连接到/usr/lib下，也就是虽然生成的是exe，但是是没法离开msys2运行的&#10;而mingw-w64-i686-gcc与mingw-w64-x86_64-gcc实际上是个交叉工具链，编译出来的exe是只依赖宿主系统的库的，所以可以直接在windows系统下运行的&#10;甚至只要吧msys2下的mingw64/bin目录加到系统系统变量，是可以随便调用的。&#10;python配合msys2的使用方式：&#10;python也可以有3种安装方式，&#10;1，直接从python官方下载安装包安装，这是最普遍的做法，跟msys2完全没关系，可以直接通过系统环境变量调用相应的mingw32或者mingw64编译器，编译自己的包&#10;2，在msys2直接安装python，配合msys2的gcc，这样类似直接在linux安装gcc python，最方便，编译连接时也不需要指定路径，类似linux下的体验，缺点是编译生成的exe文件无法离开msys2运行&#10;3，安装mingw-w64-x86_64-gcc mingw-w64-x86_64-python这种工具链下的包，这个其实跟1类似，可以编译直接在系统下运行的exe，也可以直接在msys2下使用。&#10;因为我系统下已经安装了python3 64bit，并且安装了大量的包，所以装完msys2以后，直接安装mingw-w64-x86_64-gcc就可以在pyhon3中使用这个编译器了。&#10;pacman -S mingw-w64-x86_64-gcc 然后把mingw64加到系统环境变量比如我msys2安装在E:\linux（没错我伪装成linux了哈）下，系统环境变量就加一条E:\linux\mingw64\bin。&#10;根据传送门的教程：在python安装目录C:\Program Files\Python\Lib\distutils中新建distutils.cfg文件，内容如下：&#10;[build] compiler=mingw32 [build_ext] compiler=mingw32 注意，这地方是没错的，不要因为是mingw64就写mingw64，写mingw32是对的。&#10;这时候，编译一个cython程序，会报VC版本1900 1906之类，根据教程这么改：&#10;三、修改cygwinccompiler.py文件&#10;进入python安装目录C:\Program Files\Python\Lib\distutils中，修改cygwinccompiler.py文件，添加以下内容到get_msvcr()函数（用于解决ValueError: Unknown MS Compiler version 1900错误）。&#10;elif msc_ver == '1900': # Visual Studio 2015 / Visual C++ 14.0 # "msvcr140.dll no longer exists" return ['vcruntime140'] 因为我这报的是1906，所以就改成了&#10;elif msc_ver == '1906': # Visual Studio 2015 / Visual C++ 14.0 # "msvcr140.dll no longer exists" return ['vcruntime140'] 这一步一定要根据实际版本改。</description></item><item><title>MicroPython与Python速度对比</title><link>http://yafengabc.github.io/cnblogs/p9034158/index.html</link><pubDate>Mon, 14 May 2018 08:33:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p9034158/index.html</guid><description>首先说明，micropython跟python是没有任何可比性的，python作为一种通用的语言，在扩展性上不是micropython能比的，比如大量的库，可以方便的用C语言加模块提升速度，有pypy这样的带JIT的解释器，micropython是适合于单片机的系统虽然可以用C写lib，但是需要重新编译整个固件，此外，micropython也缺乏加载本地代码的功能，比如加载C便宜的so库。所以不要试图用micropython代替python，这不是一个好主意，除非micropython支持的库满足你的使用了。&#10;这篇文章主要是简单的对比这两个不同的实现的性能有何差别。&#10;测试代码有两个，一个是一个大循环，一个是递归计算斐波那契数列，例子比较简单，代码如下：&#10;try: import utime as time except: import time def bigloop(): s=0 for i in range(1000000000): s+=i def fib(n): if n==0: return 0 if n==1: return 1 return fib(n-1)+fib(n-2) t=time.time() bigloop() print("bigloop time:",time.time()-t) t=time.time() print("The 40th fibric is:",fib(40)) print("fibn time:",time.time()-t) 结果如下：&#10;[yafeng@ArchV ~]$ python micromark.py bigloop time: 60.44254755973816 The 40th fibric is: 102334155 fibn time: 48.39746880531311 [yafeng@ArchV ~]$ micropython micromark.py bigloop time: 51.92846608161926 The 40th fibric is: 102334155 fibn time: 65.70703196525574 可以看到，效率基本是一样的，循环micropython稍快一点，递归cpython稍快一点，顺便贴一下pypy pypy3的结果： [yafeng@ArchV ~]$ pypy micromark.py ('bigloop time:', 1.7053859233856201) ('The 40th fibric is:', 102334155) ('fibn time:', 7.795623064041138) [yafeng@ArchV ~]$ pypy3 micromark.py bigloop time: 1.2033970355987549 The 40th fibric is: 102334155 fibn time: 7.820451974868774 可以看到，pypy速都还是很明显的，喜闻乐见的是，pypy3甚至超过了pypy。</description></item><item><title>用Cython加速Python程序以及包装C程序简单测试</title><link>http://yafengabc.github.io/cnblogs/p6130849/index.html</link><pubDate>Sun, 04 Dec 2016 15:02:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p6130849/index.html</guid><description>用Cython加速Python程序 我没有拼错，就是Cython，C+Python=Cython!&#10;我们来看看Cython的威力,先运行下边的程序：&#10;import time&#10;def fib(n):&#10;if n0:&#10;return 0&#10;if n1:&#10;return 1&#10;return fib(n-1)+fib(n-2)&#10;t=time.time()&#10;print(fib(40))&#10;print(time.time()-t)&#10;$ python fib.py&#10;102334155&#10;59.367255449295044&#10;在我的渣渣笔记本上，用时59.3秒，差不多一分钟。当然，在你那可能比我快一点，这也很正常。&#10;好了，我们再试试Cython：&#10;$ cython fib.py –embed&#10;$ gcc -O3 fib.c -I /usr/include/python3.5m/ -lpython3.5m&#10;$ ./a.out&#10;102334155&#10;14.487313747406006&#10;嗯，快了那么一点点，4倍左右;我解释一下前边的几句代码：&#10;首先，用cython命令把python生成c文件，也就是cython fib.py会生成一个fib.c的文件&#10;–embed参数就是自动生成一个main函数，以便让gcc生成可执行程序。&#10;接下来就是用gcc把fib.c编译成了个a.out程序，运行之，结果快了4倍（从60秒减少到15秒以内）。&#10;当然，这只是小试牛刀，区区4倍而已，这也太少了！&#10;接下来我吧这个文件复制成fib.pyx，并修改了一句代码：&#10;import time&#10;cdef int fib(int n):&#10;if n0:&#10;return 0&#10;if n1:&#10;return 1&#10;return fib(n-1)+fib(n-2)&#10;t=time.time()&#10;print(fib(40))&#10;print(time.time()-t)</description></item><item><title>web编程速度大比拼（nodejs go python）（非专业对比）</title><link>http://yafengabc.github.io/cnblogs/p5431695/index.html</link><pubDate>Mon, 25 Apr 2016 17:17:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p5431695/index.html</guid><description>C10K问题的解决，涌现出一大批新框架，或者新语言，那么问题来了:到底谁最快呢？非专业程序猿来个非专业对比。&#10;比较程序：输出Hello World！&#10;测试程序：siege –c 100 –r 100 –b&#10;例子包括：&#10;1.go用http模块实现的helloworld&#10;2.go用martini微框架实现的Helloworld&#10;3.python3 python2 pypy分别用gevent server tornado实现的Hello world&#10;4.python3 python2 pypy分别用微框架bottle+gevent实现的Hello world&#10;5.NodeJS纯JS实现的Helloworld&#10;6.NodeJS用express框架实现的Helloworld&#10;测试平台：&#10;公司老旧的奔腾平台 Pentium(R) Dual-Core CPU E6700 @ 3.20GHz&#10;内存2GB（够弱了吧）&#10;先来宇宙最快的GO的测试：&#10;package main import ( "fmt" "net/http" ) func sayhelloName(w http.ResponseWriter, r *http.Request){ fmt.Fprintf(w, "hello world!") } func main() { http.HandleFunc("/", sayhelloName) http.ListenAndServe(":9090", nil) } 连续测试5次，成绩大体如下：&#10;Transactions: 10000 hits Availability: 100.00 % Elapsed time: 4.11 secs Data transferred: 0.11 MB Response time: 0.03 secs Transaction rate: 2433.09 trans/sec Throughput: 0.03 MB/sec Concurrency: 79.76 Successful transactions: 10000 Failed transactions: 0 Longest transaction: 0.20 Shortest transaction: 0.00 4.11秒，不错的成绩</description></item><item><title>简单的实现树莓派的WEB控制</title><link>http://yafengabc.github.io/cnblogs/p5197844/index.html</link><pubDate>Thu, 18 Feb 2016 12:55:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p5197844/index.html</guid><description>最终效果如图：&#10;用到的知识：Python Bottle HTML Javascript JQuery Bootstrap AJAX 当然还有 linux&#10;我去，这么多……我还是一点一点说起吧……&#10;先贴最终的源代码：&#10;#!/usr/bin/env python3 from bottle import get,post,run,request,template @get("/") def index(): return template("index") @post("/cmd") def cmd(): print("按下了按钮: "+request.body.read().decode()) return "OK" run(host="0.0.0.0") 没错，就10句，我一句一句解释：&#10;1.#!/usr/bin/env python3 ，告诉shell这个文件是Python源代码，让bash调用python3来解释这段代码&#10;2.from bottle import get,post,run,request,template ，从bottle框架导入了我用到的方法、对象&#10;下边几句是定义了2个路由，一个是“/”一个是“/cmd”,前者是get类型（用@get装饰），后者是POST类型（用的@post装饰）&#10;第一个路由很简单，就是读取index模版（模版就是个html啦）并发送到客户端（浏览器），因为路径是“/”也就是比如树莓派的IP地址是：192.168.0.10&#10;那用http://192.168.0.10:8080就访问到了我们的"/”路由（bottle默认端口是8080）&#10;同理，第二个路由的路径是“/cmd”也就是访问http://192.168.0.10:8080/cmd就访问到了第二个路由&#10;最后一句：run(host=“0.0.0.0”)就是调用bottle的run方法，建立一个http服务器，让我们能通过浏览器访问我们的界面。&#10;下边我详细的解释一下这些代码的作用：&#10;第一个路由的作用就是扔给浏览器一个HTML（index.tpl）文档，显示这个界面：&#10;这个文件的源代码如下：&#10;&lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt; &lt;title&gt;遥控树莓派&lt;/title&gt; &lt;link href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" media="screen"&gt; &lt;script src="http://code.jquery.com/jquery.js"&gt;&lt;/script&gt; &lt;style type="text/css"&gt; #up { margin-left: 55px; margin-bottom: 3px; } #down { margin-top: 3px; margin-left: 55px; } &lt;/style&gt; &lt;script&gt; $(function(){ $("button").click(function(){ $.post("/cmd",this.id,function(data,status){}); }); }); &lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;div id="container" class="container"&gt; &lt;div&gt; &lt;button id="up" class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-up"&gt;&lt;/button&gt; &lt;/div&gt; &lt;div&gt; &lt;button id='left' class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-left"&gt;&lt;/button&gt; &lt;button id='stop' class="btn btn-lg btn-primary glyphicon glyphicon-stop"&gt;&lt;/button&gt; &lt;button id='right' class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-right"&gt;&lt;/button&gt; &lt;/div&gt; &lt;div&gt; &lt;button id='down' class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-down"&gt;&lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"&gt;&lt;/script&gt; &lt;/body&gt; &lt;/html&gt; 这个内容有点多，不过很简单，就是引用了jquery bootstrap这两个前端框架，加了5个按钮(之间的代码)。当然我用了bootstrap内置的上下左右停止这几个图标，这5个按钮的id分辨定义成up，down，left，right，stop，然后写了如下的关键代码：</description></item><item><title>树莓派高级GPIO库，wiringpi2 for python使用笔记（五）i2c读取测试</title><link>http://yafengabc.github.io/cnblogs/p5107768/index.html</link><pubDate>Wed, 06 Jan 2016 22:52:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p5107768/index.html</guid><description>wiringpi2显然也把i2c驱动带给了Python，手头上正巧有一个DS3231的模块，上边带了一个DS3231 RTC（实时时钟），与一片24C32，两个芯片均为iic总线设备，与树莓派接线如下：&#10;也就是VCC GND SDA SCL四个脚分别接到树莓派的1（3.3v）、9（0v）、3（SDA.1）、5（SCL.1）上，因为树莓派的I2C接口默认是关闭的，需要先编辑一下/boot/config.txt,去掉 device_tree_param=i2c_arm=on上的注释（ArchlinuxARM RasperryPi2），然后重启（注：Raspbian可以用raspi-config打开）&#10;然后重启，重启完成后，运行&#10;modprobe i2c-dev 若想这个模块自动装载，请把它写到 /etc/modules-load.d/raspberrypi.conf&#10;安装i2c-tools，Archlinux下为：&#10;pacman –S i2c-tools 安装后，运行i2cdetect –y 1结果如下：&#10;嗯，发现了57，68两个设备，哪个是DS3231，哪个又是24C32呢，我们把里边的数据dump出来看看：&#10;可以看到0x57设备里边是空的，应该就是24C32了，0x68里边读出来20个字节，就是DS3231了。&#10;我先解释下这几个命令：&#10;i2cdetect顾名思义就是搜索i2c总线的设备，树莓派有2条i2c总线，咱们接的SDA.1,SCL.1，当然就是搜索1这条总线了（另外一条是SDA.0 SCL.0）&#10;-y参数没啥意义，就是自己帮你按下y(yes).&#10;i2cdump也很容易理解，就是dump出指定总线，指定设备的数据这里是1总线0x57 0x68两个设备。-y参数跟上个命令是一样的。&#10;这样，我们的i2c设备就都通讯上了，下边就是用wiringpi2库读写之。&#10;wringpi中操作i2c设备的函数主要有一下几个：</description></item><item><title>树莓派高级GPIO库，wiringpi2 for python使用笔记（四）实战DHT11解码</title><link>http://yafengabc.github.io/cnblogs/p5100741/index.html</link><pubDate>Tue, 05 Jan 2016 00:12:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p5100741/index.html</guid><description>DHT11是一款有已校准数字信号输出的温湿度传感器。 精度湿度+-5%RH， 温度+-2℃，量程湿度20-90%RH， 温度0~50℃。&#10;我买的封装好的模块，上边自带了上拉电阻，直接查到树莓派上即可灰、紫、蓝分别代表数据、3.3V、0V,接到树莓派的3，1，10脚，分别对应PIN8，3.3V，0V。&#10;DHT11与单片机通讯协议为单线协议（1-wire），其实单线协议蛮厉害的，一个GPIO就能实现数据的读取，但是这个协议没有同步脉冲，所以对时序要求比较高，比如DHT11对高低电平定义如下：&#10;低电平50us，然后一个26-28us的高电平，代表0&#10;低电平50us，然后一个70us的高电平，代表1&#10;也就是说，需要能分辨出40us以下的时间才能准确的测出，下边看看具体的时序：&#10;总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。&#10;数字0表示如下图：&#10;数字1表示如下图：&#10;可以看出，每一位包括一开始的响应信号，都是由一个低电平跟一个高电平组成，其中响应信号为80us+80us=160us&#10;数字0为50+26=76us&#10;数字1为50+70=120us&#10;为读到DHT11的状态，我编写了以下的程序：&#10;import wiringpi2 as gpio owpin=8 #第8脚为1-wire脚 tl=[] #存放每个数据位的时间 gpio.wiringPiSetup() #初始化wiringpi库 gpio.pinMode(owpin,1) #设置针脚为输出状态 gpio.digitalWrite(owpin,1) #输出高电平 gpio.delay(1) ###发开始指令，要求DHT11传输数据 gpio.digitalWrite(owpin,0) #拉低25ms开始指令 gpio.delay(25) gpio.digitalWrite(owpin,1) #输出高电平，开始指令结束 gpio.pinMode(owpin,0) #设针脚为输入状态 ###开始指令发送完毕，把管脚设置为高电平，并等待DHT11拉低管脚。传输数据 while(gpio.digitalRead(owpin)==1): pass #如果管脚一直是1，则一直等待。 ###若被拉低，说明传输开始，应答信号+40位数据+结束标志共42位 ###下边共循环45次，故意多循环几次看结果。 for i in range(45): #测试每个数据周期的时间（包括40bit数据加一个发送开始标志 tc=gpio.micros() #记下当前us数（从初始化开始算起，必要时重新初始化） ''' 一个数据周期，包括一个低电平，一个高电平，从DHT11第一次拉低信号线开始 到DHT11发送最后一个50us的低电平结束（然后被拉高，一直维持高电平，所以 最后的完成标志是一直为高，超过500ms） ''' while(gpio.digitalRead(owpin)==0):pass #一位数据由一个低电平 while(gpio.digitalRead(owpin)==1): #加一个高电平组成 if gpio.micros()-tc&gt;500: #如果超过500us就结束了本次循环,传输结束后 break #会被上拉电阻拉成高电平，防止进入死循环 tl.append(gpio.micros()-tc) #记录每个周期时间的us数，存到tl这个列表 print(tl) #打印结果 程序里有详细的解释，我就不再赘述，这里贴出我这里的执行结果：</description></item><item><title>树莓派高级GPIO库，wiringpi2 for python使用笔记（三）GPIO操作</title><link>http://yafengabc.github.io/cnblogs/p5096720/index.html</link><pubDate>Sun, 03 Jan 2016 16:57:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p5096720/index.html</guid><description>GPIO库的核心功能，当然就是操作GPIO了，GPIO就是“通用输入/输出”接口，比如点亮一个LED、继电器等，或者通过iic spi 1-wire等协议，读取、写入数据，这都是GPIO的用处，可以说没有GPIO，树莓派只能当小电脑用，有了GPIO，就升级成一个控制器了。先来说说怎么操作一个数字量（高低电平）。&#10;先看代码：&#10;import wiringpi2 as gpio from wiringpi2 import GPIO gpio.wiringPiSetup() #初始化 gpio.pinMode(25,GPIO.OUTPUT) # 把pin25设置为输出模式 gpio.digitalWrite(25,GPIO.HIGH) #pin25输出为高电平 print(gpio.digitalRead(25)) #打印pin25的状态 值的注意的是，GPIO在输出模式时，也可以读取GPIO状态。&#10;wiringpi对树莓派2的GPIO定义如下：&#10;[root@RasPi ~/testcode]# gpio readall +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+ | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM | +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+ | | | 3.3v | | | 1 || 2 | | | 5v | | | | 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5V | | | | 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | | | 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT0 | TxD | 15 | 14 | | | | 0v | | | 9 || 10 | 1 | ALT0 | RxD | 16 | 15 | | 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 | | 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | | | 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 | | | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 | | 10 | 12 | MOSI | IN | 0 | 19 || 20 | | | 0v | | | | 9 | 13 | MISO | IN | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 | | 11 | 14 | SCLK | IN | 0 | 23 || 24 | 1 | IN | CE0 | 10 | 8 | | | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 | | 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 | | 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | | | 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 | | 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | | | 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 | | 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 | | | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 | +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+ | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM | +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+ 我们看到，wringpi对针脚有三种定义方式，BCM代表GPIO模式，wPi代表pin模式，Physical代表物理针脚模式。</description></item><item><title>树莓派高级GPIO库，wiringpi2 for python使用笔记（二）高精度计时、延时函数</title><link>http://yafengabc.github.io/cnblogs/p5096445/index.html</link><pubDate>Sun, 03 Jan 2016 15:11:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p5096445/index.html</guid><description>学过单片机的同学应该清楚，我们在编写传感器驱动时，需要用到高精度的定时器、延时等功能，wiringpi提供了一组函数来实现这些功能，这些函数分别是：&#10;micros() #返回当前的微秒数，这个数在调用wiringPiSetup()后被清零并重新计时&#10;millis() #返回当前的毫秒数，同上，这个数在调用wiringPiSetup()后被清零并重新计时&#10;delayMicroseconds() #高精度微秒延时&#10;delay() #毫秒延时。&#10;python相对于C，一个很大的问题就是执行速度慢，所以指令执行速度不可忽视，我们可以用micos函数来检测指令执行时间，用来避免实际使用中遇到的坑，请看以下代码：&#10;import wiringpi2 as gpio for i in range(5): t1=gpio.micros() t2=gpio.micros() print(t2-t1) 连续调用两次micros，然后打印出差值，运行结果如下：&#10;[root@RasPi ~/testcode]# python testus.py 12 4 4 5 5 我们看到第一次的结果明显比以后的结果要大，多了接近10微秒，一般的程序来说，这无关紧要，要是要求更高，可以把代码改成这个样子:&#10;import wiringpi2 as gpio for i in range(5): t1=gpio.micros() t1=gpio.micros() t2=gpio.micros() print(t2-t1) 运行结果如下：&#10;[root@RasPi ~/testcode]# python testus.py 3 3 3 3 2 基本一致了再看以下代码：&#10;import wiringpi2 as gpio for i in range(5): t1=gpio.micros() t1=gpio.micros() gpio.delayMicroseconds(10) t2=gpio.micros() print(t2-t1) 延时10us，结果如下：&#10;[root@RasPi ~/testcode]# python testus.py 21 21 18 18 18 减去两次调用micros()之间的5us左右的延时，实际延时10us会有5us左右的延时。</description></item><item><title>树莓派高级GPIO库，wiringpi2 for python使用笔记（一）安装</title><link>http://yafengabc.github.io/cnblogs/p5096300/index.html</link><pubDate>Sun, 03 Jan 2016 14:06:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p5096300/index.html</guid><description>网上的教程，一般Python用RPi.GPIO来控制树莓派的GPIO，而C/C++一般用wringpi库来操作GPIO，RPi.GPIO过于简单，很多高级功能不支持，比如i2c/SPI库等，也缺乏高精度定时等高级特性。相比之下，wiringpi则功能丰富的多，其实wringpi已经有了python绑定，可以非常简单的在python中使用这个库。鉴于网上基本没有这个库的中文说明，我一边学习，一边以做笔记的形式，写几篇关于这个库的基本使用的文章。&#10;安装：首先安装python-pip：&#10;我用的Archlinux，python3，安装命令为：&#10;pacman -S python-pip 如果用python2，安装命令为：&#10;pacman -S python2-pip Raspbian下则为：&#10;apt-get install python3-pip apt-get install python-pip 安装完后，就可以用pip install来安装python库了。为避免繁琐，我下边的命令都以pip命令安装，Archlinux下默认为python3的pip3，如果使用个python2则用pip2来代替pip，debian下pip默认为pip2，若使用python3，则使用pip3来代替。&#10;pip install wiringpi2 pip库里除了wiringpi2外，还有老版本的wiringpi库，大家按需安装。&#10;安装完后，运行pip list，可以看到列表中包含了新装的wringpi2库了：&#10;在终端中敲入python，进入python控制台，导入一下，如果不报错，说明安装成功：</description></item><item><title>树莓派读取DHT11传感器的源代码</title><link>http://yafengabc.github.io/cnblogs/p5096184/index.html</link><pubDate>Sun, 03 Jan 2016 13:27:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p5096184/index.html</guid><description>import wiringpi2 as gpio owpin=8 #第8脚为1-wire脚 def getval(owpin): tl=[] #存放每个数据位的时间 tb=[] #存放数据位 gpio.wiringPiSetup() #初始化wiringpi库 gpio.pinMode(owpin,1) #设置针脚为输出状态 gpio.digitalWrite(owpin,1) #输出高电平 gpio.delay(1) gpio.digitalWrite(owpin,0) #拉低20ms开始指令 gpio.delay(25) gpio.digitalWrite(owpin,1) #抬高20-40us gpio.delayMicroseconds(20) gpio.pinMode(owpin,0) #设针脚为输入状态 while(gpio.digitalRead(owpin)==1): pass #等待DHT11拉低管脚 for i in range(45): #测试每个数据周期的时间（包括40bit数据加一个发送开始标志 tc=gpio.micros() #记下当前us数（从初始化开始算起，必要时重新初始化） ''' 一个数据周期，包括一个低电平，一个高电平，从DHT11第一次拉低信号线开始 到DHT11发送最后一个50us的低电平结束（然后被拉高，一直维持高电平，所以 最后的完成标志是一直为高，超过500ms） ''' while(gpio.digitalRead(owpin)==0):pass while(gpio.digitalRead(owpin)==1): if gpio.micros()-tc&gt;500: #如果超过500ms就结束了 break if gpio.micros()-tc&gt;500: #跳出整个循环 break tl.append(gpio.micros()-tc) #记录每个周期时间的us数，存到tl这个列表 # print(tl) #反注释后可打印时间列表 tl=tl[1:] #去掉第一项，剩下40个数据位 for i in tl: if i&gt;100: #若数据位为1，时间为50us低电平+70us高电平=120us tb.append(1) else: tb.append(0) #若数据位为0，时间为50us低电平+25us高电平=75us #这里取大于100us就为1 # print(tb) #反注释可查看每一位状态 return tb def GetResult(owpin): for i in range(10): SH=0;SL=0;TH=0;TL=0;C=0 result=getval(owpin) # print(len(result)) if len(result)==40: for i in range(8): #计算每一位的状态，每个字8位，以此为湿度整数，湿度小数，温度整数，温度小数，校验和 SH*=2;SH+=result[i] SL*=2;SL+=result[i+8] TH*=2;TH+=result[i+16] TL*=2;TL+=result[i+24] C*=2;C+=result[i+32] if ((SH+SL+TH+TL)%256)==C and C!=0: break else: print("Read Sucess,But checksum error! retrying") else: print("Read failer! Retrying") gpio.delay(200) return SH,SL,TH,TL SH,SL,TH,TL=GetResult(owpin) print("湿度:",SH,SL,"温度:",TH,TL)</description></item></channel></rss>