当前位置:   article > 正文

基于OrangePi AIpro开发一个电子纸屏时钟

基于OrangePi AIpro开发一个电子纸屏时钟

OrangePi AIpro

简介

 OrangePi AIpro(8T)采用昇腾AI技术路线,具体为4核64位处理器+AI处理器,集成图形处理器,支持8TOPS AI算力,拥有8GB/16GB LPDDR4X,可以外接32GB/64GB/128GB/256GB eMMC模块,支持双4K高清输出。 Orange Pi AIpro引用了相当丰富的接口,包括两个HDMI输出、GPIO接口、Type-C电源接口、支持SATA/NVMe SSD 2280的M.2插槽、TF插槽、千兆网口、两个USB3.0、一个USB Type-C 3.0、一个Micro USB(串口打印调试功能)、两个MIPI摄像头、一个MIPI屏等,预留电池接口,可广泛适用于AI边缘计算、深度视觉学习及视频流AI分析、视频图像分析、自然语言处理、智能小车、机械臂、人工智能、无人机、云计算、AR/VR、智能安防、智能家居等领域,覆盖 AIoT各个行业。 Orange Pi AIpro支持Ubuntu、openEuler操作系统,满足大多数AI算法原型验证、推理应用开发的需求。

开发板的硬件规格

开发板的顶层视图和底层视图

顶层视图

 

底层视图 

 开发板的接口详情图

 

开发板40 pin UART 测试

开发板 40 pin 接口引脚的功能如下表所示, 其中标红部分的引脚具有 uart 功能,并且 Linux 系统默认配置为了 uart 功能, 可以直接使用。 另外请注意 uart0 默认设置为调试串口功能, 请不要将其当成普通串口使用。

启动 Linux 系统后, 先确认下/dev 下存在 uart 的设备节点。

  1. (base) root@orangepiaipro:~# ls /dev/ttyAMA*
  2. /dev/ttyAMA0 /dev/ttyAMA1 /dev/ttyAMA2
  3. (base) root@orangepiaipro:~#

uart 设备节点和 uart 对应关系如下所示:

然后开始测试 uart 接口, 先使用杜邦线短接要测试的 uart 接口的 rx 和 tx 引脚。不同的 uart 的 rx 和 tx 引脚对应的 40 pin 接口中的引脚如下所示:

绿色线短接的uart2、蓝色线短接的是uart7

然后进入串口测试程序的路径。

  1. (base) root@orangepiaipro:/opt/opi_test# cd /
  2. (base) root@orangepiaipro:/# cd /opt/opi_test/uart/
  3. (base) root@orangepiaipro:/opt/opi_test/uart# ls
  4. serial serial.c

串口测试程序 serial 的使用方法如下所示:

  1. (base) root@orangepiaipro:/opt/opi_test/uart# ./serial
  2. Usage: ./serial <serialport>

使用 serial 测试程序可以测试下串口的自收自发。 serial 程序会打开对应的串口发送一个字符串——Hello, Serial Port!, 然后打印接收到的字符串。 如果自发自收的字符串相同, 说明测试成功。

1) uart2 测试命令如下所示:

  1. (base) root@orangepiaipro:/opt/opi_test/uart# ./serial /dev/ttyAMA1
  2. W: Hello, Serial Port!
  3. R: Hello, Serial Port!

2) uart7 测试命令如下所示:

  1. (base) root@orangepiaipro:/opt/opi_test/uart# ./serial /dev/ttyAMA2
  2. W: Hello, Serial Port!
  3. R: Hello, Serial Port!

开发板40 pin GPIO 测试

开发板 40 pin 接口引脚的功能如下表所示, 其中标红部分的引脚默认配置为GPIO 功能, 可以直接使用, 其他具有 GPIO 复用功能的引脚需要修改 DTS 配置才能正常使用 GPIO 的功能。

