一直想玩一玩电子设备,一般的单片机需要浪费太多时间在电子基础知识的学习上,不适合我这类人。
最后发现了 Arduino 这个开源的硬件平台,社区活跃,对电子相关知识要求已是最低,于是订购了一个Arduino UNO的兼容版,上手挺容易,很快就折腾出了这个简单的小实验,功能是间隔三十秒获取新浪微博上好友状态更新数量并在数码管上显示。
1. Arduino实验板连接
实验板的连接不做详述,参考极客工坊的 这篇文章 ,保证数码管引脚 E D C DP B A F G 分别对应Arduino数字输出2~9即可,Pin13做为电源输出。
2. 程序源代码
代码是Python2.7的,因此Arduino需预先写入 StandardFirmata ,而Python则需安装 pyFirmata 模块。
#!/usr/bin/env python
# -*- coding: gbk -*-
#! 强制默认编码为gbk
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import pyfirmata, urllib, json, time
from datetime import datetime
#! 微博的API调用需要OAuth2.0登陆授权
ACCESS_TOKEN = 'YOUR ACCESS TOKEN'
# Arduino硬件接口
ARDUINO_PORT = 'YOUR ARDUINO PORT'
POWER_PIN = 13
DOTPOINT_PIN = 5
NUMBERS = [
#E D C DP B A F G // 数码管
#2 3 4 5 6 7 8 9 // 输出端口
[0, 0, 0, 1, 0, 0, 0, 1], # 0
[0, 1, 1, 1, 1, 1, 0, 1], # 1
[0, 0, 1, 1, 0, 0, 1, 0], # 2
[1, 0, 0, 1, 0, 0, 1, 0], # 3
[1, 1, 0, 1, 0, 1, 0, 0], # 4
[1, 0, 0, 1, 1, 0, 0, 0], # 5
[0, 0, 0, 1, 1, 0, 0, 0], # 6
[1, 1, 0, 1, 0, 0, 1, 1], # 7
[0, 0, 0, 1, 0, 0, 0, 0], # 8
[1, 0, 0, 1, 0, 0, 0, 0], # 9
[1, 1, 1, 0, 1, 1, 1, 1], # dot point
[1, 1, 1, 1, 1, 1, 1, 0], # line
[1, 1, 1, 1, 1, 1, 1, 1] # nothing
]
class WBftc(object):
def __init__(self):
self.arduino = None
self.lastStatusID = ''
self.initArduino()
def __del__(self):
if isinstance(self.arduino, pyfirmata.Arduino):
for i in xrange(2, 14):
self.arduino.digital[i].write(0)
def initArduino(self):
if isinstance(self.arduino, pyfirmata.Arduino):
return
try:
self.arduino = pyfirmata.Arduino(ARDUINO_PORT)
self.arduino.digital[13].write(1)
except Exception, e:
print('init arduino fail.')
sys.exit(1)
def outputArduino(self, num):
if not isinstance(self.arduino, pyfirmata.Arduino):
return
# 输出 0 - 9 的数字
show = num
# 小于0 错误
if num < 0:
show = 12
# 大于 9 超出量程
elif num > 9:
show = 11
for x in range(2, 10):
self.arduino.digital[x].write(NUMBERS[show][x - 2])
def flashDotPoint(self, interval = 1, count = 30):
show_dot = True
for x in range(count):
self.arduino.digital[DOTPOINT_PIN].write(0 if show_dot else 1)
show_dot = False if show_dot else True
time.sleep(interval)
def fetchWeiboStatusCount(self):
# -1 错误
data = {
'access_token' : ACCESS_TOKEN
}
if self.lastStatusID:
data.update({'since_id' : self.lastStatusID })
data = urllib.urlencode(data)
try:
requst = urllib.urlopen('{}?{}'.format(url, data))
res = json.load(requst)
if not res.has_key('statuses'):
return -1
statuses = res['statuses']
if len(statuses):
self.lastStatusID = statuses[0]
return len(statuses)
except Exception, e:
print('something error.')
return -1
def run(self):
while (True):
count = self.fetchWeiboStatusCount()
now = datetime.now().strftime('%H:%M:%S')
print('{}: {}'.format(now, count))
self.outputArduino(count)
self.flashDotPoint()
if __name__ == '__main__':
try:
WBftc().run()
except KeyboardInterrupt:
print('\rexit.')
except Exception, e:
raise e
Source on gist
需配置 ACCESS_TOKEN 和 ARDUINO_PORT 。