Passing char to a function

#include <Arduino.h>
#ifdef ARDUINO_M5STACK_Core2
  #include <M5Core2.h>
  #include <driver/i2s.h>
#else
  #include <M5Stack.h>
#endif

#include "AudioFileSourceSD.h"
#include "AudioFileSourceID3.h"
#include "AudioGeneratorWAV.h"
#include "AudioOutputI2S.h"

AudioGeneratorWAV *wav;
AudioFileSourceSD *file;
AudioOutputI2S *out;
AudioFileSourceID3 *id3;
bool playing = false;
#define OUTPUT_GAIN 40

//////sound file////
void playWAV (char effect, int 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;      
      }
////conditions////
//////////////////////CONFIG STATE///////////////////////
void handleAlarmsInfoLine(struct NSinfo *ns) {
  struct tm timeinfo;

  // calculate sensor time difference
  // calculate last alarm time difference
  int sensorDifSec=24*60*60; // too much
  int alarmDifSec=24*60*60; // too much
  int snoozeRemaining = 0;
  bool timeOK = getLocalTime(&timeinfo);
  if(timeOK){
    sensorDifSec=difftime(mktime(&timeinfo), ns->sensTime);
    alarmDifSec=difftime(mktime(&timeinfo), lastAlarmTime);
    if(timeOK) {
      snoozeRemaining = difftime(snoozeUntil, mktime(&timeinfo));
      if(snoozeRemaining < 0)
        snoozeRemaining = 0;
    }
  }
  unsigned int sensorDifMin = (sensorDifSec+30)/60;

  Serial.print("Alarm time difference = "); Serial.print(alarmDifSec); Serial.println(" sec");
  Serial.print("Snooze time remaining = "); Serial.print(snoozeRemaining); Serial.print(" sec, Snooze until "); Serial.println(snoozeUntil);
  char tmpStr[10];
  M5.Lcd.setTextDatum(TL_DATUM);
  if( snoozeRemaining>0 ) {
    sprintf(tmpStr, "%i", (snoozeRemaining+59)/60);
    if(dispPage<maxPage)
      drawIcon(icon_xpos[1], icon_ypos[1], (uint8_t*)clock_icon16x16, TFT_RED);
  } else {
    strcpy(tmpStr, "Snooze");
    if(dispPage<maxPage)
      M5.Lcd.fillRect(icon_xpos[1], icon_ypos[1], 16, 16, BLACK);
  }
  M5.Lcd.setTextSize(1);
  M5.Lcd.setFreeFont(FSSB12);
  // prapare intensity variables for LED strip brightness
  int maxint = 255;
  maxint *= cfg.LED_strip_brightness;
  maxint /= 100;
  int lessint = 192;
  lessint *= cfg.LED_strip_brightness;
  lessint /= 100;
  // Serial.print("sensSgv="); Serial.print(sensSgv); Serial.print(", cfg.snd_alarm="); Serial.println(cfg.snd_alarm);
  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) ) {
        sndAlarm();
        alarm_low = true;
        
        lastAlarmTime = mktime(&timeinfo);
          red();
    }
    
  } else {
    if((ns->sensSgv<=cfg.snd_warning) && (ns->sensSgv>=0.1)) {
      // yellow warning state
      // M5.Lcd.fillRect(110, 220, 100, 20, TFT_YELLOW);
      Serial.println("WARNING LOW");
      M5.Lcd.fillRect(0, 220, 320, 20, TFT_YELLOW);
      M5.Lcd.setTextColor(TFT_BLACK, TFT_YELLOW);
      int stw=M5.Lcd.textWidth(tmpStr);
      M5.Lcd.drawString(tmpStr, 159-stw/2, 220, GFXFF);
      if( (alarmDifSec>cfg.alarm_repeat*60) && (snoozeRemaining<=0) ) {
        sndWarning();
        warn_low = true;
        lastAlarmTime = mktime(&timeinfo);
      yellow();
      }
      
    } else {
      if( ns->sensSgv>=cfg.snd_alarm_high ) {
        // red alarm state
        // M5.Lcd.fillRect(110, 220, 100, 20, TFT_RED);
        Serial.println("ALARM HIGH");
        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) ) {
          sndAlarm();
          alarm_high = true;
          lastAlarmTime = mktime(&timeinfo);
       red();}
      } else {
        if( ns->sensSgv>=cfg.snd_warning_high ) {
          // yellow warning state
          // M5.Lcd.fillRect(110, 220, 100, 20, TFT_YELLOW);
          Serial.println("WARNING HIGH");
          M5.Lcd.fillRect(0, 220, 320, 20, TFT_YELLOW);
          M5.Lcd.setTextColor(TFT_BLACK, TFT_YELLOW);
          int stw=M5.Lcd.textWidth(tmpStr);
          M5.Lcd.drawString(tmpStr, 159-stw/2, 220, GFXFF);
          if( (alarmDifSec>cfg.alarm_repeat*60) && (snoozeRemaining<=0) ) {
            sndWarning();
            warn_high = true;
            lastAlarmTime = mktime(&timeinfo);
          yellow();
          
          }
        } else {
          if( sensorDifMin>=cfg.snd_no_readings ) {
            // LONG TIME NO READINGS -> yellow warning state
            // M5.Lcd.fillRect(110, 220, 100, 20, TFT_YELLOW);
            Serial.println("WARNING NO READINGS");
            M5.Lcd.fillRect(0, 220, 320, 20, TFT_CYAN);
            M5.Lcd.setTextColor(TFT_BLACK, TFT_CYAN);
            int stw=M5.Lcd.textWidth(tmpStr);
            M5.Lcd.drawString(tmpStr, 159-stw/2, 220, GFXFF);
            if( (alarmDifSec>cfg.alarm_repeat*60) && (snoozeRemaining<=0) ) {
              no_readings = true;
              sndnoreadings();
              
              lastAlarmTime = mktime(&timeinfo);
              cyan();           
            }
          } else {
            if( strstr(ns->loop_display_label,"Err" )>0 ) {
              // LOOP ERROR -> red alarm state
              // M5.Lcd.fillRect(110, 220, 100, 20, TFT_RED);
              Serial.println("LOOP ERROR");
              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);
              M5.Lcd.drawString("LOOP", 2, 220, GFXFF);
              M5.Lcd.drawString("ERR", 267, 220, GFXFF);
              if( (alarmDifSec>cfg.alarm_repeat*60) && (snoozeRemaining<=0) ) {
                sndAlarm();
                lastAlarmTime = mktime(&timeinfo);
              }
              if(cfg.LED_strip_mode>=2) {
                pixels.fill(pixels.Color(maxint, 0, 0));
                pixels.show();
              } else {
                if(cfg.LED_strip_mode==1) {
                  pixels.clear();
                  pixels.show();
                }
              }
            } else {
              // normal glycemia state
              M5.Lcd.fillRect(0, 220, 320, 20, TFT_BLACK);
              M5.Lcd.setTextColor(TFT_LIGHTGREY, TFT_BLACK);
             playWAV('h', 3.0);
              green();
           
  

  //volume/100*35
  //float volumeGain = (float)OUTPUT_GAIN / (volume * 100.0);
  float volumeGain = ((float)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);


void loop()





void alarm_high1(){

if (alarm_high){
   (playWAV('b', 3.0);}
}
void alarm_low1(){

if (alarm_low){
   (playWAV('c', 3.0);
}

void error1(){

if (error){
  (playWAV('e', 3.0);

void no_readings1(){

if (no_readings){
   (playWAV('g', 3.0));
    
}
}
void normal_range1(){

if (normal_range){
(playWAV('h', 3.0);

}

void update1(){
(playWAV('n', 3.0);

}

Its a quick sketch, but should give you an idea, i have the conditions, the loop for detecting if there is a true statement. and the sound cases

if you indented the code in the IDE before copying (that's done by pressing ctrlT on a PC or cmdT on a Mac) you would see that it's not a suitable code (the loop is not there / missing brackets probably)

I'm not using arduino ide I'm using vscode wasn't sure how to format it. Also yes it's probably not working code I drafted it just as a way to see what I'm doing and specifying the cases

OK - try to post some code that makes sense - we can't do much with that

Will it let me do more than 2000 lines? If so I'll post the whole thing

before you do that, can you try to re-explain in plain English what it is you are struggling with?

Sure, im sorry if I was not clear (ive been up all night and brain is foggy :))
I have a loop going that checks if the conditions are true or false, if true it plays a wav file specified in the case argument. what I am having a problem with is passing (char effect, int volume) to another function. ie the timer function

#include <M5Stack.h>
#include "utility/M5Timer.h"

M5Timer M5timer;
void playwav(){
}
void setup() {
  M5.begin();
  M5timer.setTimeout(5000, playwav);
}
void loop() {
  M5timer.run();
}

What is the purpose of the timer? From your description, I would expect you would start playing as soon as you know which one is required.

the timer callback function does not take any parameters, so you should save the current values for the char effect and volume in global variables that are visible within the callback or implement the business logic into the callback

to repeat the file every 30 minutes while the condition is active. and if the condition changes during that time period it plays the new conditions file.

im going to sound like an idiot, but how should i go about that? i know how to specify global variables. but not store dynamic values.

The timer appears to be more trouble than it is worth. You can just manage your timing using millis.

tried that. can't get it to work right no matter what i do. upon boot of the device it plays the file but never repeats it.

something like this?

#include <M5Stack.h>
#include "utility/M5Timer.h"

char currentCharEffect = '\0'; // none
int currentVolume = 0; // OFF

M5Timer M5timer;

void playWAV (char effect, int volume)
{
  ...
}

void playCallback() {
  playWAV(currentCharEffect, currentVolume);
}

void setup() {
  M5.begin();
  M5timer.setTimeout(5000, playCallback);
}

void loop() {
  M5timer.run();
  // here some code modifying currentCharEffect and currentVolume
}

ok, now i am an idiot i should have thought of something like that :slight_smile: thank you!

we all started somewhere. Don't feel bad.

if you want to get rid of the timer, you can do this

#include <M5Stack.h>

char currentCharEffect = '\0'; // none
int currentVolume = 0; // OFF

unsigned long lastTrigger;
const unsigned long period = 5000;

void playWAV (char effect, int volume)
{
  ...
}

void setup() {
  M5.begin();
  lastTrigger = millis();
}

void loop() {
  if (millis() - lastTrigger >= period) {
    lastTrigger = millis();
    playWAV(currentCharEffect, currentVolume);
  }

  // here some code modifying currentCharEffect and currentVolume
}

It's marginally dirty though because it requires a couple of globals that would be better avoided. Of course, in a small Arduino program, it doesn't really matter.

I'll try that haven't had luck with Millis yet but we shall see

well, if you need to remember the current values, you'll need variables. with the millis() option they could be static to the loop if this is the only place they are being used, limited gain (and probably best if the business logic was in its own function so I think the globals are OK)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.