mingzhe123 发表于 2025-1-12 12:10

【Follow me第二季第4期】任务汇总

本帖最后由 mingzhe123 于 2025-1-21 18:11 编辑

<p><span style="font-size:24px;"><strong>物料清单:</strong></span></p>

<p><strong>任务使用物料:</strong></p>

<ul>
        <li>主板1:<a href="https://www.digikey.cn/zh/products/detail/arduino/ABX00052/14123941" target="_blank">ABX00052 Arduino | 开发板,套件,编程器 | DigiKey</a>&nbsp;&nbsp;&nbsp;</li>
        <li>主板2:<a href="https://www.digikey.cn/zh/products/detail/raspberry-pi/SC1631/24627136" target="_blank">RASPBERRY PI PICO 2 RP2350</a></li>
        <li></li>
</ul>

<p><strong>任务一:</strong></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 基础实现: 搭建环境并开启第一步Blink三色LED / 串口打印Hello DigiKey &amp; EEWorld!链接:<a href="https://bbs.eeworld.com.cn/thread-1300565-1-1.html" target="_blank">任务一链接</a></p>

<p><strong>基础代码:</strong>&nbsp; &nbsp; &nbsp;&nbsp;</p>

<pre>
<code class="language-cpp">#include &lt;WiFiNINA.h&gt;
//#include &lt;Arduino.h&gt;

void setup() {

Serial.begin(115200);

pinMode(LEDB, OUTPUT);
pinMode(LEDR,OUTPUT);
pinMode(LEDG,OUTPUT);

digitalWrite(LEDB,LOW);
digitalWrite(LEDR,LOW);
digitalWrite(LEDG,LOW);
Serial.println("The task began!!!");
Serial.println();
}

void loop() {

    delay(2000);
    digitalWrite(LEDB, HIGH);
    digitalWrite(LEDG, LOW);
    Serial.println("Hello DigiKey &amp; EEWorld!");
    delay(2000);
    digitalWrite(LEDB, LOW);//状态翻转
    digitalWrite(LEDG, HIGH);

}

</code></pre>

<p><strong>进阶代码:</strong></p>

<p>&nbsp; 任务一进阶适用PICO2开发板与<strong><u>Arduino</u>&nbsp;Nano RP2040 Connect</strong>,其主要原理是PICO2的按键通过串口控制<strong><u>Arduino</u>&nbsp;Nano RP2040 Connect</strong>开发板上的RGB 灯,其系统架构图如下图所示:</p>

<div></div>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>其主要代码如下:</p>

<p>PICO2代码:</p>

<pre>
<code class="language-cpp">int val;
const int BUTTON_PIN = 21; // the number of the pushbutton pin
const int SHORT_PRESS_TIME = 500; // 500 milliseconds
// Variables will change:
int lastState = LOW;// the previous state from the input pin
int currentState;   // the current reading from the input pin
unsigned long pressedTime= 0;
unsigned long releasedTime = 0;
char key_flag = 0;

