第一个Arduino实验: 新浪微博关注好友状态更新数量

  一直想玩一玩电子设备,一般的单片机需要浪费太多时间在电子基础知识的学习上,不适合我这类人。

  最后发现了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: utf-8 -*-
#! 强制默认编码为utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf8')

import pyfirmata, urllib, json, time
from datetime import datetime

#! 微博的API调用需要OAuth2.0登陆授权
#! 这里不做授权过程,需使用开发者账号测试 参考:http://t.cn/zYDjFan
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 错误
        url = 'https://api.weibo.com/2/statuses/friends_timeline/ids.json'
        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_TOKENARDUINO_PORT

  NOTE: 访问微博API需要OAuth2.0授权,这里使用了开发者测试账户,详细请参考这篇文章

3. 显示结果

  程序每隔30秒获取关注好友更新的微博数量并以以下方式显示:

  • 更新数量在0-9间,数码管正常显示
  • 更新数量大于9,数码管显示『-』
  • 出错,数码管不显示任何内容
  • 小数点闪动

  同时,电脑终端也会打印相应的更新数量信息,CTRL+C退出程序。

Read more...