触觉智能 Purple Pi开发板是一块很小巧的板子,板载了兼容树莓派的40Pin,在开发板的背后,丝印清晰的列出了所有的接口:
拿到板子第一件事,就是点灯。这次不点一个灯了,直接点一个交通灯吧。
通过板子备好的丝印,决定使用GPIO87、GPIO88、GPIO89,具体连线如下:
Purple Pi默认的系统,启动后是root用户,通过uname可以查看当前系统信息:
Linux buildroot 4.9.84 #736 SMP PREEMPT Thu Aug 4 10:07:16 CST 2022 armv7l GNU/Linux
在这个环境下,可以直接通过sysfs来操控GPIO,从而控制LED。
通过sysfs操控GPIO,由下面两个文件控制:
# ls -l /sys/class/gpio/*export
--w------- 1 root root 4096 Jan 1 00:29 /sys/class/gpio/export
--w------- 1 root root 4096 Jan 1 00:29 /sys/class/gpio/unexport
export用于启用对应的GPIO口,unexport用于停用对应的GPIO口。
# ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 Jan 1 00:37 export
lrwxrwxrwx 1 root root 0 Jan 1 00:29 gpio72 -> ../../devices/gpiochip0/gpio/gpio72
lrwxrwxrwx 1 root root 0 Jan 1 00:29 gpiochip0 -> ../../devices/gpiochip0/gpio/gpiochip0
--w------- 1 root root 4096 Jan 1 00:37 unexport
#
# echo 87 > /sys/class/gpio/export
# ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 Jan 1 00:37 export
lrwxrwxrwx 1 root root 0 Jan 1 00:29 gpio72 -> ../../devices/gpiochip0/gpio/gpio72
lrwxrwxrwx 1 root root 0 Jan 1 00:37 gpio87 -> ../../devices/gpiochip0/gpio/gpio87
lrwxrwxrwx 1 root root 0 Jan 1 00:29 gpiochip0 -> ../../devices/gpiochip0/gpio/gpiochip0
--w------- 1 root root 4096 Jan 1 00:29 unexport
#
# echo 87 > /sys/class/gpio/unexport
# ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 Jan 1 00:37 export
lrwxrwxrwx 1 root root 0 Jan 1 00:29 gpio72 -> ../../devices/gpiochip0/gpio/gpio72
lrwxrwxrwx 1 root root 0 Jan 1 00:29 gpiochip0 -> ../../devices/gpiochip0/gpio/gpiochip0
--w------- 1 root root 4096 Jan 1 00:37 unexport
#
从上面的操作输出可以看到,如果要启用某个GPIO口,就将其编号,写入到export,如果要停用,则写入unexport
我们要使用GPIO87、GPIO88、GPIO89来控制交通灯,所以启用这三个GPIO端口:
# echo 87 > /sys/class/gpio/export
# echo 87 > /sys/class/gpio/export
# echo 87 > /sys/class/gpio/export
#
# ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 Jan 1 00:39 export
lrwxrwxrwx 1 root root 0 Jan 1 00:29 gpio72 -> ../../devices/gpiochip0/gpio/gpio72
lrwxrwxrwx 1 root root 0 Jan 1 00:39 gpio87 -> ../../devices/gpiochip0/gpio/gpio87
lrwxrwxrwx 1 root root 0 Jan 1 00:39 gpio88 -> ../../devices/gpiochip0/gpio/gpio88
lrwxrwxrwx 1 root root 0 Jan 1 00:39 gpio89 -> ../../devices/gpiochip0/gpio/gpio89
lrwxrwxrwx 1 root root 0 Jan 1 00:29 gpiochip0 -> ../../devices/gpiochip0/gpio/gpiochip0
--w------- 1 root root 4096 Jan 1 00:37 unexport
#
启用后,就会出现三个目录,分别为:
- /sys/class/gpio/gpio87/
- /sys/class/gpio/gpio88/
- /sys/class/gpio/gpio89/
这三个目录内,都有着控制GPIO具体表现的文件:
# ls -l /sys/class/gpio/gpio87/
total 0
-rw-r--r-- 1 root root 4096 Jan 1 00:40 active_low
lrwxrwxrwx 1 root root 0 Jan 1 00:40 device -> ../../../gpiochip0
-rw-r--r-- 1 root root 4096 Jan 1 00:40 direction
-rw-r--r-- 1 root root 4096 Jan 1 00:40 edge
drwxr-xr-x 2 root root 0 Jan 1 00:40 power
lrwxrwxrwx 1 root root 0 Jan 1 00:40 subsystem -> ../../../../class/gpio
-rw-r--r-- 1 root root 4096 Jan 1 00:39 uevent
-rw-r--r-- 1 root root 4096 Jan 1 00:40 value
#
其中:
- direction:控制输入in,还是输出out
- value:当前电平值
- active_low:翻转电平
- edge:中断触发模式
一般情况下,主要使用direction和value,其他有需要可以深入了解。
其基本使用如下的方式:
cd /sys/class/gpio/gpio87/
echo out > direction
echo 1 > value
echo 0 > value
echo in > direction
cat value
了解以上逻辑后,就可以用shell脚本编写控制程序了。
控制交通灯的shell脚本如下:
#!/bin/sh
idx=0
p1=89
p2=88
p3=87
gpio_dir=/sys/class/gpio
export_file=$gpio_dir/export
if [ ! -d $gpio_dir/gpio$p1 ]; then
echo $p1 > $export_file
fi
if [ ! -d $gpio_dir/gpio$p2 ]; then
echo $p2 > $export_file
fi
if [ ! -d $gpio_dir/gpio$p3 ]; then
echo $p3 > $export_file
fi
echo out > $gpio_dir/gpio$p1/direction
echo out > $gpio_dir/gpio$p2/direction
echo out > $gpio_dir/gpio$p3/direction
echo 0 > $gpio_dir/gpio$p1/value
echo 0 > $gpio_dir/gpio$p2/value
echo 0 > $gpio_dir/gpio$p3/value
while [ 1 ]
do
let p=idx%3
echo 0 > $gpio_dir/gpio$p1/value
echo 0 > $gpio_dir/gpio$p2/value
echo 0 > $gpio_dir/gpio$p3/value
if [ $p -eq 0 ]; then
echo "Pin$p1-LED ON"
echo 1 > $gpio_dir/gpio$p1/value
fi
if [ $p -eq 1 ]; then
echo " Pin$p2-LED ON"
echo 1 > $gpio_dir/gpio$p2/value
fi
if [ $p -eq 2 ]; then
echo " Pin$p3-LED ON"
echo 1 > $gpio_dir/gpio$p3/value
fi
let idx=idx+1
sleep 0.3
done
上述控制逻辑比较简单,就是设置了一个计数器,然后对其值对3取整,来确定具体要点亮的LED。
将上述脚本保存为test_led.sh,然后运行,输出如下:
实际的效果如视频所示: