【ELF-RK3506开发板】不需手写代码,就能搞定GY-30光感传感器
本文介绍了如何通过TRAE工具自动生成GY-30光感传感器的硬件控制代码。作者首先创建详细的需求文件,包括硬件配置、功能要求(周期性读取并转换光照数据)和编译部署任务。使用豆包的coder模型生成C语言代码,实现了I2C通信、数据转换和光照等级判断功能,并生成了VS Code的tasks.json文件用于交叉编译和部署。虽然部署任务存在转义字符问题,但整体实现了预期功能,验证了AI工具在硬件编程中
目录
引言
昨天已经介绍了如何搭建一个AI编程的开发环境,不过当时用于测试的场景比较简单,生成代码和硬件关系不大。今天我们来挑战一下能不能不手写代码,纯靠TRAE工具生成硬件外设相关的代码。我们采用的硬件外设就是前一篇博文介绍的GY-30光感传感器。
书写任务需求
首先创建一个“功能需求.md”文件。文件内容如下:
硬件配置:
1. ELF-RK3506开发板
2. GY-30传感器模块
3. 杜邦线若干
ELF-RK3506开发板的I2C2接口已经正确连接了GY-30传感器模块,传感器模块的地址为0x23。
GY-30传感器使用的BH1750FVI传感器,其数据手册可以在BH1750FVI.pdf中找到。请注意其中对I2C接口的描述,以及对传感器的地址的说明。
完成如下任务:
1. 创建一个基于Linux控制台的测试程序,周期读取GY-30传感器的数据,显示读取到的I2C原始数据方便调试,并将其转换为lux单位。每次显示一个数据,数据格式为"光照: %d lux",其中%d为传感器读取到的光照值。并参照下面的数据给出光照等级的显示:
* 室内强光照射:约 1000~3000 lux
* 阴天室外:约 500~1000 lux
* 晴天室外阴影处:约 10000~20000 lux
* 普通办公室照明:约 300~500 lux
2. 创建vscode的tasks.json中的任务进行交叉编译生成可执行文件,任务名为"Build",使用~/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc进行编译,编译参数为"-o test_gy30 test_gy30.c",其中test_gy30.c为测试程序的源文件,test_gy30为编译得到的可执行文件。
3. 创建vscode的tasks.json中的任务进行SSH连接的任务"Deploy via SSH"拷贝编译得到的可执行文件到服务器上并修改权限为777,服务器IP为192.168.1.123,用户名为root,无密码。本任务的执行不依赖任务2。注意对JSON中转义字符处理。
这次使用的提示词相对于我们上次的测试要复杂很多,一是因为任务更复杂了,二是为了让TRAE生成的代码更接近我们的需求。
我首先向模型介绍了硬件连接的相关情况,这里还提供了GY-30所使用BH1750FVI.pdf文件,我的目的是为了让模型能够通过读取文件获得关键的接口信息,因为我在此前使用模型生成代码时经常发现不是所有模型都对GY-30的模块信息很熟悉,有的模型会输出幻觉代码,或者不知道在转换原始数据到Lux时需要除以1.2。
在任务1需求方面,我限制了输出的格式,这样可以方便调试。
任务2是一个生成业务,相对比较简单,和以前测试时使用的描述差不多,只是稍微详细了一些。
任务3是部署任务,和构建AI编程环境那次相比有几点变化:
- 明确了生成的文件为tasks.json,避免模型生成到laugh.json中去;
- 删除了运行程序的要求,主要的原因是上次是一次执行完执行输出结果,而这次是循环输出,如果还让TRAE去执行,会导致程序一直不输出,好像死机了,所以这次改为手动运行;
- 在外面先前测试中,发现模型会把任务2当做任务3的前置任务,这完全不必要,所以明确说了任务2和任务3无关联。
总之,任务描述越详细,越容易得到正确结果。
代码生成
在代码生成时,我把模式由Auto改为豆包的coder模型,因为我不确定我的任务需求在不同下表现相同,这样做可以避免由于TRAE选择不同的模型运行导致调试困难。然后把“功能需求.md”文件拖到聊天框中,让它根据需求执行就可以了。

TRAE会自动分析我们的需求,根据分析结果确定任务,并开始执行。中间有几个步骤需要人工确认,但很快就能输出正确结果。
test_gy30.c代码
下面是生成的C代码:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#define I2C_DEVICE "/dev/i2c-2"
#define SENSOR_ADDR 0x23
#define CONTINUOUS_HIGH_RES_MODE 0x10
int main() {
int i2c_fd = open(I2C_DEVICE, O_RDWR);
if (i2c_fd < 0) {
perror("无法打开I2C设备");
return 1;
}
if (ioctl(i2c_fd, I2C_SLAVE, SENSOR_ADDR) < 0) {
perror("无法设置I2C从设备地址");
close(i2c_fd);
return 1;
}
unsigned char mode_cmd = CONTINUOUS_HIGH_RES_MODE;
if (write(i2c_fd, &mode_cmd, 1) != 1) {
perror("无法设置传感器模式");
close(i2c_fd);
return 1;
}
usleep(180000);
printf("GY-30传感器测试程序已启动\n");
printf("按Ctrl+C退出\n\n");
while (1) {
unsigned char buf[2];
if (read(i2c_fd, buf, 2) != 2) {
perror("读取传感器数据失败");
break;
}
printf("原始数据: buf[0]=0x%02X, buf[1]=0x%02X\n", buf[0], buf[1]);
int lux = (buf[0] << 8) | buf[1];
lux = (int)(lux / 1.2);
printf("光照: %d lux\n", lux);
if (lux >= 10000 && lux <= 20000) {
printf("光照等级: 晴天室外阴影处\n");
} else if (lux >= 1000 && lux <= 3000) {
printf("光照等级: 室内强光照射\n");
} else if (lux >= 500 && lux <= 1000) {
printf("光照等级: 阴天室外\n");
} else if (lux >= 300 && lux <= 500) {
printf("光照等级: 普通办公室照明\n");
} else if (lux < 300) {
printf("光照等级: 较暗环境\n");
} else {
printf("光照等级: 极强光照\n");
}
printf("\n");
sleep(1);
}
close(i2c_fd);
return 0;
}
tasks.json文件
这个文件中包括我们的两个任务:
{
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"command": "~/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc",
"args": [
"-o",
"test_gy30",
"test_gy30.c"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": ["$msCompile"]
},
{
"label": "Deploy via SSH",
"type": "shell",
"command": "bash",
"args": [
"-c",
"scp test_gy30 root@192.168.1.123:/root/ && ssh root@192.168.1.123 'chmod 777 /root/test_gy30'"
],
"problemMatcher": [],
"dependsOn": [],
"dependsOrder": "sequence"
}
]
}
这个文件的第二个任务其实有问题的,尽管我提示模型注意转义字符,但是它的处理还是不太对,不过可以通过分析运行结果让TRAE自动修正。
测试结果
下面是一段测试结果:

从程序结果看,传感器可以感知不同的光照。
结束语
整个过程有点波折,但是总体还算顺利。借助AI进行编程是大势所趋,虽然嵌入式系统的编程可能比一般的编程场景复杂一些,但是只要稍加努力,仍然可以得到满意的结果。欢迎朋友们一起尝试,也期待朋友们能够分享宝贵的经验体会。
更多推荐


所有评论(0)