Go Down

Topic: Problem getting sound to play at the same time as counter  (Read 596 times) previous topic - next topic

philipedwards

Hi all,

Having problems getting a sound to play at the same time as the counter runs down on a Seven Segment display.

The counter runs down while the button is pressed. This is as it should be.

If I try to add a sound to play it plays once the button is released.

If I try adding the sound to play before the counter starts the display flashes rapidly on the static number, but when the button is pressed the counter counts down and the sound plays.

Once the button is released the display goes back to flashing rapidly.

The trigger state is LOW and HIGH when pressed, but I think the sound is trying to play over and over causing the screen to flash on and off rapidly. ( I added a long delay to find this out)

If I try to change anything else the display does not work correctly.

So basically how do I get the sound to play and the counter count down at the same time when the button is pressed.

This is the first time I have ever used a Seven Segment display.

Attached is the section of code causing problems. If you want to see the whole code please contact me.

Code: [Select]

  if (selectPushCounter == 0) {
               
  triggerState = digitalRead(triggerPin);
  clipState = digitalRead(clipSwitch);
    digitalWrite(LED, LOW);

 
  if (clipState == HIGH)          // Magazine Clip Inserted
//      pulse_fire_sound ();      // Pulse Sound - If placed here the counter flashes rapidly. When the Trigger is pressed the sound plays
{                                //  and the counter counts down as as it should, but when released the counter flashes rapidy again due to the state being LOW
  sevseg.setNumber(triggerPushCounter);   
  sevseg.refreshDisplay();
         
  if (triggerState == HIGH)
{
                 
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis >= interval1)
{       
  previousMillis = currentMillis;
  sevseg.setNumber(triggerPushCounter);
    pulse_fire_sound ();            // Pulse Sound - If placed here the counter displays correctly and decreases on Trigger Push but
  triggerPushCounter--;             // the sound plays AFTER the button is released         
  digitalWrite(LED, LOW);
                                                   
  while (triggerPushCounter <= -1)
{               
  triggerPushCounter++;   
}
}
  sevseg.refreshDisplay();
}
}
}
  pulse_empty_sound ();
  if (clipState == LOW)
{
  triggerPushCounter = 95;
  digitalWrite(LED, LOW);
  sevseg.setNumber(noAmmo,1);
  sevseg.refreshDisplay();





  ammo_out_sound ();
}         
Norfolk Bits

slipstick

Your code snippet doesn't include any of the functions that play the sounds and you've given no hint about what you are using to play these sounds...so I have no idea what might be wrong.

Please post the COMPLETE program but before you do please get rid of some of the useless empty lines and use the AutoFormat tool (Ctrl-T) so things line up properly.

Steve

philipedwards

Code: [Select]

#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#include <SPI.h>
#include <Wire.h>
#include <SevSeg.h>

#define STRIP_PIN A4
#define N_LEDS 1

#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, STRIP_PIN, NEO_GRB + NEO_KHZ800);

SevSeg sevseg;

const int triggerPin = A1;        // Weapon Fire Pin 15
const int clipSwitch = 5;         // Reload
const int selectPin = A0;         // Weapon Selector Pin 14

int noAmmo = 0;
unsigned long previousMillis = 0;
unsigned long previousMillis1 = 500;
long interval = 500;
long interval1 = 60;

int LED = 3;
int laserPin = A3;                 // Laser Pin 17

int clipState = 0;

unsigned long start_hold;
boolean allow = false;
int HOLD_DELAY = 2000;           // Sets the hold delay of switch for LED state change
int sw_laststate = LOW;

long TrackCounter = 0;
long TrackCounter1 = 0;

int selectPushCounter = 0;       // counter for the number of button presses weapon #1
int selectState = 0;             // current state of the button
int lastselectState = 0;         // previous state of the button
int val = 0;                     // status input   pin

int triggerPushCounter = 95;     // counter for the number of button presses weapon #2
int triggerState = 1;            // current state of the button

int grenadePushCounter = 5;
int grenadeState = 0;


