【SeeedXIAO ESP32S3 Sense 基本外设驱动】

活动地址:第四届2024年“寒假在家一起练”
资料地址:Seeed Studio XIAO ESP32S3 (Sense) 开发板

如果你是新手,可以先看这份【Seeed Studio XIAO ESP32S3 Sense 开箱Arduino教程】

在这里插入图片描述

本教程是参加2024年“寒假在家一起练”的【Seeed XIAO ESP32S3 Sense开发板】测评。

在这里插入图片描述

1. GPIO调试

查看对应User_LED匹配IO21,源码修改如下,即可实现闪烁灯效果

1.1 源码分享

  1. 数字输出
/*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

// the setup function runs once when you press reset or power the board
void setup() {
   
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
   
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(1000);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);                      // wait for a second
}




一旦程序成功上传,您将看到以下输出消息,您可以观察到XIAO ESP32S3右侧的橙色LED正在闪烁。

在这里插入图片描述

祝贺你,你已经学会了如何为XIAO ESP32S3编写和上传程序!👍👍👍

:::提示 只有当XIAO ESP32S3上的用户LED引脚设置为高电平时,LED才会熄灭,只有当引脚设置为低电平时,它才会点亮。 :::

  1. 下面是呼吸灯驱动LED PWM输出案例
/*
  Fading

  This example shows how to fade an LED using the analogWrite() function.

  The circuit:
  - LED attached from digital pin 9 to ground through 220 ohm resistor.

  created 1 Nov 2008
  by David A. Mellis
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Fading
*/

int ledPin = 21;  // LED connected to digital pin 9

void setup() {
   
  // nothing happens in setup
}

void loop() {
   
  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0; fadeValue <= 255; fadeValue += 5) {
   
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(30);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255; fadeValue >= 0; fadeValue -= 5) {
   
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(30);
  }
}

1.2 实验效果

板载LED灯分别会呈现闪烁或呼吸效果🤣🤣🤣

2. ADC调试

在文件实例基础中选择AnalogRead

查看对应模拟量端口匹配IO00~01,源码修改如下,即可实现A0、A1端口读取模拟量并打印效果

2.1 源码分享

/*
  ReadAnalogVoltage

  Reads an analog input on pin 0, converts it to voltage, and prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/ReadAnalogVoltage
*/

// the setup routine runs once when you press reset:
void setup() {
   
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
   
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 4095) to a voltage (0 - 5V):
  float voltage = sensorValue * (3.34 / 4095.0);
  // print out the value you read:
  Serial.println(voltage);
  delay(100); 
}

在setup()函数中,初始化串口通信模块,设置波特率为9600bps,xiao开发板模数转换器(Analog-to-Digital Converter,ADC)的分辨率到12位(0~4096)。

在loop()函数中:

  1. 读取从板子的第1个模拟端口(analog pin 1)获得模拟值,并存储在变量sensorValue 中;
  2. 将该模拟值转换成V,并存储在变量voltage 中;
  3. 输出voltage 值到串口中;
  4. 延时100ms,以防止误读。

2.2 实验效果

A0手动接触,看其变化,串口绘图仪效果如下

在这里插入图片描述

在这里插入图片描述

3. 麦克风测试

安装扩展板(for Sense)
安装扩展板非常简单,只需要将扩展板上的连接器对准小ESP32S3上的B2B连接器,然后用力按下,听到“咔”的一声,安装完成。

在这里插入图片描述

3.1 声音响度检测

在第一个项目案例中,我们使用Arduino IDE的串口波形图来检测环境中的噪声,并展示麦克风检测到的环境响度。

下面是完整的示例程序。

#include <I2S.h>

