Sound friert bei einem Trigger Event ein

Hallo Leute

Ich versuche gerade mit dem Adafruit Music Maker Shield und FSR (Druckabhängige Widerstand) etwas aus. Meine Idee ist, mithilfe eines FSR's einen Sound abspielen zu lassen, sobald es eine bestimmte Widerstand (in meinem Beispiel 200) erkennt. Leider wird das Soundfile schnell hintereinander abgespielt und nach einer Zeit friert es ein und man hört nichts mehr. Wie kann ich dieses Problem lösen?

Vielen Dank im Voraus!

#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// These are the pins used for the breakout example
#define BREAKOUT_RESET  9      // VS1053 reset pin (output)
#define BREAKOUT_CS     10     // VS1053 chip select pin (output)
#define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)

// These are the pins used for the music maker shield
#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

// These are common pins between breakout and shield
#define CARDCS 4     // Card chip select pin

// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

Adafruit_VS1053_FilePlayer musicPlayer =
  // create breakout-example object!
  //Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
  // create shield-example object!
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

int fsrAnalogPin = 0;
int fsrReading;

void setup() {
  Serial.begin(9600);
  Serial.println("Adafruit VS1053 Simple Test");

  if (! musicPlayer.begin()) { // initialise the music player
    Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
    while (1);
  }
  Serial.println(F("VS1053 found"));

  if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    while (1);  // don't do anything more
  }

  // list files
  printDirectory(SD.open("/"), 0);

  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(20, 20);

  // Timer interrupts are not suggested, better to use DREQ interrupt!
  //musicPlayer.useInterrupt(VS1053_FILEPLAYER_TIMER0_INT); // timer int

  // If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background
  // audio playing
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int
  if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT)) {
    Serial.println(F("DREQ pin is not an interrupt pin"));
  }
}

void loop() {
  fsrReading = analogRead(fsrAnalogPin);
  Serial.print("Analog reading = ");
  Serial.println(fsrReading);

  if (fsrReading > 200) {
    musicPlayer.startPlayingFile("track001.mp3");
    Serial.println(F("Playing track001"));
  } else {
    musicPlayer.stopPlaying();
  }

  if (Serial.available()) {
    char c = Serial.read();

    // if we get an 's' on the serial console, stop!
    if (c == 's') {
      musicPlayer.stopPlaying();
    }

    // if we get an 'p' on the serial console, pause/unpause!
    if (c == 'p') {
      if (! musicPlayer.paused()) {
        Serial.println("Paused");
        musicPlayer.pausePlaying(true);
      } else {
        Serial.println("Resumed");
        musicPlayer.pausePlaying(false);
      }
    }
  }

  delay(100);
}


/// File listing helper
void printDirectory(File dir, int numTabs) {
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      //Serial.println("**nomorefiles**");
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

Du mußt auf die Flanke Triggern und nicht das Stück immer wieder aufrufen wenn der Analogwert unter dem Grenzwert ist.
Grüße Uwe

Wie bringe ich das Zustande? Versuche es schon seit 2h ohne Erfolg...

Mit einer Zustandsvariablen
siehe Switching Things On And Off With An Arduino | Martyn Currey

Grüße Uwe

Ok super danke! Mit der sogenannten State Change Detection (Edge Detection) funktioniert es, leider kann ich dies nur mit dem Digitalen Pins zustande bringen. Für mich wäre es interessant, je mehr Gewicht auf dem FSR registriert wird, desto lauter sollte die Musik sein.

JKR137:
Ok super danke! Mit der sogenannten State Change Detection (Edge Detection) funktioniert es, leider kann ich dies nur mit dem Digitalen Pins zustande bringen. Für mich wäre es interessant, je mehr Gewicht auf dem FSR registriert wird, desto lauter sollte die Musik sein.

Dann musst du die Auswertung in Abhängigkeit des analogen Wertes bringen.
Davon dann die Lautstärke abhängig machen.

Genau :slight_smile: die Frage ist nur mit welchem Code ich das hinbringen kann. Bin absolut ein neu in diesem Gebiet...

 musicPlayer.setVolume(fsreading/10, fsreading/10);

Im loop könnte vielleicht was bewirken

ElEspanol:

 musicPlayer.setVolume(fsreading/10, fsreading/10);

Im loop könnte vielleicht was bewirken

Cool! Komischerweise habe ich es nicht geschafft es umzukehren (bei 0 pressure = am leisesten bzw. kein ton mehr und bei Maximum pressure = max. volume). Wieso geht nicht: musicPlayer.setVolume(fsreading10, fsreading10)?

Ausserdem ist hier ein aktueller Code vom Projekt...

#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// These are the pins used for the breakout example
#define BREAKOUT_RESET  9      // VS1053 reset pin (output)
#define BREAKOUT_CS     10     // VS1053 chip select pin (output)
#define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)

// These are the pins used for the music maker shield
#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

// These are common pins between breakout and shield
#define CARDCS 4     // Card chip select pin

// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

Adafruit_VS1053_FilePlayer musicPlayer =
  // create breakout-example object!
  //Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
  // create shield-example object!
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);


