894|0

20

帖子

8

TA的资源

一粒金砂(中级)

楼主
 

【玄铁杯第三届RISC-V应用创新大赛】华山派外设接入,I2C与GPIO,蜂鸣器的使用,... [复制链接]

  本帖最后由 eew_dy9f48 于 2023-10-19 15:30 编辑

这周的计划是调通华山派的各种外设使用,并为最终制作老人防跌倒装置做好准备。

 

我预想的老人防跌倒装置需要包含以下这些功能:

1,跌倒检测:这需要外置运动传感器的使用,项目中使用的是常见的MPU-6050,因此我们需要调通i2c通讯。

2,报警装置:如果检测到跌倒,需要播放警报以引起周围人的注意,因此我们需要使用GPIO,来操纵蜂鸣器工作。

3,邮件求助:检测到跌倒的同时,应同步发送一封求助邮件到预设的邮箱,以尽快获得帮助。要实现这个功能,我们首先需要调通板载的wifi,其次需要使用stmp服务来发送邮件。

 

看了一下资料,华山派上并不可以运行python。传统C语言较为硬核,虽然资料很丰富,但奈何水平有限。由于官方资料中关于外设的部分都是在shell下控制的,因此这个项目我打算使用一种比较异类的方式完成,将整个程序写在shell中,并通过sh脚本来运行。

 

首先看一下外置运动传感器的使用。参考下面的原理图:

 
我们找到I2C引脚的位置,注意这个i2c是i2c3,原理图上有标注,在使用时不要搞错。

 

将MPU6050的VCC, GND, SDA. SCL四根线接好后,我们试着运行下 i2c-tool命令:

得到以下输出:

  • [root@cvitek]/mnt/data# i2cdetect -yr 3
  • 0 1 2 3 4 5 6 7 8 9 a b c d e f
  • 00: -- -- -- -- -- -- -- -- -- -- -- -- --
  • 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  • 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  • 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  • 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  • 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  • 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
  • 70: -- -- -- -- -- -- -- --

谢天谢地,linux环境中已经自带了i2c-tool,这省去了我们很多麻烦。从输出中我们可以看到,已经可以正确识别到MPU6050,地址是0x68.

 

那么下一步,我们需要初始化它。网上有很多MPU6050的驱动,因此并不需要去啃规格书。随便找一个C语言的驱动程序,找到初始化部分代码,其实就是一系列寄存器的写入操作。我们只需要把它转换为用i2c-tool写入就可以了。具体初始化代码如下:

  • i2cset -y 3 0x68 0x6B 0x80
  • sleep 1
  • i2cget -y 3 0x68 0x75
  • i2cset -y 3 0x68 0x6B 0x00
  • sleep 1
  • i2cset -y 3 0x68 0x19 0x07
  • i2cset -y 3 0x68 0x1A 0x06
  • i2cset -y 3 0x68 0x1B 0x18
  • i2cset -y 3 0x68 0x1C 0x01

初始化完成后,我们就可以正常读取到MPU6050的数值。所有的数值都是2字节输出,MSB在前,LSB在后,int16结构。因此我们需要先写一个简单的函数来读数,并将它转换成我们可读的数字:

  • get_value(){
  • let "val=$(i2cget -y 3 0x68 $1)<<8|$(i2cget -y 3 0x68 $(echo "obase=16; $(($1+0x01))" | bc))"
  • if [ $val -gt 32767 ];
  • then
  • val=$(( $val - 65536 ))
  • fi
  • echo $val
  • }

这个函数使用时需要传入一个参数,也就是我们所需要读的数据的MSB地址。我们可以测试一下读取温度,并根据规格书中的公式进行一下转换:

  • temp=`get_value 0x41`
  • temp=$(echo "scale=2; ($temp/340)+36.53" | bc)
  • echo $temp

得到输出25.21,嗯非常正常的一个温度,那么接下来我们再读取一下加速度计和陀螺仪的数字:

  • while [ TRUE ]
  • do
  • ax=`get_value 0x3B`
  • ay=`get_value 0x3D`
  • az=`get_value 0x3F`
  • ax=$(echo "scale=2; $ax/16384" | bc)
  • ay=$(echo "scale=2; $ay/16384" | bc)
  • az=$(echo "scale=2; $az/16384" | bc)
  • gx=`get_value 0x43`
  • gy=`get_value 0x45`
  • gz=`get_value 0x47`
  • gx=$(echo "scale=2; $gx/16.4" | bc)
  • gy=$(echo "scale=2; $gy/16.4" | bc)
  • gz=$(echo "scale=2; $gz/16.4" | bc)
  • echo "ax: $ax"
  • echo "ay: $ay"
  • echo "az: $az"
  • echo "gx: $gx"
  • echo "gy: $gy"
  • echo "gz: $gz"
  • done

然后我们看一下效果:

看起来一切都很正常。至此,MPU6050外设我们已经可以成功使用。

 

接下来是蜂鸣器的使用。因为主要的目的是发出警报,因此蜂鸣器的音量很关键。在这里我们选用一颗有源蜂鸣器,用NMOS管来驱动,以实现大音量。

 

参考上面的原理图,在I2C附近有一个GPIOB22,我们就使用这个引脚来控制蜂鸣器吧。

 

接线一共有三根,mos管的门级接GPIOB22,接着接好供电和地线即可。

 

蜂鸣器控制比较简单,只需要使用常规GPIO操作方法即可。需要注意的是,linux系统中的GPIO index与实际电路的对应关系如下:

GPIO 编号 = GPIO 组号值 + 偏移值. 
以我们选用的管脚为例,查表对应 GPIOB22  GPIOB 对应组号值 448, 偏移值为 22. 