void setup() {

  byte numDigits = 2;
  byte digitPins[] = {2, 3}; //Digit 1 - 15,  Digit 2 - 16
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13}; //  8-A,  9-B,  10-C,  11-D,  12-E,  13-F,  14-G,  45-DP (DO NOT USE PIN 45)
  byte hardwareConfig = COMMON_CATHODE; // See README.md for options
  //byte hardwareConfig = COMMON_ANODE; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = true; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = true; // Use 'true' if your decimal point doesn't exist or isn't connected

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, updateWithDelays, leadingZeros, disableDecPoint);

  sevseg.setBrightness(10);

  strip.begin();
  strip.show();

  delay(1000);

  pinMode(triggerPin, INPUT);                  // Fire Button
  pinMode(clipSwitch, INPUT);                  // Reload
  pinMode(selectPin, INPUT);                   // Select Button

  pinMode(laserPin, OUTPUT);                   // Red Laser
  pinMode(LED, OUTPUT);

  Serial.begin(9600);
  randomSeed(analogRead(6));
  mp3_set_serial (Serial);
  delay(10);

  mp3_set_volume (10);

  mp3_reset();
  delay(1000);

  mp3_play (19 );

}

void loop() {

  // Start of Weapon Select Button
  selectState = digitalRead(selectPin);
  if (selectState == HIGH && sw_laststate == LOW) {
    start_hold = millis();
    allow = true;
  }
  if (allow == false && selectState == HIGH && sw_laststate == HIGH) {
    if ((millis() - start_hold) >= HOLD_DELAY) {
      allow = false;
    }
  }
  if (allow == true && selectState == LOW && sw_laststate == LOW) {
    if ((millis() - start_hold) < 700 ) {

      mp3_play (12);

      selectPushCounter++;
      allow = false;
    }
  }
  sw_laststate = selectState;
  // End of Weapon Select Button


  //  ************************************   WEAPONS   ***************************************

  // -------------------------------- WEAPON 1 --- PULSE RIFLE --------------------------------

  if (selectPushCounter == 0) {

    triggerState = digitalRead(triggerPin);
    clipState = digitalRead(clipSwitch);
    digitalWrite(LED, LOW);
    if (clipState == HIGH)          // Magazine Clip Inserted
      //      pulse_fire_sound ();      // Pulse Sound - If placed here the counter flashes rapidly. When the Trigger is pressed the sound plays
    { //  and the counter counts down as as it should, but when released the counter flashes rapidy again due to the state being LOW
      sevseg.setNumber(triggerPushCounter);
      sevseg.refreshDisplay();
      if (triggerState == HIGH)
      {
        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis >= interval1)
        {
          previousMillis = currentMillis;
          sevseg.setNumber(triggerPushCounter);

          pulse_fire_sound ();            // Pulse Sound - If placed here the counter displays correctly and decreases on Trigger Push but
          pulse_laser_fire ();

          triggerPushCounter--;             // the sound plays AFTER the button is released
          digitalWrite(LED, LOW);
          while (triggerPushCounter <= -1)
          {
            triggerPushCounter++;
          }
        }
        sevseg.refreshDisplay();
      }
    }
  }
  pulse_empty_sound ();
  if (clipState == LOW)
  {
    triggerPushCounter = 95;
    digitalWrite(LED, LOW);
    sevseg.setNumber(noAmmo, 1);
    sevseg.refreshDisplay();

    ammo_out_sound ();
  }


  // -------------------------------- WEAPON 2 --- GRENADE LAUNCHER --------------------------------

  if (selectPushCounter == 1) {

    grenadeState = digitalRead(triggerPin);
    clipState = digitalRead(clipSwitch);
    digitalWrite(LED, LOW);
    if (clipState == HIGH)
    {
      sevseg.setNumber(grenadePushCounter);
      sevseg.refreshDisplay();
      if (grenadeState == HIGH)
      {
        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis1 >= interval)
        {
          previousMillis1 = currentMillis;
          sevseg.setNumber(grenadePushCounter);

          grenade_fire_sound ();

          grenadePushCounter--;
          digitalWrite(LED, HIGH);

          while (grenadePushCounter <= -1)
          {
            grenadePushCounter++;
          }
        }
        sevseg.refreshDisplay();
      }
    }
  }
  grenade_out_sound ();
  if (clipState == LOW)
  {
    grenadePushCounter = 5;
    digitalWrite(LED, LOW);
    sevseg.setNumber(noAmmo, 1);
    sevseg.refreshDisplay();
  }

  if (selectPushCounter > 1) {
    selectPushCounter = 0;
    selectState = 0;         // current state of the button
    lastselectState = 0;     // previous state of the button
    val = 0;                 // status input   pin
  }
}

