本帖最后由 不爱胡萝卜的仓鼠 于 2025-1-13 15:44 编辑
1、展示所有任务的视频
任务1:
EE大学堂视频链接:https://training.eeworld.com.cn/video/42146
任务2:
EE大学堂视频链接:https://training.eeworld.com.cn/video/42148
任务3:
EE大学堂视频链接:https://training.eeworld.com.cn/video/42150
汇总:
0b22599687a1f7972126a82660f1e48a_raw
2、所使用的物料清单
本次任务我在得捷电子采购的产品有ARDUINO NANO RP2040 CONNECT、SEEEDSTUDIO XIAO ESP32S3
3、展示每个任务
3.1 任务一:搭建环境并开启第一步Blink三色LED / 串口打印Hello DigiKey & EEWorld!
详细内容:【Follow me第二季第4期】①任务一:Blink与串口打印
基础的点灯,串口功能比较基础,有点没意思,我看到RP2040 connect有带BLE和WiFi,因此我额外购买了一块ESP32-S3。我想实现通过WiFi的方式实现点灯,顺便可以学习一下Arduino上如何连接WiFi、启动server、作为client连接server、TCP通讯数据收发等。
RP2040:上电后实现三色LED、LED的闪烁,并串口打印指定内容。随后连接WiFi,启动server,等待client连接,并接收控制指令,执行指令对应的代码。
ESP32:上电后连接WiFi,并以Client的角色连接server,通过TCP通讯发送控制指令给RP2040,控制2040的LED灯
RP2040代码
/***************************/
//RGB LED需要安装WiFiNINA库,
/***************************/
#include <WiFiNINA.h>
#include <SPI.h>
#define WIFI_CTL_LED (1)
#if WIFI_CTL_LED
#include "wifi_info.h"
const char wifi_ssid[] = SECRET_SSID;
const char wifi_password[] = SECRET_PASS;
int wifi_conn_state = WL_IDLE_STATUS;
#define SERVER_PORT (80)
WiFiServer server(SERVER_PORT);
void printWifiStatus()
{
/* 打印WiFi SSID */
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
/* 打印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");
}
#endif
void setup()
{
/* 初始化串口 */
Serial.begin(115200);
/* delay一下,保证串口监视器成功连接 */
delay(3000);
/* 初始化LED灯的GPIO,并开灯 */
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
/* 初始RGB LED灯的GPIO,并开灯 */
pinMode(LEDR, OUTPUT);
pinMode(LEDG, OUTPUT);
pinMode(LEDB, OUTPUT);
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, HIGH);
/* 打印和闪灯,完成指定任务 */
for(uint8_t j = 0; j < 4; j++)
{
Serial.println("Hello DigiKey & EEWorld!");
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(LEDR, LOW);
digitalWrite(LEDG, LOW);
digitalWrite(LEDB, LOW);
delay(1000);
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, HIGH);
delay(1000);
}
#if WIFI_CTL_LED
/* 检查wifi模块状态是否可用 */
if (WiFi.status() == WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
while (1);
}
/* 检查wifi模块版本号(非必选,可去掉) */
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION)
{
Serial.println("now wifi firmware = " + fv + ", lastest version is " +
WIFI_FIRMWARE_LATEST_VERSION + ", suggest update!");
}
/* 检查SSID和PSW是否填写 */
if (strlen(wifi_ssid) <= 0)
{
Serial.println("ERROR: Plase enter WiFi SSID in \"wifi_info.h\"");
while(1);
}
if (strlen(wifi_password) <= 0)
{
Serial.println("ERROR: Plase enter WiFi password in \"wifi_info.h\"");
while(1);
}
/* 尝试使用预设的账号密码,连接路由器 */
uint8_t i = 0;
for (i = 0; i < 5; i++) //wifi连接超时时间5 * 10s
{
wifi_conn_state = WiFi.begin(wifi_ssid, wifi_password);
if (WL_CONNECTED == wifi_conn_state)
{
Serial.println("wifi connect success");
break;
}
delay(10000);
}
if (i == 5)
{
Serial.println("wifi connect failed");
while(1);
}
/* 打印wifi信息 */
printWifiStatus();
/* 开启客户端 */
server.begin();
Serial.print("server started,addr:");
Serial.print(WiFi.localIP());
Serial.print(":");
Serial.println(SERVER_PORT);
#endif
}
void loop()
{
#if WIFI_CTL_LED
WiFiClient client = server.available(); // listen for incoming clients
/* 是否有客户端连接我 */
if (client)
{
/* 打印,提示有客户端连接我 */
Serial.println("new client");
/* 从client接收到的数据的buffer */
String recv_buffer = "";
/* 持续监测客户端是否与我断连 */
while (client.connected())
{
/* 客户端是否可用 */
if (client.available())
{
/* 读取客户端发送的数据,并串口打印 */
/* read接口一次只能读一个字节,每读取一个字节后就把它拼到recv_buffer中 */
char c = client.read();
Serial.write(c);
recv_buffer += c;
/* 通过检查字符串结尾和制定的字符串是否一致,来决定是否需要执行开关灯指令 */
if (recv_buffer.endsWith("CTL_RGB_R_ON"))
{
digitalWrite(LEDR, HIGH);
}
if (recv_buffer.endsWith("CTL_RGB_R_OFF"))
{
digitalWrite(LEDR, LOW);
}
if (recv_buffer.endsWith("CTL_RGB_G_ON"))
{
digitalWrite(LEDG, HIGH);
}
if (recv_buffer.endsWith("CTL_RGB_G_OFF"))
{
digitalWrite(LEDG, LOW);
}
if (recv_buffer.endsWith("CTL_RGB_B_ON"))
{
digitalWrite(LEDB, HIGH);
}
if (recv_buffer.endsWith("CTL_RGB_B_OFF"))
{
digitalWrite(LEDB, LOW);
}
if (recv_buffer.endsWith("CTL_LED_ON"))
{
digitalWrite(LED_BUILTIN, HIGH);
}
if (recv_buffer.endsWith("CTL_LED_OFF"))
{
digitalWrite(LED_BUILTIN, LOW);
}
}
}
/* 客户端与我断连,需要关闭client连接,并打印提示信息 */
client.stop();
Serial.println("client disconnected");
/* 断连后灯回复原装 */
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, HIGH);
}
#else
Serial.println("Hello DigiKey & EEWorld!");
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, HIGH);
delay(1000);
Serial.println("Hello DigiKey & EEWorld!");
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(LEDR, LOW);
digitalWrite(LEDG, LOW);
digitalWrite(LEDB, LOW);
delay(1000);
#endif
}
ESP32代码
#include <Arduino.h>
#include <WiFi.h>
#include "wifi_info.h"
const char wifi_ssid[] = SECRET_SSID;
const char wifi_password[] = SECRET_PASS;
int wifi_conn_state = WL_IDLE_STATUS;
const IPAddress serverIP(192,168,31,215); //填写服务器的实际IP地址
uint16_t serverPort = 80; //端口默认80,服务器端也是默认80
WiFiClient client;
void printWifiStatus()
{
/* 打印WiFi SSID */
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
/* 打印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");
}
void wifi_init()
{
/* 设置工作在STA模式 */
WiFi.mode(WIFI_STA);
/* 断开之前的连接 */
WiFi.disconnect(true, true);
}
void wifi_connect_AP()
{
/* 检查SSID和PSW是否填写 */
if (strlen(wifi_ssid) <= 0)
{
Serial.println("ERROR: Plase enter WiFi SSID in \"wifi_info.h\"");
while(1);
}
if (strlen(wifi_password) <= 0)
{
Serial.println("ERROR: Plase enter WiFi password in \"wifi_info.h\"");
while(1);
}
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(wifi_ssid);
/* 尝试使用预设的账号密码,连接路由器 */
uint8_t i = 0;
WiFi.begin(wifi_ssid, wifi_password);
/* 检测是否链接成功 */
for (i = 0; i < 20; i++)
{
delay(500);
if (WiFi.status() != WL_CONNECTED)
{
Serial.println("wifi connect success");
/* delay一会儿,等待IP等信息都拿到了再继续后续操作 */
delay(3000);
break;
}
}
if (i == 20)
{
Serial.println("wifi connect failed");
while(1);
}
/* 打印wifi信息 */
printWifiStatus();
}
void connect_server()
{
if (client.connect(serverIP, serverPort))
{
Serial.println("Connected to server");
}
else
{
Serial.println("Connection failed");
while(1);
}
}
void setup()
{
/* 初始化串口 */
Serial.begin(115200);
/* 初始化wifi模块 */
wifi_init();
/* wifi连接路由器 */
wifi_connect_AP();
/* 连接到服务器 */
connect_server();
}
void loop()
{
String cmd1 = "CTL_LED_ON";
String cmd2 = "CTL_LED_OFF";
/* 如果连接到服务器,就定时发送开关灯指令 */
if (client.connected())
{
Serial.println("ON");
client.write(cmd1.c_str());
delay(1000);
Serial.println("0FF");
client.write(cmd2.c_str());
delay(1000);
}
}
3.2 任务二:学习IMU基础知识,调试IMU传感器,通过串口打印六轴原始数据
详细内容:【Follow me第二季第4期】②任务二:IMU传感器
代码
/***************************/
//IMU需要安装Arduino_LSM6DSOXk库
/***************************/
#include <Arduino_LSM6DSOX.h>
float ACC_x, ACC_y, ACC_z, GYR_x, GYR_y, GYR_z;
void setup()
{
/* 初始化串口 */
Serial.begin(115200);
/* 初始化IMU传感器 */
if (!IMU.begin())
{
Serial.println("Failed to initialize IMU!");
while (1);
}
/* 打印ACC和GYR的采样率 */
Serial.print("Accelerometer sample rate = ");
Serial.print(IMU.accelerationSampleRate());
Serial.println("Hz");
Serial.print("Gyroscope sample rate = ");
Serial.print(IMU.gyroscopeSampleRate());
Serial.println("Hz");
}
void loop()
{
if (IMU.accelerationAvailable())
{
IMU.readAcceleration(ACC_x, ACC_y, ACC_z);
}
if (IMU.gyroscopeAvailable())
{
IMU.readGyroscope(GYR_x, GYR_y, GYR_z);
}
Serial.print("ACC_x: ");
Serial.print(ACC_x);
Serial.print(", ");
Serial.print("ACC_y: ");
Serial.print(ACC_y);
Serial.print(", ");
Serial.print("ACC_z: ");
Serial.print(ACC_z);
Serial.print(", ");
Serial.print("GYR_x: ");
Serial.print(GYR_x);
Serial.print(", ");
Serial.print("GYR_y: ");
Serial.print(GYR_y);
Serial.print(", ");
Serial.print("GYR_z: ");
Serial.println(GYR_z);
delay(100);
}
3.3 任务三:学习PDM麦克风技术知识,调试PDM麦克风,通过串口打印收音数据和音频波形。
详细内容:【Follow me第二季第4期】③任务三:PDM麦克风
代码;
#include <PDM.h>
/* 输出通道的数量 */
static const char channels = 1;
/* 采样频率 */
static const int frequency = 20000;
/* 采样buffer,每次采样的数据大小为16bit,所以变量类型为short */
short sampleBuffer[512];
/* 已经读到的采样次数 */
volatile int samplesRead;
void onPDMdata()
{
/* 查询一共有多少数据 */
int bytesAvailable = PDM.available();
/* 把采样数据保存到buffer里 */
PDM.read(sampleBuffer, bytesAvailable);
/* 更新采样计数。一次采样的数据大小为16bit,所以采样计数需要除以2 */
samplesRead = bytesAvailable / 2;
}
void setup()
{
/* 初始化串口 */
Serial.begin(9600);
/* 设置PDM数据接收回调函数 */
PDM.onReceive(onPDMdata);
/* 初始化PDM,并开始采样 */
if (!PDM.begin(channels, frequency))
{
Serial.println("Failed to start PDM!");
while (1);
}
}
void loop()
{
/* 是否有采样数据 */
if (samplesRead)
{
/* 打印buffer中的所有数据 */
for (int i = 0; i < samplesRead; i++)
{
Serial.println(sampleBuffer[i]);
}
/* 清零采样计数 */
samplesRead = 0;
}
}
4、对本活动的心得体会
很感谢得捷电子与EEWORLD共同举办的本次活动,这次的开发板非常有意思,板载各种传感器十分丰富,还有WiFi和BLE,可玩性很高。本次活动我学习到麦克风传感器、开启一个Server、client连接server、TCP通讯等新知识,收获颇丰。希望下次有机会继续参加类似的活动。
5.可编译下载的代码包
任务一:EEWORLD论坛下载中心下载链接:https://download.eeworld.com.cn/detail/%E7%9A%84%E5%88%A0%E9%99%A4%E5%A4%B1%E8%B4%A5v/635430
任务二:EEWORLD论坛下载中心下载链接:https://download.eeworld.com.cn/detail/%E7%9A%84%E5%88%A0%E9%99%A4%E5%A4%B1%E8%B4%A5v/635431
任务三:EEWORLD论坛下载中心下载链接:https://download.eeworld.com.cn/detail/%E7%9A%84%E5%88%A0%E9%99%A4%E5%A4%B1%E8%B4%A5v/635432
|