那个男孩不想玩树莓派呢?机缘巧合之下,我得到了一台价值上百美元的智能小车的使用权。

小车的核心是NVIDIA家的jetson-nano开发板,这款19年三月才发布的微型AI计算机可谓是平民级核弹,四核A57的CPU,128核心Maxwell架构的GPU,4g内存,支持4k视频解码,而且这只五脏俱全的麻雀只需要5W的电源支持,任何一支充电宝都可以胜任。而它的定位是用它简单的搭建人工智能应用,非常的amazing。

本文的目的,不完全是新手教程,还有自己学习过程的记录和分享.初次接触,多有疏漏,欢迎指教.

【图片:主板证件照】

给萌新理清几个概念:

单片机:Single-Chip Microcomputer。

树莓派:一款著名的微型电脑品牌(本文介绍的jetson-nano可以理解为是树莓派的竞品,相比树莓派,这款单片机价格更高,性能更好,主打AI应用)

jetbot:以jetson-nano为平台搭建的ai机器人应用,也就是所谓智能小车

硬件组装:积木和电工

本人拿到的是零件状态的小车,所以首先讲一讲组装的问题。有关具体步骤,官网教程十分详细,贴个连接给懒人吧:https://www.ncnynl.com/archives/201904/2927.html

这里只讲一讲我作为初学者的一些理解。首先,玩单片机和玩积木的区别就在于编程。当然,入门单片机还需要其他技能。比如,电工技能:你需要进行线材的简单加工,引脚的焊接,准备基本的工具就好,毕竟那个男孩没有一根热热的棒子呢(指电烙铁)。然后,各个部件的拼接固定需要一些做手工的技巧,这个也不用怕,赫鲁晓夫曾经说过:热熔胶可以让我们创造奇迹。

在这个层面上,初学者会浪费许多耗材,这是必要的练习手段,所以初学者也可以从最简单的芯片入手。同时你还要学习诊断硬件方面的问题,万用表会很有帮助。关于更详细的工具和耗材的需要,请自行查阅单片机入门有关资料。

在本项目中,焊接工作已经完成,剩下的连接都是可插拔式的。我们只需要两把螺丝刀即可完成组装。即便如此,本人还是花了一晚上才把小车点亮,原因是我得到的线材损坏近半,只得自己寻找和修理。

下面分析一下小车的结构:

  • jetson-nano开发板:即本机的主板,可以看到有两层芯片,上层为核心层,包括cpu,gpu和内存可以像笔记本内存条一样拆卸;下层为主板,用于连接各种设备
  • intel无线网卡:将上层拆下即可安装.令连出两根天线,缠绕机身即可.
  • PiOLED显示器和拓展版:连接在I2C主线上
  • 相机模块:官方样例展示了只用一个摄像头通过深度学习进行自动避障的demo.
  • 马达和其驱动板:下文重点讲解

开发板就可以运行一个完整的Ubuntu系统,其余设备是为其拓展功能的.

硬件架构:驱动芯片和I2C主线

我在玩小车的过程中耽误最长时间的就是电机(即马达)驱动了,借此讲一讲系统架构的事。

让轮子前进要靠马达,给马达供电不能直接让主板来做,要让主板给另一块小芯片发送指令,这块小芯片连接着独立的电源,收到指令才会给马达通电。这块小芯片即是电机驱动板。

驱动芯片是从硬件走向软件的第一道桥梁,可以类比PC的IO设备来理解。和物理世界交互的各种功能,都需要有专门的驱动芯片。包括马达,摄像头,扬声器,机械臂等等,只不过有的可以集成在一起,如:小车上的摄像头,PiOLED显示器等;有的出于体积,安全性,模块化的考虑需要分开,如电机和驱动板。

电机驱动板

官方给出的电机驱动板型号为:DC-Stepper-Motor PCA9685+TB6612.可以驱动两个步进电机或四个直流电机。(四轴飞行器gkd)本项目只用到了两个直流电机。

各个引脚的讲解:https://learn.adafruit.com/adafruit-stepper-dc-motor-featherwing/pinouts

电机驱动板上共连接有10根跳线。一对电源输入,两对为马达输出。还需四根母-母杜邦线来连接至主板的I2C总线,具体来说,是在LED屏旁边的拓展板。分别是:

驱动板引脚 主板I2C引脚 功能
3V3 3V3 为驱动板供电,即电源正极
GND GND 接地,即电源负极
SDA 3 串行数据线,传输数据
SCL 5 串行时钟线,传输控制信号

【图片:驱动板引脚】

接错了有可能烧坏板子哦

I2C总线

所谓总线,可以理解为一条街道,每个设备就是街道两旁的房子,房内的住户出门走亲访友就是数据在不同设备间的传输。

I2C总线是常用于嵌入式系统的一种简易串行总线.他有简洁的双线结构(SCL+SDA),每个设备都有一个地址码,以此实现多个设备相互通讯。设备有主从之分,主设备/主端必须是带有CPU的逻辑模块,在同一总线上同一时刻使能有一个主端,可以有多个从端,从端的数量受地址空间和总线的最大电容 400pF的限制。