Linux 镜像中预装了 gpio_operate 工具用于设置 GPIO 管脚的输入与输出方向,也可将每个 GPIO 管脚独立的设为 0 或 1。 gpio_operate 工具的详细使用方法如下所示:
1) gpio_operate 工具必须使用 root 帐号执行。

2) gpio_operate -h 命令可以获取 gpio_operate 工具的帮助信息:

  1. (base) root@orangepiaipro:/# gpio_operate -h
  2. Usage: gpio_operate <Command|-h> [Options...]
  3. gpio_operate Command:
  4. -h : This command's help information.
  5. set_value : Set gpio pin value.
  6. get_value : Get gpio pin value.
  7. set_direction : Set gpio pin direction value.
  8. get_direction : Get gpio pin direction value.
  9. (base) root@orangepiaipro:/#

3) gpio_operate get_direction gpio_group gpio_pin 用于查询 GPIO 管脚方向。

1. gpio_group 和 gpio_pin 参数说明如下所示:

 2. 比如 40 pin 中的第 31 号引脚对应的 GPIO 为 GPIO2_20, 那么其 GPIO组号为 2, GPIO 管脚号为 20, 获取其方向的命令为:

  1. (base) root@orangepiaipro:~# gpio_operate get_direction 2 20
  2. Get gpio pin direction value successed, value is 0.
  3. (base) root@orangepiaipro:~#

3. 输出的打印信息说明

4) gpio_operate set_direction gpio_group gpio_pin direction 用于设置 GPIO 管脚方向。

  1. gpio_group、 gpio_pin 和 direction 参数说明如下所示 :

  2. 比如 40 pin 中的第 31 号引脚对应的 GPIO 为 GPIO2_20, 那么其 GPIO组号为 2, GPIO 管脚号为 20, 设置其方向为输出的命令为:
  1. (base) root@orangepiaipro:~# gpio_operate set_direction 2 20 1
  2. Set gpio pin direction value successed.
  3. (base) root@orangepiaipro:~#

5) gpio_operate get_value gpio_group gpio_pin 命令用于查询 GPIO 管脚值

  1. gpio_group 和 gpio_pin 参数说明如下所示:

  2. 比如 40 pin 中的第 31 号引脚对应的 GPIO 为 GPIO2_20, 那么其 GPIO组号为 2, GPIO 管脚号为 20, 查询其管脚值的命令如下所示:
  1. (base) root@orangepiaipro:~# gpio_operate get_value 2 20
  2. Get gpio pin value successed, value is 0. #这里查询到的值为 0, 也就是低电平
  3. (base) root@orangepiaipro:~#

6) gpio_operate set_value gpio_group gpio_pin value 命令用于设置 GPIO 管脚值为高电平或者低电平, 注意设置管脚值前, 请确保已将 GPIO 管脚的方向设置为输出了

  1. gpio_group、 gpio_pin 和 value 参数说明如下所示:

 2. 比如 40 pin 中的第 31 号引脚对应的 GPIO 为 GPIO2_20, 那么其 GPIO组号为 2, GPIO 管脚号为 20, 设置其输出为高电平的命令为:

  1. (base) root@orangepiaipro:~# gpio_operate set_value 2 20 1
  2. Set gpio pin value successed.
  3. (base) root@orangepiaipro:~#

关机和重启开发板的方法

1) 在 Linux 系统运行的过程中, 如果直接拔掉电源断电, 可能会导致文件系统丢失某些数据, 建议断电前先使用 poweroff 命令关闭开发板的 Linux 系统, 然后再拔掉电源。

(base) root@orangepiaipro:~# poweroff

2) 除了 poweroff 命令可以关闭 Linux 系统外, 还可以使用开发板上的关机按键来关闭开发板的 Linux 系统, 然后再拔掉电源。 请注意, 关机按键是没有开机功能的。

3) 使用 reboot 命令即可重启开发板中的 Linux 系统。

(base) root@orangepiaipro:~# reboot

