树莓派上的 flask 框架实时读取串口信息?

2017-08-22 12:50:02 +08:00
 kisscucci
硬件用的是树莓派+二维码扫描器,程序上用的是 python、flask、pyserial,这套方案现在遇到的问题就是,二维码数据有更新的时候,怎样去实时将数据显示在 html 页面中?
各位高手帮忙提点意见,最好有现成案例
5284 次点击
所在节点    Python
17 条回复
leavic
2017-08-22 12:56:01 +08:00
实时更新这一般是前段通过 js 的 ajax 动态更新的,和 flask 关系不大吧。
cassia
2017-08-22 13:09:06 +08:00
长连接 websocket
NoAnyLove
2017-08-22 13:15:07 +08:00
websocket 正解
but0n
2017-08-22 13:59:28 +08:00
做过类似的
https://github.com/but0n/Avem_HUD

用 pyserial 读取数据
flask 返回 json
js ajax 获取数据
canvas 渲染数据
kisscucci
2017-08-22 17:14:16 +08:00
@NoAnyLove 有案例代码可以参考吗?
kisscucci
2017-08-22 17:14:45 +08:00
@cassia 请问有类似的代码可以参考吗?
kisscucci
2017-08-22 17:16:34 +08:00
我网上找不到 flask+pyserial 的案例,哪位大神提供一下给我吧
phy25
2017-08-22 20:13:18 +08:00
轮询的话直接在 Flask 的请求里面调 pyserial 就能做,不需要案例,用 WebSocket 的话可能麻烦点。
ila
2017-08-22 20:19:55 +08:00
@kisscucci 4 楼啊
HoHoibin
2017-08-22 21:05:59 +08:00
二维码扫描器淘宝买的么
kisscucci
2017-08-22 21:14:44 +08:00
@HoHoibin 买了
HoHoibin
2017-08-22 21:32:55 +08:00
@kisscucci 好像很贵 = =
kisscucci
2017-08-22 22:00:07 +08:00
@HoHoibin 400 元左右
kisscucci
2017-08-23 11:43:35 +08:00
@but0n 请问 @app.route('/api/status') def api():…后为什么不用 render_template('xxx.html'),我看 flask 的教程上是每个 app.route 都要引入 html 模板啊,难道可以和 def index():共同 index.html 模版?
kisscucci
2017-08-23 11:45:21 +08:00
@but0n 还有想问你不用 websocket 为什么可以保持数据实时更新?
but0n
2017-08-23 19:57:00 +08:00
这里 Flask 有两个 route:
- '/' : 返回页面 index.html
- '/api/status': 通过串口通信获取数据并返回 json 数据

https://github.com/but0n/Avem_HUD/blob/master/static/scripts/canvas.js#L43#L51
通过 $.getJSON('api/status', (json) 获取数据。

至于数据实时更新, 这里通过单片机的串口中断实现的, 这个就属于我的另一个开源飞控项目: https://github.com/but0n/Avem

其中单片机串口中断处理函数:
https://github.com/t01y/H0p3/blob/master/Software/libs/source/uart.c#L45#L62
这里定义了当单片机通过串口接收到 '$' 字符就会将最新的数据通过串口发送出去
在 flask 中
ser.write('$')
st = ser.readline().replace('\00','').replace('\n','').replace('\r','').split('@')
解析数据
kisscucci
2017-08-24 01:22:36 +08:00
@but0n 你好,参照你的项目给了我很大的帮助;最近在做一个扫描器的项目,遇到了一个问题就是 python 和 html 之间的通信建立不起来,代码如下:

#红外传感器
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#16 进制库
import binascii

#FLASK 框架
from flask import Flask, url_for, render_template, jsonify

#实例化串口
import serial
import time
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout = None) #一直等待

app = Flask(__name__)

@app.route('/')
def index():
return render_template('index.html')

@app.route("/json/")
def scan(channel):
def order_list():
a = '7e 00 08 01 00 02 01 ab cd' #触发扫描器的指令
a_list = []
for i in a.split():
a_list.append(binascii.a2b_hex(i)) #转为 16 进制
return a_list
ser.write(order_list()) #触发扫描
scandata = ser.readline() #读取数据
data = {"zhipinming": "brian","age": scandata,"has_car": False}
return jsonify(data=data)

#18 引脚的中断和边缘检测,发生改变时调用 scan 函数
#红外感应一次,扫描器工作一次
GPIO.add_event_detect(18, GPIO.FALLING, callback=scan)
if __name__ == '__main__':
app.run()


运行后提示错误:
Traceback (most recent call last):
File "/home/pi/Desktop/tgpscan/scan.py", line 35, in scan
return jsonify(data=data)
File "/usr/lib/python2.7/dist-packages/flask/json.py", line 234, in jsonify
if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] \
File "/usr/lib/python2.7/dist-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/usr/lib/python2.7/dist-packages/werkzeug/local.py", line 297, in _get_current_object
return self.__local()
File "/usr/lib/python2.7/dist-packages/flask/globals.py", line 34, in _find_app
raise RuntimeError('working outside of application context')
RuntimeError: working outside of application context

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/384808

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX