串口通讯
问题描述
TX2上深度学习算法布置好了,但是却无法与下位机进行串口通讯。使用J17口,始终不能打开串口;使用J21上的串口,由于其作为Console接口用于调试,会向下位机传输很多调试信息,并且读取串口信息存在问题。
解决办法
-
官方论坛讨论。经过论坛的解释,原来是官方系统默认没有打开J17的串口通讯(J17同时还兼任板载相机接口的通讯),虽然给出了补丁文件,可是并不知道怎么使用(主要是文件路径找不到啊,欢迎大神指导)。打开
patch
文件后发现与linuxdev
大神给出的回答更改内容一致,于是抱着试一试的态度,参照他给出的具体内容进行操作,最后还真地出现了J17对应的串口号ttyTHS2
。下面给出具体的步骤(大部分搬运大神的作品):
- 通过
sudo apt-get install device-tree-compiler
命令安装DTC
; - 然后是:
sudo -s
cd /tmp
dtc -I dtb -O dts -o extracted.dts /boot/tegra186-quill-p3310-1000-c03-00-base.dtb
# Search for "serial@c280000" where it is a block of code and not just a single line...
# Change status = "disabled" to status = "okay";
# Build a modified version:
dtc -I dts -o dtb /boot/modified_tegra186-quill-p3310-1000-c03-00-base.dtb extracted.dts
cd /boot/extlinux
# edit extlinux.conf...add this line between MENU LABEL line and LINUX line:
FDT /boot/modified_tegra186-quill-p3310-1000-c03-00-base.dtb
注意:1.部分命令与大神有所不同,大概就是dtc
的参数设置,如果报错的话,可以采用man dtc
查看命令详情。
2./tmp
在重启之后会自动删除文件,可以考虑放到其他盘里面去。
这种做法的大致思路是,将设备树文件(相当于二进制文件?)反编译为源代码,然后更改其某种属性,然后再编译为其二进制文件,最后在开机的时候加载。这样在重启之后通过ls /dev
就可以看到ttyTHS2
了。
可是在转换到J17之后,各方面表现正常,但是无论是DJI
给的串口通讯C语言接口,以及在网上找的C语言接口(同样的代码在笔记本上运行可以和下位机完美通讯),都无法接收数据。为了寻找错误的来源,使用python
的pyserial
库进行串口的读写操作,发现能够完美通讯。而且,更为神奇的是,在使用python
打开串口之后再使用同样的C程序时,竟然可以实现完美通讯。不得不感叹,这简直是玄学啊!(其实是自己太菜,对于底层了解太少。大神请指导)。所以,最后的解决办法是,开机之后首先运行如下的python
脚本:
import serial
ser = serial.Serial('/dev/ttyTHS2')
ser.close()
然后再执行深度学习相关命令。
开机运行
- Ubuntu下如何将普通用户提升到root权限_百度经验
-
Ubuntu15.04系统开机自动登录,不需密码_百度经验
设置完以上两项之后,编辑~/.profile
文件在文件最后加入xterm -e python pytest.py
就可以打开终端,并显示程序中的输出了。
摄像头动态打开
为了减少程序执行对摄像头打开的要求,可以通过一个循环不断地尝试打开摄像头,然后检测摄像头是否打开成功,如果成功则跳出循环。,本来很好的逻辑,但是在Linux
(至少是Jetson板载的L4T
和笔记本的Ubuntu 14.04
)下,使用的视频流处理库V4L
(Video for linux)在程序内部不能动态地更新设备,必须要结束程序后才能更新。基于此点,运用如下思路动态打开摄像头:使用一个 runpython.py
脚本使用os.system('python camtest.py')
命令来不断地调用camtest.py
,并根据其返回结果决定是否跳出循环;而camtest.py
只需要尝试打开摄像头,并根据摄像头是否打开成功使用exit(number)
来返回不同的程序结束状态。注意,使用exit()
而不是return
。
代码如下:
runpython.py
import os
import time
count = 0
while True:
print count
if os.system("python camtest.py") == 0:
print "Open Successfully!"
break
else:
print "Cam open failed!\n\n"
count += 1
time.sleep(1)
camtest.py
import cv2
import time
count = 0
cam = cv2.VideoCapture(1)
if not cam.isOpened():
exit(1)
# while(True):
# # Capture frame-by-frame
# ret, frame = cam.read()
# gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# # Display the resulting frame
# cv2.imshow('frame',gray)
# if cv2.waitKey(1) & 0xFF == ord('q'):
# break
exit(0)
总结
将检测摄像头中的runpython.py
的代码放到开机执行的pytest.py
中,这样在开机之后将先执行串口初始化和摄像头动态打开的任务,即在执行深度算法之前确保所有的基础条件已经具备。这样将条件准备和算法执行分开,具有模块化的一些优点。另外,还可以考虑在无显示器的状态下通过GPIO
(Python有对应的库)操作LED或者使用USB扬声器通过语音的方式来报告程序内部执行状态,这样可以增强与人的交互,可以起到缓解紧张的作用。