坛/我=佬

  • 2025-01-14
  • 回复了主题帖: 以拆会友!看看2.3寸“大”电视和32寸的大彩电内里乾坤

    00后表示头回看见过这种小型电视,跟着楼主开眼界

  • 2025-01-12
  • 发表了主题帖: 【Follow me第二季第4期】任务提交

    本帖最后由 坛/我=佬 于 2025-1-13 14:18 编辑 一、视频介绍   二、任务实现详情 必做任务一:搭建环境并开启第一步Blink三色LED / 串口打印Hello DigiKey & EEWorld! 物料清单:Arduino Nano RP2040 Connect 设计思路: Arduino Nano RP2040 Connect板载一颗共阳RGB LED,但是没有直接连接到RP2040的IO上,而是连接到Nina W102 Wi-Fi/Bluetooth模组的IO上。 由原理图可知,当Nina W102的IO输出高电平时,LED熄灭;输出低电平时,LED点亮。对应代码为digitalWrite(LEDR, LOW)熄灭LED,digitalWrite(LEDR, HIGH)点亮LED。 所以本质上是RP2040通过SPI控制W102模组的IO,使其输出高低电平,进一步控制RGB LED亮灭。但是Arduino通过WiFiNINA library简化了这个步骤,使用pinMode、digitalWrite等函数就可以控制,具体的实现流程被封装到WiFiNINA库里面。因此,要控制板载的RGB LED,首先需要安装WiFiNINA库并调用。 RP2040片上具有USB1.1控制器和PHY,支持Host和Device模式。Arduino官方基于此硬件设计了bootloader,使该USB接口具有下载代码和串口调试的功能。 软件流程图   代码实现 #include <SPI.h> #include <WiFiNINA.h> void setup() { Serial.begin(115200); // initialize serial communication delay(500); while(!Serial); //等待串口初始化完毕 // { // Serial.println("Serial init failed!"); // while(1); // } Serial.println("Programme Starting!"); Serial.println("Hello DigiKey & EEWorld!"); //打印信息 pinMode(LEDR, OUTPUT); //初始化RGB引脚 pinMode(LEDG, OUTPUT); pinMode(LEDB, OUTPUT); digitalWrite(LEDR, LOW); //设置RGB引脚默认状态为低,对应熄灭状态 digitalWrite(LEDG, LOW); digitalWrite(LEDB, LOW); } void loop() { digitalWrite(LEDR, HIGH); //显示红色 digitalWrite(LEDG, LOW); digitalWrite(LEDB, LOW); delay(500); digitalWrite(LEDR, LOW); //显示绿色 digitalWrite(LEDG, HIGH); digitalWrite(LEDB, LOW); delay(500); digitalWrite(LEDR, LOW); //显示蓝色 digitalWrite(LEDG, LOW); digitalWrite(LEDB, HIGH); delay(500); } 功能展示 必做任务二:学习IMU基础知识,调试IMU传感器,通过串口打印六轴原始数据 物料清单:Arduino Nano RP2040 Connect 设计思路: Arduino Nano RP2040 Connect板载一颗六轴IMU(LSM6DSOXTR),内置3轴加速度计和3轴陀螺仪,通过3轴加速度计可以获得物体的运动方向,通过3轴陀螺仪可以获得物体的旋转角度。LSM6DSOXTR的具体参数如下 LSM6DSOXTR通过IIC与LSM6DSOXTR进行通信,并且由于RP2040配置为IIC模式时,IO口为开漏输出,需要通过硬件对SCL和SDA两根信号线进行上拉操作。 要通过IIC对LSM6DSOXTR进行操作,首先需要安装对应的Arduino_LSM6DSOX library,里面包含Arduino官方封装过的API函数,可以快速上手获取IMU的加速度和陀螺仪原始数据。 软件流程图   代码实现 #include <Arduino_LSM6DSOX.h> float Ax, Ay, Az; float Gx, Gy, Gz; void setup() { Serial.begin(115200); while(!Serial); //防止程序run直到串口打开 if (!IMU.begin()) { Serial.println("Failed to initialize IMU!"); while (1); } Serial.print("Accelerometer sample rate = "); Serial.print(IMU.accelerationSampleRate()); Serial.println("Hz"); Serial.println(); Serial.print("Gyroscope sample rate = "); Serial.print(IMU.gyroscopeSampleRate()); Serial.println("Hz"); Serial.println(); } void loop() { if (IMU.accelerationAvailable()) { IMU.readAcceleration(Ax, Ay, Az); Serial.println("Accelerometer data: "); Serial.print(Ax); Serial.print('\t'); Serial.print(Ay); Serial.print('\t'); Serial.println(Az); Serial.println(); } if (IMU.gyroscopeAvailable()) { IMU.readGyroscope(Gx, Gy, Gz); Serial.println("Gyroscope data: "); Serial.print(Gx); Serial.print('\t'); Serial.print(Gy); Serial.print('\t'); Serial.println(Gz); Serial.println(); } delay(500); } 功能展示   必做任务三:学习PDM麦克风技术知识,调试PDM麦克风,通过串口打印收音数据和音频波形 物料清单:Arduino Nano RP2040 Connect 设计思路: Arduino Nano RP2040 Connect板载一颗全向MEMS麦克风(MP34DT06JTR),可以用来感知外界环境的声音变化,并将其记录并量化为数值。MP34DT06JTR的具体参数如下 MP34DT06JTR通过PDM接口与RP2040连接。操作MEMS麦克风也需要额外的PDM library,但是与任务一和任务二不同的是,在安装Arduino Nano RP2040 Connect板的时候,内部就已经带了PDM library,不需要额外搜索安装,直接用就可以。 软件流程图   代码实现 #include <PDM.h> // default number of output channels static const char channels = 1; // default PCM output frequency static const int frequency = 20000; // Buffer to read samples into, each sample is 16-bits short sampleBuffer[512]; // Number of audio samples read volatile int samplesRead; void setup() { Serial.begin(115200); while (!Serial); // Configure the data receive callback PDM.onReceive(onPDMdata); if (!PDM.begin(channels, frequency)) { Serial.println("Failed to start PDM!"); while (1); } } void loop() { // Wait for samples to be read if (samplesRead) { // Print samples to the serial monitor or plotter for (int i = 0; i < samplesRead; i++) { if (channels == 2) { Serial.print("L:"); Serial.print(sampleBuffer[i]); Serial.print(" R:"); i++; } Serial.println(sampleBuffer[i]); } // Clear the read count samplesRead = 0; } } void onPDMdata() { // Query the number of available bytes int bytesAvailable = PDM.available(); // Read into the sample buffer PDM.read(sampleBuffer, bytesAvailable); // 16-bit, 2 bytes per sample samplesRead = bytesAvailable / 2; } 功能展示   扩展任务:雷达感应氛围灯 物料清单:Arduino Nano RP2040 Connect、6x10 RGB MATRIX、24GHz mmWave 来自seeed的XIAO RGB灯板,上面一共有6x10个RGB灯珠 来自seeed的24GHz mmWave雷达传感器,可以用来检测附近是否有人存在 设计思路: 当人离开电脑长时间不使用时,电脑会进入休眠状态节省电量。同理,当人离开桌面时,氛围灯关闭;重新回来时,氛围灯开启。一方面可以带来绚丽多彩的氛围特效,另一方面还可以节省电量。 24GHz mmWave通过串口与RP2040通信,RP2040接收到串口数据后,对数据进行解析,从而获取到传感器识别到的当前状态。在使用前需要安装mmwave_for_xiao library。模块参数如下 6x10 RGB MATRIX通过级联方式可以控制60个RGB,同时还可以通过板与板之间级联,方便扩展,采用WS2812灯珠。使用前需要安装Adafruit_NeoPixel library可以方便控制指定颜色和指定灯珠。特性如下 软件流程图   代码实现 #include <mmwave_for_xiao.h> #include <Adafruit_NeoPixel.h> // Which pin on the Arduino is connected to the NeoPixels? #define PIN 25 // On Trinket or Gemma, suggest changing this to 1 // How many NeoPixels are attached to the Arduino? #define NUMPIXELS 60 // Popular NeoPixel ring size // Creates a global Serial object for printing debugging information #define ShowSerial Serial // Initialising the radar configuration // Seeed_HSP24 xiao_config(COMSerial, ShowSerial); Seeed_HSP24 xiao_config(Serial1); Seeed_HSP24::RadarStatus radarStatus; // When setting up the NeoPixel library, we tell it how many pixels, // and which pin to use to send signals. Note that for older NeoPixel // strips you might need to change the third parameter -- see the // strandtest example for more information on possible values. Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); #define DELAYVAL 500 // Time (in milliseconds) to pause between pixels void setup() { ShowSerial.begin(115200); Serial1.begin(115200); while(!ShowSerial); delay(500); strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) strip.setBrightness(64); ShowSerial.println("Programme Starting!"); xiao_config.disableEngineeringModel(); //关闭工程上报模式,此时为基本上报模式 // xiao_config.enableEngineeringModel(); //开启工程上报模式 } void loop() { int retryCount = 0; const int MAX_RETRIES = 10; // Maximum number of retries to prevent infinite loops //Get radar status do { radarStatus = xiao_config.getStatus(); retryCount++; } while (radarStatus.targetStatus == Seeed_HSP24::TargetStatus::ErrorFrame && retryCount < MAX_RETRIES); //Parses radar status and prints results from debug serial port if (radarStatus.targetStatus != Seeed_HSP24::TargetStatus::ErrorFrame) { ShowSerial.print("Status: " + String(targetStatusToString(radarStatus.targetStatus)) + " ---- "); ShowSerial.println("Distance: " + String(radarStatus.distance) + " Mode: " + String(radarStatus.radarMode)); if (radarStatus.radarMode == 1) { //如果工程上报模式开启,为1 ShowSerial.print("Move:"); for (int i = 0; i < 9; i++) { ShowSerial.print(" " + String(radarStatus.radarMovePower.moveGate[i]) + ","); } ShowSerial.println(""); ShowSerial.print("Static:"); for (int i = 0; i < 9; i++) { ShowSerial.print(" " + String(radarStatus.radarStaticPower.staticGate[i]) + ","); } ShowSerial.println(""); ShowSerial.println("Photosensitive: " + String(radarStatus.photosensitive)); } } delay(100); } // Parsing the acquired radar status const char* targetStatusToString(Seeed_HSP24::TargetStatus status) { switch (status) { case Seeed_HSP24::TargetStatus::NoTarget: { // if(radarStatus.noTargrtduration > 1000) // { // } return "NoTarget"; } case Seeed_HSP24::TargetStatus::MovingTarget: { colorWipe(strip.Color(255, 0, 0), 50); // Red colorWipe(strip.Color( 0, 255, 0), 50); // Green colorWipe(strip.Color( 0, 0, 255), 50); // Blue // theaterChase(strip.Color(127, 127, 127), 50); // White // theaterChase(strip.Color(127, 0, 0), 50); // Red // theaterChase(strip.Color( 0, 0, 127), 50); // Blue return "MovingTarget"; } case Seeed_HSP24::TargetStatus::StaticTarget: { rainbow(10); return "StaticTarget"; } case Seeed_HSP24::TargetStatus::BothTargets: { theaterChaseRainbow(200); return "BothTargets"; } default: return "Unknown"; } } // Fill strip pixels one after another with a color. Strip is NOT cleared // first; anything there will be covered pixel by pixel. Pass in color // (as a single 'packed' 32-bit value, which you can get by calling // strip.Color(red, green, blue) as shown in the loop() function above), // and a delay time (in milliseconds) between pixels. void colorWipe(uint32_t color, int wait) { for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip... strip.setPixelColor(i, color); // Set pixel's color (in RAM) strip.show(); // Update strip to match delay(wait); // Pause for a moment } } // Theater-marquee-style chasing lights. Pass in a color (32-bit value, // a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms) // between frames. void theaterChase(uint32_t color, int wait) { for(int a=0; a<10; a++) { // Repeat 10 times... for(int b=0; b<3; b++) { // 'b' counts from 0 to 2... strip.clear(); // Set all pixels in RAM to 0 (off) // 'c' counts up from 'b' to end of strip in steps of 3... for(int c=b; c<strip.numPixels(); c += 3) { strip.setPixelColor(c, color); // Set pixel 'c' to value 'color' } strip.show(); // Update strip with new contents delay(wait); // Pause for a moment } } } // Rainbow cycle along whole strip. Pass delay time (in ms) between frames. void rainbow(int wait) { // Hue of first pixel runs 3 complete loops through the color wheel. // Color wheel has a range of 65536 but it's OK if we roll over, so // just count from 0 to 3*65536. Adding 256 to firstPixelHue each time // means we'll make 3*65536/256 = 768 passes through this outer loop: for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) { for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip... // Offset pixel hue by an amount to make one full revolution of the // color wheel (range of 65536) along the length of the strip // (strip.numPixels() steps): int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels()); // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or // optionally add saturation and value (brightness) (each 0 to 255). // Here we're using just the single-argument hue variant. The result // is passed through strip.gamma32() to provide 'truer' colors // before assigning to each pixel: strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue))); } strip.show(); // Update strip with new contents delay(wait); // Pause for a moment } } // Rainbow-enhanced theater marquee. Pass delay time (in ms) between frames. void theaterChaseRainbow(int wait) { int firstPixelHue = 0; // First pixel starts at red (hue 0) for(int a=0; a<30; a++) { // Repeat 30 times... for(int b=0; b<3; b++) { // 'b' counts from 0 to 2... strip.clear(); // Set all pixels in RAM to 0 (off) // 'c' counts up from 'b' to end of strip in increments of 3... for(int c=b; c<strip.numPixels(); c += 3) { // hue of pixel 'c' is offset by an amount to make one full // revolution of the color wheel (range 65536) along the length // of the strip (strip.numPixels() steps): int hue = firstPixelHue + c * 65536L / strip.numPixels(); uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB strip.setPixelColor(c, color); // Set pixel 'c' to value 'color' } strip.show(); // Update strip with new contents delay(wait); // Pause for a moment firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames } } } 功能展示   心得体会: 这是我第一次参加得捷follow me的活动,整体上来说收获很多,而且提供的板子非常适合大家快速上手,希望明年还会有类似活动,积极参加!   三、可编译下载的代码 完成任务源码下载地址https://download.eeworld.com.cn/detail/%E5%9D%9B/%E6%88%91=%E4%BD%AC/635603

  • 加入了学习《【Follow me第二季第4期】任务提交》,观看 【Follow me第二季第4期】任务提交

  • 上传了资料: 【Follow me第二季第4期】任务提交

最近访客

< 1/1 >

统计信息

已有3人来访过

  • 芯积分:29
  • 好友:--
  • 主题:1
  • 回复:1

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言