测评实验内容

这里基于OrangePi AIpro + 4.3寸电子纸屏 + ESP8266WIFI模块 开发电子纸屏时钟,成品图如下:

开机动画

运行时钟

显示 OrangePi AIpro CPU 实时温度

这里为了美观,减少一堆的接线, OrangePi AIpro与电子墨水屏之间的通信采用的是无线串口通信的方式,485温湿度传感器与OrangePi AIpro也是采用无线通信的方式。编程语言基于Erlang,开发框架基于emqx,这里基于emqx搭建MQTT服务器,简单期间同时对emqx进行二次开发,集成驱动电子纸墨水屏时钟运转的驱动程序。这里涉及到所有软件程序都在OrangePi AIpro部署运行。下面将对开发搭建过程中涉及到的所有内容进行详细介绍。

 所用的硬件

  • OrangePi AIpro
  • 4.3寸串口电子墨水屏
  • ESP8266 WIFI模块
  • RS485温湿度传感器
  • RS485转WIFI串口服务器模块
  • 竹木抽纸盒

硬件连接

4.3寸串口电子墨水屏ESP8266 WIFI模块
DINTX(D4)
DOUTWAKE(D8)
GNDG
VCCVV

 

实物接线图↑

RS485温湿度传感器RS485转WIFI串口服务器模块
AA
BB
VCCC
GNDD

 ​

实物接线图 ↑

所用的软件

  • JDK  > 1.8
  • Erlang 26.2.3
  • Emqx  > v5.6.0
  • Arduino IDE
  • 串口调试助手

登录香橙派

第一次使用在不知道IP的情况下可以通过串口登录

1) 首先需要准备一根 Micro USB 接口的数据线

2) 然后将 Micro USB 接口一端插入开发板的 Micro USB 接口中。

3) 再将数据线的另一端插入电脑的 USB 接口中即可。
4) 打开电脑上的设备管理器查看一下端口号。

5) 打开电脑上的串口调试助手。 

  • 端口选择:COM3
  • 波特率选择:115200

6) 当看到登录界面时, 就可以使用下面的账号和密码来登录 Linux 系统了

7) 用串口调试助手不是很方便,这里我们输入:ifconfig 指令查询一下系统的IP地址,然后改为使用SSH工具连接,这里使用FinalShell。

8) 这里改为以SSH远程登录系统

安装JDK 1.8

源码安装Erlang 需要依赖Java所以这里我们需要安装一下JDK。

1. 下载JDK

下载地址:Java Archive Downloads - Java SE 8u211 and later

 

2. 下载完成后上传至香橙派
3. 安装
  • 解压
tar -zxvf jdk-8u401-linux-aarch64.tar.gz 
  • 安装
mv jdk1.8.0_401 /usr/local/jdk1.8/
  • 配置环境变量
vim /etc/profile
  • 在打开的文件末尾添加
  1. export JAVA_HOME=/usr/local/jdk1.8
  2. export PATH=$JAVA_HOME/bin:$PATH
  3. export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

  • 刷新环境变量
source /etc/profile
  • 查看JDK版本
java -version

 

至此JDK 1.8 已安装完成。 

安装Erlang 26.2.5

Emqx是基于erlang进行开发的。

这里​使用 Kerl 安装及管理 Erlang​。https://github.com/kerl/kerl

1. 安装依赖
sudo apt-get update
  1. sudo apt-get install make
  2. sudo apt-get install build-essential
  3. sudo apt-get install m4
  4. sudo apt-get install rsync
  5. sudo apt-get install lrzsz
  6. sudo apt-get install bc
  7. sudo apt-get install sysstat
  8. sudo apt-get install lsof
  9. sudo apt-get install wget
  10. sudo apt-get install automake
  11. sudo apt-get install autoconf
  12. sudo apt-get install libssl-dev
  13. sudo apt-get install libreadline-dev
  14. sudo apt-get install libncurses5-dev
  15. sudo apt-get install xsltproc
  16. sudo apt-get install libxml2-utils
  17. sudo apt-get install unixodbc unixodbc-dev
  18. sudo apt-get install libtool
  19. sudo apt-get install libxml2-utils xsltproc fop
  20. sudo apt install libwxbase3.0-dev
  21. sudo apt-get install mesa*
  22. sudo apt-get install tk