void setup() {
   
  // Open serial communications and wait for port to open:
  // A baud rate of 115200 is used instead of 9600 for a faster data rate
  // on non-native USB ports
  Serial.begin(115200);
  while (!Serial) {
   
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // start I2S at 16 kHz with 16-bits per sample
  I2S.setAllPins(-1, 42, 41, -1, -1);
  if (!I2S.begin(PDM_MONO_MODE, 16000, 16)) {
   
    Serial.println("Failed to initialize I2S!");
    while (1); // do nothing
  }
}

void loop() {
   
  // read a sample
  int sample = I2S.read();

  if (sample && sample != -1 && sample != 1) {
   
    Serial.println(sample);
  }
}

上传此程序为XIAO ESP32S3 Sense并打开Serial Plotter,您将看到声音的响度变化曲线。

3.2 程序注释

在程序开始时,为了使用麦克风引脚,我们首先需要导入I2S库。

#include <I2S.h>

在I2S对象上调用setAllPins()函数来配置I2S接口使用的引脚。该函数接受5个整数参数,分别表示连接到I2S接口的位时钟、单词选择、数据输入、数据输出和通道选择线的GPIO引脚。

I2S.setAllPins(-1, 42, 41, -1, -1);

在这个特定的代码中,-1值表示没有使用相应的引脚,而42和41值分别表示连接到单词选择和数据输入行的GPIO引脚。数据输出和通道选择行在此配置中不使用,而是设置为-1。

if (!I2S.begin(PDM_MONO_MODE, 16000, 16)) {
   
    Serial.println("Failed to initialize I2S!");
    while (1); // do nothing
}

在I2S对象上调用begin()函数,用指定的参数初始化I2S接口:PDM_MONO_MODE、16000 Hz采样率和16-bit分辨率。

TIPs: 值得注意的是,对于目前的ESP32-S3芯片,我们只能使用PDM_MONO_MODE,采样位宽只能为16bit。只有采样率可以修改,但经过测试,16kHz的采样率比较稳定。

int sample = I2S.read();

if (sample && sample != -1 && sample != 1) {
   
    Serial.println(sample);
}

3.3 实验效果

在I2S对象上调用read()函数,从I2S接口读取单个音频样本。if语句检查sample变量的值。如果采样值不是0、-1或1,它就被认为是有效的音频采样,并且If块中的代码会被执行。在这种情况下,使用 serial .println()函数将样本值打印到串行控制台。
在这里插入图片描述

具体保存到SD卡教程见:https://wiki.seeedstudio.com/cn/xiao_esp32s3_sense_mic/

4. 双cpu双线程测试

ESP32-C3 系列芯片,搭载 RISC-V 32 位双核处理器。那就可以跑多线程,下面就是两个线程。程序中避免有过多的延迟函数😘😘😘

4.1 源码分享

int testdata0 = 10;
int testdata1 = 0;
 
void CpuLoop(void *pvParameters){
   
  while(1){
   
    Serial.println("cpu"+String(xPortGetCoreID())+"---testdata0:"+String(testdata0));
    testdata1 ++;
    if(testdata1 == 10)
    testdata1 = 0;
    delay(2000);
  }
 
  vTaskDelete(NULL);
}
void setup() {
   
    Serial.begin(9600);
    xTaskCreatePinnedToCore(CpuLoop,    //具体实现的函数
                            "CPU_LOOP",  //任务名称
                            8192,       //堆栈大小
                            NULL,       //输入参数
                            1,          //任务优先级
                            NULL,       //
                            0           //核心  0\1
                            );
}
 
void loop() {
   
  Serial.println("cpu"+String(xPortGetCoreID())+"---testdata1:"+String(testdata1));
  testdata0 --;
  if(testdata0 == 0)
    testdata0 = 10;
  delay(1000);
}
 

设置串口波特率为9600bps。

在setup()函数中创建一个名为“CPU_LOOP”的任务,并将其实现的函数appCpuLoop()、堆栈大小为8192、输入参数为空、优先级为1、绑定到核心0上进行运行。

在CpuLoop()函数中,当while循环条件为真时,持续执行循环体内的内容。首先打印出字符串“Cpu1”和变量testdata0相加的结果,然后让testdata1自增1,如果testdata1等于10,则将其值设为0;最后延时2000毫秒后继续下一次循环。

在loop()函数中默认是在cpu核心1上运行,打印出字符串“cpu0”和变量testdata1相加的结果,然后让testdata0自减1,如果testdata0等于0,则将其值设为10;最后延时1000毫秒后继续下一次循环。

4.2 测试效果

打开串口显示两个内核运行效果

在这里插入图片描述

5. BLE蓝牙和安卓端蓝牙数据交互实验

🔖ESP32低功耗(BLE)蓝牙实验.
🛠调试工具
🔧安卓系统BLE调试工具:BLEAssist
📍APP下载地址:http://www.wch.cn/downloads/BLEAssist_ZIP.html
首先安装BLE调试助手
在这里插入图片描述
安装后打开,下拉刷新蓝牙,连接对应蓝牙

在这里插入图片描述
在第三项中选择查看和发送数据
在这里插入图片描述

5.1 源码分享

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
char BLEbuf[32] = {
    0 };
uint32_t cnt = 0;
String message_c;
int i = 0;
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"  // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

class MyServerCallbacks : public BLEServerCallbacks {
   
  void onConnect(BLEServer *pServer) {
   
    deviceConnected = true;
  };

  void onDisconnect(BLEServer *pServer) {
   
    deviceConnected = false;
  }
};

class MyCallbacks : public BLECharacteristicCallbacks {
   
  void onWrite(BLECharacteristic *pCharacteristic) {
   
    std::string rxValue = pCharacteristic->getValue();

    if (rxValue.length() > 0) {
   
      Serial.print("------>Received Value: ");

      for (int i = 0; i < rxValue.length(); i++) {
   
        Serial.print(rxValue[i]);
      }
      Serial.println();
    }
  }
};
void setup() {
   
  Serial.begin(115200);

  // Create the BLE Device
  BLEDevice::init("ESP32 BLE Test");

  // 创建蓝牙服务器
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // // 创建广播服务的UUID
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // 创建广播服务的UUID
  pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic->addDescriptor(new BLE2902());

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);

  pCharacteristic->setCallbacks(new MyCallbacks());

  // 开始蓝牙服务
  pService->start();

  // 开始广播
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
}

