左手阿飞

  • 2025-01-21
  • 回复了主题帖: 【Follow me第二季第3期】任务提交

    本次活动提供的开发板是EK-RA6M5,主芯片R7FA6M5BH3CFC,是一款功能非常强大的开发板,因此,仅需要购买相应的开发板就能完成所有任务。 所有任务如视频所示。 https://www.bilibili.com/video/BV1gDwxeQEeY/ 任务一:00:10 任务二:01:58 任务三:03:06 任务四:04:27   本次任务是在快速开始实例程序中实现的,主要框架不变,只是在原有代码上增加一些功能,主要流程图如:    心得体会:非常感谢得捷和EEWorld提供的这次学习机会!经过本次学习,了解了瑞萨芯片R7FA6M5BH3CFC 的强大功能,学到了很多知识,比如菜单功能,ADC等等。以前接触到的单片机都是一些外设较少的简单MCU。第一次接触到这么多外设,这么多功能的单片机,很多功能没有完全发掘出他们的潜力,还需要继续研究。芯片功能很强大,可能是因为我是新手,对开发环境不太熟悉,这款芯片得开发环境较以前接触得芯片,更难搭建。 代码链接:https://download.eeworld.com.cn/detail/%E5%B7%A6%E6%89%8B%E9%98%BF%E9%A3%9E/635741      

  • 2025-01-20
  • 加入了学习《FollowMe 第二季:3 - EK_RA6M5 开发板入门》,观看 EK-RA6M5 开发板入门

  • 2025-01-15
  • 回复了主题帖: 【Follow me第二季第4期】任务提交:全部任务

    yilonglucky 发表于 2025-1-15 13:30 短接rec到GND,进入recovery模式试试 可能是图形编程工具的问题。刚才解决了,然后试了一下图形编程工具,又出现了。等会儿再试试解决。

  • 发表了主题帖: 【Follow me第二季第3期】任务提交

    本帖最后由 左手阿飞 于 2025-1-15 15:10 编辑 感谢得捷以及EEWorld论坛提供的这次学习机会,让我学到不少知识。现在对本次【Follow me第二季第3期】活动的任务做一次总结,有成功也有失败,但还是收获很多。 任务1:搭建环境,下载调试示例程序,Blink,按键 https://bbs.eeworld.com.cn/thread-1301685-1-1.html 在环境搭建中,看到很多网友环境有问题。我第一次也有工具链的问题,我采用的方式简单粗暴,直接重装。 在重装中,选择安装工具链。然后得到解决。   完成任务后,可显示LED闪烁频率和呼吸灯的PWM占空比。     任务2:quad-spi flash和octo-spi flash配置及读写速度测试 https://bbs.eeworld.com.cn/thread-1301884-1-1.html   实例中已经有QSPI和OSPI的对比选项,只要按下相应的按键,并输入数据大小,就可以对比;   任务3:示例程序中新增命令打印信息 https://bbs.eeworld.com.cn/thread-1304313-1-1.html 找到开始菜单,增加相应的行   然后增加相应的回调函数     然后菜单中就可以看到了。   任务4:设计一个类似信号发生器功能的例程 https://bbs.eeworld.com.cn/thread-1304315-1-1.html 最后扩展任务,设计一个类似信号发生器例程。 信号发生器需要有相应波形的原始波形数据。 在这个任务卡了很多天了,也参考了其他大佬的帖子,但是还是没搞定,做了一些二级菜单,波形出不来。 展示一下现有成果吧。 增加了一个一级菜单,      

  • 回复了主题帖: 【Follow me第二季第4期】任务提交:全部任务

    戈壁滩上的辉煌 发表于 2025-1-15 11:48 可以图形化编程?试试能不能通过选择板子的方式进行连接,应该是固件掉了 重新刷了固件,刚才又好了

  • 回复了主题帖: 【Follow me第二季第4期】-任务4:选做任务一(非必做):通过RGB LED不同颜色、亮...

    Jacktang 发表于 2025-1-15 07:33 下面看一下演示视频。 没有视频上传吧 上传失败了。重新发了。在楼下。

  • 回复了主题帖: 【Follow me第二季第4期】-任务4:选做任务一(非必做):通过RGB LED不同颜色、亮...

    电子烂人 发表于 2025-1-15 10:53 这个滑动平均滤波是选取了多少个数据,会不会对效果有影响?   滑动平均滤波取得是10个数据。灯的变化可能会缓慢一点。

  • 回复了主题帖: 【Follow me第二季第4期】-任务4:选做任务一(非必做):通过RGB LED不同颜色、亮...

     

  • 加入了学习《直播回放: DigiKey FollowMe 第二季 第4期 Arduino Nano RP2040 Connect 任务讲解》,观看 Arduino Nano RP2040 Connect 任务讲解

  • 发表了主题帖: 【Follow me第二季第4期】任务提交:全部任务

    本帖最后由 左手阿飞 于 2025-1-15 11:20 编辑 悲剧了,显示不出串口了。后面录不了视频了。     很高兴能够参加本期Follow me活动。活动要求的任务如下: 必做任务一:搭建环境并开启第一步Blink三色LED / 串口打印Hello DigiKey & EEWorld!; https://bbs.eeworld.com.cn/thread-1303458-1-1.html 必做任务二:学习IMU基础知识,调试IMU传感器,通过串口打印六轴原始数据; https://bbs.eeworld.com.cn/thread-1303469-1-1.html 必做任务三:学习PDM麦克风技术知识,调试PDM麦克风,通过串口打印收音数据和音频波形。 https://bbs.eeworld.com.cn/thread-1303574-1-1.html 选做任务一(非必做):通过RGB LED不同颜色、亮度显示PDM麦克风收到的声音大小; https://bbs.eeworld.com.cn/thread-1304613-1-1.html 选做任务二(非必做):通过IMU数据结合机器学习算法,识别运动状态,并通过串口打印。 下面分别对各任务完成情况进行说明 任务一:搭建环境并开启第一步Blink三色LED / 串口打印Hello DigiKey & EEWorld!。 https://bbs.eeworld.com.cn/thread-1303458-1-1.html 这次的开发板支持Arduino IDE,开发环境设置比较简单。 1、官网下载Arduino IDE,安装; 2、打开IDE后,在工具(tool)中下载相应的支持包; 3、连结板子,自动识别板子型号及对应串口。 任务第一步Blink三色LED / 串口打印Hello DigiKey & EEWorld! 在任务中,分别LEDR、LEDG、LEDB进行PWM写入就行。 串口输出分为两步: 1、设置波特率; 2、打印输出相应内容(Hello DigiKey & EEWorld!)。 #include "WiFiNINA.h" #define Led1 LEDR #define Led2 LEDG #define Led3 LEDB float angle1; float angle2; float angle3; void setup() { // put your setup code here, to run once: pinMode(Led1, OUTPUT); pinMode(Led2, OUTPUT); pinMode(Led3, OUTPUT); for(int i =0; i < 5 ; i++) { digitalWrite(Led1, LOW); digitalWrite(Led2, HIGH); delay(200); digitalWrite(Led2, LOW); digitalWrite(Led3, HIGH); delay(200); digitalWrite(Led3, LOW); digitalWrite(Led1, HIGH); delay(200); } angle1 = 0.0; angle2 = 0.0 + PI /3.0; angle3 = 0.0 + 2.0 * PI /3.0; Serial.begin(115200); } void loop() { // put your main code here, to run repeatedly: Serial.println("Hello Digikey & EEWorld"); angle1 += 0.01; angle2 += 0.01; angle3 += 0.01; if(angle1 >= PI) angle1 -= PI; if(angle2 >= PI) angle2 -= PI; if(angle3 >= PI) angle3 -= PI; int a = sin (angle1) * 255; int b = sin (angle2) * 255; int c = sin (angle3) * 255; analogWrite(Led1 ,a); analogWrite(Led2 ,b); analogWrite(Led3 ,c); delay(50); }   必做任务二:学习IMU基础知识,调试IMU传感器,通过串口打印六轴原始数据; https://bbs.eeworld.com.cn/thread-1303469-1-1.html 任务二也比较简单。安装IMU对应的库LSM6DSOX.h,然后进行调用就行。 具体步骤: 1、陀螺仪初始化(设置采样频率);串口初始化(设置波特率), 2、采集陀螺仪数据, 3、串口打印响应数据。 #include <Arduino_LSM6DSOX.h> float acc_x,acc_y,acc_z; float gyro_x,gyro_y,gyro_z; float temp; int update_flag; void setup() { // put your setup code here, to run once: Serial.begin(115200); if(!IMU.begin()) { Serial.println("Falled to initialize IMU"); while(1); } Serial.print("Acc sample rate = "); Serial.print(IMU.accelerationSampleRate()); Serial.println("Hz"); Serial.print("Gyro sample rate = "); Serial.print(IMU.gyroscopeSampleRate()); Serial.println("Hz"); } void loop() { // put your main code here, to run repeatedly: Serial.print("Acc sample rate = "); Serial.print(IMU.accelerationSampleRate()); Serial.println("Hz"); Serial.print("Gyro sample rate = "); Serial.print(IMU.gyroscopeSampleRate()); Serial.println("Hz"); if (IMU.accelerationAvailable()) { IMU.readAcceleration(acc_x,acc_y,acc_z); update_flag = 1; } if (IMU.gyroscopeAvailable()) { IMU.readGyroscope(gyro_x,gyro_y,gyro_z); update_flag = 1; } if (IMU.temperatureAvailable()) { IMU.readTemperatureFloat(temp); update_flag = 1; } if (update_flag) { update_flag=0; Serial.print(acc_x); Serial.print(','); Serial.print(acc_y); Serial.print(','); Serial.print(acc_z); Serial.print(','); Serial.print(gyro_x); Serial.print(','); Serial.print(gyro_y); Serial.print(','); Serial.print(gyro_z); Serial.print(','); Serial.print(gyro_x); Serial.print(','); Serial.println(temp); delay(500); } }   任务3:学习PDM麦克风技术知识,调试PDM麦克风,通过串口打印收音数据和音频波形。 https://bbs.eeworld.com.cn/thread-1303574-1-1.html 该任务同样是需要相应的库“PDM.h”,本次用到的库,板载库已经自带,不需要单独下载。 具体步骤: 1、麦克风初始化(设置采样频率);串口初始化(设置波特率), 2、采集麦克风数据, 3、串口打印响应数据。 #include "PDM.h" static const char channels = 1; static const int frequncy = 24000; short sampleBuffer[512]; volatile int samplesRead; void setup() { // put your setup code here, to run once: Serial.begin(115200); PDM.onReceive(onPDMdata); if(!PDM.begin(channels,frequncy)) { Serial.println("Failed to start PDM!!!"); while(1); } } void loop() { // put your main code here, to run repeatedly: if(samplesRead) { for(int i = 0; i < samplesRead; i++) { Serial.println(sampleBuffer[i]); } samplesRead=0; } delay(1); } void onPDMdata(){ int bytesAvailable = PDM.available(); PDM.read(sampleBuffer,bytesAvailable); samplesRead = bytesAvailable / 2; }   选做任务一(非必做):通过RGB LED不同颜色、亮度显示PDM麦克风收到的声音大小; https://bbs.eeworld.com.cn/thread-1304613-1-1.html 选做任务需要结合必做任务3和1,对采集到的数据进行处理。 观察任务3的数据,发现数据有两个问题: 1、数据波动较大; 2、会出现负值。 针对上面两个问题,进行数据处理,具体处理方式: 问题1、采用滑动平均滤波; 问题2、取绝对值。 解决上面两个问题之后,再用处理后的值控制LEDR和LEDG就行了。 #include "PDM.h" #include "WiFiNINA.h" #define Led1 LEDR #define Led2 LEDG #define Led3 LEDB #define MAX_SIZE 10 int head = 0; int tail = 0; int count = 0; int queue[MAX_SIZE]; static const char channels = 1; static const int frequncy = 24000; short sampleBuffer[512]; volatile int samplesRead; int LEDR_Value; int LEDG_Value; double MIC_Value; void setup() { // put your setup code here, to run once: Serial.begin(115200); pinMode(Led1, OUTPUT); pinMode(Led2, OUTPUT); PDM.onReceive(onPDMdata); if(!PDM.begin(channels,frequncy)) { Serial.println("Failed to start PDM!!!"); while(1); } } void loop() { // put your main code here, to run repeatedly: if(samplesRead) { for(int i = 0; i < samplesRead; i++) { //Serial.println(sampleBuffer[i]); MIC_Value=get_sliding_average(sampleBuffer[i]); Serial.println(MIC_Value); LEDR_Value=map(MIC_Value, 1, 3000, 1, 255); LEDG_Value=map(MIC_Value, 1, 3000, 255, 1); // analogWrite(Led1 ,LEDR_Value); // analogWrite(Led2 ,LEDG_Value); analogWrite(Led2 ,LEDR_Value); analogWrite(Led1 ,LEDG_Value); } samplesRead=0; } delay(1); } void onPDMdata(){ int bytesAvailable = PDM.available(); PDM.read(sampleBuffer,bytesAvailable); samplesRead = bytesAvailable / 2; } void enqueue(int value) { if ((tail + 1) % MAX_SIZE == head) { // 队列已满,需要先移除一个元素 head = (head + 1) % MAX_SIZE; } queue[tail] = value; tail = (tail + 1) % MAX_SIZE; count++; } int dequeue() { int value = queue[head]; head = (head + 1) % MAX_SIZE; count--; return value; } double get_sliding_average(int new_value) { static int init = 1; if (init) { // 初始化添加MAX_SIZE-1个0,保证头尾指针不会相遇 for (int i = 0; i < MAX_SIZE - 1; i++) { enqueue(0); } init = 0; } // 添加新的样本值 enqueue(sqrt(new_value * new_value)); // 计算滑动平均值 double sum = 0; for (int i = 0; i < count; i++) { sum += queue[(head + i) % MAX_SIZE]; } return sum / count; } 自选任务: 本次还买了一个超声波测距。准备做一个倒车雷达。 本次使用的是米思齐(Mixly)软件。该软件是一个图形化编程软件,适合儿童编程,从小培养兴趣爱好。 1、在官网下载软件,可以一键安装。http://mixly.org/ 2、下载相应的库       然后就可以进行编程了。   还可以看到相应的C语言。  

  • 2025-01-14
  • 发表了主题帖: 【Follow me第二季第4期】-任务4:选做任务一(非必做):通过RGB LED不同颜色、亮...

    由于任务3是PDM麦克风相关任务,所以本次选择的可选任务是通过LED显示麦克风收到声音大小。 本次任务是在任务3 的基础上,结合任务1,对代码进行修改。 主要思路是对麦克风的取值进行存储,然后控制LED灯亮度。本次只用到红灯和绿灯。 观测到任务3中,麦克风采集的数据有两个问题; 1、麦克风采集到的声音波动非常大,不利于LED的控制,如下图(图片来自任务3的内容); 2、采集到的数值会出现负值。 所以需要对采集到的数值进行处理。 本次处理的方式是,先求绝对值,将负值变为正值,再进行滑动平均滤波。     全部带码如下: #include "PDM.h" #include "WiFiNINA.h" #define Led1 LEDR #define Led2 LEDG #define Led3 LEDB #define MAX_SIZE 10 int head = 0; int tail = 0; int count = 0; int queue[MAX_SIZE]; static const char channels = 1; static const int frequncy = 24000; short sampleBuffer[512]; volatile int samplesRead; int LEDR_Value; int LEDG_Value; double MIC_Value; void setup() { // put your setup code here, to run once: Serial.begin(115200); pinMode(Led1, OUTPUT); pinMode(Led2, OUTPUT); PDM.onReceive(onPDMdata); if(!PDM.begin(channels,frequncy)) { Serial.println("Failed to start PDM!!!"); while(1); } } void loop() { // put your main code here, to run repeatedly: if(samplesRead) { for(int i = 0; i < samplesRead; i++) { //Serial.println(sampleBuffer[i]); MIC_Value=get_sliding_average(sampleBuffer[i]); Serial.println(MIC_Value); LEDR_Value=map(MIC_Value, 1, 3000, 1, 255); LEDG_Value=map(MIC_Value, 1, 3000, 255, 1); // analogWrite(Led1 ,LEDR_Value); // analogWrite(Led2 ,LEDG_Value); analogWrite(Led2 ,LEDR_Value); analogWrite(Led1 ,LEDG_Value); } samplesRead=0; } delay(1); } void onPDMdata(){ int bytesAvailable = PDM.available(); PDM.read(sampleBuffer,bytesAvailable); samplesRead = bytesAvailable / 2; } void enqueue(int value) { if ((tail + 1) % MAX_SIZE == head) { // 队列已满,需要先移除一个元素 head = (head + 1) % MAX_SIZE; } queue[tail] = value; tail = (tail + 1) % MAX_SIZE; count++; } int dequeue() { int value = queue[head]; head = (head + 1) % MAX_SIZE; count--; return value; } double get_sliding_average(int new_value) { static int init = 1; if (init) { // 初始化添加MAX_SIZE-1个0,保证头尾指针不会相遇 for (int i = 0; i < MAX_SIZE - 1; i++) { enqueue(0); } init = 0; } // 添加新的样本值 enqueue(sqrt(new_value * new_value)); // 计算滑动平均值 double sum = 0; for (int i = 0; i < count; i++) { sum += queue[(head + i) % MAX_SIZE]; } return sum / count; } 滑动平均滤波函数中,直接对采集到的数值进行取绝对值;   在主程序中,通过映射,将数值转换为1-255,控制LEDR和LEDG;当声音小的时候,绿灯亮,声音大的时候,红灯亮。   下面看一下演示视频。

  • 发表了主题帖: 【Follow me第二季第3期】任务4:设计一个类似信号发生器功能的例程

    本帖最后由 左手阿飞 于 2025-1-14 12:21 编辑 最后扩展任务,设计一个类似信号发生器例程。 信号发生器需要有相应波形的原始波形数据。 在这个任务卡了很多天了,也参考了其他大佬的帖子,但是还是没搞定,做了一些二级菜单,波形出不来。 展示一下现有成果吧。 增加了一个一级菜单, static st_menu_fn_tbl_t s_menu_items[] = { {"Wave Generator" , wave_generator}, {"Hello Information" , Hello_display_menu}, {"Kit Information" , kis_display_menu}, {"Web Server" , eth_emb_display_menu}, {"Network Name Lookup" , eth_www_display_menu}, {"Quad-SPI and Octo-SPI Speed Comparison" , ext_display_menu}, {"Cryptography and USB High speed (MSC)" , enc_display_menu}, {"Next Steps", ns_display_menu }, {"", NULL } };     在菜单中加入选项。但是在增加波形,编译就通不过了。 #define WAVE_TRIANGLE 1 #define WAVE_SQUARE 2 #define WAVE_SINE 3 uint16_t amplitude_scale; uint16_t period_scale; uint16_t wavetype; // Function to get user input for customization bool customize_wave(uint16_t* amplitude_scale, uint16_t* period_scale) { char choice; sprintf(s_print_buffer, "Use default wave settings? (y/n): "); print_to_console((void*)s_print_buffer); choice = input_from_console(); if (choice == 'n' || choice == 'N') { // Prompt for amplitude scaling factor sprintf(s_print_buffer, "Enter amplitude scaling factor (1-10): "); print_to_console((void*)s_print_buffer); // Assume input_from_console returns ASCII digits; convert to integer char amp_input = input_from_console(); *amplitude_scale = (uint16_t)(amp_input - '0'); if (*amplitude_scale < 1 || *amplitude_scale > 10) { *amplitude_scale = 1; // Default value if out of range } // Prompt for period scaling factor sprintf(s_print_buffer, "Enter period scaling factor (1-10): "); print_to_console((void*)s_print_buffer); char per_input = input_from_console(); *period_scale = (uint16_t)(per_input - '0'); if (*period_scale < 1 || *period_scale > 10) { *period_scale = 1; // Default value if out of range } return true; // Customized settings } // Use default settings *amplitude_scale = 1; *period_scale = 1; return false; // Default settings } test_fn wave_generator(void) // Added { int8_t c = -1; uint16_t buffer[3]; // Increased buffer size to store wave type, amplitude, and period amplitude_scale = 1; period_scale = 1; // Clear the screen and move cursor to home position sprintf(s_print_buffer, "%s%s", gp_clear_screen, gp_cursor_home); print_to_console((void*)s_print_buffer); // Display the wave control menu sprintf(s_print_buffer, "Wave Control:\r\n" "1: Triangle Wave\r\n" "2: Square Wave\r\n" "3: Sine Wave\r\n" "r: Read from flash\r\n" "w: Write to flash\r\n" "space: Exit\r\n"); print_to_console((void*)s_print_buffer); while (CONNECTION_ABORT_CRTL != c) { c = input_from_console(); if ((MENU_EXIT_CRTL == c) || (CONNECTION_ABORT_CRTL == c)) { break; } if (0 != c) { // Display the selected option sprintf(s_print_buffer, "Selected option: %c\r\n", c); print_to_console((void*)s_print_buffer); if ('1' == c) { wavetype = WAVE_TRIANGLE; // Select Triangle Wave } else if ('2' == c) { wavetype = WAVE_SQUARE; // Select Square Wave } else if ('3' == c) { wavetype = WAVE_SINE; // Select Sine Wave } else if ('r' == c) { // Read saved parameters from flash readFromFlash(buffer); sprintf(s_print_buffer, "Read from buffer: Wave Type=%d, Amplitude Scale=%d, Period Scale=%d\r\n", buffer[0], buffer[1], buffer[2]); print_to_console((void*)s_print_buffer); wavetype = buffer[0]; amplitude_scale = buffer[1]; period_scale = buffer[2]; continue; // Continue to next iteration } else if ('w' == c) { // Write current parameters to flash buffer[0] = wavetype; buffer[1] = amplitude_scale; buffer[2] = period_scale; SaveWaveToFlash(buffer); sprintf(s_print_buffer, "Wave parameters saved to flash.\r\n"); print_to_console((void*)s_print_buffer); continue; // Continue to next iteration } else { sprintf(s_print_buffer, "Invalid option selected.\r\n"); print_to_console((void*)s_print_buffer); continue; // Continue to next iteration } // After selecting wave type, prompt for customization if (wavetype == WAVE_TRIANGLE || wavetype == WAVE_SQUARE || wavetype == WAVE_SINE) { bool is_custom = customize_wave(&amplitude_scale, &period_scale); if (is_custom) { sprintf(s_print_buffer, "Custom settings applied: Amplitude Scale=%d, Period Scale=%d\r\n", amplitude_scale, period_scale); } else { sprintf(s_print_buffer, "Default settings applied: Amplitude Scale=1, Period Scale=1\r\n"); } print_to_console((void*)s_print_buffer); } } } // Clear the display menu event bit xEventGroupClearBits(g_update_console_event, STATUS_DISPLAY_MENU_KIS); return (0); }  

  • 2025-01-11
  • 发表了主题帖: 【Follow me第二季第3期】任务3:示例程序中新增命令打印信息

    本期任务3:在实例程序中,增加命令打印信息 具体步骤如下: 1、找到menu_main.c文件,找到目录对应的列表,增加新的命令“Hello Information”,以及相应的函数“Hello_display_menu”;    2、增加相应的函数,函数的功能借用kis_display_menu; (1)先在 menu_kis.h  中找到函数声明位置,声明函数   Hello_display_menu; (2)menu_kis.c 中完成函数体  Hello_display_menu;函数体实现功能与  kis_display_menu函数一致,就简单的复制。   编译,下载之后,通过终端连接,可以看到,菜单列表里,增加一行:“Hello_display_menu”   输入数字1,显示板载信息,功能与  Kit Information一致。  

  • 发表了主题帖: 【Follow me第二季第3期】任务2:quad-spi flash和octo-spi flash配置及读写速度测试

    本帖最后由 左手阿飞 于 2025-1-11 12:53 编辑 任务二:quad-spi flash和octo-spi flash配置及读写速度测试: 使用快速开始程序,内部已经有相应的功能函数,跟随视频一起完成。   主菜单内,数字5则是对比QSPI和OSPI读写速度(原文件为数字4),出现下面界面:   提示输入测试的大小,2KB到64KB,输入64,按TAB:   对比出QSPI和OSPI的读写速度。 后面分别对比32KB、16KB、8KB、4KB、2KB读写:   (32KB)   (16KB)   (8KB)  (4KB)  (2KB) 根据以上对比,读写时间基本和文件大小成正比,读写速度基本一样。 QSPI的速度和OSPI的速度对比: 写速度:QSPI的时间大约是OSPI的2倍, 读速度:QSPI的时间大约是OSPI的6倍。

  • 2025-01-03
  • 发表了主题帖: 【Follow me第二季第4期】-任务3:学习PDM麦克风技术知识,调试PDM麦克风,通过串...

    本次任务为学习PDM麦克风,并打印麦克风采集到的数据。 1、麦克风不需要安装单独的库,在板载资源里有“PDM.h”; 2、初始化串口,启动PDM,选择通道及设置采样频率;如果启动失败,则打印启动PDM失败; static const char channels = 1; static const int frequncy = 24000; short sampleBuffer[512]; volatile int samplesRead; void setup() { // put your setup code here, to run once: Serial.begin(115200); PDM.onReceive(onPDMdata); if(!PDM.begin(channels,frequncy)) { Serial.println("Failed to start PDM!!!"); while(1); } } 3、循环执行声音采样,并打印采样值; void loop() { // put your main code here, to run repeatedly: if(samplesRead) { for(int i = 0; i < samplesRead; i++) { Serial.println(sampleBuffer[i]); } samplesRead=0; } delay(1); } 4、用串口查看数据;可选择数据才看,也可选择波形查看;波形查看更直观。     总体代码如下: #include "PDM.h" static const char channels = 1; static const int frequncy = 24000; short sampleBuffer[512]; volatile int samplesRead; void setup() { // put your setup code here, to run once: Serial.begin(115200); PDM.onReceive(onPDMdata); if(!PDM.begin(channels,frequncy)) { Serial.println("Failed to start PDM!!!"); while(1); } } void loop() { // put your main code here, to run repeatedly: if(samplesRead) { for(int i = 0; i < samplesRead; i++) { Serial.println(sampleBuffer[i]); } samplesRead=0; } delay(1); } void onPDMdata(){ int bytesAvailable = PDM.available(); PDM.read(sampleBuffer,bytesAvailable); samplesRead = bytesAvailable / 2; }  

  • 2025-01-02
  • 发表了主题帖: 【Follow me第二季第4期】-任务2:学习IMU基础知识,调试IMU传感器,通过串口打印...

    任务要求:打印加速度、角速度和温度 根据视频介绍,引入库LSM6DSOX.h #include <Arduino_LSM6DSOX.h> 初始化之前,声明变量,存放相应数据: float acc_x,acc_y,acc_z; float gyro_x,gyro_y,gyro_z; float temp; int update_flag;   初始化中,对串口和陀螺仪进行初始化,并打印陀螺仪的采样频率: void setup() { // put your setup code here, to run once: Serial.begin(115200); if(!IMU.begin()) { Serial.println("Falled to initialize IMU"); while(1); } Serial.print("Acc sample rate = "); Serial.print(IMU.accelerationSampleRate()); Serial.println("Hz"); Serial.print("Gyro sample rate = "); Serial.print(IMU.gyroscopeSampleRate()); Serial.println("Hz"); } 循环函数中,为了更好的观察采样数据,循环打印采样频率,并打印三轴加速度、三轴角速度和温度 void loop() { // put your main code here, to run repeatedly: Serial.print("Acc sample rate = "); Serial.print(IMU.accelerationSampleRate()); Serial.println("Hz"); Serial.print("Gyro sample rate = "); Serial.print(IMU.gyroscopeSampleRate()); Serial.println("Hz"); if (IMU.accelerationAvailable()) { IMU.readAcceleration(acc_x,acc_y,acc_z); update_flag = 1; } if (IMU.gyroscopeAvailable()) { IMU.readGyroscope(gyro_x,gyro_y,gyro_z); update_flag = 1; } if (IMU.temperatureAvailable()) { IMU.readTemperatureFloat(temp); update_flag = 1; } if (update_flag) { update_flag=0; Serial.print(acc_x); Serial.print(','); Serial.print(acc_y); Serial.print(','); Serial.print(acc_z); Serial.print(','); Serial.print(gyro_x); Serial.print(','); Serial.print(gyro_y); Serial.print(','); Serial.print(gyro_z); Serial.print(','); Serial.print(gyro_x); Serial.print(','); Serial.println(temp); delay(500); } } 全部代码如下: #include <Arduino_LSM6DSOX.h> float acc_x,acc_y,acc_z; float gyro_x,gyro_y,gyro_z; float temp; int update_flag; void setup() { // put your setup code here, to run once: Serial.begin(115200); if(!IMU.begin()) { Serial.println("Falled to initialize IMU"); while(1); } Serial.print("Acc sample rate = "); Serial.print(IMU.accelerationSampleRate()); Serial.println("Hz"); Serial.print("Gyro sample rate = "); Serial.print(IMU.gyroscopeSampleRate()); Serial.println("Hz"); } void loop() { // put your main code here, to run repeatedly: Serial.print("Acc sample rate = "); Serial.print(IMU.accelerationSampleRate()); Serial.println("Hz"); Serial.print("Gyro sample rate = "); Serial.print(IMU.gyroscopeSampleRate()); Serial.println("Hz"); if (IMU.accelerationAvailable()) { IMU.readAcceleration(acc_x,acc_y,acc_z); update_flag = 1; } if (IMU.gyroscopeAvailable()) { IMU.readGyroscope(gyro_x,gyro_y,gyro_z); update_flag = 1; } if (IMU.temperatureAvailable()) { IMU.readTemperatureFloat(temp); update_flag = 1; } if (update_flag) { update_flag=0; Serial.print(acc_x); Serial.print(','); Serial.print(acc_y); Serial.print(','); Serial.print(acc_z); Serial.print(','); Serial.print(gyro_x); Serial.print(','); Serial.print(gyro_y); Serial.print(','); Serial.print(gyro_z); Serial.print(','); Serial.print(gyro_x); Serial.print(','); Serial.println(temp); delay(500); } }   运行 结果如下:  

  • 发表了主题帖: 【Follow me第二季第4期】-任务1:搭建环境并开启第一步Blink三色LED / 串口打印He...

    一、搭建开发环境: 推荐使用的开发环境位AduinoIDE,正好原来使用过Arduino,已经安装好了,不需要再次安装。只需要添加相应开发板(RP2040)就可以使用了。   二、跟着视频完成LED闪烁和打印“Hello Digikey & EEWorld”; 视频中,延时时间为5ms,LED呼吸效果不好,闪烁太快。 我改为50 ms,呼吸想过更自然。 #include "WiFiNINA.h" #define Led1 LEDR #define Led2 LEDG #define Led3 LEDB float angle1; float angle2; float angle3; void setup() { // put your setup code here, to run once: pinMode(Led1, OUTPUT); pinMode(Led2, OUTPUT); pinMode(Led3, OUTPUT); for(int i =0; i < 5 ; i++) { digitalWrite(Led1, LOW); digitalWrite(Led2, HIGH); delay(200); digitalWrite(Led2, LOW); digitalWrite(Led3, HIGH); delay(200); digitalWrite(Led3, LOW); digitalWrite(Led1, HIGH); delay(200); } angle1 = 0.0; angle2 = 0.0 + PI /3.0; angle3 = 0.0 + 2.0 * PI /3.0; Serial.begin(115200); } void loop() { // put your main code here, to run repeatedly: Serial.println("Hello Digikey & EEWorld"); angle1 += 0.01; angle2 += 0.01; angle3 += 0.01; if(angle1 >= PI) angle1 -= PI; if(angle2 >= PI) angle2 -= PI; if(angle3 >= PI) angle3 -= PI; int a = sin (angle1) * 255; int b = sin (angle2) * 255; int c = sin (angle3) * 255; analogWrite(Led1 ,a); analogWrite(Led2 ,b); analogWrite(Led3 ,c); delay(50); }   串口打印结果如下图。:  

  • 2024-12-12
  • 发表了主题帖: 【Follow me第二季第3期】任务1:搭建环境,下载调试示例程序,Blink,按键

    1,环境搭建: 本次安装的的是5.6.0版本。安装完成之后,无法开启连接器。重新安装,需要勾选连接器安装。如下图3所示,红色方框标出的勾选。         2、打开快速开始程序_quickstart。 3、跟视频学习Blink,按键程序。 1)、找到LED闪烁频率和 呼吸灯占空比的函数,在原来基础上 增加 一个状态:   2)运行显示主菜单,通过键盘进入Kit Information。     3)通过两个蓝色按键,控制LED1和LED2的闪烁频率和占空比。  但是显示有个问题,已经用红框标出来:温度显示两行,造成闪烁频率和占空比错位。      

  • 2024-10-31
  • 发表了主题帖: 【2024 DigiKey创意大赛】会议声源追踪器

    会议声源追踪器 作者:左手阿飞   作品简介 随着网络直播技术的发展,许多线下活动转移到线上,比如线上会议、网络课堂等。为进一步提高线上会议或网络课堂的收音质量,本设计提出一种会议声源追踪系统,主要功能如下: 1、声源定位,识别声音方向; 2、声源追踪,用步进电机控制麦克风方向,追踪声源,减少干扰噪声;(未完成) 3、检测会议室环境,上传云端,可以提醒工作人员提前开启空调等设备。   图1 作品照片 用到的物料及想用的作用如下: 1、sipeed麦克风阵列(MIC_ARRAY):用于声音的收集; 2、K210开发板:用于声音数据分析,识别声音方向,并发送相应数据给STM32F411; 3、STM32F411开发板:接收K210数据,并控制步进电机,改变麦克风阵列的方向,使麦克风正面对应声源; 4、SGP30&DHT11:SGP30为空气质量传感器,可检测空气中挥发性有机物(TVOC)和CO2的含量;DHT11为温湿度传感器,可检测温度和湿度; 5、ESP32S3开发板:将检测到的空气质量(TVOC、CO2、温度和湿度)数据上传到云端(阿里云),通过手机APP查看,在会议开始前,提前打开空调等设备。 二、系统框图 硬件设计包含硬件设计框图如图2所示:   图2 系统框图 声源方向检测部分,由麦克风阵列和K210卡发版完成。麦克风方向由STM32提供控制信号,控制两个步进电机调整。两个步进电机分别调整X轴方向和Y轴方向。空气质量检测部分,由传感器SGP30和DHT11检测,并通过ESP32连接WIFI上传阿里云,实现远程检测和控制。 三、各部分功能说明 第一部为声源方向检测部分,由麦克风阵列和K210卡发版完成。   图3 声源方向检测 麦克风阵列为sipeed厂家出厂,由6+1个麦克风,圆周均匀分布6个,中央1个。传输方式为I2S传输方式,可检测不同方向的声音强度。圆周上有12个串行LED,可显示声源方向。LED控制方式为串行数字控制,串行控制协议类似于SPI。 K210开发板资源丰富,自带LCD屏幕(480*320)和麦克风阵列接口,可直接与麦克风阵列连接。开发语言为microPython。microPython开发方便,有丰富的三方库可供使用,开发方便。 K210接收麦克风阵列检测到的声音数据,通过对6个麦克风的数据差值,计算出声源的方向及距离,并控制LED显示出相应方向,并将数据通过串口发送给STM32F411。 第二部分为方向控制部分。由STM32F411和2个步进电机组成。   图4 麦克风方向控制 STM32通过串口,接收声音方向数据,控制2个步进电机。2个步进电机分别控制x轴方向和Y轴方向的运动,使麦克风阵列正对声源方向,达到声音降噪的目的。 第三部分为会议室环境检测部分。由SPG30、DHT11和ESP32S3组成。   图5 会议室空气质量检测 SPG30可检测空气中TVOC、CO2的浓度。通过I2C通信协议传输,传输数据格式为6个字节一组数据,前三个字节传送TVOC浓度,后三字节传送CO2浓度。每个分组数据,有两个字节为数据字节(16位),第三字节位CRC校验位。 DHT11为温湿度检测传感器,通过单总线协议传输。每帧数据5个字节,前2个字节为湿度数据,紧接着2个字节为温度数据,最后一个字节为校验位。 ESP32S3接收SPG30和DHT11检测到的空气质量数据,上传阿里云平台。可在阿里云平台和手机APP上查看。APP上设置有开关,可远程控制一个LED。在实际应用中,LED可替换为空调、新风风扇、空气净化器等设备。如有必要,可增加开关,控制更多设备。 四、作品源码 https://download.eeworld.com.cn/detail/%E5%B7%A6%E6%89%8B%E9%98%BF%E9%A3%9E/634860 五、作品功能演示视频   六、项目总结 这是第一次参加得捷主办的创新设计大赛。经过这次大赛的练习,对嵌入式开发有了更深的理解。感谢得捷提供的这次难得的机会。 本次设计完成了一个会议声源追踪器。该设备可完成会议室声源方向追踪、空气环境检测以及空气质量改善等功能。由于时间较为紧迫,所选方案为开发时间最短、最容易实现的方案,存在一些问题。最大的问题就是成本太高。一共用到3个控制器:K210、STM32、ESP32。控制器功能有重复,后续可从降成本方向考虑,用ESP32+STM32方案或者单独使用其中一个控制器方案。其次,方案多采用库函数,对底层研究不够深入,设备运行效率较低。后续可试试从底层开发,提升自己手册阅读能力与开发能力。 总之,经过这次训练,个人的嵌入式开发水平有了很大提升,开阔了眼界,为后续工作提供更多思路。再次感谢得捷提供的机会,祝愿大赛越办越好!!! 开箱贴:https://bbs.eeworld.com.cn/thread-1294810-1-1.html 温湿度检测:https://bbs.eeworld.com.cn/thread-1296460-1-1.html TVOC和CO2检测:https://bbs.eeworld.com.cn/thread-1294810-1-1.html

  • 上传了资料: 声源定位

最近访客

< 1/1 >

统计信息

已有5人来访过

  • 芯积分:135
  • 好友:--
  • 主题:14
  • 回复:10

留言

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


现在还没有留言