- 2024-03-05
-
发表了主题帖:
【安信可BW16-Kit】 8、使用WiFi控制RGB灯
# 【安信可BW16-Kit】 8、使用WiFi控制RGB灯
## 1、程序功能介绍
### 1.1 先决设置
1、BW16和电脑要处于同一个局域网。电脑上需要访问网页。
### 1.2 功能解释
该程序是一个基于BW16开发板的简单Web服务器示例,能够通过WiFi连接到一个网络,并允许用户通过Web浏览器控制连接到BW16的三个LED灯(红色、绿色、蓝色)的开关状态。程序的主要功能分为几个部分:
### 1. 初始化和WiFi连接
- **设置WiFi凭据**:程序开始时,首先定义了连接到WiFi网络所需的SSID(网络名称)和密码。
- **初始化WiFi连接**:在`setup()`函数中,程序尝试使用提供的凭据连接到WiFi网络。这一过程在一个循环中进行,直到设备成功连接到WiFi网络为止。连接成功后,它还会启动一个在端口80上监听的Web服务器,这是HTTP默认端口。
- **串行通信初始化**:通过`Serial.begin(115200)`启动串行通信,以便在串行监视器中打印调试信息和WiFi状态信息。
### 2. 设置LED引脚
- **定义LED引脚**:定义了三个LED灯(红、绿、蓝)所连接的GPIO引脚号。
- **初始化LED引脚**:将这些LED引脚设置为输出模式,准备接收高低电平信号以控制LED的亮灭。
### 3. Web服务器功能
- **处理客户端请求**:在`loop()`函数中,ESP32作为Web服务器不断监听是否有客户端(如Web浏览器)连接。一旦有客户端连接,服务器就读取客户端发送的HTTP请求。
- **解析HTTP请求**:服务器读取和解析来自客户端的HTTP请求。特别是,它检查请求的URL,看看用户是否请求了开启或关闭某个颜色LED的路径(例如`/RH`表示打开红色LED,`/RL`表示关闭红色LED)。
- **控制LED状态**:根据解析出的请求路径,服务器通过向相应的LED引脚写高电平(HIGH)或低电平(LOW)来开启或关闭LED灯。
- **发送HTTP响应**:服务器对客户端的请求做出响应,发送一个简单的HTML页面,其中包含链接,用户可以点击这些链接来控制每个颜色LED的状态。
### 4. 打印WiFi状态信息
- **打印连接信息**:`printWifiStatus()`函数用于打印ESP32连接到的WiFi网络的信息,包括SSID、设备的IP地址以及信号强度(RSSI)。这些信息有助于调试和确认设备是否成功连接到了指定的WiFi网络。
总的来说,这个程序通过结合WiFi模块和Web服务器功能,实现了一个简单的物联网(IoT)应用,用户可以通过网络远程控制硬件设备(LED灯)的状态。这种模式为开发更复杂的基于ESP32的IoT应用提供了一个基础模板。
## 2、程序详解
```cpp
#include
char ssid[] = "xxss"; // WiFi网络名称
char pass[] = "999999999"; // WiFi网络密码
int status = WL_IDLE_STATUS; // WiFi连接状态
WiFiServer server(80); // 创建一个在端口80监听的服务器
// 定义红、绿、蓝LED的引脚
#define LED_PINR 11
#define LED_PING 12
#define LED_PINB 7
void setup() {
Serial.begin(115200); // 启动串行通信,波特率设置为115200
// 将LED引脚设置为输出模式
pinMode(LED_PINR, OUTPUT);
pinMode(LED_PING, OUTPUT);
pinMode(LED_PINB, OUTPUT);
// 尝试连接到WiFi网络
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to Network named: ");
// 显示正在尝试连接的网络SSID
Serial.println(ssid);
// 开始连接到WPA/WPA2网络,如果使用开放或WEP网络,需要修改此行代码
status = WiFi.begin(ssid, pass);
// 等待10秒以完成连接
delay(10000);
}
server.begin(); // 启动web服务器
printWifiStatus(); // 打印连接状态信息
}
void loop() {
WiFiClient client = server.available(); // 监听是否有客户端连接
if (client) { // 如果有客户端连接,
Serial.println("new client"); // 通过串行端口输出消息
String currentLine = ""; // 创建一个String对象,用于存储来自客户端的数据
while (client.connected()) { // 当客户端保持连接状态时
if (client.available()) { // 如果客户端有数据发送
char c = client.read(); // 读取一个字节的数据
Serial.write(c); // 并通过串行端口输出
if (c == '\n') { // 如果读取的字节是换行符
// 如果当前行为空,表示收到了连续的两个换行字符,即HTTP请求的结束
if (currentLine.length() == 0) {
// 发送HTTP响应头
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
// 发送HTML内容,包括控制LED状态的链接
client.print("Click here to turn the LED on R on");
client.print("Click here to turn the LED on R off");
client.print("Click here to turn the LED on G on");
client.print("Click here to turn the LED on G off");
client.print("Click here to turn the LED on B on");
client.print("Click here to turn the LED on B off");
// HTTP响应结束
client.println();
// 结束循环
break;
} else { // 如果读取到的是新的一行
currentLine = ""; // 清空当前行,准备读取下一行
}
} else if (c != '\r') { // 如果读取到的不是回车符
currentLine += c; // 将其添加到当前行的末尾
}
// 根据请求路径,控制LED的开关
if (currentLine.endsWith("GET /RH")) {
digitalWrite(LED_PINR, HIGH); // 打开红色LED
}
if (currentLine.endsWith("GET /RL")) {
digitalWrite(LED_PINR, LOW); // 关闭红色LED
}
if (currentLine.endsWith("GET /GH")) {
digitalWrite(LED_PING, HIGH); // 打开绿色LED
}
if (currentLine.endsWith("GET /GL")) {
digitalWrite(LED_PING, LOW); // 关闭绿色LED
}
if (currentLine.endsWith("GET /BH")) {
digitalWrite(LED_PINB, HIGH); // 打开蓝色LED
}
if (currentLine.endsWith("GET /BL")) {
digitalWrite(LED_PINB, LOW); // 关闭蓝色LED
}
}
}
// 断开客户端连接
client.stop();
Serial.println("client disconnected");
}
}
void printWifiStatus() {
// 打印当前连接的WiFi网络SSID
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// 打印WiFi IP地址
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// 打印信号强度
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
// 提示用户在浏览器中访问的地址
Serial.print("To see this page in action, open a browser to http://");
Serial.println(ip);
}
```
## 3、效果展示
[localvideo]583d0931824670fdb0aa613775ea0485[/localvideo]
-
回复了主题帖:
【安信可BW16-Kit】7、手机搜索蓝牙
本帖最后由 xiyou2020eeeee 于 2024-3-5 08:34 编辑
Jacktang 发表于 2024-3-5 07:57 能和手机蓝牙配对上吧
这个主要是实现手机搜索BW16 蓝牙
- 2024-03-04
-
发表了主题帖:
【安信可BW16-Kit】7、手机搜索蓝牙
# 【安信可BW16-Kit】7、手机搜索蓝牙
## 1、实验步骤
这段代码用于创建一个iBeacon设备,iBeacon是一种基于蓝牙低功耗(BLE)技术的室内定位系统,它可以广播一个信号,被附近的设备识别和解析。下面是对代码功能的详细解释:
1. **引入库**:
- `#include "BLEDevice.h"`:引入BLEDevice库,这个库提供了用于处理BLE设备初始化和配置的函数和类。
- `#include "BLEBeacon.h"`:引入BLEBeacon库,这个库提供了创建和配置iBeacon信标的功能。
2. **定义iBeacon对象**:
- `iBeacon beacon;`:创建一个iBeacon对象,这个对象将用于设置iBeacon的参数并广播iBeacon信号。
3. **定义UUID**:
- `#define UUID "00112233-4455-6677-8899-AABBCCDDEEFF"`:定义一个UUID(Universally Unique Identifier),这是iBeacon的唯一标识符,用于区分不同的iBeacon设备。
4. **设置iBeacon参数**:
- `beacon.setManufacturerId(0x004C);`:设置iBeacon的制造商ID,0x004C是Apple公司的ID,用于iBeacon。
- `beacon.setRSSI(0xBF);`:设置iBeacon的RSSI(Received Signal Strength Indicator),这个值用于估算与iBeacon的距离。
- `beacon.setMajor(0x007B);`:设置iBeacon的Major值,这个值用于区分同一位置的不同iBeacon群组。
- `beacon.setMinor(0x01C8);`:设置iBeacon的Minor值,这个值用于区分同一群组内的不同iBeacon。
- `beacon.setUUID(UUID);`:设置iBeacon的UUID。
5. **初始化BLE设备**:
- `BLE.init();`:初始化BLE设备,准备开始广播。
6. **配置广播参数**:
- `BLE.configAdvert()->setAdvType(GAP_ADTYPE_ADV_NONCONN_IND);`:设置广播类型为非连接广播,这意味着设备只广播数据,不接受连接。
- `BLE.configAdvert()->setAdvData(beacon.getAdvData(), beacon.advDataSize);`:设置广播数据为iBeacon的广播数据。
- `BLE.configAdvert()->setScanRspData(beacon.getScanRsp(), beacon.scanRspSize);`:设置扫描响应数据为iBeacon的扫描响应数据。
7. **开始广播**:
- `BLE.beginPeripheral();`:开始以外围设备的身份广播BLE信号,这时iBeacon设备开始广播其信号。
8. **循环函数**:
- `void loop() { delay(1000); }`:在这个示例中,loop函数只包含一个延时,因为iBeacon的广播是自动进行的,不需要在循环中进行额外的操作。
总体来说,这段代码通过设置iBeacon的各种参数并初始化BLE设备,创建了一个可以广播特定信号的iBeacon设备。这个信号可以被附近的设备识别和解析,用于室内定位、接近检测和其他基于位置的服务。
## 2、代码解释
```cpp
#include "BLEDevice.h" // 引入BLEDevice库,用于处理BLE设备的初始化和配置
#include "BLEBeacon.h" // 引入BLEBeacon库,用于创建和配置iBeacon信标
iBeacon beacon; // 创建一个iBeacon对象
// 定义一个UUID,这是iBeacon的唯一标识符
#define UUID "00112233-4455-6677-8899-AABBCCDDEEFF"
void setup() {
// 设置iBeacon的制造商ID,0x004C是Apple公司的ID,用于iBeacon
beacon.setManufacturerId(0x004C);
// 设置iBeacon的RSSI(接收信号强度指示),用于估算与iBeacon的距离
beacon.setRSSI(0xBF);
// 设置iBeacon的Major值,用于区分同一位置的不同iBeacon群组
beacon.setMajor(0x007B);
// 设置iBeacon的Minor值,用于区分同一群组内的不同iBeacon
beacon.setMinor(0x01C8);
// 设置iBeacon的UUID
beacon.setUUID(UUID);
// 初始化BLE设备
BLE.init();
// 配置广告类型为非连接广告,这意味着设备只广播数据,不接受连接
BLE.configAdvert()->setAdvType(GAP_ADTYPE_ADV_NONCONN_IND);
// 设置广告数据为iBeacon的广告数据
BLE.configAdvert()->setAdvData(beacon.getAdvData(), beacon.advDataSize);
// 设置扫描响应数据为iBeacon的扫描响应数据
BLE.configAdvert()->setScanRspData(beacon.getScanRsp(), beacon.scanRspSize);
// 开始以外围设备的身份广播BLE信号
BLE.beginPeripheral();
}
void loop() {
// 每隔一秒重复循环,但在这个示例中,loop函数为空,因为iBeacon的广播是自动进行的
delay(1000);
}
```
## 3、效果
- 2024-02-17
-
回复了主题帖:
【安信可BW16-Kit】5、coremark测试
Jacktang 发表于 2024-2-16 22:33
需要从 EEMBC 网站下载 CoreMark 基准测试源代码
EEMBC 网站在哪
https://www.eembc.org/coremark/
arduino有专业的~~~
- 2024-02-16
-
回复了主题帖:
【安信可BW16-Kit】6、基于HC-SR312微型人体感应模块的人存在探测
秦天qintian0303 发表于 2024-2-14 23:29
HC-SR312能调整配置吗?设置距离或者灵敏度
我买的这一款不能调整。但是,按照理论是可以调整的。需要自己画板子
- 2024-02-12
-
发表了主题帖:
【安信可BW16-Kit】6、基于HC-SR312微型人体感应模块的人存在探测
# 【安信可BW16-Kit】6、基于HC-SR312微型人体感应模块的人存在探测
## 1、HC-SR312微型人体感应模块
HC-SR312 是一款红外热释电红外传感器,用于检测人体或动物的运动。它通常用于自动门、安全系统和其他需要检测运动的应用中。
### 工作原理
HC-SR312 使用热释电红外传感器来检测运动。热释电红外传感器是一种能够将红外辐射转化为电信号的器件。当人体或动物进入传感器的检测范围时,它们会发出红外辐射,这些红外辐射会被传感器检测到并转化为电信号。电信号然后被放大和处理,以确定是否有运动发生。
### 特点
HC-SR312 具有以下特点:
* 检测距离:2米至5米
* 检测角度:120度
* 工作电压:5V至24V
* 工作电流:20mA
* 输出信号:数字信号
* 延时时间:可调,范围为5秒至300秒
* 灵敏度:可调
* 抗干扰能力强
* 使用寿命长
### 应用
HC-SR312 可用于各种应用中,包括:
* 自动门
* 安全系统
* 照明系统
* 玩具
* 机器人
### 接线图
HC-SR312 的接线如下:
* VCC:连接到电源的正极
* GND:连接到电源的负极
* OUT:输出信号,高电平时表示检测到运动
### 使用方法
1. 将 HC-SR312 连接到电源。
2. 将 HC-SR312 的 OUT 引脚连接到微控制器的输入引脚。
3. 编写代码来读取 HC-SR312 的输出信号。
4. 当 HC-SR312 检测到运动时,微控制器将执行相应的操作。
### 注意
* HC-SR312 对光线敏感,因此应避免在阳光直射或强光下使用。
* HC-SR312 的检测距离和角度会受到环境因素的影响,如温度、湿度和气流。
* HC-SR312 的灵敏度是可调的,但应根据具体应用进行调整。
## 2、连接图
```
GNDGND
VCC5V
OUT6
```
## 3、程序解释
```cpp
const int pirSensorPin = 6; // 定义PIR运动传感器连接的引脚为数字引脚6。
const int ledPin = 10; // 定义第一个LED灯连接的引脚为数字引脚10。
const int ledPin2 = 11; // 定义第二个LED灯连接的引脚为数字引脚11。
void setup() {
pinMode(pirSensorPin, INPUT); // 设置PIR传感器引脚为输入模式,用于读取传感器信号。
pinMode(ledPin, OUTPUT); // 设置第一个LED灯引脚为输出模式,用于控制LED灯的状态。
pinMode(ledPin2, OUTPUT); // 设置第二个LED灯引脚为输出模式,用于控制LED灯的状态。
Serial.begin(9600); // 开始串口通信,设置波特率为9600,用于数据输出。
}
void loop() {
int pirSensorState = analogRead(pirSensorPin); // 从PIR传感器引脚读取模拟值,并将其存储在变量pirSensorState中。
Serial.println(pirSensorState); // 通过串口输出当前读取的PIR传感器值。
if (pirSensorState >= 100) { // 判断PIR传感器读取的值是否大于或等于100。
digitalWrite(ledPin2, HIGH); // 如果是,将第二个LED灯设置为高电平(点亮LED灯)。
digitalWrite(ledPin, LOW); // 同时将第一个LED灯设置为低电平(关闭LED灯)。
Serial.println("Motion detected! Light turned on."); // 通过串口输出检测到运动的信息。
} else {
digitalWrite(ledPin, HIGH); // 如果PIR传感器读取的值小于100,将第一个LED灯设置为高电平(点亮LED灯)。
digitalWrite(ledPin2, LOW); // 同时将第二个LED灯设置为低电平(关闭LED灯)。
Serial.println("No motion detected. Light turned off."); // 通过串口输出未检测到运动的信息。
}
delay(500); // 程序暂停500毫秒,之后继续执行。
}
```
## 4、效果
[localvideo]e84d887b4a82ac382d54788fca5a185b[/localvideo]
-
发表了主题帖:
【安信可BW16-Kit】5、coremark测试
# 【安信可BW16-Kit】5、coremark测试
## 1、Coremark简介
CoreMark 是一个小型嵌入式系统基准,用于测量处理器的性能。它最初由 EEMBC(嵌入式微处理器基准联盟)于 2002 年开发,旨在为嵌入式系统设计人员提供一种简单、准确的方法来比较不同处理器的性能。CoreMark 基准由一组用 C 语言编写的函数组成,这些函数执行各种常见的嵌入式系统任务,例如内存移动、循环、函数调用和中断处理。基准测试使用这些函数来测量处理器的执行速度和效率。CoreMark 基准测试结果以每秒迭代数 (Iterations/Sec) 表示。基准测试结果越高,处理器的性能就越好。
CoreMark 基准测试的优点包括:
* **简单易用:**CoreMark 基准测试易于设置和运行,并且不需要任何特殊的硬件或软件。
* **准确可靠:**CoreMark 基准测试经过精心设计,可以准确可靠地测量处理器的性能。
* **跨平台:**CoreMark 基准测试可以在各种不同的处理器和操作系统上运行。
CoreMark 基准测试的缺点包括:
* **仅适用于小型嵌入式系统:**CoreMark 基准测试仅适用于小型嵌入式系统,不适用于大型服务器或工作站。
* **不反映真实世界的性能:**CoreMark 基准测试仅测量处理器的执行速度和效率,而不反映真实世界的性能。
总体而言,CoreMark 基准测试是一个简单、准确、跨平台的基准测试,可以用于比较不同处理器的性能。
**CoreMark 部分**
* **初始化函数:**初始化函数用于初始化基准测试所需的数据结构。
* **基准测试函数:**基准测试函数执行各种常见的嵌入式系统任务,例如内存移动、循环、函数调用和中断处理。
* **最终函数:**最终函数用于计算基准测试的结果。
基准测试函数执行以下任务:
* **内存移动:**将数据从一个内存位置移动到另一个内存位置。
* **循环:**执行一个简单的循环。
* **函数调用:**调用一个简单的函数。
* **中断处理:**处理一个简单中断。
基准测试的结果以每秒迭代数 (Iterations/Sec) 表示。基准测试结果越高,处理器的性能就越好。
CoreMark 基准测试可以在各种不同的处理器和操作系统上运行。要运行 CoreMark 基准测试,您需要:
* 一个支持 C 语言的编译器
* 一个能够运行 C 程序的操作系统
* CoreMark 基准测试源代码
您可以从 EEMBC 网站下载 CoreMark 基准测试源代码。
要运行 CoreMark 基准测试,请按照以下步骤操作:
1. 将 CoreMark 基准测试源代码解压缩到您的计算机上。
2. 使用支持 C 语言的编译器编译 CoreMark 基准测试源代码。
3. 运行 CoreMark 基准测试可执行文件。
4. CoreMark 基准测试将输出基准测试结果。
## 2、安装相关库
1、去github下载coremark库 https://github.com/lindevs/arduino-coremark
2、使用arduino ide离线安装库
3、新建sketch,运行例程
## 3、测试结果分析
```
**10:05:26.511 -> 2K performance run parameters for coremark.**
CoreMark 基准的性能运行参数。
**10:05:26.511 -> CoreMark Size : 666**
CoreMark 基准的大小,即 666 字节。
**10:05:26.511 -> Total ticks : 19031**
CoreMark 基准运行的总滴答数,即 19031。
**10:05:26.511 -> Total time (secs) : 19.03**
CoreMark 基准运行的总时间,即 19.03 秒。
**10:05:26.511 -> Iterations/Sec : 578.00**
CoreMark 基准每秒运行的迭代次数,即 578.00。
**10:05:26.511 -> Iterations : 11000**
CoreMark 基准运行的总迭代次数,即 11000。
**10:05:26.511 -> Compiler version : GCC6.5.0**
用于编译 CoreMark 基准的编译器版本,即 GCC6.5.0。
**10:05:26.511 -> Compiler flags : (flags unknown)**
用于编译 CoreMark 基准的编译器标志,但这些标志未知。
**10:05:26.568 -> Memory location : STACK**
CoreMark 基准在内存中的位置,即堆栈。
**10:05:26.568 -> seedcrc : 0xE9F5**
CoreMark 基准的种子 CRC,即 0xE9F5。
**10:05:26.568 -> [0]crclist : 0xE714**
CoreMark 基准的 CRC 列表,即 0xE714。
**10:05:26.568 -> [0]crcmatrix : 0x1FD7**
CoreMark 基准的 CRC 矩阵,即 0x1FD7。
**10:05:26.568 -> [0]crcstate : 0x8E3A**
CoreMark 基准的 CRC 状态,即 0x8E3A。
**10:05:26.568 -> [0]crcfinal : 0x33FF**
CoreMark 基准的 CRC 最终值,即 0x33FF。
**10:05:26.568 -> Correct operation validated. See README.md for run and reporting rules.**
CoreMark 基准的运行是正确的,并且提供了有关运行和报告规则的更多信息。
**10:05:26.568 -> CoreMark 1.0 : 578.00 / GCC6.5.0 (flags unknown) / STACK**
CoreMark 基准的版本、得分、编译器版本、编译器标志和内存位置。
```
## 4、横向对比
- 2024-02-11
-
发表了主题帖:
【安信可BW16-Kit】4、WIFI热点连接测试
## 1、WPA和WEP之间的区别
| 特征 | WPA | WEP |
|---|---|---|
| 安全级别 | 更安全 | 不安全 |
| 加密算法 | TKIP、AES | RC4 |
| 密钥长度 | 128 位、256 位 | 64 位、128 位 |
| 认证协议 | 802.1x、PSK | 开放系统认证、共享密钥认证 |
| 数据完整性保护 | MIC | CRC |
| 重放攻击保护 | 重放计数器 | 无 |
| 密钥管理 | 由认证服务器管理 | 由用户管理 |
| 兼容性 | 与大多数现代设备兼容 | 与旧设备兼容 |
| 速度 | 比 WEP 慢 | 比 WPA 快 |
| 成本 | 比 WEP 贵 | 比 WPA 便宜 |
## 2、设置
需要在手机端开启一个热点,热点的名称和密码符合要求即可。
## 3、运行程序
使用Arduino WiFi库连接到WiFi网络,并在成功连接后打印出网络的详细信息,包括IP地址、MAC地址、SSID、BSSID、信号强度(RSSI)和加密类型。在setup()函数中,程序检查WiFi模块是否存在,然后尝试连接到WiFi网络。程序将允许用户通过串口手动输入SSID和密码。在loop()函数中,程序定期打印当前网络的状态。此外,printWifiData()和printCurrentNet()函数用于输出与WiFi连接相关的详细信息。
```cpp
#include // 引入WiFi库,用于处理WiFi功能。
#ifdef MANUAL_INPUT
// 如果定义了MANUAL_INPUT,允许通过串口手动输入SSID和密码。
String str_ssid, str_pass;
#endif
char ssid[] = "xxss"; // 预定义的WiFi网络SSID。
char pass[] = "999999999"; // 预定义的WiFi密码。
int status = WL_IDLE_STATUS; // 设置WiFi连接的初始状态为IDLE。
void setup() {
Serial.begin(115200); // 开始串口通信,设置波特率为115200。
while (!Serial) { // 等待串口连接。
; // 空操作,确保串口准备就绪。
}
if (WiFi.status() == WL_NO_SHIELD) { // 检查WiFi模块是否安装。
Serial.println("WiFi shield not present"); // 如果没有WiFi模块,打印消息。
while (true); // 无限循环,停止执行。
}
while (status != WL_CONNECTED) { // 循环直到连接到WiFi网络。
#ifdef MANUAL_INPUT
// 如果启用了手动输入,通过串口读取SSID和密码。
Serial.println("Enter your ssid");
while (Serial.available() == 0) {} // 等待输入。
str_ssid = Serial.readString(); // 读取SSID。
str_ssid.trim(); // 去除SSID字符串两端的空格。
Serial.print("SSID entered: ");
Serial.println(str_ssid); // 打印输入的SSID。
Serial.println("Enter your password");
while (Serial.available() == 0) {} // 等待输入密码。
str_pass = Serial.readString(); // 读取密码。
str_pass.trim(); // 去除密码字符串两端的空格。
if (str_pass.length() != 0) { // 如果输入了密码。
while (str_pass.length() = 0; --i) {
if (bssid < 16) Serial.print("0");
Serial.print(bssid, HEX);
if (i > 0) Serial.print(":");
}
Serial.println();
// 打印信号强度(RSSI)。
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
// 打印加密类型。
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
```
## 4、效果
-
发表了主题帖:
【安信可BW16-Kit】3、HC-SR04超声波测距
# 【安信可BW16-Kit】3、HC-SR04超声波测距
## 1、 HC-SR04 简介
HC-SR04超声波测距传感器是一种利用超声波来测量距离的电子元件。它由一个超声波发射器和一个超声波接收器组成,发射器发出超声波脉冲,接收器接收反射回来的超声波脉冲,并计算出超声波脉冲从发射到接收的时间。通过已知超声波在空气中的传播速度,就可以计算出超声波脉冲传播的距离,从而得到目标物体的距离。
HC-SR04超声波测距传感器具有以下特点:
* 测量范围:2cm~400cm
* 分辨率:0.3cm
* 测量精度:±3mm
* 工作电压:5V
* 工作电流:15mA
* 工作温度:-20℃~+80℃
* 尺寸:45mm x 20mm x 15mm
HC-SR04超声波测距传感器有四个引脚:
* VCC:电源正极
* GND:电源负极
* TRIG:触发引脚
* ECHO:回波引脚
HC-SR04超声波测距传感器的使用方法如下:
1. 将VCC引脚连接到5V电源,GND引脚连接到电源负极。
2. 将TRIG引脚连接到微控制器的数字输出引脚。
3. 将ECHO引脚连接到微控制器的数字输入引脚。
4. 在微控制器上编写程序,向TRIG引脚发送一个高电平脉冲,持续时间为10μs。
5. 等待ECHO引脚上的电平变为高电平,并记录下高电平持续的时间。
6. 通过已知超声波在空气中的传播速度,计算出超声波脉冲传播的距离,从而得到目标物体的距离。
HC-SR04超声波测距传感器可以广泛应用于机器人、智能家居、工业自动化等领域。
## 2、 连线
## 3、 程序
```
const int trigger_pin = 12; // 定义触发引脚为数字引脚12,用于向超声波传感器发送触发信号。
const int echo_pin = 11; // 定义回声引脚为数字引脚11,用于接收超声波传感器返回的信号。
void setup() {
Serial.begin(115200); // 初始化串口通信,设置波特率为115200,用于数据输出。
pinMode(trigger_pin, OUTPUT); // 设置触发引脚为输出模式,用于发送触发信号给超声波传感器。
pinMode(echo_pin, INPUT); // 设置回声引脚为输入模式,用于接收超声波传感器返回的信号。
}
void loop() {
float duration, distance; // 定义两个浮点变量,duration用于存储回声信号的持续时间,distance用于存储计算出的距离。
digitalWrite(trigger_pin, HIGH); // 将触发引脚设为高电平,开始发送超声波。
delayMicroseconds(10); // 等待10微秒,确保超声波信号发送完毕。
digitalWrite(trigger_pin, LOW); // 将触发引脚设为低电平,停止发送超声波。
duration = pulseIn(echo_pin, HIGH); // 测量回声引脚高电平的持续时间,即超声波发射出去并返回所需的时间。
distance = duration / 58; // 根据超声波的速度(约340m/s)和回声时间计算距离,单位为厘米。这里使用的58是基于公式distance = (duration / 2) / 29.1的简化,考虑到声波往返距离和速度转换成厘米的因素。
Serial.print(distance); // 通过串口输出计算出的距离值。
Serial.println(" cm"); // 添加单位“cm”并换行。
delay(80); // 稍作延迟,减缓测量频率,防止数据输出过于频繁。
}
```
## 4、 效果
-
发表了主题帖:
【安信可BW16-Kit】2、SPI驱动8个WS2812B
# 【安信可BW16-Kit】2、SPI驱动8个WS2812B
## 1、WS2812概述
WS2812是一种数字可控LED灯珠,也被称为Neopixel。它由三个颜色的LED(红、绿、蓝)和一个集成的控制电路组成。WS2812通常以表面贴装的方式制造,具有小尺寸、低功耗和高亮度的特点。WS2812特点
* 小尺寸:WS2812的尺寸通常为5mm x 5mm,非常小巧,适合于各种紧凑的应用场景。
* 低功耗:WS2812的功耗非常低,通常在0.3W左右,非常节能。
* 高亮度:WS2812的亮度非常高,通常可以达到120流明以上。
* 数字可控:WS2812可以通过单线串行通信控制每个灯珠的颜色和亮度,非常灵活。
WS2812应用:WS2812广泛应用于各种LED灯带、装饰灯、彩灯等应用场景。同时,由于其小尺寸和低功耗,也可以应用于穿戴设备、智能家居等领域。
WS2812控制:WS2812的控制采用了一种特殊的时序通信协议,称为WS2812B协议。这种协议通过发送特定格式的数据来控制灯光的颜色和亮度。
WS2812B协议的基本数据格式如下:
```
0 1
```
其中,0和1分别代表协议的起始位和结束位,24bit RGB数据代表灯珠的颜色和亮度信息。WS2812B协议的通信速率通常为800Kbps,每个数据位由一个高电平和一个低电平组成,高电平的持续时间为0.7μs,低电平的持续时间为0.35μs。
WS2812连接:WS2812通常以串联的方式连接,即每个灯珠的输出端连接到下一个灯珠的输入端。这种连接方式可以形成一个灯带或灯条,实现更丰富的灯光效果。
WS2812的电源和数据线通常通过一个三针插头连接,插头的引脚定义如下:
* VCC:电源正极
* GND:电源负极
* DIN:数据输入
WS2812是一种灵活、高亮度、低功耗的数字可控LED灯珠,具有广泛的应用前景。通过了解WS2812的特点、应用、控制和注意事项,可以更好地使用WS2812来实现各种创意的灯光效果。
## 2、连线
## 3、程序解读
```
#include "WS2812B.h" // 引入WS2812B LED灯带的库文件。
#define NUM_OF_LEDS 8 // 定义连接的LED灯珠数量为8。
uint32_t rgbhue; // 定义一个用于存储颜色值的变量(未在程序中直接使用)。
WS2812B led(SPI_MOSI, NUM_OF_LEDS); // 创建WS2812B对象,指定数据信号线连接的引脚(使用SPI的MOSI引脚)和LED的数量。
void setup() {
Serial.begin(115200); // 初始化串口通信,波特率设置为115200。
Serial.println("WS2812B test"); // 通过串口打印测试信息。
led.begin(); // 初始化LED灯带。
}
void loop() {
// 下面三个调用逐个点亮LED为红、绿、蓝色,每个颜色的显示时间间隔为50ms。
colorWipe(50, 0, 0, 50); // 红色擦除效果。
colorWipe(0, 50, 0, 50); // 绿色擦除效果。
colorWipe(0, 0, 50, 50); // 蓝色擦除效果。
// 以下调用创建追逐效果,不同颜色的追逐,每次间隔50ms。
theaterChase(0, 50, 50, 50); // 青色追逐效果。
theaterChase(50, 0, 50, 50); // 紫色追逐效果。
theaterChase(50, 50, 0, 50); // 黄色追逐效果。
rainbow(20); // 彩虹效果,每次更新间隔20ms。
theaterChaseRainbow(50); // 彩虹追逐效果,每次更新间隔50ms。
}
void colorWipe(uint8_t rColor, uint8_t gColor, uint8_t bColor, uint8_t wait) {
// 逐个点亮LED到指定颜色,之后有短暂延迟。
for (uint16_t i = 0; i < NUM_OF_LEDS; i++) {
led.setPixelColor(i, rColor, gColor, bColor); // 设置特定LED的颜色。
led.show(); // 更新LED灯带的显示。
delay(wait); // 等待一段时间。
}
}
void rainbow(uint8_t wait) {
// 创建一个彩虹效果,通过改变颜色的'Hue'值。
for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
led.rainbow(firstPixelHue); // 设置彩虹效果的起始颜色。
led.show(); // 更新LED灯带的显示。
delay(wait); // 等待一段时间。
}
}
void theaterChase(uint8_t rColor, uint8_t gColor, uint8_t bColor, uint8_t wait) {
// 创建一个追逐效果,每三个灯中点亮一个,然后移动。
for (uint8_t a = 0; a < 10; a++) { // 总共迭代10次。
for(uint8_t b = 0; b < 3; b++) { // 每次移动一步。
led.clear(); // 清除LED灯带的当前显示。
for(uint8_t c = b; c < NUM_OF_LEDS; c += 3) {
led.setPixelColor(c, rColor, gColor, bColor); // 设置特定LED的颜色。
}
led.show(); // 更新LED灯带的显示。
delay(wait); // 等待一段时间。
}
}
}
void theaterChaseRainbow(uint8_t wait) {
// 创建一个彩虹追逐效果。
int firstPixelHue = 0; // 彩虹的起始颜色'Hue'值。
for(int a = 0; a < 30; a++) { // 总共迭代30次。
for(int b = 0; b < 3; b++) {
led.clear(); // 清除LED灯带的当前显示。
for(int c = b; c < NUM_OF_LEDS; c += 3) {
int hue = firstPixelHue + c * 65536L / NUM_OF_LEDS; // 计算每个LED的'Hue'值。
uint32_t color = led.colorHSV(hue, 255, 255); // 根据'Hue'值生成颜色。
// 提取RGB分量。
uint8_t r = (color & 0x00FF0000) >> 16;
uint8_t g = (color & 0x0000FF00) >> 8;
uint8_t b = (color & 0x000000FF);
led.setPixelColor(c, r, g, b); // 设置特定LED的颜色。
}
led.show(); // 更新LED灯带的显示。
delay(wait); // 等待一段时间。
firstPixelHue += 65536 / 90; // 更新起始'Hue'值,使颜色在迭代中逐渐变化。
}
}
}
```
## 4、效果
[localvideo]de5a0c9815f4e8eb930c4bc53f427ea4[/localvideo]
-
发表了主题帖:
【安信可BW16-Kit】1、开发板简介和开发环境搭建
本帖最后由 xiyou2020eeeee 于 2024-2-11 20:28 编辑
开发板简介和开发环境搭建
开发板简介
BW16-Kit开发板基于Realtek RTL8720DN,是一款Wi-Fi和蓝牙IC,支持用于Wi-Fi通信的2.4 GHz和5 GHz双频段,以及蓝牙低能量(BLE)5.0。BW16模块是B&T公司生产的一款高度集成的Wi-Fi和蓝牙模块,它以RTL8720DN为主要的SoC(片上系统),可以被认为是一个典型的带有SBCS的Wi-Fi和蓝牙应用的SoC。BW16 C型板是一款集成了模块的开发板。有2块BW16板卡,BW16和BW16 C类板卡。BW16 C类板卡使用USB C类连接器,具有自动上传电路。
开发板管脚如下:
GPIO pin
GPIO INT
ADC
PWM
UART
SPI
I2C
IR
RGB LED
SWD
0
PA7
✓
LOG_TX
1
PA8
✓
LOG_RX
2
PA27
✓
SWD_DATA
3
PA30
✓
✓
4
PB1
✓
Serial_TX
5
PB2
✓
Serial_RX
6
PB3
✓
A2
SWD_CLK
7
PA25
✓
✓
I2C_SCL
IR_TX
8
PA26
✓
✓
I2C_SDA
IR_RX
9
PA15
✓
SPI_SS
10
PA14
✓
SPI_SCLK
LED_G
11
PA13
✓
✓
SPI_MISO
LED_B
12
PA12
✓
✓
SPI_MOSI
LED_R
开发环境搭建
BW16-Kit开发板开发环境多样,官方给出的是基于arduino进行开发。
首先,寻找正确的json文件。
在arduino官方给出了一个连接、在github上也有链接。但是均不可用。
https://github.com/arduino/Arduino/wiki/Unofficial-list-of-3rd-party-boards-support-urls
最后,可用的json为
https://github.com/Ameba8195/Arduino/raw/master/release/package_realtek.com_ameba_index.json
其次,安装BW16开发板。在开发板中搜索BW16,安装BW16开发板即可。
- 2024-01-24
-
发表了主题帖:
【Sipeed Tang Primer 25K】评测:4、I2C搞起来
//声明,定义了输入输出端口。clk是时钟信号,start是开始信号,DCn用于区分数据和命令,Data是要传输的8位数据。输出包括busy表示模块是否忙碌,scl和sda分别是I2C协议的时钟线和数据线。//
module I2C(
input clk, // 时钟输入
input start, // 开始信号
input DCn, // 1 -> 数据 / 0 -> 命令
input [7:0]Data, // 8位数据
output reg busy=0, // I2C忙碌状态
output reg scl=1, // 串行时钟
output reg sda=1); // 串行数据
// 定义一些参数,用于表示状态机的各个状态和等待时间。//
parameter IDEL = 0;
parameter START = 1;
parameter ADDR = 2;
parameter CBYTE = 3;
parameter DATA = 4;
parameter STOP = 5;
parameter T_WAIT= 6;
// 定义一些寄存器用于存储状态、计数器、延迟、从设备地址、控制字节和数据。//
reg DCn_r=0;
reg [2:0]state=0;
reg [3:0]i=0;
reg [3:0]step=0;
reg [12:0]delay=1;
reg [7:0]slave= 8'b01111000; // 从设备地址
reg [7:0]cbyte= 8'b10000000; // 命令的控制字节
reg [7:0]dbyte= 8'b01000000; // 数据的控制字节
reg [7:0]data= 0;
//通过有限状态机(FSM)的方式实现了I2C通信协议。在每个状态中,根据子状态(step)的不同,控制时钟线(scl)和数据线(sda)的电平,以及处理延迟和计数器,从而实现了I2C协议的各个阶段:开始、地址发送、控制字节发送、数据发送和停止。//
always @(posedge clk)
begin
// 时钟上升沿触发
if(delay != 1) // 如果延迟不为1
begin
delay <= delay - 1; // 延迟计数器减1
end
else begin // 如果延迟为1
case(state) // 根据当前状态执行相应操作
IDEL:begin // 空闲状态
scl <= 1; // 保持时钟线高
sda <= 1; // 保持数据线高
if(start) // 如果接收到开始信号
begin
DCn_r <= DCn; // 读取数据/命令标志
data <= Data; // 读取数据
busy <= 1; // 设置忙碌标志
state <= START; // 转移到开始状态
step <= 0; // 子状态设置为0
end
end
START:begin // 开始状态
case(step)
0:begin
sda <= 0; // 数据线拉低,表示开始条件
delay <= T_WAIT; // 等待一定周期
step <= step + 1; // 转到下一个子状态
end
1:begin
scl <= 0; // 时钟线拉低,准备发送数据
state <= ADDR; // 转移到地址发送状态
step <= 0; // 子状态设置为0
end
endcase
end
ADDR:begin // 地址发送状态
case(step)
0:begin
if(i < 8) // 如果还没有发送完8位地址
begin
scl <= 0; // 时钟线拉低
step <= 1; // 转到下一个子状态
end
else if(i == 8) // 如果地址发送完毕
begin
scl <= 0; // 时钟线拉低
sda <= 0; // 数据线拉低,准备接收应答位
delay <= T_WAIT;// 等待一定周期
i <= i + 1; // 计数器加1
step <= 2; // 转到下一个子状态
end
end
1:begin
sda <= slave[7 - i]; // 发送地址位
delay <= T_WAIT - 1; // 等待一定周期
i <= i + 1; // 计数器加1
step <= 2; // 转到下一个子状态
end
2:begin
if(i < 9) // 如果还没有接收完应答位
begin
scl <= 1; // 时钟线拉高,锁存数据
delay <= T_WAIT; // 等待一定周期
step <= 0; // 转到下一个子状态
end
else begin
scl <= 1; // 时钟线拉高
delay <= T_WAIT; // 等待一定周期
step <= 3; // 转到下一个子状态
end
end
3:begin
scl <= 0; // 时钟线拉低
sda <= 0; // 数据线拉低
delay <= T_WAIT; // 等待一定周期
step <= 4; // 转到下一个子状态
end
4:begin
step <= 0; // 子状态设置为0
i <= 0; // 计数器清零
state <= CBYTE; // 转移到控制字节发送状态
end
endcase
end
CBYTE:begin // 控制字节发送状态
case(step)
0:begin
if(i < 8) // 如果还没有发送完8位控制字节
begin
scl <= 0; // 时钟线拉低
step <= 1; // 转到下一个子状态
end
else if(i == 8) // 如果控制字节发送完毕
begin
scl <= 0; // 时钟线拉低
sda <= 0; // 数据线拉低,准备接收应答位
delay <= T_WAIT;// 等待一定周期
i <= i + 1; // 计数器加1
step <= 2; // 转到下一个子状态
end
end
1:begin
if(DCn_r) // 如果是数据
begin
sda <= dbyte[7 - i]; // 发送数据控制字节
end
else begin
sda <= cbyte[7 - i]; // 发送命令控制字节
end
delay <= T_WAIT - 1; // 等待一定周期
i <= i + 1; // 计数器加1
step <= 2; // 转到下一个子状态
end
2:begin
if(i < 9) // 如果还没有接收完应答位
begin
scl <= 1; // 时钟线拉高,锁存数据
delay <= T_WAIT; // 等待一定周期
step <= 0; // 转到下一个子状态
end
else begin
scl <= 1; // 时钟线拉高
delay <= T_WAIT; // 等待一定周期
step <= 3; // 转到下一个子状态
end
end
3:begin
scl <= 0; // 时钟线拉低
sda <= 0; // 数据线拉低
delay <= T_WAIT; // 等待一定周期
step <= 4; // 转到下一个子状态
end
4:begin
step <= 0; // 子状态设置为0
i <= 0; // 计数器清零
state <= DATA; // 转移到数据发送状态
end
endcase
end
DATA:begin // 数据发送状态
case(step)
0:begin
if(i < 8) // 如果还没有发送完8位数据
begin
scl <= 0; // 时钟线拉低
step <= 1; // 转到下一个子状态
end
else if(i == 8) // 如果数据发送完毕
begin
scl <= 0; // 时钟线拉低
sda <= 0; // 数据线拉低,准备接收应答位
delay <= T_WAIT;// 等待一定周期
i <= i + 1; // 计数器加1
step <= 2; // 转到下一个子状态
end
end
1:begin
sda <= data[7 - i]; // 发送数据位
delay <= T_WAIT - 1; // 等待一定周期
i <= i + 1; // 计数器加1
step <= 2; // 转到下一个子状态
end
2:begin
if(i < 9) // 如果还没有接收完应答位
begin
scl <= 1; // 时钟线拉高,锁存数据
delay <= T_WAIT; // 等待一定周期
step <= 0; // 转到下一个子状态
end
else begin
scl <= 1; // 时钟线拉高
delay <= T_WAIT; // 等待一定周期
step <= 3; // 转到下一个子状态
end
end
3:begin
scl <= 0; // 时钟线拉低
sda <= 0; // 数据线拉低
delay <= T_WAIT; // 等待一定周期
step <= 4; // 转到下一个子状态
end
4:begin
step <= 0; // 子状态设置为0
i <= 0; // 计数器清零
state <= STOP; // 转移到停止状态
end
endcase
end
STOP:begin // 停止状态
case(step)
0:begin
scl <= 1; // 时钟线拉高
sda <= 0; // 数据线拉低
delay <= T_WAIT; // 等待一定周期
step <= step + 1; // 转到下一个子状态
end
1:begin
state <= IDEL; // 转移到空闲状态
busy <= 0; // 清除忙碌标志
step <= 0; // 子状态设置为0
end
endcase
end
endcase
end
end
endmodule
- 2024-01-15
-
发表了主题帖:
【Sipeed Tang Primer 25K】评测:3、来个蠕虫灯,何如?
本帖最后由 xiyou2020eeeee 于 2024-1-15 20:53 编辑
简要介绍
Tang Primer 25K有丰富的接口,核心板引出了76个GPIO、1路硬核4lane MIPI线路和3路电源输出给用户使用。用户只需给核心板提供一路5V供电和正确设置配置引脚,即可轻松使用Tang Primer 25K核心板。
其次,开发板配套了很多PMOD,尤其以LED*2最为养眼。
链接板子
例程运行
首先,可以下载很多示例。
Github链接:https://github.com/sipeed/TangPrimer-25K-example
其次,下载之后打开。
再次,打开例程
最后,经过整合、约束、规划。
最后,下载
USB端口检查
下载完成
设计一个蠕虫灯
3.1 程序
这个程序主要用于生成一个“蠕虫”效果,通过循环移位LED灯来实现。计数器用于控制移位的时机。当复位信号激活时,LED灯会被重置到初始状态。
// 定义一个名为Worms_led的模块,有时钟输入、复位输入和16位LED输出
module Worms_led
(
input clk, // 输入信号:时钟
input rst, // 输入信号:复位
output reg [15:0]led // 输出信号:16位LED控制
);
// 定义一个28位的寄存器cnt,用于计数
reg [27:0] cnt;
// 当时钟上升沿到来或复位信号下降沿到来时执行
always @(posedge clk or negedge rst)
begin
if(!rst) // 如果复位信号为低电平
cnt <= 28'd0; // 将计数器清零
else if (cnt < 28'd25_000_000) // 如果计数器小于25,000,000
cnt <= cnt + 1'd1; // 计数器加1
else // 否则
cnt <= 28'd0; // 计数器清零
end
// 当时钟上升沿到来或复位信号下降沿到来时执行
always @(posedge clk or negedge rst)
begin
if(!rst) // 如果复位信号为低电平
led <= 8'b1111_1110; // LED高位为灭,低位为亮,因此16个LED中有7个灭、9个亮
else if (cnt == 28'd25_000_000) // 如果计数器达到25,000,000
led[15:0] <= {led[14:0],led[15]}; // 循环移位LED灯(产生“蠕虫”效果)
else // 否则
led <= led; // 保持LED状态不变
end
endmodule // 模块结束
3.2 下载步骤
首先,整合Synthesize
然后,布局FloorPlanner
然后,I/O设置
最后保存设置
然后布线
最后下载程序
效果
[localvideo]ebefed57fb4a18b7ba50211392e7167b[/localvideo]
4、修改程序,实现贪吃蛇效果
module Worms_led (
input clk,
input rst,
output reg [15:0] led
);
reg [24:0] cnt; // 优化:减少计数器位数,只需足够的计数范围
// 时钟和复位信号触发的逻辑
always @(posedge clk or negedge rst) begin
if (!rst) begin
cnt <= 0; // 同步复位计数器
led <= 16'b1111_1111_1111_1110; // 初始化LED状态
end else begin
if (cnt < 25_000_000) cnt <= cnt + 1; // 计数直到特定值
else begin
cnt <= 0; // 重置计数器
led <= {led[14:0], led[15]}; // 循环移位LED
end
end
end
endmodule
效果
[localvideo]9cae3ed75a520d0da1ea2adde2fc0d0d[/localvideo]
- 2024-01-11
-
回复了主题帖:
【入围名单】: 安信可BW16-Kit
收到 ,地址没有错,请发货