void setup() {

Serial1.setRX(17);
Serial1.setTX(16);
Serial1.begin(115200); // opensserial port, sets data rate to 9600 bps
while(Serial.read()&gt;= 0){}//clear serialbuffer
pinMode(25,OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
Serial1.write(49);

}

void Key(void) {

delay(1);
}

void loop() {


delay(10);

// read the state of the switch/button:
currentState = digitalRead(BUTTON_PIN);

if(lastState == HIGH &amp;&amp; currentState == LOW)      // button is pressed
    pressedTime = millis();
else if(lastState == LOW &amp;&amp; currentState == HIGH) { // button is released
    releasedTime = millis();
    long pressDuration = releasedTime - pressedTime;

    if( pressDuration &lt; SHORT_PRESS_TIME )
      Serial.println("A short press is detected");
      key_flag = !key_flag;
       if(key_flag) {
          Serial1.write(49);
          Serial.println("49");
          digitalWrite(25,LOW);
       } else {
          Serial1.write(50);
          Serial.println("50");
          digitalWrite(25,HIGH);
       }
      
      
}

// save the the last state
lastState = currentState;

}
</code></pre>

<p><u>Arduino</u>&nbsp;Nano RP2040 Connect代码:</p>

<pre>
<code class="language-cpp">#include &lt;WiFiNINA.h&gt;


int val;
void setup() {
Serial.begin(115200); // opensserial port, sets data rate to 9600 bps

Serial1.begin(115200); // opensserial port, sets data rate to 9600 bps
while(Serial1.read()&gt;= 0){}//clear serialbuffer
while(Serial.read()&gt;= 0){}//clear serialbuffer

pinMode(LEDB, OUTPUT);
pinMode(LEDR,OUTPUT);
pinMode(LEDG,OUTPUT);

digitalWrite(LEDB,LOW);
digitalWrite(LEDR,LOW);
digitalWrite(LEDG,LOW);
Serial.println("The pro task began!!!");
Serial.println();
}

void loop() {
if (Serial1.available() &gt; 0) {
    delay(100); // 等待数据传完
    int numdata = Serial1.available();
    val=Serial1.read();
    Serial1.println(val);
    if(val==49)
    {
      Serial.println("Test OK");
      Serial.println(val);

   // delay(2000);
      digitalWrite(LEDB, HIGH);
      Serial.println("Hello DigiKey &amp; EEWorld!");
      digitalWrite(LEDG, HIGH);
    }
    if(val==50)
    {
      Serial.println("Test OK!!!");
      Serial.println(val);

   //   delay(2000);
      digitalWrite(LEDB, LOW);
      Serial.println("Turn off the lights!");
      digitalWrite(LEDG, LOW);
    }
    while(Serial1.read()&gt;=0){} //清空串口缓存
}
}
</code></pre>

<p><strong>总结:</strong></p>

<p>&nbsp;树莓派的MCU,通过arduino来开发难度降低了很多,用户只需要调动封装好的库函数即可。但是有一点要吐槽一下,本来是个及其简单的程序,适用arduino IDE开发却需要很长的编译时间,实在不敢恭维,后期有时间尝试一下VS Code。</p>

<p><strong>任务视频:</strong></p>

<p>a630efe2d622147a2861f70ce74fddcd<br />
&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:24px;"><strong>任务二:</strong></span><br />
学习IMU基础知识,调试IMU传感器,通过串口打印输出。链接:<a href="https://bbs.eeworld.com.cn/thread-1300577-1-1.html" target="_blank">任务二链接</a></p>

<p> &nbsp;</p>

<p><strong>IMU编程与调试</strong></p>

<p><b><a href="https://www.digikey.cn/zh/products/detail/arduino/ABX00052/14123941" target="_blank">Arduino&reg; Nano RP2040 Connect</a>代码:</b></p>

<pre>
<code class="language-cpp">
/* WIRING
In order to use the Adafruit lsm6dsox sensor with a ST nucleo board,
plug Nucleo "+3.3V" to AdafruitLSM6DOX "VIN",
plug Nucleo "GND" to AdafruitLSM6DOX "GND",
plug Nucleo "SCL"(D15) to AdafruitLSM6DOX "SCL",
plug Nucleo "SDA"(D14) to AdafruitLSM6DOX "SDA".*/

#include "LSM6DSOXSensor.h"
#include &lt;Arduino.h&gt;
// Declare LSM6DSOX sensor. Sensor address can have 2 values LSM6DSOX_I2C_ADD_L (corresponds to 0x6A I2C address) or LSM6DSOX_I2C_ADD_H (corresponds to 0x6B I2C address)
// On Adafruit lsm6dsox sensor, LSM6DSOX_I2C_ADD_L is the default address
LSM6DSOXSensor lsm6dsoxSensor = LSM6DSOXSensor(&amp;Wire, LSM6DSOX_I2C_ADD_L);

int flag;
longlast_update_time;


// Timer variables
unsigned long lastTime = 0;
unsigned long timerDelay = 1000;

void setup() {
Serial.begin(115200);

Serial1.begin(115200); // opensserial port, sets data rate to 115200 bps
while(Serial1.read()&gt;= 0){}//clear serialbuffer

pinMode(LED_BUILTIN,OUTPUT);

digitalWrite(LED_BUILTIN,LOW);

Wire.begin();

// Default clock is 100kHz. LSM6DSOX also supports 400kHz, let's use it
Wire.setClock(400000);

// Init the sensor
lsm6dsoxSensor.begin();

// Enable accelerometer and gyroscope, and check success
if (lsm6dsoxSensor.Enable_X() == LSM6DSOX_OK &amp;&amp; lsm6dsoxSensor.Enable_G() == LSM6DSOX_OK) {
    Serial.println("Success enabling accelero and gyro");
} else {
    Serial.println("Error enabling accelero and gyro");
}

// Read ID of device and check that it is correct
uint8_t id;
lsm6dsoxSensor.ReadID(&amp;id);
if (id != LSM6DSOX_ID) {
    Serial.println("Wrong ID for LSM6DSOX sensor. Check that device is plugged");
} else {
    Serial.println("Receviced correct ID for LSM6DSOX sensor");
}

// Set accelerometer scale at +- 2G. Available values are +- 2, 4, 8, 16 G
lsm6dsoxSensor.Set_X_FS(2);

// Set gyroscope scale at +- 125 degres per second. Available values are +- 125, 250, 500, 1000, 2000 dps
lsm6dsoxSensor.Set_G_FS(125);


// Set Accelerometer sample rate to 208 Hz. Available values are +- 12.0, 26.0, 52.0, 104.0, 208.0, 416.0, 833.0, 1667.0, 3333.0, 6667.0 Hz
lsm6dsoxSensor.Set_X_ODR(208.0f);


// Set Gyroscope sample rate to 208 Hz. Available values are +- 12.0, 26.0, 52.0, 104.0, 208.0, 416.0, 833.0, 1667.0, 3333.0, 6667.0 Hz
lsm6dsoxSensor.Set_G_ODR(208.0f);


}


void IMU_update(int interval)
{
// Read accelerometer
uint8_t acceleroStatus;
lsm6dsoxSensor.Get_X_DRDY_Status(&amp;acceleroStatus);
if (acceleroStatus == 1) { // Status == 1 means a new data is available
    int32_t acceleration;
    lsm6dsoxSensor.Get_X_Axes(acceleration);
    // Plot data for each axis in mg
    Serial.print("AccelerationX=");

    Serial.print(acceleration);

    Serial.print("mg, AccelerationY=");

    Serial.print(acceleration);

    Serial.print("mg, AccelerationZ=");

    Serial.print(acceleration);
    Serial.println("mg");


    if (millis() - last_update_time &gt; interval)
          {
                  if (acceleration &gt; 1000)
                  {
                        //encoder_diff--;
                        flag = 1;
      Serial.print("flag=1");
      Serial1.write(49);
      digitalWrite(LED_BUILTIN,LOW);
                  }
                else if (acceleration &lt; -1000)
                {
                //        encoder_diff++;
                        flag = 2;
      Serial.print("flag=2");
      Serial1.write(50);
      digitalWrite(LED_BUILTIN,HIGH);
                }
                else
                {
                        flag = 0;
                }

                last_update_time = millis();
          }
}

       

// Read gyroscope
uint8_t gyroStatus;
lsm6dsoxSensor.Get_G_DRDY_Status(&amp;gyroStatus);
if (gyroStatus == 1) { // Status == 1 means a new data is available
    int32_t rotation;
    lsm6dsoxSensor.Get_G_Axes(rotation);
    // Plot data for each axis in milli degrees per second
    Serial.print("RotationX=");

    Serial.print(rotation);

    Serial.print("mdps, RotationY=");

    Serial.print(rotation);

    Serial.print("mdps, RotationZ=");

    Serial.print(rotation);
    Serial.println("mdps");
}

}


void loop() {


IMU_update(200);

}
</code></pre>

<p><strong>PICO2端代码:</strong></p>

<pre>
<code class="language-cpp">int val;



void setup() {



Serial1.setRX(17);

Serial1.setTX(16);

Serial1.begin(115200); // opensserial port, sets data rate to 9600 bps

while(Serial.read()&gt;= 0){}//clear serialbuffer

pinMode(25,OUTPUT);



}



void loop() {



   if (Serial1.available() &gt; 0) {

    delay(100); // 等待数据传完

    int numdata = Serial1.available();

    val=Serial1.read();

    Serial1.println(val);

    if(val==49)

    {

      Serial.println("Test OK");

      Serial.println(val);



   // delay(2000);

      digitalWrite(25, LOW);

    }

    if(val==50)

    {

      Serial.println("Test OK!!!");

      Serial.println(val);



      digitalWrite(25, HIGH);



    }

    while(Serial1.read()&gt;=0){} //清空串口缓存

}

   




}
</code></pre>

<p><img src="https://bbs.eeworld.com.cn/data/attachment/forum/202412/01/121103ocucc7gukkzjdq7k.png.thumb.jpg" /></p>

<p><strong>总结:</strong></p>

<p><b>&nbsp;</b>实现IMU的控制与数据读取还是十分简单的,只需调用官方Arduino库即可,这大大降低了开发者的开发难度。</p>

<p><strong>任务视频:</strong></p>

<p>a51009e6090e2b27a92609dbf549ae37</p>

<p>&nbsp;</p>

<p><span style="font-size:22px;"><strong>任务三:</strong></span><br />
学习并调试PDM麦克风,通过串口打印收音数据和音频&nbsp;。链接:<a href="https://bbs.eeworld.com.cn/thread-1301147-1-1.html" target="_blank">任务三链接</a><br />
驱动程序:</p>

<pre>
<code class="language-cpp">#include &lt;PDM.h&gt;


static const char channels = 1;

static const int frequency = 20000;


short sampleBuffer;

volatile int samplesRead;

void setup() {
Serial.begin(115200);
while (!Serial);

PDM.onReceive(onPDMdata);


if (!PDM.begin(channels, frequency)) {
    Serial.println("Failed to start PDM!");
    while (1);
}
}

void loop() {

if (samplesRead) {


    for (int i = 0; i &lt; samplesRead; i++) {
      if (channels == 2) {
      Serial.print("L:");
      Serial.print(sampleBuffer);
      Serial.print(" R:");
      i++;
      }
      Serial.println(sampleBuffer);
   
    }

    samplesRead = 0;
}
}


void onPDMdata() {
int bytesAvailable = PDM.available();


PDM.read(sampleBuffer, bytesAvailable);

samplesRead = bytesAvailable / 2;
}
</code></pre>

<p><strong>查看串口打印的波形数据</strong></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 将代码下载到 Arduino Nano RP2040 Connect。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 打开&nbsp;<strong>串口监视器</strong>,设置波特率为&nbsp;<strong>115200</strong>。</p>

<p>使用&nbsp;<strong>Arduino IDE 串口绘图器</strong>(Serial Plotter),观察音频数据的波形变化,如下图所示,下图为1KHz正弦波声音产生的波形数据。</p>

<p><img src="https://bbs.eeworld.com.cn/data/attachment/forum/202412/06/224213onxdv52j99ovc5hn.png.thumb.jpg" /></p>

<p><strong>总结</strong>&nbsp;</p>

<p>Arundio自带的函数库,大大降低了开发难度,我们只需要调用相应的API函数即可配置麦克风的采样频率,配合开发板的多种数据传输功能,可以实现很多有意思的功能。</p>

<p>92596a8368d38aa81897cc36d925d52d<br />
<span style="font-size:24px;"><strong>任务代码:</strong></span></p>

<div></div>

<p><strong><span style="font-size:24px;">任务总结:</span></strong></p>

<p>此次EEWORD论坛的活动,不仅增强了个人的实践能力,在硬件操作、编程技能以及传感器应用方面都有了显著提升。这些知识与经验为后面开发奠定了坚实的基础,同时也激发了个人更多的创新精神。</p>

<p><span style="font-size:24px;"><strong>任务汇总视频:</strong></span></p>

<p>0054b15e32e32d5f61f8f739b24dc49f<br />
&nbsp;</p>

mingzhe123 发表于 2025-1-21 15:45

<div></div>

mingzhe123 发表于 2025-1-21 15:47

<div></div>
页: [1]
查看完整版本: 【Follow me第二季第4期】任务汇总