int lastSensorState = LOW;   // sensor's previous state

void setup() {
  Serial.begin(9600);
  Serial.println("Adafruit VS1053 Simple Test");

  if (! musicPlayer.begin()) { // initialise the music player
    Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
    while (1);
  }
  Serial.println(F("VS1053 found"));

  if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    while (1);  // don't do anything more
  }

  // list files
  printDirectory(SD.open("/"), 0);

  // Set volume for left, right channels. lower numbers == louder volume!


  // Timer interrupts are not suggested, better to use DREQ interrupt!
  //musicPlayer.useInterrupt(VS1053_FILEPLAYER_TIMER0_INT); // timer int

  // If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background
  // audio playing
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int
  if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT)) {
    Serial.println(F("DREQ pin is not an interrupt pin"));
  }
}

void loop() {

  // read the sensor:
  int sensorState = analogRead(A0);
  int sensorState1 = analogRead(A1);

  musicPlayer.setVolume(sensorState / 10, sensorState / 10);

  if (sensorState > 500) {
    musicPlayer.startPlayingFile("track001.mp3");
    Serial.println(F("Playing track001"));
    if (lastSensorState < 500) {
      musicPlayer.stopPlaying();
    }
  }

  if (sensorState1 > 500) {
    musicPlayer.startPlayingFile("track002.mp3");
    Serial.println(F("Playing track002"));
    if (lastSensorState < 500) {
      musicPlayer.stopPlaying();
    }
  }

  Serial.println(sensorState);

  // save button state for next comparison:
  lastSensorState = sensorState, sensorState1;

  if (Serial.available()) {
    char c = Serial.read();

    // if we get an 's' on the serial console, stop!
    if (c == 's') {
      musicPlayer.stopPlaying();
    }

    // if we get an 'p' on the serial console, pause/unpause!
    if (c == 'p') {
      if (! musicPlayer.paused()) {
        Serial.println("Paused");
        musicPlayer.pausePlaying(true);
      } else {
        Serial.println("Resumed");
        musicPlayer.pausePlaying(false);
      }
    }
  }

  delay(100);
}


