在共创社内部的交流中,先前有一位成员展示了如何借助C语言来实现对AHT20温湿度传感器数据的读取。这一实例触发了另一位共创官的灵感,他决定采纳Go语言重新构建这一数据采集流程。接下来,我们将详细解析整个利用Go语言从AHT20温湿度传感器获取数据的完整步骤和实现方法。
一、C程序获取AHT20温湿度
1、参考ElfBoard官方例程:03-例程源码\03-1 命令行例程源码\09_elf1_cmd_aht20\elf1_cmd_aht20.c
#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "sys/ioctl.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"
#include <poll.h>
#include <sys/select.h>
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#define AHT20_DEV "/dev/aht20"
int main(int argc, char *argv[])
{
int fd;
unsigned int databuf[2];
int c1,t1;
float hum,temp;
int ret = 0;
fd = open(AHT20_DEV, O_RDWR);
if(fd < 0) {
printf("can't open file %s\r\n", AHT20_DEV);
return -1;
}
while (1) {
ret = read(fd, databuf, sizeof(databuf));
if(ret == 0) { /* ?????? */
c1 = databuf[0]*1000/1024/1024; //
t1 = databuf[1] *200*10/1024/1024-500;
hum = (float)c1/10.0;
temp = (float)t1/10.0;
printf("hum = %0.2f temp = %0.2f \r\n",hum,temp);
usleep(500000);
}
}
close(fd);
return 0;
}
2、使用交叉编译环境编译,拷贝到开发板
3、运行程序查看结果
二、Go程序获取AHT20温湿度
1、参考C程序使用Go程序复现,代码如下:
package main
import (
"fmt"
"syscall"
"time"
"unsafe"
)
const Aht20Dev = "/dev/aht20"
func main() {
fd, err := syscall.Open(Aht20Dev, syscall.O_RDWR, 0)
if err != nil {
fmt.Printf("can't open file %s: %s\n", Aht20Dev, err)
return
}
defer syscall.Close(fd)
buf := make([]byte, 8)
const delay = 500 * time.Millisecond
var c1, t1 int
var hum, temp float32
for {
n, err := syscall.Read(fd, buf)
if err != nil {
fmt.Println("Read err", err)
}
if n == 0 {
c1 = int(*(*uint32)(unsafe.Pointer(&buf[0]))) * 1000 / 1024 / 1024
t1 = int(*(*uint32)(unsafe.Pointer(&buf[4])))*200*10/1024/1024 - 500
hum = float32(c1) / 10.0
temp = float32(t1) / 10.0
fmt.Printf("hum = %.2f temp = %.2f\n", hum, temp)
time.Sleep(delay)
}
}
syscall.Close(fd)
}
2、修改构建配置,添加环境参数:GOOS=linux;GOARCH=arm;GOARM=7。编译输出后拷贝到开发板。并修改可执行权限:chmod 777 go_temp_linux
3、运行查看结果
三、将该功能整合到Web服务中
1、建立Gin Web项目
为了方便后续功能拓展,我这里重新建立了一个较为完整的Web项目。目录结构如下:
并且对resp进行了简单的封装。
2、有关AHT20温湿度传感器的部分
(1)AHT20温湿度传感器Logic
package aht20Logic
import (
"fmt"
"syscall"
"unsafe"
)
const Aht20Dev = "/dev/aht20"
type HumAndTemp struct {
Hum float32 `json:"hum,omitempty"`
Temp float32 `json:"temp,omitempty"`
}
func ReadHumAndTemp() (HumAndTemp, error) {
fd, err := syscall.Open(Aht20Dev, syscall.O_RDWR, 0)
if err != nil {
fmt.Printf("can't open file %s: %s\n", Aht20Dev, err)
return HumAndTemp{}, nil
}
defer syscall.Close(fd)
buf := make([]byte, 8)
n, err := syscall.Read(fd, buf)
if err != nil {
fmt.Println("Read err", err)
}
if n == 0 {
c1 := int(*(*uint32)(unsafe.Pointer(&buf[0]))) * 1000 / 1024 / 1024
t1 := int(*(*uint32)(unsafe.Pointer(&buf[4])))*200*10/1024/1024 - 500
_ = syscall.Close(fd)
return HumAndTemp{Hum: float32(c1) / 10.0, Temp: float32(t1) / 10.0}, nil
}
return HumAndTemp{}, nil
}
(2)ATH20温湿度传感器Handler
package aht20Handler
import (
"Web/logic/aht20Logic"
"Web/utils/resp"
"github.com/gin-gonic/gin"
)
func HumAndTemp(c *gin.Context) {
data, err := aht20Logic.ReadHumAndTemp()
if err != nil {
resp.Fail(c, 500, resp.CodeSystemErr)
}
resp.Success(c, data)
}
(3)router(由于目前只有两个路由组所以就先写到一个文件中,后续模块增加了再继续分隔)
package routers
import (
"Web/controller/aht20Handler"
"Web/controller/testHandler"
"github.com/gin-gonic/gin"
)
const (
baseUrl = "elf1"
)
func SetRouter() *gin.Engine {
r := gin.Default()
test := r.Group(baseUrl + "/test")
{
test.GET("ping", testHandler.PingPong)
}
aht20 := r.Group(baseUrl + "/aht20")
{
aht20.GET("hum-temp", aht20Handler.HumAndTemp)
}
return r
}
四、编译、测试
1、添加编译环境参数:GOOS=linux;GOARCH=arm;GOARM=7,执行编译,拷贝到开发板,修改可执行权限
2、启动服务,进行测试
3、可以看到服务正常运行,得到温湿度信息
至此,就完成了通过Go语言实现对AHT20温湿度数据的有效采集。这一成果的达成,充分展现了共创社成员对嵌入式研发的探索精神。期待这一实践经历能够为更多的嵌入式爱好者提供有价值的参考借鉴。