因此 GPIOB22 编号index为 448 + 22 = 470 
组号值对应如下: 
GPIOA 对应 linux 组号值为 480 
GPIOB 对应 linux 组号值为 448 
GPIOC 对应 linux 组号值为 416 
GPIOD 对应 linux 组号值为 404 
GPIOPWR 对应 linux 组号值为 381

 

因此,初始化GPIOB22,并将其设置为输出模式,我们需要用以下命令:

  • echo 470 > /sys/class/gpio/export
  • echo out > /sys/class/gpio/gpio470/direction

在这里我硬件设计上出了点小问题。

由于华山派的GPIO在未定义状态下是默认上拉的,当我们将它设置为输出模式后,才会变成低电平。而我的蜂鸣器是使用NMOS驱动,高电平有效,这就导致在初始化管脚前蜂鸣器会一直叫,直到初始化完成后才会停止,非常烦人。如果大家想自己做,建议使用PMOS,就不会有这个问题。

 

接下来我们尝试下让蜂鸣器鸣叫五秒,接着关闭:

  • echo 1 > /sys/class/gpio/gpio470/value
  • sleep 5
  • echo 0 > /sys/class/gpio/gpio470/value

可以听到蜂鸣器正常工作,那么这一块我们也就完成了。

 

下面我们来说说如何连接WiFi。WiFi连接比较麻烦,主要是官方资料中的内容不是缺失就是错误,导致耽误了很多时间。最后在平头哥工程师的帮助下,终于在硬十上找到了一篇正确的资料,这才成功连接。

首先我们去以下地址下载所需的可执行文件:

https://www.hw100k.com/play?id=195&chapterId=2572

 

下载完成后,我们在华山派的/mnt/data中新建一个WiFi文件夹,将下载里面的wpa_cli和wpa_supplicant放进去,然后输入以下命令赋予执行权限:

 

然后新建一个wpa_supplicant.conf的文件,将以下代码输入进去:

  • ctrl_interface=/var/run/wpa_supplicant
  • update_config=1
  • network={
  • ssid="SSID1"
  • psk="password1"
  • }
  • network={
  • ssid="SSID2"
  • psk="password2"
  • }

修改好自己的SSID和password,你有几个可以连接的AP就填几个network,程序会按照顺序一个一个尝试连接,如果连不上超时就换下一个。

 

完成后我们在/mnt/data中新建一个auto.sh文件,按照上文方法添加执行权限,接着在里面写入以下内容:

  • insmod /mnt/system/ko/3rd/8723ds.ko
  • ifconfig wlan0 up
  • /mnt/data/WiFi/wpa_supplicant -i wlan0 -Dnl80211 -c /mnt/data/WiFi/wpa_supplicant.conf &
  • udhcpc -b -i wlan0 -R &

然后重启,我们就可以发现板子已经成功的连上了WiFi,可以不再需要接线,用ssh直接透过wifi连接使用,非常方便。

 

但这板子有一个比较蛋疼的地方是,每一次重新启动,似乎网卡的信息都会改变。经过测试,每次重启有线网卡的mac地址都不相同。WiFi的mac地址虽然不会变,但实际上某些配置也发生了变化,导致无论是使用有线连接还是无线连接,在每次重启后,连接ssh总会得到以下提示:

因此只能在连接前先输入清除keygen命令,再连接才行。目前不太清楚这个问题如何妥善解决,只能先用临时方案凑合。

  • ssh-keygen -R 目标IP地址
  • ssh root@目标IP地址

 

下面是邮件使用的介绍。

依旧,没有任何现成的库,我们只能用最基础的shell工具来实现接入smtp服务器发送邮件。由于固件并不支持expect命令,因此我们只能用简单粗暴的sleep方式来确保脚本可以在交互指令中正常工作:

  • ip="smtp.qq.com 587"
  • user="email in Base64"
  • pass="app pwd in Base64"
  • sender="xxx@qq.com"
  • receiver="xxx@qq.com"
  • subject="HELP"
  • content="Please help me! Call xxxxxxxx"
  • mail(){
  • {
  • sleep 1
  • echo "helo test"
  • sleep 1
  • echo "auth login"
  • sleep 1
  • echo "$user"
  • sleep 1
  • echo "$pass"
  • sleep 1
  • echo "mail from:<$sender>"
  • sleep 1
  • echo "rcpt to:<$receiver>"
  • sleep 1
  • echo "data"
  • sleep 1
  • echo "from: $sender"
  • echo "to: $receiver"
  • echo "subject: $subject"
  • echo ""
  • echo "$content"
  • echo "."
  • sleep 1
  • echo "quit"
  • sleep 1
  • }|telnet $ip >> /tmp/mail.log
  • }

现在的邮箱要使用stmp登录都需要专用的app密码,这里大家自行去自己的邮箱中申请。需要注意的是,登陆中填入的邮箱地址和密码我们需要先转换为Base64再填入,不能直接明文填入。

 

填写好邮箱地址了密码后,将以上变量中的xxx都进行替换,之后运行一下这个函数,应该就可以看到邮箱中有正常收到邮件了。大家可以自行更改邮件的标题的内容。

 

至此,所有的功能都已成功实现。下面就是把所有的功能整合在一起,完成最终项目。

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
Microchip 直播|利用motorBench开发套件高效开发电机磁场定向控制方案 报名中!
直播主题:利用motorBench开发套件高效开发电机磁场定向控制方案
直播时间:2025年3月25日(星期二)上午10:30-11:30
快来报名!

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表