可以使用i2c-tools调试i2c总线:

  • 检测有几组i2c总线在系统上i2cdetect -l
  • 检测挂载在i2c-1上的设备i2cdetect -r -y 1
  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
  00:          -- -- -- -- -- -- -- -- -- -- -- -- --
  10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --(led)
  40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --(电机驱动)
  70: 70 -- -- -- -- -- -- --
  • 查看设备(地址为0x20)上所有寄存器的值i2cdump -f -y 1 0x20

  • 对单个寄存器进行读写:

    i2cset -f -y 1 0x20 0x77 0x3f(设置i2c-1上0x20器件的0x77寄存器值为0x3f)

    i2cget -f -y 1 0x20 0x77 (读取i2c-1上0x20器件的0x77寄存器值)

jetson-nano开发板提供了6条I2C主线,以及其他丰富的接口。理解这些接口是拓展各种设备的前提。

软件连接:ssh远程桌面

从头开始的话,我们还需要往sd卡里烧写系统镜像,不过我拿到的已经完成了这一步骤,故不再赘述。

在官方教程中,需要hdmi线连接显示屏,usb连接鼠标键盘,来进入jetson-nano的Ubuntu系统.其目的在于首次连接一个无线网络(手机热点),之后只要电脑和nano在同一网络,即可用电脑访问nano的IP(8888端口),直接操纵jetbot.

由于我并没有hdmi线,只有一根网线,反正都能插,插谁不一样?所以用网线把小车和笔记本连接起来组成局域网.用ssh的方式进入nano的系统.具体步骤如下:

  • ip发现:在插入网线前后执行两次:arp -a,比较不同,会发现多出一个地址,类型为动态,此即为小车的内网IP.小车的led屏也会自动显示其ip.如eth0:192.168.x.x

  • (如此,我们可以直接从浏览器访问这个ip的8888端口,并能运行jupyter notebook了.但我们不能让小车拖着网线跑啊,所以还是要配置无线网络.)

  • 将笔记本的wifi连接设为对以太网可共享,这一步是为了让小车能通过笔记本联网

  • 端口扫描:nmap -sT 192.168.x.x发现22端口开放,故连接之:ssh jetbot@192.168.x.x,就用官方教程给的账户密码.

  • 连接成功后,就可以用命令行工具连接WiFi了,但还是安装一下远程桌面吧.

  • 配置远程桌面:执行以下命令:

    sudo apt-get install tightvncserver
    sudo apt-get install xrdp
    sudo apt-get install vnc4server tightvncserver
    
  • 之后在你的主机win+R,输入mstsc,进入远程登录桌面,输入小车的ip地址,点击连接

  • 在xrdp的登陆界面输入用户名密码即可打开远程桌面

    (这里我用jetbot用户登陆遭遇闪退,用root就可以,不清楚原因)(另外开了远程桌面内存疯涨,就很离谱)

  • 连接上wifi后,你能在小车的led板上看到另一个ip:wlan0:192.168.x.x

不管怎样,连接上wifi之后的操作就很简单了.跟着教程,跑一跑demo,还是很有成就感的.

排查bug

然而demo并没有让我跑出来,且指向同一个错误:

OSError: [Errno 121] Remote I/O error

沿着jupyter notebook的报错一直走,一直到了最底层,向设备写入数据报错,remote IO error.

看起来像是硬件的问题。一步一步排查呗

  • 怀疑跳线错误

    • 更换跳线——无果
    • 用万用表测量线两端的信号——正常,排除连接问题
      • 时钟线保持3.3v每隔几秒跳到2.2v又回来,结合i2c的原理应该是正常现象?
      • 数据线同样保持3.3v,间断跳至2.3,2.0
  • 软件方法检验设备连接性

    • 用i2ctools可以检测到设备,拔下4根接线,在0x60,0x70处的设备消失(一个是i2c线,一个是逻辑供电?)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- --
    

然而,在通电状态下,把连线拔下又插上之后,i2c又能检测到设备,然后示例代码就能运行了???

迷惑。所以开机时机器并没能正确载入设备,反倒是重新连接后能识别了???本来我都要换驱动板了,orz。

又或者是和驱动板上的reset按钮有关?等下次遇到问题再说吧。

拾遗

linux内存占用

led屏会显示内存占用,然鹅时间长了总会到90%以上,可我并没有运行什么程序。

经查阅此处显示的是实际占有的加上buffer和cached mem部分,可以理解为缓存的,随时清理,并不占用实际内存。

可用top命令查看内存详情。

供电问题

用充电宝供电方便,但是只要一断电系统就会重启,这对linux系统而言伤害很大。

而在充电宝电量不满时,经常发生开不了机的问题,大概是因为电量不足导致电压不稳。

关机命令:

sudo shutdown -h now

重启:

shutdown -h now -r

下一篇:操纵小车和AI初探

参考链接

https://github.com/NVIDIA-AI-IOT/jetbot/wiki/Hardware-Setup

https://robocarstore.cn/

http://www.gpus.cn/gpus_list_page_techno_support_content?id=50

https://www.jianshu.com/p/789944463fd7