2.  安装 kerl
  •   安装位置
 mkdir /home/SummerGao/kerl && cd /home/SummerGao/kerl
  •  下载kerl
curl -O https://raw.githubusercontent.com/kerl/kerl/master/kerl
  •  修改执行权限 
chmod a+x kerl
  • 配种环境变量
vim /etc/profile
  •  在打开的文件末尾添加
  1. export KERL_HOME=/home/SummerGao/kerl
  2. export PATH=${KERL_HOME}/:$PATH

  •  刷新环境变量
source /etc/profile
  •  查看kerl版本
kerl version 

至此kerl已安装完成。

3. 安装Erlang
  •  更新可用的已发布版本
 kerl update releases

 

  • 构建 26.2.5
kerl build 26.2.5 26.2.5

构建需要一段时间请耐心等待 

  •  查询已构建版本
kerl list builds

  •  状态查看
kerl status

  •  安装 26.2.5
kerl install 26.2.5 ~/kerl/26.2.5

  •  显示已安装版本
kerl list installations

 

  •  激活26.2.5
. /root/kerl/26.2.5/activate

 激活将备份您的 $ PATH,并将其添加到安装的 bin / 目录中。因此,它仅对当前 shell 会话有效,直到您激活另一个安装或调用 kerl_deactivate。

  • 查看已激活的 Erlang 版本
kerl active

 

  • 运行 erl 
erl

 至此Erlang已安装完成。

4. 安装Erlang 串口驱动

如果想直接通过香橙派AIPro的串口驱动电子纸屏,需要为Erlang安装一下串口驱动,如果使用ESP8266模块借助MQTT通信实现无线连接香橙派AIPro下面的步骤可跳过。

  • 下载驱动 
git clone https://github.com/tonyg/erlang-serial.git

这是一个带有 erlang 驱动程序的用于串行通信的端口程序,最初由 Johan Bevemyr 于 1996 年编写,从 2007 年起由 Tony Garnock-Jones 偶尔维护。

  •  修改Makefile 
  1. . /root/kerl/26.2.5/activate
  2. cd erlang-serial/

注意,安装之前我们需要修改一下Makefile 文件

vim Makefile

  将 FULL_INSTALL_DIR=$(DESTDIR)/erlang/lib/$(INSTALL_DIR)  调整为:

FULL_INSTALL_DIR=$(DESTDIR)/$(INSTALL_DIR)

这样可以完全按照我们自己指定的路径位置安装 

  • 安装 
  1. make
  2. DESTDIR=/root/kerl/26.2.5/lib make install

  •  测试

可以看到已经成功安装到了erlang 的lib 包下,然后运行一下看一下

  1. Erlang/OTP 26 [erts-14.2.5] [source] [64-bit] [smp:4:3] [ds:4:3:10] [async-threads:1] [jit]
  2. Eshell V14.2.5 (press Ctrl+G to abort, type help(). for help)
  3. 1> serial:start().
  4. <0.92.0>
  5. 2>

至此erlang串口驱动已安装成功。 

安装Arduino IDE、下载MQTT转串口驱动程序至ESP8266 WIFI模块

编译ESP8266 WIFI模块驱动程序使用。

1. 下载 ArduinoIDE
git clone git@github.com:technologiescollege/ArduinoTechnoEduc.git
2. 配置 ArduinoIDE

  • 选择开发板类型 

3. 编译及下载程序至ESP8266WIFI模块

