85|0

88

帖子

3

TA的资源

一粒金砂(高级)

楼主
 

【Follow me第二季第4期】④汇总篇 [复制链接]

  本帖最后由 不爱胡萝卜的仓鼠 于 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.可编译下载的代码包

DigiKey_EEWorld_FollowMe_2-4.rar (14.01 KB, 下载次数: 2)

任务一: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

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表