void loop() {
   
  if (deviceConnected) {
     //设备连接后,每秒钟发送txValue。
    memset(BLEbuf, 0, 32);
    message_c = "s  " + String(i) + "\r\n";
    i++;
    char *p = const_cast<char *>(message_c.c_str());
    memcpy(BLEbuf, p, 32);
    pCharacteristic->setValue(BLEbuf);

    pCharacteristic->notify();  // Send the value to the app!
    Serial.print("*** Sent Value: ");
    Serial.print(BLEbuf);
    Serial.println(" ***");
  }
  delay(1000);
}

设置串口波特率为115200bps。

在setup()函数中:

  1. 使用BLEDevice类初始化Bluetooth Low Energy设备,并设定其名称为"ESP32 BLE Test";
  2. 创建并返回一个服务器对象,并将其回调函数设置为MyServerCallbacks类型的实例;
  3. 使用BLEServer类创建一个服务,并使用SERVICE_UUID定义该服务的唯一标识符;
  4. 在创建的服务中添加一个特性,该特性具有可写属性,其唯一标识符为CHARACTERISTIC_UUID_RX;
  5. 将可写特性的回调函数设置为MyCallbacks类型的实例; 启动创建的服务; 启动广告活动。

在loop()函数中:

  1. 检查设备是否已连接。如果设备已连接,则按照以下步骤执行: 清空BLEbuf数组;
  2. 定义一个字符串message_c,其中包含字符’s’和变量i的当前值,两者之间用空格分隔,并在其末尾添加换行符;
  3. 将message_c转换为字符指针类型,并复制到BLEbuf数组中; 设置特性值为BLEbuf数组的内容;
  4. 调用notify()方法向应用程序发送数据; 打印已经发送的数据;

延迟1000ms后继续下一次循环。

5.2 实验效果

  1. esp32c3发送数据,手机接收数据
    在这里插入图片描述
    在这里插入图片描述

  2. esp32c3接收数据,手机发送数据
    在这里插入图片描述

6. 总结

通过SeeedXIAO ESP32S3 Sense 基本外设驱动教程,我们可以让ESP32作为主心骨,GPIO、ADC、麦克风、多线程、蓝牙外设有机衔接从而完成功能,进而丰富我们的生活。🛹🛹🛹

从而实现对外部世界进行感知,充分认识这个有机与无机的环境,科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣

  1. 我会持续更新对应专栏博客,非常期待你的三连!!!🎉🎉🎉
  2. 如果鹏鹏有哪里说的不妥,还请大佬多多评论指教!!!👍👍👍
  3. 下面有我的🐧🐧🐧群推广,欢迎志同道合的朋友们加入,期待与你的思维碰撞😘😘😘

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-01-25 08:28:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-25 08:28:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-25 08:28:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-25 08:28:01       18 阅读

热门阅读

  1. git从远程分支合并到本地分支

    2024-01-25 08:28:01       31 阅读
  2. Flutter踩坑记之二

    2024-01-25 08:28:01       27 阅读
  3. #Uniapp: uni.previewImage(OBJECT) 预览图片

    2024-01-25 08:28:01       42 阅读
  4. Python编程-利用缓存管理实现程序提速

    2024-01-25 08:28:01       30 阅读
  5. 设计模式四(适配器模式)

    2024-01-25 08:28:01       37 阅读