// ********************* END 2 WEAPONS, RESTART VARIABLES *********************


// *********************************** FUNCTIONS *************************


bool pulse_empty_sound () {
  if (triggerPushCounter <= 0 && digitalRead(triggerPin) == HIGH) { // if BOTH the switches read HIGH
    mp3_play (20);
    delay (1000);
  }
}

bool grenade_out_sound () {
  if (grenadePushCounter <= 0 && digitalRead(triggerPin) == HIGH) { // if BOTH the switches read HIGH
    mp3_play (20);
    delay (1000);
  }
}

bool grenade_fire_sound () {
  if (grenadePushCounter >= 0 && digitalRead(triggerPin) == HIGH) {
    mp3_play (7);
  }
}
bool pulse_fire_sound () {

  if (triggerPushCounter >= 0)
    TrackCounter = random(0, 4);
  if ( TrackCounter == 0 )
  {
    mp3_play (1);
  }
  if ( TrackCounter == 1 )
  {
    mp3_play (2);
  }
  if ( TrackCounter == 2 )
  {
    mp3_play (3);
  }
  if ( TrackCounter == 3 )
  {
    mp3_play (4);
  }
  if ( TrackCounter == 4 )
  {
    mp3_play (5);
  }
}

void ammo_out_sound () {
  boolean play_state = digitalRead(clipSwitch);// connect Pin3 to BUSY pin of player
  if (play_state == HIGH) {
    mp3_play (14);
  }
}

static void pulse_chase(uint32_t c) {   // LED Chase Sequence
  strip.updateLength(1);
  strip.setBrightness(255);
  for (uint16_t i = 0; i < strip.numPixels() + 5; i++) {
    strip.setPixelColor(i  , c); // Draw new pixel
    strip.setPixelColor(i - 5, 0); // Erase pixel a few steps back

    strip.show();
    delay(2); // Speed
  }
}

void pulse_laser_fire () {
  digitalWrite(laserPin, HIGH);
  delay (1);
  digitalWrite(laserPin, LOW);
  delay (1);
}

void pulse_fire () {
  //  pulse_chase(strip.Color(255, 0, 0)); // Red
  //  strip.setPixelColor(1, 255, 0, 0);
  //  strip.show();
  //  delay (1);
  //  strip.setPixelColor(1, 0, 0, 0);
  //  strip.show();
  //  delay (1);
}
Norfolk Bits

philipedwards

This is still a work in progress, all the blank empty lines help me find parts of code and also while I edit it.

I'm no programmer, not by a mile, I basically take bits of code and try to put them together, at my age 60+ its a little too late to try to learn form the ground up.

I have managed to get everything else working as I want it too, but would just like the counter to count down whilst the Pulse Rifle sounds play (Button held Down) then stop when the button is released.

So if you can help please laymen's terms please with an explanation of how it works, this is how I learn.

Many thanks in advance to all.

Stay Safe everyone.
Norfolk Bits

slipstick

I don't know if it is anything to do with your problem but you're using a very old DF Mini Player library that was replaced years ago. The new library is a lot better but it works very differently so it would need code changes to all of the MP3 playing parts of your code.

Another thing I see is that some of your existing MP3 play functions contain long delays which stop anything else from happening while they run. That may be causing some problems. What happens if you take those delay(1000)s out? Mixing up delay() and millis() for the timing often causes all sorts of trouble.

You have 5 different variables called xxxxcounter. Which one is the counter you're talking about?

Steve

philipedwards

Many thanks Steve, will have a look at a newer DFPLayer library. Those 2 delays 1000 make no difference as they are only when no ammo.

It does all work but would just like to sound to play at the same time as the counter not after its counted down.

i will keep at it

Many thanks Phil
Norfolk Bits

MarkT

Its worth learning about state machines and state-transition diagrams, as they facilitate coding complex
behaviours - state transition diagrams are intuitive, and they map to code free from delays straightforwardly.

They also make it easy to have several bits of behaviour running in parallel independently.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Go Up