在IDE中打开 mqtt_to_serial_wifi_multi.ino 编译,然后选择端口号,下载至WIFI模块。

  1. #include <ESP8266WiFi.h>
  2. #include <PubSubClient.h>
  3. #include <ESP8266WiFiMulti.h>
  4. //WiFi相关配置,候选Wifi
  5. const char* ssid_1 = "SummerGao1"; //WiFi名称
  6. const char* password_1 = "123456";//WiFi密码
  7. const char* ssid_2 = "SummerGao2"; //WiFi名称
  8. const char* password_2 = "123456";//WiFi密码
  9. const char* ssid_3 = "SummerGao3"; //WiFi名称
  10. const char* password_3 = "123456";//WiFi密码
  11. //MQTT Client相关配置
  12. const char* mqtt_server = "localhost"; //MQTT服务器地址
  13. const char* mqtt_username = "SummerGao"; //MQTT用户名
  14. const char* mqtt_password = "123456"; //MQTT密码
  15. const char* TOPIC = "home/devices/onoff/"; // 订阅消息主题
  16. const char* TOPIC_WAKEUP = "home/devices/wake_up/"; // 订阅消息主题
  17. const char* client_id = "clientId-ApjJZcy2024Dh"; // 标识当前设备的客户端编号
  18. // WiFi connect timeout per AP. Increase when connecting takes longer.
  19. const uint32_t connectTimeoutMs = 5000;
  20. ESP8266WiFiMulti wifiMulti;
  21. WiFiClient espClient; // 定义wifiClient实例
  22. PubSubClient client(espClient); // 定义PubSubClient的实例
  23. long lastMsg = 0; // 记录上一次发送信息的时长
  24. void setup() {
  25. pinMode(BUILTIN_LED, OUTPUT); // 定义板载LED灯为输出方式
  26. pinMode(D8, OUTPUT); //D8引脚连接串口墨水屏WAKE引脚
  27. Serial.begin(115200);
  28. //D4->TX引脚
  29. Serial1.begin(115200);
  30. // 板子通电后要启动,稍微等待一下让板子点亮
  31. delay(10);
  32. setup_wifi(); //执行Wifi初始化,下文有具体描述
  33. client.setServer(mqtt_server, 1883); //设定MQTT服务器与使用的端口,1883是默认的MQTT端口
  34. client.setCallback(callback); //设定回调方式,当ESP8266收到订阅消息时会调用此方法
  35. }
  36. void setup_wifi() {
  37. // Don't save WiFi configuration in flash - optional
  38. WiFi.persistent(false);
  39. // Register multi WiFi networks
  40. wifiMulti.addAP(ssid_1, password_1);
  41. wifiMulti.addAP(ssid_2, password_2);
  42. wifiMulti.addAP(ssid_3, password_3);
  43. // More is possible
  44. // Maintain WiFi connection
  45. if (wifiMulti.run(connectTimeoutMs) == WL_CONNECTED) {
  46. Serial.print("WiFi connected: ");
  47. Serial.println(WiFi.SSID());
  48. Serial.print("IP address: ");
  49. Serial.println(WiFi.localIP());
  50. } else {
  51. Serial.println("WiFi not connected!");
  52. }
  53. }
  54. //\xA5\x00\x09\x0A\xCC\x33\xC3\x3C\xA6
  55. //A500090ACC33C33CA6
  56. void callback(char* topic, byte* payload, unsigned int length) {
  57. //Serial.println(topic);
  58. if (strcmp(topic, TOPIC_WAKEUP) == 0) {
  59. String message = "";
  60. for (int i = 0; i < length; i++)
  61. {
  62. message += (char)payload[i];
  63. }
  64. if (message == "WAKE_UP_0") {
  65. digitalWrite(D8, LOW);
  66. Serial.println(message);
  67. } else if (message == "WAKE_UP_1") {
  68. digitalWrite(D8, HIGH);
  69. Serial.println(message);
  70. }
  71. } else if (strcmp(topic, TOPIC) == 0) {
  72. char x;
  73. for (int i = 0; i < length; i++)
  74. {
  75. x = (char)payload[i];
  76. //串口0:打印指令消息
  77. Serial.write(x);
  78. //串口1:转发指令消息
  79. Serial1.write(x);
  80. }
  81. } else {
  82. }
  83. if ((char)payload[0] == '1') {
  84. digitalWrite(BUILTIN_LED, HIGH); // 亮灯
  85. } else {
  86. digitalWrite(BUILTIN_LED, LOW); // 熄灯
  87. }
  88. }
  89. void reconnect() {
  90. while (!client.connected()) {
  91. Serial.print("Attempting MQTT connection...");
  92. // Attempt to connect
  93. if (client.connect(client_id, mqtt_username, mqtt_password)) {
  94. Serial.println("connected");
  95. // 连接成功时订阅主题
  96. client.subscribe(TOPIC);
  97. client.subscribe(TOPIC_WAKEUP);
  98. } else {
  99. Serial.print("failed, rc=");
  100. Serial.print(client.state());
  101. Serial.println(" try again in 5 seconds");
  102. //重置wifi连接
  103. setup_wifi();
  104. // Wait 5 seconds before retrying
  105. delay(5000);
  106. }
  107. }
  108. }
  109. void loop() {
  110. if (!client.connected()) {
  111. reconnect();
  112. }
  113. client.loop();
  114. long now = millis();
  115. if (now - lastMsg > 2000) {
  116. lastMsg = now;
  117. client.publish("home/status/", "{device:client_id,'status':'on'}");
  118. }
  119. }

 代码中需要调整的部分:

  1. //WiFi相关配置,候选Wifi
  2. const char* ssid_1 = "SummerGao1"; //WiFi名称
  3. const char* password_1 = "123456";//WiFi密码
  4. const char* ssid_2 = "SummerGao2"; //WiFi名称
  5. const char* password_2 = "123456";//WiFi密码
  6. const char* ssid_3 = "SummerGao3"; //WiFi名称
  7. const char* password_3 = "123456";//WiFi密码
  8. //MQTT Client相关配置
  9. const char* mqtt_server = "localhost"; //MQTT服务器地址
  10. const char* mqtt_username = "SummerGao"; //MQTT用户名
  11. const char* mqtt_password = "123456"; //MQTT密码
  12. const char* TOPIC = "home/devices/onoff/"; // 订阅消息主题
  13. const char* TOPIC_WAKEUP = "home/devices/wake_up/"; // 订阅消息主题
  14. const char* client_id = "clientId-ApjJZcy2024Dh"; // 标识当前设备的客户端编号

至此ESP8266WIFI 模块已配置完成。

Emqx v5.6.0搭建MQTT服务器及二次开发

基于Emqx搭建MQTT服务器,基于Emqx进行二次开发集成电子纸屏驱动程序。这里已集成完成,可以直接下载develop分支源码编译运行。

1. 下载源码
git clone -b develop git@github.com:SummerGaoPlus/emqx_epaper_clock.git 
2. 参数配置 
  • 重点部分

  • 开启uart2串口

4. 源码构建
  1. cd emqx_epaper_clock
  2. make
4. 运行
  1. cd emqx_epaper_clock
  2. _build/emqx/rel/emqx/bin/emqx console

总结

这是对香橙派AIPro的开发板的初次尝试,之前一直在用树莓派4B进行开发。经过使用对比发现香橙派更加的强大,Linux 镜像中预装了很多实用的工具, 接口比树莓派要多,更易使用,生态比想象的要完善,官方给出的文档非常的全面,而且是国产中文的,值得拥有,值得去探索。刚到手还在探索中,后期会输出更多有关香橙派AIPro的使用教程及技术博文,分享更多有趣的内容。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
  

闽ICP备14008679号