毕设做到这,愈发地感觉Alios Things好像还有很长的路要走,但也或许是我没有触及到他真正牛逼的地方吧,不过就其官方群,github的stars,API适配情况,或者是网络资料来看,这或许还是一个偏小众的物联网系统。
这个部分还是很简单的,几乎可以省略,总体就是led连接到地线和一个gpio,然后可以使用alios适配好的API,用结构体来对IO口做配置,最后用API来操控IO口电平来实现led的明暗效果
有源蜂鸣器只需给一个电平即可驱动,所以对其的操作与LED类似
(发现alios的API都有其特点,就是感觉比较傻瓜式,从它的API的源码来看,是调用了板子的官方IDF中较为复杂的API来的)
这里一开始我使用的是alios适配后的PWM的API,那真叫一个憋屈,好像给esp32适配漏了个更改配置的函数
hal_pwm_para_chg();
其他函数倒是有,这个偏偏是找不到的。
然后去官方IDF套件API里也找不到PWM的API,最后在一些文章里发现esp32用来操作PWM用的是ledc.h这个头文件所指向的库。(ledc库原本是给渐变灯做渐变控制的)
用其做PWM控制要使用两个配置结构体,一个是timer的一个是channel的,然后因为是比较硬核的API,那个参数都挺复杂的,大致来看,主要是频率frequence,速度模式speed mode,引脚gpio,占空比duty这四个需要注意的。
frequence,这个后面其实是需要变得,决定了音调的高低,不过我发现这个的初始值决定了后面变化的音调的起点,换言之,这个初始值设置得越高,整首音乐的音调也就越高了。
speed mode,这个有两种可选,一个是高速一个低速,低速演奏的音乐奇奇怪怪,感觉完全不在调上,所以设置高速。
gpio,单个无源蜂鸣器没有模块的那种,就随便接一个gpio口基本都可支持PWM
duty,这个占空比实际上是有一定的学问的,他的赋值受到frequence的限制,不过只要freq不要定的太高太高,这个的取值也没啥关系,它代表的意义基本上就是输出的方波在整个输出周期所占比例,但duty不是小数形式,而是分辨率,或者说是2
的次方形式的,一般别超过1024就行吧。经验证发现这个变量在音乐中表现为音量大小,数值越大越响。
然后要想演奏音乐就需要根据事先确定好的音调与拍子来循环调整这些参数。我的代码如下,(演奏葫芦娃,前面被注释掉的是超级玛丽)
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include
#include
#define GPIO_LED_IO 19
// int melody[] = {330, 330, 330, 262, 330, 392, 196, 262,
// 196, 165, 220, 247, 233, 220, 196, 330, 392, 440, 349,
// 392, 330, 262, 294, 247, 262, 196, 165, 220, 247, 233,
// 220, 196, 330, 392,440, 349, 392, 330, 262, 294, 247,
// 392, 370, 330, 311, 330, 208, 220, 262, 220, 262,
// 294, 392, 370, 330, 311, 330, 523, 523, 523, 392,
// 370, 330, 311, 330, 208, 220, 262,220, 262, 294,
// 311, 294, 262, 262, 262, 262, 262, 294, 330, 262,
// 220, 196, 262, 262,262, 262, 294, 330, 262, 262,
// 262, 262, 294, 330, 262, 220, 196};
// //创建音调持续时间列表
// int noteDurations[] = {8,4,4,8,4,2,2,3,3,3,4,4,8,4,
// 8,8,8,4,8,4,3,8,8,3,3,
// 3,3,4,4,8,4,8,8,8,4,8,
// 4,3,8,8,2,8,8,8,4,4,8,
// 8,4,8,8,3,8,8,8,4,4,4,
// 8,2,8,8,8,4,4,8,8,4,8,
// 8,3,3,3,1,8,4,4,8,4,8,
// 4,8,2,8,4,4,8,4,1,8,4,
// 4,8,4,8,4,8,2};
#define NOTE_D0 199
#define NOTE_D1 294
#define NOTE_D2 330
#define NOTE_D3 350
#define NOTE_D4 393
#define NOTE_D5 441
#define NOTE_D6 495
#define NOTE_D7 556
#define NOTE_DL1 147
#define NOTE_DL2 165
#define NOTE_DL3 175
#define NOTE_DL4 196
#define NOTE_DL5 221
#define NOTE_DL6 248
#define NOTE_DL7 278
#define NOTE_DH1 589
#define NOTE_DH2 661
#define NOTE_DH3 700
#define NOTE_DH4 786
#define NOTE_DH5 882
#define NOTE_DH6 990
#define NOTE_DH7 112
#define WHOLE 1
#define HALF 0.5
#define QUARTER 0.25
#define EIGHTH 0.25
#define SIXTEENTH 0.625
int melody[] = {
NOTE_DH1,NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,
NOTE_DH1,NOTE_D6,NOTE_D5,NOTE_DH1,NOTE_D6,NOTE_D0,NOTE_D6,
NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D6,NOTE_D0,NOTE_D6,
NOTE_DH1,NOTE_D6,NOTE_D5,NOTE_DH1,NOTE_D6,NOTE_D0,
NOTE_D1,NOTE_D1,NOTE_D3,
NOTE_D1,NOTE_D1,NOTE_D3,NOTE_D0,
NOTE_D6,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D6,
NOTE_D5,NOTE_D1,NOTE_D3,NOTE_D0,
NOTE_DH1,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D6,
NOTE_D5,NOTE_D1,NOTE_D2,NOTE_D0,
NOTE_D7,NOTE_D7,NOTE_D5,NOTE_D3,
NOTE_D5,
NOTE_DH1,NOTE_D0,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D5,NOTE_D6,NOTE_D6,
NOTE_D0,NOTE_D5,NOTE_D1,NOTE_D3,NOTE_D0,
NOTE_DH1,NOTE_D0,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D5,NOTE_D6,NOTE_D6,
NOTE_D0,NOTE_D5,NOTE_D1,NOTE_D2,NOTE_D0,
NOTE_D3,NOTE_D3,NOTE_D1,NOTE_DL6,
NOTE_D1,
NOTE_D3,NOTE_D5,NOTE_D6,NOTE_D6,
NOTE_D3,NOTE_D5,NOTE_D6,NOTE_D6,
NOTE_DH1,NOTE_D0,NOTE_D7,NOTE_D5,
NOTE_D6
};
float noteDurations[]=
{
1,1,0.5,0.5,1,
0.5,0.5,0.5,0.5,1,0.5,0.5,
0.5,1,0.5,1,0.5,0.5,
0.5,0.5,0.5,0.5,1,1,
1,1,1+1,
0.5,1,1+0.5,1,
1,1,0.5,0.5,1,
0.5,1,1+0.5,1,
0.5,0.5,0.5,0.5,1+1,
0.5,1,1+0.5,1,
1+1,0.5,0.5,1,
1+1+1+1,
0.5,0.5,0.5+0.25,0.25,0.5+0.25,0.25,0.5+0.25,0.25,
0.5,1,0.5,1,1,
0.5,0.5,0.5+0.25,0.25,0.5+0.25,0.25,0.5+0.25,0.25,
0.5,1,0.5,1,1,
1+1,0.5,0.5,1,
1+1+1+1,
0.5,1,0.5,1+1,
0.5,1,0.5,1+1,
1+1,0.5,0.5,1,
1+1+1+1
};
#include "ledc.h"
int application_start(int argc, char *argv[]){
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_13_BIT, // resolution of PWM duty
.freq_hz = 600, // 决定了初始的音调高度
.speed_mode = LEDC_HIGH_SPEED_MODE, // timer mode 如果用LOW_SPEED音调会很奇怪
.timer_num = LEDC_TIMER_1, // timer index
// .clk_cfg = LEDC_REF_TICK, // Auto select the source clock
};
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
ledc_channel_config_t ledc_ch = {
.channel = LEDC_CHANNEL_0,
.duty = 300, //占空比,指的是输出时间占一个周期的比例,这里的数值并不是比例,没深究其与比例的关系,不过这与音量直接相关
.gpio_num = GPIO_LED_IO,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.hpoint = 0,
.timer_sel = LEDC_TIMER_1
};
// ESP_ERROR_CHECK(ledc_channel_config(&ledc_ch));
int len = sizeof(melody)/sizeof(melody[0]);
for(int i = 0; i