- 2025-01-17
-
回复了主题帖:
新年新挑战,任务打卡赢好礼!
-
加入了学习《TI DLP?技术于3D 机器视觉与自动化光学检测之应用》,观看 TI DLP 全新 3D 扫描与 3D 列印晶片 DLPC347x 简介
-
加入了学习《TI DLP?技术于3D 机器视觉与自动化光学检测之应用》,观看 TI DLP 3D SDK 介绍与解析
-
加入了学习《TI DLP?技术于3D 机器视觉与自动化光学检测之应用》,观看 TI DLP 技术于 3D 扫描之应用
-
加入了学习《TI DLP?技术于3D 机器视觉与自动化光学检测之应用》,观看 3D 扫描技术介绍
-
回复了主题帖:
《深度学习的数学——使用Python语言》统计学
兼顾趣味和知识深度的好书,学习了!
-
回复了主题帖:
RDK X3测评 快速上手
包装很精美,期待更多的评测内容
-
回复了主题帖:
RDK X3测评:2.摄像头使用
opencv-python的部署效果好不好呢?
- 2024-12-29
-
加入了学习《follow me 4演示视频》,观看 follow me 4演示视频
-
上传了资料:
follow me4代码
-
发表了主题帖:
【Follow me第二季第4期】+任务提交
本帖最后由 SeasonMay 于 2025-1-10 17:22 编辑
# 演示视频
https://training.eeworld.com.cn/video/42212
# 物料介绍
本次活动选用以及下单的是一块Arduino RP2040主控板以及Adafruit的TFT显示屏,写真如下:
Arduino Nano RP2040隶属于Arduino Nano系列,这个系列以小巧精致的板型、丰富强大的功能以及易于上手的学习特性而著称。每一块开发板都经过精心设计,尽显匠心独运。
Arduino平台旨在让人们以更实惠、更便捷的方式控制机器人。Arduino的函数库和传感器库具备高度的一致性和通用性,非常适合新手入门学习。而这款开发板所搭载的MCU是树莓派的RP2040。作为树莓派首次尝试制作的MCU,RP2040内置了两个ARM Cortex-M0+内核,时钟频率高达133Mhz,并配备了264kb的RAM。同时,它还拥有多组常用的外设接口,如UART、SPI、I2C、USB、ADC等。
RP2040支持多种开发环境。树莓派官方的Pico-sdk是基于C/C++语言开发的,可以算作RP2040的原生开发环境。不过,要使用这个SDK,需要自己搭建cmake编译、下载调试的环境。但现在也有基于VSCODE的官方扩展或PlatformIO环境,这些集成开发环境(IDE)提供了从编写代码到编译、下载、调试的一站式服务。当然了,开发也可以基于MPY进行,也是非常简单,本文将基于PlatformIO完成任务。
# PlatformIO介绍以及配置
PlatformIO是一个开源的物联网(IoT)开发平台,它整合了一系列工具和服务,旨在为开发者提供一个全面、高效且易于使用的开发环境。无论是在Windows、Linux还是macOS上,PlatformIO都能提供一致的开发体验,无需担心操作系统之间的兼容性问题。
PlatformIO的核心优势之一在于它对多种硬件平台的广泛支持。从Arduino到ESP8266,再到STM32等,PlatformIO为这些不同的硬件平台提供了统一的编程接口和工具链。这意味着,无论正在开发什么类型的物联网设备,PlatformIO都能为你提供所需的工具和资源。通过其内置的库管理器,你可以轻松地搜索、安装和更新各种设备驱动、协议栈和中间件库,从而加速你的开发进程。
在开发环境方面,PlatformIO提供了基于VSCode、Atom等流行文本编辑器或IDE的插件。这些插件集成了代码编辑、编译、上传和调试等关键功能,让你能够在同一个环境中完成整个开发流程。此外,PlatformIO还提供了一个命令行工具,为那些更喜欢在命令行界面下工作的开发者提供了灵活的选择。
## 配置环境
在Vscode中下载安装PlatformIO插件后,根据向导进行初始化,然后就可以在主页新建项目,输入芯片型号选择对应的开发板,就可以完成项目创建工作。
项目中一般会用到其他的库,比如Adafruit或者Arduino自己框架的库,可以在主页点击libraries然后选择对应的库添加到项目里,同时也可以查看已经安装的库,如图所示
需要注意的是,如果基于Arduino的框架进行开发,需要在代码中# include 头文件,不像Arduino IDE中可以直接使用自带的库文件。
编译烧录上传等功能按钮在底部工具栏,也很容易分辨
# 任务一
任务目标:搭建环境并开启第一步Blink三色LED / 串口打印Hello DigiKey & EEWorld!
任务一实现较为简单,点灯嘛,调调库就ok,不过查询资料得知需要基于WIFININA库进行实现,在WIFI框架里点灯,还是入门级别的罕见事物了,学到新东西了hhh,在PlatformIO中进行库添加
再用自带的serial.println函数输出指定内容到串口
流程如下:
实现代码如下:
```c
#include
#include
int delayTime = 500;
void setup() {
// 引脚设置为输出模式
pinMode(LEDR, OUTPUT);
pinMode(LEDG, OUTPUT);
pinMode(LEDB, OUTPUT);
}
void loop() {
// 红色LED闪烁
digitalWrite(LEDR, HIGH);
delay(delayTime);
digitalWrite(LEDR, LOW);
delay(delayTime);
// 绿色LED闪烁
digitalWrite(LEDG, HIGH);
delay(delayTime);
digitalWrite(LEDG, LOW);
delay(delayTime);
// 蓝色LED闪烁
digitalWrite(LEDB, HIGH);
delay(delayTime);
digitalWrite(LEDB, LOW);
delay(delayTime);
// 串口打印
Serial.println("Hello DigiKey & EEWorld!");
delay(delayTime);
}
```
实现效果如图所示,串口打印成功,小灯也成功点亮
# 任务二
任务目标:学习IMU基础知识,调试IMU传感器,通过串口打印六轴原始数据;
## IMU基础知识
IMU(Inertial Measurement Unit),即惯性测量单元,是测量物体三轴角速度和加速度的设备。IMU的应用非常广泛,可以用于姿态控制、导航定位、运动跟踪等领域。
IMU通常由三轴加速度计和三轴陀螺仪组成,形成一个6轴IMU,用于测量物体在三维空间中的角速度和加速度。在Arduino RP2040上,集成的LSM6DSOX传感器就是这样一款6轴IMU传感器,它可以提供三轴加速度和三轴角速度的测量数据。
加速度计是一种用于测量加速力的电机械设备,这种力可以是静态的,如持续的重力作用力,也可以是动态的,以感知运动或振动。在Arduino RP2040的IMU中,加速度计用于检测载体坐标系统独立三轴的加速度信号,提供有关板的位置的信息。通过这个应用,可以读取板的相对位置,以及通过将板向上、向下、向左或向右倾斜而获得的度数。
陀螺仪传感器则是一种可以测量和保持物体方向和角速度的设备。陀螺仪比加速计更先进,因为它们可以测量物体的倾斜和横向方向,而加速计只能测量其线性运动。在Arduino RP2040的IMU中,陀螺仪用于检测载体相对于导航坐标系的角速度信号,可以作为衡量施加于板上的力的方向的指示器。
在使用Arduino RP2040上的IMU时,首先,需要安装Arduino_LSM6DSOX库,这是用于与LSM6DSOX IMU传感器通信的库。然后,可以使用IMU.begin()函数来初始化IMU传感器,使用IMU.readAcceleration()函数来读取加速度数据,使用IMU.readGyroscope()函数来读取陀螺仪数据。读取到的数据可以通过串口监视器打印出来,以便进行观察和分析。
## 任务实现
在购买物料时,我选购了一块基于ST7735的屏幕,因此也基于GFX等库将IMU数据打印到了屏幕上进行显示,实现代码如下:
```c
#include
#include
#include
#include
#include
#include
#include
#include
#include
// 存储加速度和陀螺仪数据
float Ax, Ay, Az;
float Gx, Gy, Gz;
// 屏幕引脚定义
#define TFT_CS 9
#define TFT_RST 7
#define TFT_DC 8
#define TFT_LITE 6
// LED引脚定义
#define LEDR 4 // 红色LED
#define LEDG 5 // 绿色LED
#define LEDB 6 // 蓝色LED
// 创建ST7735屏幕对象,分辨率128x128
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// 时间间隔参数(非阻塞式输出控制)
unsigned long previousMillis = 0;
const long interval = 500; // 每500毫秒更新一次数据
// LED切换控制
int ledState = 0; // 用于控制LED的状态,0表示红色,1表示绿色,2表示蓝色
unsigned long ledPreviousMillis = 0; // 上次LED切换的时间
const long ledInterval = 500; // LED切换的时间间隔
// 绘制图案
void drawGraphics() {
// 绘制渐变色矩形:从蓝色到紫色的渐变
for (int i = 0; i < 80; i++) {
uint16_t color = tft.color565(0, 0, i * 3); // 渐变蓝色到紫色
tft.drawFastVLine(10 + i, 120, 60, color);
}
tft.setTextColor(ST77XX_BLUE);
tft.setTextSize(1.5);
tft.setCursor(20, 100);
// tft.println("hello");
}
void setup() {
Serial.begin(9600);
// 初始化IMU传感器
if (!IMU.begin()) {
Serial.println("错误:IMU 初始化失败,请检查硬件连接!");
while (1); // 如果初始化失败,程序停留在这里
}
Serial.println("IMU 初始化成功!");
Serial.println();
// 初始化ST7735屏幕
tft.initR(INITR_144GREENTAB); // 使用绿色tab版本
tft.setRotation(1); // 设置屏幕旋转方向
pinMode(TFT_LITE, OUTPUT); // 设置背光控制引脚为输出模式
analogWrite(TFT_LITE, 128); // 背光亮度设置为50%
// 清除屏幕并填充黑色背景
tft.fillScreen(ST77XX_BLACK);
// 绘制图案
drawGraphics();
// 打印固定的标签文字(只需要打印一次)
tft.setTextColor(ST77XX_BLUE);
tft.setTextSize(1.5);
tft.setCursor(10, 0);
tft.print("Accel:Ax=");
tft.setCursor(10, 20);
tft.print("Accel:Ay=");
tft.setCursor(10, 40);
tft.print("Accel:Az=");
tft.setCursor(10, 60);
tft.print("Gyros:Gx=");
tft.setCursor(10, 80);
tft.print("Gyros:Gy=");
tft.setCursor(10, 100);
tft.print("Gyros:Gz=");
}
void loop() {
unsigned long currentMillis = millis();
int delayTime=500;
// 每500毫秒更新一次数据
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// 读取加速度和陀螺仪数据
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(Ax, Ay, Az);
} else {
Serial.println("警告:未能读取到加速度数据!");
}
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(Gx, Gy, Gz);
} else {
Serial.println("警告:未能读取到陀螺仪数据!");
}
// 串口输出加速度和陀螺仪数据
Serial.print("Accel:Ax=");
Serial.print(Ax, 2);
Serial.print(" m/s², Ay=");
Serial.print(Ay, 2);
Serial.print(" m/s², Az=");
Serial.print(Az, 2);
Serial.print(" m/s² | ");
Serial.print("Gyros:Gx=");
Serial.print(Gx, 2);
Serial.print(" dps, Gy=");
Serial.print(Gy, 2);
Serial.print(" dps, Gz=");
Serial.print(Gz, 2);
Serial.println(" dps");
// 局部刷新:更新加速度和陀螺仪的数据
tft.fillRect(80, 0, 48, 20, ST77XX_BLACK); // 清空Ax数据区域
tft.setCursor(80, 0);
tft.print(Ax, 2); // 只更新Ax数据部分
tft.fillRect(80, 20, 48, 20, ST77XX_BLACK); // 清空Ay数据区域
tft.setCursor(80, 20);
tft.print(Ay, 2); // 只更新Ay数据部分
tft.fillRect(80, 40, 48, 20, ST77XX_BLACK); // 清空Az数据区域
tft.setCursor(80, 40);
tft.print(Az, 2); // 只更新Az数据部分
tft.fillRect(80, 60, 48, 20, ST77XX_BLACK); // 清空Gx数据区域
tft.setCursor(80, 60);
tft.print(Gx, 2); // 只更新Gx数据部分
tft.fillRect(80, 80, 48, 20, ST77XX_BLACK); // 清空Gy数据区域
tft.setCursor(80, 80);
tft.print(Gy, 2); // 只更新Gy数据部分
tft.fillRect(80, 100, 48, 20, ST77XX_BLACK); // 清空Gz数据区域
tft.setCursor(80, 100);
tft.print(Gz, 2); // 只更新Gz数据部分
}
// 延时100毫秒,控制屏幕刷新速率
delay(500);
}
```
实现效果:
# 任务三
任务目标:学习PDM麦克风技术知识,调试PDM麦克风,通过串口打印收音数据和音频波形。
PDM麦克风,即采用脉冲密度调制(Pulse Density Modulation)技术的麦克风,是一种高效的数字音频信号处理方式,PDM麦克风的应用非常广泛,包括语音识别、音频采集、音频录制等领域。
PDM麦克风的工作原理是将音频模拟信号进行脉冲密度调制。PDM是一种调制形式,用于在数字域中表示模拟信号。它是1位数字采样的高频数据流,在PDM信号中,脉冲的相对密度对应于模拟信号的幅度。大量的“1”对应于高(正)幅度值,而大量的“0”对应于低(负)幅度值,交替的“1”和“0”则对应于幅度值0。这种调制方式使得PDM麦克风能够输出数字信号,便于直接进行数字音频处理。
在Arduino RP2040上,PDM麦克风通常通过I2C接口与微控制器进行通信。Arduino Nano RP2040 Connect板载的MP34DT06JTR型号的PDM麦克风采用电容式传感元件和IC接口构建,具有超紧凑、低功耗、全向等特点。该麦克风能够检测声波,并将其转换为PDM格式的数字信号,然后通过I2C接口传输给RP2040微控制器进行处理。
可以基于提供的PDM库实现,代码如下:
```c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// 声道数量(仅支持单声道,固定为 1)
static const char channels = 1;
// PDM 数据的采样率(单位:Hz)
static const int frequency = 20000;
short sampleBuffer[512];
volatile int samplesRead;
void onPDMdata() {
// 查询缓冲区中可用字节数
int bytesAvailable = PDM.available();
// 从缓冲区读取音频数据到样本缓冲区
PDM.read(sampleBuffer, bytesAvailable);
samplesRead = bytesAvailable / 2;
}
void setup() {
Serial.begin(115200);
while (!Serial);
// 配置 接收回调函数
PDM.onReceive(onPDMdata);
// 初始化 PDM 麦克风
if (!PDM.begin(channels, frequency)) {
Serial.println("PDM 初始化失败!");
while (1);
}
}
void loop() {
// 检查是否有新的音频样本
if (samplesRead > 0) {
for (int i = 0; i < samplesRead; i++) {
Serial.println(sampleBuffer);
}
samplesRead = 0;
}
}
```
实现效果(当然环境有点嘈杂,特别电脑在编译时候噪音挺大):
# 心得体会
感谢eeworld和得捷举办的活动,我受益匪浅,希望以后能举办更多这样的活动!
# 代码链接
https://download.eeworld.com.cn/detail/SeasonMay/635464
- 2024-10-30
-
回复了主题帖:
【2024 DigiKey创意大赛】+基于大语言模型的智能家居平台+大语言模型学习分享
wangerxian 发表于 2024-10-30 09:26
在我的认知里,大模型做不了这么精细的活才对。
怎么给他训练嘞。
基于prompt工程引导他的输出,是可以达到这种效果的,当然最好能结合Function Call技术实现
- 2024-10-29
-
发表了主题帖:
【2024 DigiKey创意大赛】+基于大语言模型的智能家居平台+最终提交贴
本帖最后由 SeasonMay 于 2024-10-29 22:55 编辑
基于大语言模型的智能家居平台
作者:SeasonMay
一、作品简介
本作品以乐鑫的ESP32-S3-LCD-EV-BOARD为家居平台的核心主控,搭配以DFROBOT的TCS3200颜色传感器(SEN0101)以及Adafruit的15x7矩阵灯板作为家居平台的主要演示场景平台,并以Adafruit的Feather TFT ESP32-S3作为协控中心,处理器件与上位机等的通信服务等任务。全家福如下:
1.ESP32-S3-LCD-EV-Board 是一款基于 ESP32-S3 芯片的屏幕交互开发板,通过搭配不同类型的 LCD 子板,可以驱动 IIC、SPI、8080 以及 RGB 接口的 LCD 显示屏。同时它还搭载双麦克风阵列,支持语音识别和近/远场语音唤醒,具有触摸屏交互和语音交互功能,满足用户对多种不同分辨率以及接口的触摸屏应用产品的开发需求。
2. TCS3200颜色传感器(SEN0101)是一款全彩的颜色检测器,包括了一块TAOS TCS3200RGB感应芯片和4个白色LED灯,TCS3200能在一定的范围内检测和测量几乎所有的可见光。TCS3200有大量的光检测器,每个都有红绿蓝和清除4种滤光器。每6种颜色滤光器均匀地按数组分布来清除颜色中偏移位置的颜色分量。内置的振荡器能输出方波,其频率与所选择的光的强度成比例关系。
3.Adafruit的两个板卡,自然不用多说,在此前得捷的Follow Me等活动就有过出场,性能强大,功能丰富,作为本次任务的辅助器件,也起到了非常关键的作用。
二、系统框图
本项目的设计框图如下所示,其中大致可以分为三部分,首先是PC机上的云端服务,负责提供flask的总体通信交互框架,用于不同板卡间以及与上位机的通信交互,同时也在上位机上部署了大语言模型的推理服务,在通过ESP32-S3-LCD-EV-BOARD的LVGL界面完成与用户的人机交互,收集到用户的意向(比如通过文本输入等)后,经由GPT-4o模型的分析,通过Function Call等技术完成推理,进行决策,下发需要完成的任务,如开灯、开启空调等,而这些细节任务的执行则由Adafruit的ESP32板辅助完成。
三、各部分功能说明
首先在上位机pc上启动flask服务以及大语言模型推理服务的接口,启动成功如图所示:
然后将Adafruit的ESP32S3板卡与矩阵灯板以及SEN0101传感器相连(本项目主要使用其4个闪亮的白色LED灯,用以模拟家庭环境中的开灯如白炽灯场景),连接对应引脚,配置完I2C地址后,上电,可以看到默认情况下,灯板以及LED灯都是熄灭状态,而ESP32由于烧录的CPY固件,因此板载的小屏幕上会显示输出信息,可以看到板子上电后连接到wifi,并且自动显示地址,并且已经在监听5005端口,等待大语言模型下发的指令传递至此,从而继续操作其他两个外设。
将ESP32的EV板上电,可以看到基于LVGL构建的交互界面,最上方显示连接wifi后分配的IP地址,中间则是一个文本输入框,用来接收用户输入的文字文本信息,下方一个按钮,用来确认用户输入的信息。
点击文本输入框,界面会自动弹出一个软键盘,方便用户直接输入信息,免去要外接键盘的麻烦。
然后用户可以自由输入感受、想法等等一切文本信息,借由大语言模型的出色的理解能力,可以与用户共情,懂你所想,从而完成用户需要的任务。比如这里输入“it is night already”,并点击确认,首先会回显确认信息,然后借由flask服务将文本信息转发至PC机,基于Function Call技术进行大语言模型处理。
这里查看大语言模型输出可以发现,模型成功意识到现在天色已晚,潜台词需要开灯照明了
然后查看“白炽灯”状态,果然已经由大语言模型智能处理,打开了灯泡开始照明,“Enjoy your brightness”!
同理,可以输入如“I am hot”之类的主观感受,大语言模型也会懂你意思,指挥开启空调服务
而且也可以输入比如“I am so bored”让大模型帮忙找点乐子,然后就会发现大模型用灯板摆了些字符图案什么的逗你开心
具体细节可以通过视频观看了解,总体来说,智能性以及可拓展性还是很强的。
四、作品源码
https://download.eeworld.com.cn/detail/SeasonMay/634838
五、作品功能演示视频
六、项目总结
最后,首先还是要感谢EEWorld和得捷电子举办这个活动,让我能够学习到这么多知识,也可以将之前计划许久的项目付诸实践,虽然有些许地方不太完美,还有不少优化空间,但我也会继续学习,早日将这些不足进行完善 ,下面是一些学习过程中整理的知识分享链接,供参考,感谢观看!
项目中学习知识分享链接:
1.开箱贴:https://bbs.eeworld.com.cn/thread-1291486-1-1.html
2.ESP32学习分享贴:https://bbs.eeworld.com.cn/thread-1297569-1-1.html
3.大语言模型学习分享贴:https://bbs.eeworld.com.cn/thread-1297572-1-1.html
-
回复了主题帖:
【2024 DigiKey创意大赛】+基于大语言模型的智能家居平台+大语言模型学习分享
wangerxian 发表于 2024-10-29 19:20
用大模型搭建积木?这应该不是大模型的功能吧
也可以做,也有很多方法实现了
-
上传了资料:
基于大语言模型的智能家居平台源码
-
发表了主题帖:
【2024 DigiKey创意大赛】+基于大语言模型的智能家居平台+大语言模型学习分享
## 大语言模型介绍
大语言模型(Large Language Model,LLM),也称大型语言模型,是一种人工智能模型,旨在理解和生成人类语言。它们在大量的文本数据上进行训练,可以执行广泛的任务,包括文本总结、翻译、情感分析等等。LLM的特点是规模庞大,包含数十亿的参数,帮助它们学习语言数据中的复杂模式。
在实际生活或者项目中融入大语言模型,可以进一步提高智能性以及项目的可拓展性,能够实现许多新功能。而需要在实际项目中部署使用大模型服务,一般可以通过Function Call等技术结合使用,会更加便利。
## Function Call应用说明
首先可以参考下面两个视频链接:
【基于chatgpt实现简单的机器人抓取仿真】 https://www.bilibili.com/video/BV16u411x7Vy/?share_source=copy_web&vd_source=173bfb5e5cb20afa5371691cd1151515
【用文心一言驱使机械臂搭积木,从感知到理解到编排与生成,探索CV+大语言模型的落地开发】 https://www.bilibili.com/video/BV1UN411M7q4/?share_source=copy_web&vd_source=173bfb5e5cb20afa5371691cd1151515
不难发现,上面的两个视频中都有提到”函数调用“以及”using function“这类关键词,而诸如这种将预先实现的函数作为工具并且将函数的描述一起传给大模型,供大模型进行使用就是简单的工具调用(Function Call/Tool Call)。
在人类历史的长河中,对工具的创造和使用无疑展现了我们的智慧与创新能力。自人类文明出现以来,工具一直是我们生存的本质所不可或缺的一部分。工具是人类能力的扩展,旨在提高人类活动的生产力、效率和解决问题的能力。随着工具的进步,我们可以轻松高效地完成日益复杂的任务,从而解放时间和资源,以追求更宏伟的目标。
大语言模型拥有丰富的社会经验与基础知识,在理解和生成自然语言文本方面表现优异,但由于大模型预训练数据的滞后性以及私域数据的使用限制,再加上大语言模型存在的幻觉问题,有时基于RAG也很难满足所有需求,因此类似于人类发展,大模型也需要借助工具来与外部世界交互或者实现动态功能
借助工具,不仅可以打破传统静态文本处理的限制,使得模型能够根据实时数据和信息来生成更加准确和有用的输出,还能够与其他先进技术进行无缝集成,例如机器学习算法、图像处理或数据分析工具等,从而提供更加全面和深入的服务。总的来说,工具调用为大语言模型赋予了更强的交互性和实用性,使其能够成为真正意义上的智能助手,帮助人类解决各种复杂问题。
因此,在本次大赛项目中,我也基于Function Call的理念对大语言模型进行应用部署。
## 示例代码框架
实际使用,我个人基于Langchain框架进行开发,也推荐初学者采用此框架。Langchain是一个流行的开源大语言模型操作框架,为开发者提供了一系列的工具和组件,使得与语言模型中的各种数据(如SQL、PDF、CSV)等的连接、语言模型的应用和优化直接简洁。
下面代码主要部分有两处,一处是@tool下的Function的功能定义说明以及具体实现,另一处则是基于OpenAI的chat框架,应用langchain提供的Agent进行Function Call的效果实现。
```
import httpx
from langchain import hub
from langchain.agents import AgentExecutor, create_react_agent, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
api_key = "Your_API_Key"
# Define tools to be used with the agent
@tool
def call_ambulance(position: str) -> str:
"""Call ambulance in terms of emergency like accident to the given position """
return "Ambulance called successfully."
@tool
def call_police(position: str) -> str:
"""Call police in terms of heavy emergency to maintain situation to the given position"""
return "Police called successfully."
tools = [call_ambulance, call_police]
llm = ChatOpenAI(
openai_api_key=api_key,
model="gpt-4o")
question = "发生交通事故了"
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
# Invoke the agent with the combined input
result = agent_executor.invoke(
{"input": question, "tools": tools}).values()
```
运行结果如图所示,可以发现,大语言模型在得到输入的query后,会搜寻自带的先验知识,得出Thought想法,然后会进行推理决策,利用可以使用的工具进行具体决策以及行动,相比传统方法融入了更多社会常识以及智能性,也有望为未来的具身智能、机器人开发等提供更多选择。
## 其他
当然了,Function Call的使用只是大模型应用部署中微小的一部分,初学上手体验后,可以继续研究开发诸如RAG、微调、Agent智能体等更多技术,从而能够更好地应用大模型的开发。
-
发表了主题帖:
【2024 DigiKey创意大赛】+基于大语言模型的智能家居平台+ESP32S3 EV BOARD上手指引
开发ESP32的环境选择有很多很多,我个人尝试过MicroPython、Arduino、VScode+ESP idf以及VScode+PlatformIO等环境,综合来看,Arduino上手比较快,mpy驱动配置有点复杂,PlatformIO上手有一些基础后最为推荐,因此本篇记录下初学者入门使用的一些开发过程,基于Arduino进行开发,由于本人也是摸着石头过河,可能存在说的不对的地方,也麻烦指出。
## 配置Arduino开发环境
首先参考官方的arduino使用说明,安装依赖,参考链接:[ESP32_Display_Panel/README_CN.md at v0.1.6 · esp-arduino-libs/ESP32_Display_Panel](https://github.com/esp-arduino-libs/ESP32_Display_Panel/blob/v0.1.6/README_CN.md)
我安装的版本如下:
```
arduino-esp32:3.0.5
ESP32_IO_Expander:0.0.4
ESP32_Display_Panel:0.18.0
lvgl:8.4.0
```
初次安装lvgl需要配置一下环境,本机环境为win11,首先定位到类似C:\Users\SeasonMay\Documents\Arduino\libraries路径下,可以看到lvgl的文件夹
刚开始是没有lv_conf.h文件的,需要去lvgl文件夹下,将lv_conf_template.h文件复制一份放到上图中的文件夹内,并修改文件中第15行来使能文件
```
#if 0 -> #if 1
```
打开示例项目,点击示例->ESP32_Display_Panel -> LVGL ->v8->Porting,打开的项目文件组织如图所示
基于EV Board使用,需要修改几处地方代码,使能对应功能代码
```
# ESP_Panel_Board_Supported.h
line 10 0>1
line44 取消注释(注意是v1.5那行)
```
其他地方按具体需求修改或者注释即可
## 编译使用
点击工具,配置下方参数,这里我修改的地方主要如下
```
# 修改Flash大小 从4MB->16MB
# 修改分区,Partition Scheme,从默认改为16M Flash(3+9.9),实际只用默认,LVGL+WIFI等功能就能把控件挤爆了,推荐改下分区大小
# 使能PSRAM,使用OPI PSRAM,否则烧录程序会不断重启,这个我看别的博主也提到了
# 其他按需修改
```
## 效果初试
在编辑完参数列表后,就可以编写修改示例代码或者直接用示例代码运行了,这里提供一个我修改后的demo,放入了一个按钮控件和文本输入框控件,其中点击文本输入框,会弹出软键盘可以输入文字,再点击按钮,就会显示所输入的文字
```c
#include
#include
#include
#include "lvgl_port_v8.h"
// 定义全局变量存储文本框和键盘对象
lv_obj_t *textarea;
lv_obj_t *keyboard;
/* 按钮事件处理函数 */
static void btn_event_cb(lv_event_t * e)
{
// 获取文本框的内容
const char * text = lv_textarea_get_text(textarea);
// 在串口输出文本框中的内容
Serial.print("Text input: ");
Serial.println(text);
// 弹出提示框
lv_obj_t *msg = lv_msgbox_create(NULL, "Input", text, NULL, true);
lv_obj_align(msg, LV_ALIGN_CENTER, 0, 0);
}
/* 文本框事件处理函数,点击文本框时弹出键盘 */
static void textarea_event_cb(lv_event_t * e)
{
// 显示虚拟键盘
lv_keyboard_set_textarea(keyboard, textarea); // 关联键盘和文本输入框
lv_obj_clear_flag(keyboard, LV_OBJ_FLAG_HIDDEN); // 显示键盘
}
/* 键盘事件处理函数 */
static void keyboard_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t *kb = lv_event_get_target(e);
if(code == LV_EVENT_CANCEL) {
lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN); // 隐藏键盘
}
}
void setup()
{
String title = "LVGL porting example with button, text area, and keyboard";
Serial.begin(115200);
Serial.println(title + " start");
Serial.println("Initialize panel device");
ESP_Panel *panel = new ESP_Panel();
panel->init();
#if LVGL_PORT_AVOID_TEAR
// 如果启用避免撕裂功能,配置RGB总线
ESP_PanelBus_RGB *rgb_bus = static_cast(panel->getLcd()->getBus());
rgb_bus->configRgbFrameBufferNumber(LVGL_PORT_DISP_BUFFER_NUM);
rgb_bus->configRgbBounceBufferSize(LVGL_PORT_RGB_BOUNCE_BUFFER_SIZE);
#endif
panel->begin();
Serial.println("Initialize LVGL");
lvgl_port_init(panel->getLcd(), panel->getTouch());
Serial.println("Create UI");
lvgl_port_lock(-1);
// 创建一个简单的标签
lv_obj_t *label = lv_label_create(lv_scr_act());
lv_label_set_text(label, title.c_str());
lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 20);
// 创建一个文本输入框
textarea = lv_textarea_create(lv_scr_act());
lv_obj_set_width(textarea, 200);
lv_obj_align(textarea, LV_ALIGN_CENTER, 0, -40); // 让文本输入框居中
lv_obj_add_event_cb(textarea, textarea_event_cb, LV_EVENT_CLICKED, NULL); // 点击文本框时弹出键盘
// 创建一个按钮
lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 40); // 让按钮位于文本输入框的下方
lv_obj_set_size(btn, 100, 50);
// 创建按钮的标签(按钮上的文字)
lv_obj_t *btn_label = lv_label_create(btn);
lv_label_set_text(btn_label, "Submit");
lv_obj_center(btn_label);
// 为按钮设置事件回调函数
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);
// 创建虚拟键盘,并设置为初始隐藏状态
keyboard = lv_keyboard_create(lv_scr_act());
lv_obj_add_flag(keyboard, LV_OBJ_FLAG_HIDDEN); // 默认隐藏键盘
lv_obj_add_event_cb(keyboard, keyboard_event_cb, LV_EVENT_CANCEL, NULL); // 设置键盘取消事件
lvgl_port_unlock();
Serial.println(title + " end");
}
void loop()
{
Serial.println("IDLE loop");
delay(1000);
}
```
## 其他
其他不说,Arduino确实配置环境起来比较方便,但编译实在太慢了,塞个LVGL,编译在我电脑上起码十分钟左右,后面我又尝试了一下VSCode+PlatformIO进行开发,编译速度快了好几倍,也推荐大家可以尝试一下,arduino入门完后就可以试试看PlatformIO开发了。此外我也看到有Circuitpython的支持,做完比赛后也会尝试用一用,效果好再发个帖子上来。
- 2024-09-09
-
回复了主题帖:
【2024 DigiKey创意大赛】基于大语言模型的智能家居平台开箱贴
wangerxian 发表于 2024-8-27 14:16
语言大模型准备接谁家的?
感觉都可以,glm的,qwen的balabala,或者直接找个开源的丢orin上本地跑拉api
- 2024-08-25
-
发表了主题帖:
【2024 DigiKey创意大赛】基于大语言模型的智能家居平台开箱贴
首先感谢EEWorld和得捷联合举办的这次活动,让作为小白的我又可以跟着各位大佬学习啦~
这次我选用的是一块ESP32-S3的带触摸屏的开发板,一块颜色传感器以及一个Matrix灯阵,晒一个全家福
然后去掉包装,再看看板子以及传感器的细节
最后再给ESP32的主控板一个单独的特写,彰显c位特质hhh
板卡在手,接下来就是认真研究技术,争取做出好的作品了,和大家一起加油!
- 2024-06-24
-
加入了学习《基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之一 》,观看 基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之一STTS751温度传感器测试