/// File listing helper
void printDirectory(File dir, int numTabs) {
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      //Serial.println("**nomorefiles**");
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

leider gibt es immer noch Probleme beim sound triggern. Ich muss den FSR loslassen, damit der soundfile abgespielt wird... ich möchte, dass ab 500 den soundfile abspielt (gedrückt halten) und beim loslassen = stoppt bzw. 0 volume hat.

Was erwartet den musicPlayer.setVolume für einen Wertebereich?

Du musst vermeiden, dass das Soundfile immer wieder neu gestartet wird, wenn du über 500 bist. Das ist dein momentanes Problem.

ElEspanol:
Was erwartet den musicPlayer.setVolume für einen Wertebereich?

Du musst vermeiden, dass das Soundfile immer wieder neu gestartet wird, wenn du über 500 bist. Das ist dein momentanes Problem.

musicPlayer.setVolume is das maximale Wert 20.

Ja genau... das ist das problem, nun weiss ich nicht wie ich den Code verbessern kann... finde einfach keine Lösung und bin seit 1 Tag schon fast dran.

JKR137:
Ok super danke! Mit der sogenannten State Change Detection (Edge Detection) funktioniert es, leider kann ich dies nur mit dem Digitalen Pins zustande bringen.

wieso?

Es ist doch kein Unterschied

ob Du ein digitales Pin LOW und HIGH kontrollierst
oder ein analoges Pin das > x oder <= x ist.

Grüße Uwe

uwefed:
wieso?

Es ist doch kein Unterschied

ob Du ein digitales Pin LOW und HIGH kontrollierst
oder ein analoges Pin das > x oder <= x ist.

Grüße Uwe

stimmt, sieht bei mir momentan so aus:

 if (sensorState >= 500) {
    musicPlayer.startPlayingFile("track001.mp3");
    Serial.println(F("Playing track001"));
    if (lastSensorState <= 500) {
      musicPlayer.stopPlaying();
    }
  }

Leider wird das Soundfile immer wieder neu gestartet, wenn ich über dem Wert 500 bin. Was mache ich falsch?

Das gleiche wie schon am Anfang. Du musst einen Merker setzen, dass das Soundfile schon läuft, und es nur starten wenn

sensorstate < 500 && spielt_ab==0

So ähnlich:

bool spielt_ab=0;

.......

if (sensorState >= 500 && merker==0) {
    musicPlayer.startPlayingFile("track001.mp3");
    spielt_ab=1;
    Serial.println(F("Playing track001"));

  }

    if (lastSensorState <= 500) {
      musicPlayer.stopPlaying();
      spielt_ab=0;
    }

Aus irgendwelchem Grund kann ich nur den Sound abspielen, wenn ich beide sensoren drücke?! Habe ich was übersehen?

  if (sensorState > 500 && trigger == false) {
    musicPlayer.startPlayingFile("track001.mp3");
    trigger = true;
    Serial.println(F("Playing track001"));
  } else if  (sensorState < 500 && trigger == true) {
    musicPlayer.stopPlaying();
    trigger = false;
    Serial.println(F("Stop track001"));
  }

  if (sensorState1 > 500 && trigger == false) {
    musicPlayer.startPlayingFile("track002.mp3");
    trigger = true;
    Serial.println(F("Playing track002"));
  } else if  (sensorState1 < 500 && trigger == true) {
    musicPlayer.stopPlaying();
    trigger = false;
    Serial.println(F("Stop track002"));
  }

Dann musst Du das laufende MP3 stoppen und das andere starten.

Gruß Tommy

Deine if ist falsch verschachtelt.
Da geht es rein, wenn >500, die darin befindliche if mit <500 wird dann nie ausgeführt

ElEspanol:
Deine if ist falsch verschachtelt.
Da geht es rein, wenn >500, die darin befindliche if mit <500 wird dann nie ausgeführt

Bei sensorState funktioniert es perfekt aber leider nicht bei sensorState1. Könntest
du den Code korrigieren? Verstehe es nicht ganz genau, wo der Fehler liegt.

  if (sensorState > 500 && trigger == false) {
    musicPlayer.startPlayingFile("track001.mp3");
    trigger = true;
    Serial.println(F("Playing track001"));
  } else  if (sensorState1 > 500 && trigger == false) {
    musicPlayer.startPlayingFile("track002.mp3");
    trigger = true;
    Serial.println(F("Playing track002"));
  } else if (sensorState < 500 && trigger == true) {
    musicPlayer.stopPlaying();
    trigger = false;
    Serial.println(F("Stop track001"));
  }
if (sensorState1 > 500 && trigger == false) {
    musicPlayer.startPlayingFile("track002.mp3");
    trigger = true;
    Serial.println(F("Playing track002"));
  } 

  if (sensorState > 500 && trigger == false) {
    musicPlayer.startPlayingFile("track001.mp3");
    trigger = true;
    Serial.println(F("Playing track001"));
  } 



if (sensorState < 500 && trigger == true) {
    musicPlayer.stopPlaying();
    trigger = false;
    Serial.println(F("Stop"));
  }

Probier mal so