【问题标题】:Defining variables esp32定义变量 esp32
【发布时间】:2021-11-28 02:56:52
【问题描述】:

我正在尝试在 esp32 中找到一种方法来获得(列表),因为缺少更好的术语,我可以将其作为变量输入来调用。我有一个 void playwav();功能。我想使用一个全局变量来定义应该播放的文件。即playwav('警报')。我有一个案例开关设置,但使用的是 a b c 方法。随着我的代码不断增长(下一步将添加 71 个新的 wav 文件),我很快意识到该方法将不再有效。有人告诉我要做一个数组,但是对于我的一生,无论我读什么,我都无法掌握如何去做,也无法按名称调用文件。有人对我应该做什么有建议吗?非常感谢任何帮助。

这是我目前拥有的。


void playWAV (char effect, int bg1248_general_volume)
{
  Serial.println("Entered playWAV");
  switch (effect)
  {
    case 'a':
      file = new AudioFileSourceSD("/wav/alarm.wav");
      break;

    case 'b':
      file = new AudioFileSourceSD("/wav/alarmhigh.wav");
      break;

    case 'c':
      file = new AudioFileSourceSD("/wav/alarmlow.wav");
      break;

    case 'd':
      file = new AudioFileSourceSD("/wav/error.wav");
      break;
  
    case 'e':
      file = new AudioFileSourceSD("/wav/error1.wav");
      break;
  
    case 'f':
      file = new AudioFileSourceSD("/wav/noread.wav");
      break;
      
    case 'g':
      file = new AudioFileSourceSD("/wav/noreadings.wav");
      break;
      
    case 'h':
      file = new AudioFileSourceSD("/wav/normalrange.wav");
      break;
      
    case 'i':
      file = new AudioFileSourceSD("/wav/warning.wav");
      break;

    case 'j':
      file = new AudioFileSourceSD("/wav/warninghigh.wav");
      break;
      
    case 'k':
      file = new AudioFileSourceSD("/wav/warninglow.wav");
      break;
      
    case 'l':
      file = new AudioFileSourceSD("/wav/startup.wav");
      break;  

      case 'm':
      file = new AudioFileSourceSD("/wav/startup.wav");
      break;      
      
      case 'n':
      file = new AudioFileSourceSD("/wav/update.wav");
      break;  
      case 'o':
      file = new AudioFileSourceSD("/wav/startup_dev.wav");  
      }

float volumeGain = ((float)bg1248_general_volume / 100.0) * 39.0;
  Serial.print("volumeGain:");
  Serial.println(volumeGain);
  id3 = new AudioFileSourceID3(file);
  out = new AudioOutputI2S(0, 0); // Output to builtInDAC
  out->SetPinout(12, 0, 2);
  out->SetOutputModeMono(true);
  out->SetGain(volumeGain);
  wav = new AudioGeneratorWAV();
  wav->begin(id3, out);

但是,因为我使用了字母表,所以我很快就会用完案例。我希望能够在项目中的任何地方调用特定的 wav 文件,最好是 playWAV(filename) 或类似的东西。

我这样调用函数(文件)(示例条件)

if((ns->sensSgv<=cfg.snd_alarm) && (ns->sensSgv>=0.1)) {
// red alarm state
// M5.Lcd.fillRect(110, 220, 100, 20, TFT_RED);
Serial.println("ALARM LOW");
M5.Lcd.fillRect(0, 220, 320, 20, TFT_RED);
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
int stw=M5.Lcd.textWidth(tmpStr);
M5.Lcd.drawString(tmpStr, 159-stw/2, 220, GFXFF);
if( (alarmDifSec>cfg.alarm_repeat*60) && (snoozeRemaining<=0) ) {
    playWAV('a', 100);

'a'=case 100 = 体积。

艾伦,这是我目前在我的枚举中的内容,我正在学习一个教程,但怀疑我做对了。即使我这样做了,我也会收到错误消息,说我没有重复的案例。

EDIT:

条件是这样设置的:

if((ns->sensSgv<=cfg.snd_alarm) && (ns->sensSgv>=0.1))

如果你注意到底部有:

if( (alarmDifSec>cfg.alarm_repeat*60) && (snoozeRemaining<=0) ) {
    playWAV('a', 100);

a 与 switch 案例中的案例 A 相关。如上所示。目前所有使用playWAV功能的地方都是手动指定的。

【问题讨论】:

  • 请以minimal reproducible example 的形式展示您拥有的东西,并详细描述您想要实现的目标。描述您认为会有所帮助的内容是可以的,但也可以用一些文字说明您想对此处提出的任何解决方案做什么。
  • 好的,给我几分钟,我会更新原帖。
  • 我知道你有一个 switch case 实现,可以实现你想要的,但是对于更多的文件来说,predictbly 太笨拙了。我认为仅仅展示这一点就足够了,即使不是完美的。如果它现在有效,那么有人将能够向您展示如何使用数组在许多文件的上下文中更优雅地实现相同的目标。
  • 我刚刚更新了主帖,够了吗?
  • 你删除了我之前的编辑。这是您的选择,但请仔细检查您是否想要这样做。

标签: c++ arduino conditional-statements case esp32


【解决方案1】:

我的理解是在开关盒中使用字母很快就会用完,因为没有大。文件数 (>26)。所以,我先用枚举实现了逻辑,下面是完整的代码。

#include<stdio.h>

enum soundEffects {
    alarm,
    alarm_high,
    alarm_low,
    Dev_startup,
    error,
    error1,
    noread,
    noreadings,
    normalrange,
    startup,
    startup_dev,
    update,
    warning,
    warning_high,
    warning_low,
};

void playWav (enum soundEffects effect, int paci_volume)
{
    //Serial.println("Entered paciplay_day");
    //printf("Entered paciplay_day\n");

    switch (effect)
    {
        case alarm:
            //file = new AudioFileSourceSD("/wav/alarm.wav");
            printf("/wav/alarm.wav\n");
            break;

        case alarm_high:
            //file = new AudioFileSourceSD("/wav/alarmhigh.wav");
            printf("/wav/alarmhigh.wav\n");
            break;

        case alarm_low:
            //file = new AudioFileSourceSD("/wav/alarmlow.wav");
            printf("/wav/alarmlow.wav\n");
            break;

        case error:
            //file = new AudioFileSourceSD("/wav/error.wav");
            printf("/wav/error.wav\n");
            break;

        case error1:
            //file = new AudioFileSourceSD("/wav/error1.wav");
            printf("/wav/error1.wav\n");
            break;

        case noread:
            //file = new AudioFileSourceSD("/wav/noread.wav");
            printf("/wav/noread.wav\n");
            break;

        case noreadings:
            //file = new AudioFileSourceSD("/wav/noreadings.wav");
            printf("/wav/noreadings.wav\n");
            break;

        case normalrange:
            //file = new AudioFileSourceSD("/wav/normalrange.wav");
            printf("/wav/normalrange.wav\n");
            break;

        case warning:
            //file = new AudioFileSourceSD("/wav/warning.wav");
            printf("/wav/warning.wav\n");
            break;

        case warning_high:
            //file = new AudioFileSourceSD("/wav/warninghigh.wav");
            printf("/wav/warninghigh.wav\n");
            break;

        case warning_low:
            //file = new AudioFileSourceSD("/wav/warninglow.wav");
            printf("/wav/warninglow.wav\n");
            break;

        case startup:
            //file = new AudioFileSourceSD("/wav/startup.wav");
            printf("/wav/startup.wav\n");
            break;

        case update:
            //file = new AudioFileSourceSD("/wav/update.wav");
            printf("/wav/update.wav\n");
            break;
    }
}

int main()
{
    //below are the 3 ways of calling your playWav() function
    //1 - using direct numbers
    //this will throw compilation error when compiled using cpp compilers
    for (int i = 0; i<14; i++)
    {
        printf("enum value: %d\n", i);
        playWav(i, 50);
    }

    //2 - directly calling using the enum
    playWav(startup, 100);

    //3 - Just another way of calling
    enum soundEffects sound;
    sound = error;
    playWav(sound, 100);
    return 0;
}

另外,我使用双数组实现了同样的逻辑。请在下面找到它。这使用文件名作为参数,因此我们可以完全消除 switch 语句的使用。

#include<stdio.h>

void playWav (const char *filename, int paci_volume)
{
    //Serial.println("Entered paciplay_day");
    printf("Entered paciplay_day\n");

    //file = new AudioFileSourceSD("/wav/update.wav");
    printf("/wav/%s\n", filename);
}

int main()
{
    const char list_of_files[][25] = { "startup.wav", "update.wav", "warning.wav", "alarm.wav" };
    for (int i = 0; i<4; i++)
    {
        printf("name: %s\n", list_of_files[i]);
        playWav(list_of_files[i], 50);
    }
    return 0;
}

请省略我用于调试的 printf 语句。我希望这很有用。

【讨论】:

  • 这看起来很完美!所以要播放一个文件,我可以简单地去 playWAV(alarm, 100)?如果是这样,那正是我想要的。第二个问题,如果我添加更多文件,是否像添加另一个案例块然后用新文件名更新顶部的列表一样简单?
  • 是的,如果您添加更多文件,您只需要根据需要更新上述枚举和 switch case 语句。
  • 完美!!!太感谢了!这是我所要求的 100% 的位置。
  • 你好 kite,我正在尝试实现你提供的枚举。我陷入了一个错误。 “int”类型的参数与“soundEffects”类型的参数不兼容,我在这里做错了吗?
  • 有问题的行是这一行 playWav(i, 50);
猜你喜欢
  • 1970-01-01
  • 2011-06-11
  • 2021-11-19
  • 1970-01-01
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 2022-10-06
  • 2011-11-20
相关资源
最近更新 更多