项目总结报告
项目介绍
本项目选择了板卡三:Arduino UNO R4WiFi的任务一、二综合实现,可以在远程云端控制LED矩阵与读取传感器数据
项目的具体功能如下:
1. 通过局域网连接到Arduino IoT Cloud
2. 可以在网页与Arduino IoT Cloud中控制LED矩阵
3. 可以在网页与Arduino IoT Cloud中读取温湿度传感器数据
设计思路
1、 通过板载的ESP32S3连接到网络
2、 使用Arduino IoT Cloud实时读写数据
3、 联动NUCLEO-G0B1RE读取X-NUCLEO-IKS4A1上的传感器数据,从串口发送到Arduino UNO R4WiFi
4、 根据选择的LED矩阵显示模式设定亮度
本期开发硬件介绍
Arduino UNO R4 WiFi 是一款基于 Renesas RA4M1 微控制器的开发板,专为物联网 (IoT) 和无线连接应用设计。以下是其主要硬件特点:
1、核心处理器:采用 48 MHz 的 Arm® Cortex®-M4 核心,性能相比传统 Arduino UNO R3 显著提升。
2、无线连接:集成了 ESP32-S3 模块,支持 Wi-Fi 和 Bluetooth® LE,方便进行无线通信和 IoT 应用。
3、接口与引脚:
兼容 Arduino UNO R3 的引脚布局。
提供多种通信接口,包括 UART、SPI 和 I2C。
4、电源管理:支持多种供电方式,包括 USB-C 接口和外部电源输入,具备更高效的电源管理能力。
5、板载功能:
内置 RGB LED,便于状态指示。
板载 12 位 DAC(数字模拟转换器),支持生成模拟信号。
5、开发支持:与 Arduino IDE 无缝兼容,同时支持多种编程语言和库,便于快速开发。
7、应用场景:适用于物联网、无线控制、环境监测和智能家居等领域。
软件流程图及主要代码片段
1.、初始化:包括硬件初始化、通信接口初始化、网络连接初始化
void setup() {
brightness = 50;
wat=0;
temperature=0;
hand=50;
mode = 0;
Serial.begin(9600);
Serial1.begin(9600);
matrix.begin();
delay(1500);
while (status != WL_CONNECTED) {
Serial.print("正在尝试连接到 SSID: ");
Serial1.print("正在尝试连接到 SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(4);
ArduinoCloud.printDebugInfo();
server.begin();
printWifiStatus();
}
2、主函数
1、处理客户端请求
2、读取串口数据
3、模式判别与控制灯光
4、更新云端数据
void loop() {
WiFiClient client = server.available(); // 监听客户端连接
if (client) { // 如果有客户端连接
boolean currentLineIsBlank = true;
String currentLine = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {
sendResponse(client);
break;
}
if (c == '\n') { // 当前行结束
currentLineIsBlank = true;
//Serial.println("Received request: " + currentLine); // Debug output
if (currentLine.startsWith("GET /on")) {
// setLight(brightness);
mode=HAND;
} else if (currentLine.startsWith("GET /off")) {
setLight(0);
mode=-1;
} else if (currentLine.startsWith("GET /brightness?value=")) {
int valueIndex = currentLine.indexOf('=');
int spaceIndex = currentLine.indexOf(' ', valueIndex);
String valueStr = currentLine.substring(valueIndex + 1, spaceIndex);
hand = valueStr.toInt();
// setLight(hand);
// mode=HAND;
}
else if (currentLine.startsWith("GET /temperature")){
mode = TEM;
Serial.print("切换到: 温度查询\n");
} else if (currentLine.startsWith("GET /humidity")){
mode = WAT;
Serial.print("切换到: 湿度查询\n");
}
currentLine = "";
} else if (c != '\r') {
currentLineIsBlank = false;
currentLine += c;
}
}
}
delay(1);
client.flush();
client.stop(); // Ensure client connection is closed
}
if (Serial1.available() > 0) { //传感器数据读取
String input = Serial1.readStringUntil('\n');
input.trim();
// 解析串口数据值
if (input.startsWith("Wat:")) {
wat = input.substring(4).toFloat(); // 接收湿度值
// Serial.print("wat = "); //串口输出测试
// Serial.println(wat);
}
if (input.startsWith("Temperature: ")) {
temperature = input.substring(12).toFloat(); // 接收温度值
if (temperature < 0) temperature = 0;
if (temperature > 100) temperature = 100;
// Serial.print("temperature= "); //串口输出测试
// Serial.println(temperature);
}
}
//判别mode
if(mode==HAND){
brightness = hand;
setLight(brightness);
} else if(mode==TEM){
brightness = temperature;
setLight(brightness);
}else if(mode==WAT){
brightness = wat;
setLight(brightness);
}else if(mode==OFF){
brightness=0;
setLight(brightness);
}
ArduinoCloud.update();
}
3、前端网页:包含一个亮度控制滑块与四个模式切换按钮
void sendResponse(WiFiClient client) {
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html lang='zh-CN'>");
client.println("<head>");
client.println("<meta charset='UTF-8'>");
client.println("<meta name='viewport' content='width=device-width, initial-scale=1.0'>");
client.println("<title>LED 控制</title>");
client.println("<style>");
client.println("body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }");
client.println("h1 { color: #333; }");
client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 15px 32px; text-align: center; font-size: 16px; margin: 4px 2px; cursor: pointer; }");
client.println("input[type=range] { width: 300px; }");
client.println("</style>");
client.println("</head>");
client.println("<body>");
client.println("<h1>LED 矩阵控制</h1>");
// 动态嵌入亮度值
client.println("<p>亮度: <span id='brightnessValue'>" + String(brightness) + "</span>%</p>");
// 第一排:亮度滑块和开关按钮
client.println("<input type='range' min='0' max='100' value='" + String(brightness) + "' id='brightnessSlider'>");
client.println("<p>");
client.println("<button class='button' onclick=\"fetch('/on').then(() => location.reload());\">\手动</button>");
client.println("<button class='button' onclick=\"fetch('/off').then(() => location.reload());\">\关灯</button>");
client.println("</p>");
// 第二排:查询温湿度按钮
client.println("<p>");
client.println("<button class='button' onclick=\"fetch('/temperature').then(() => location.reload());\">\温度查询</button>");
client.println("<button class='button' onclick=\"fetch('/humidity').then(() => location.reload());\">\湿度查询</button>");
client.println("</p>");
client.println("<script>");
client.println("var slider = document.getElementById('brightnessSlider');");
client.println("var output = document.getElementById('brightnessValue');");
client.println("slider.oninput = function() {");
client.println(" output.innerHTML = this.value;");
client.println("}");
client.println("slider.onchange = function() {");
client.println(" fetch('/brightness?value=' + this.value);");
client.println("}");
client.println("</script>");
client.println("</body></html>");
}
4、百分比亮度函数:实现LED矩阵逐渐从中心向外亮起
void setBrightnessLevel(int brightness) {
// 限制亮度百分比在 0 到 100 之间
if (brightness < 0) {
brightness = 0;
} else if (brightness > 100) {
brightness = 100;
}
// 计算总的 LED 数量
int totalLEDs = ROWS * COLUMNS;
// 计算需要亮起的 LED 数量
int ledsToTurnOn = (brightness * totalLEDs) / 100;
// 将 frame 数组所有元素设为 0 (表示关闭)
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLUMNS; j++) {
frame[i][j] = 0;
}
}
// 中心点坐标
int centerRow1 = ROWS / 2 - 1;
int centerRow2 = ROWS / 2;
int centerCol1 = COLUMNS / 2 - 1;
int centerCol2 = COLUMNS / 2;
// 创建一个二维数组保存每个 LED 的欧几里得距离
float distances[ROWS][COLUMNS] = {0};
// 计算每个 LED 到两个中心点的欧几里得距离
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLUMNS; j++) {
// 选择距离两个中心点中较小的那个作为最终距离
distances[i][j] = fmin(euclideanDistance(i, j, centerRow1, centerCol1),
euclideanDistance(i, j, centerRow2, centerCol2));
}
}
// 按照距离从小到大的顺序点亮 LED
for (float d = 0; d <= ROWS + COLUMNS; d += 0.1) { // 逐步增加半径,步长 0.1
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLUMNS; j++) {
if (distances[i][j] <= d && frame[i][j] == 0) { // 确保该 LED 尚未亮起
frame[i][j] = 1; // 点亮 LED
ledsToTurnOn--; // 计数器减 1
if (ledsToTurnOn == 0) {
return; // 已经点亮所需数量的 LED
}
}
}
}
}
}
功能展示
网页控制
云端控制
活动心得体会
在本次使用Arduino UNO R4 WiFi开发项目的过程中,我收获了许多宝贵的经验。从硬件搭建到软件编写,再到与云端的集成,每一个环节都让我对物联网技术有了更深入的理解。
1、硬件方面
Arduino UNO R4 WiFi的强大功能让我快速实现了WiFi通信和传感器数据采集。通过学习和实践,我熟悉了设备的模块化设计和串口通信机制,感受到硬件调试和优化的重要性。
2、软件方面
在软件开发中,我深入了解了HTTP请求的实现及客户端与服务器的交互原理。通过分模块开发和调试,我提升了逻辑分析能力和代码组织能力,同时也积累了处理复杂问题的经验。