Sound for model railroading scale 1/32

Status
Not open for further replies.
Hi,
I try now to mix in "one" code on Teensy 3.2 the following functions :
1) DCC frame decoding function + engine commands+ Leds commands (works well separatly)
2) Sound function (works well separatly)

As result (code hereafter) and when I command a sound (duration 5 seconds) :
- DCC frame decoding (partially) stops.
- Then sound is played during 5 seconds, then DCC frame is partially decoded .......

I wonder if it exists a method (interruption ??) in order to decode DCC frame and plays sound at the same time ?
Code:
#include <NmraDcc.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

#define This_Decoder_Address 3
const int FLASH_CHIP_SELECT = 10;  // SPI Flash Chip Select (CS)
// GUItool: begin automatically generated code (Audio.h)
    AudioPlaySerialflashRaw  playFlashRaw1;  //xy=228,273
    AudioOutputAnalog        dac1;           //xy=751,337
    AudioConnection          patchCord1(playFlashRaw1, 0, dac1, 0);
// GUItool: end automatically generated code

struct CVPair
{
  uint16_t  CV;
  uint8_t   Value;
};
CVPair FactoryDefaultCVs [] =
{
//	// The CV Below defines the Short DCC Address
  {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address},

  // These two CVs define the Long DCC Address
  {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
  {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address},

// ONLY uncomment 1 CV_29_CONFIG line below as approprate
  {CV_29_CONFIG,                                      0}, // Short Address 14 Speed Steps
  {CV_29_CONFIG,                       CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps

  {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long  Address 28/128 Speed Steps 
};

NmraDcc  Dcc ;
uint8_t FactoryDefaultCVIndex = 0;

void notifyCVResetFactoryDefault()
{
//   Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset
//   to flag to the loop() function that a reset to Factory Defaults needs to be done
  FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair);
};

// Uncomment the #define below to print all Speed Packets
#define NOTIFY_DCC_SPEED
#ifdef  NOTIFY_DCC_SPEED
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps )
{
  Serial.print("notifyDccSpeed: Addr: ");
  Serial.print(Addr,DEC);
  Serial.print( (AddrType == DCC_ADDR_SHORT) ? "-S" : "-L" );
  Serial.print(" Speed: ");
  Serial.print(Speed,DEC);
  Serial.print(" Steps: ");
  Serial.print(SpeedSteps,DEC);
  Serial.print(" Dir: ");
  Serial.println( (Dir == DCC_DIR_FWD) ? "Forward" : "Reverse" );
};
#endif

// Uncomment the #define below to print all Function Packets
#define NOTIFY_DCC_FUNC
#ifdef  NOTIFY_DCC_FUNC
  void notifyDccFunc(uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)
  {

      Serial.print("notifyDccFunc: Addr: ");
      Serial.print(Addr,DEC);
      Serial.print( (AddrType == DCC_ADDR_SHORT) ? 'S' : 'L' );
      Serial.print("  Function Group: ");
      Serial.print(FuncGrp,DEC);

    switch( FuncGrp ){
   {
      #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE   
           case FN_0:
           Serial.print(" FN0: ");
           Serial.println((FuncState & FN_BIT_00) ? "1  " : "0  ");
           break;
      #endif
 
     case FN_0_4:
       if(Dcc.getCV(CV_29_CONFIG) & CV29_F0_LOCATION) // Only process Function 0 in this packet if we're not in Speed Step 14 Mode
       {
         Serial.print(" FN 0: ");
         Serial.print((FuncState & FN_BIT_00) ? "1  ": "0  ");
       }
   }
         Serial.print("FuncState:");
         Serial.print(FuncState);
         Serial.print("FN_BIT_00:");
         Serial.print(FN_BIT_00);

 //   Test Sound       
               if( (FuncState & FN_BIT_01) == 1){
               Serial.print("CabinLight:");
               playFile1("A0AB814.TRW");

              }
//               else
//              analogWrite(CabinLight,0);

        Serial.print(" FN 1-4: ");
        Serial.print((FuncState & FN_BIT_01) ? "1  ": "0  ");
        Serial.print((FuncState & FN_BIT_02) ? "1  ": "0  ");
        Serial.print((FuncState & FN_BIT_03) ? "1  ": "0  ");
        Serial.println((FuncState & FN_BIT_04) ? "1  ": "0  ");
       break;
     
     case FN_5_8:
         Serial.print(" FN 5-8: ");
         Serial.print((FuncState & FN_BIT_05) ? "1  ": "0  ");
        Serial.print((FuncState & FN_BIT_06) ? "1  ": "0  ");
        Serial.print((FuncState & FN_BIT_07) ? "1  ": "0  ");
        Serial.println((FuncState & FN_BIT_08) ? "1  ": "0  ");
       break;
   
     case FN_9_12:
       Serial.print(" FN 9-12: ");
       Serial.print((FuncState & FN_BIT_09) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_10) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_11) ? "1  ": "0  ");
       Serial.println((FuncState & FN_BIT_12) ? "1  ": "0  ");
       break;

     case FN_13_20:
       Serial.print(" FN 13-20: ");
       Serial.print((FuncState & FN_BIT_13) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_14) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_15) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_16) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_17) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_18) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_19) ? "1  ": "0  ");
       Serial.println((FuncState & FN_BIT_20) ? "1  ": "0  ");
       break;
 
     case FN_21_28:
       Serial.print(" FN 21-28: ");
       Serial.print((FuncState & FN_BIT_21) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_22) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_23) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_24) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_25) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_26) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_27) ? "1  ": "0  ");
       Serial.println((FuncState & FN_BIT_28) ? "1  ": "0  ");
       break; 
    }
}

#endif

// Uncomment the #define below to print all DCC Packets
#define NOTIFY_DCC_MSG
#ifdef  NOTIFY_DCC_MSG
    void notifyDccMsg( DCC_MSG * Msg)
    {
        Serial.print("notifyDccMsg: ");
        for(uint8_t i = 0; i < Msg->Size; i++)
        {
          Serial.print(Msg->Data[i], HEX);
          Serial.write(' ');
        }
        Serial.println();
    }

#endif

void setup()
{
    Serial.begin(9600); // Serial setup
    while (!Serial && millis()<500 );
    AudioMemory(50);//
    analogReference(EXTERNAL);// 3,3V
    Serial.println("NMRA Dcc Multifunction Decoder - Teensy - Spi Flash");
 
//********Set up SPI Teensy without audio Card*******************
  SPI.setMOSI(11); //7
  SPI.setMISO(12);
  SPI.setSCK(14);
    delay(2000);
     if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
        while (1){
            Serial.println ("Cannot access SPI Flash chip");
            delay (10000);
        }
    }
    // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
  Dcc.pin(0, 0, 0);// Pin 0= Interrupt 0
 
  // Call the main DCC Init function to enable the DCC Receiver
  Dcc.init( MAN_ID_DIY, 10, FLAGS_MY_ADDRESS_ONLY, 0 );

  // Uncomment to force CV Reset to Factory Defaults
  notifyCVResetFactoryDefault();
   }

void loop()
{
  // You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
  Dcc.process();

  if( FactoryDefaultCVIndex && Dcc.isSetCVReady())
  {
    FactoryDefaultCVIndex--; // Decrement first as initially it is the size of the array
    Dcc.setCV( FactoryDefaultCVs[FactoryDefaultCVIndex].CV, FactoryDefaultCVs[FactoryDefaultCVIndex].Value);
  }
}
// ***********Spi Soundfile Read Function***************
    void playFile1(const char *filename)// Play audio file function
    {
      SerialFlashFile ff = SerialFlash.open(filename);
      Serial.print("Playing file1: ");
      Serial.println(ff);
      playFlashRaw1.play(filename);
     // Simply wait for the file to finish playing.
     while (playFlashRaw1.isPlaying()) {
     }
    }

// ********************************************

https://github.com/mrrwa/NmraDcc/blob/master/NmraDcc.h
https://github.com/mrrwa/NmraDcc
 
Just an idea in between: A steam engine can be simulated when using a simple noise generator with LFSR-noise generator and modulation it's volume with a LFO and an overlay of an EQ emphesizing the lower frequencies.
 
Just an idea in between: A steam engine can be simulated when using a simple noise generator with LFSR-noise generator and modulation it's volume with a LFO and an overlay of an EQ emphesizing the lower frequencies.
Thanks,
I try to have the same hardware for different types of engine (Diesel, Steam, Electric).
Moreover, I need to generate special sounds (horn, bell, coupling, brake, . . . ).

I tried to use only one Teensy 3.2 to command both : Sound and DCC protocol decoding.
But, in fact, Sound generating (Audio.h) cuts the DCC protocol decoding (NmraDcc.h).

So, I try now with an Arduino Nano for Dcc Decoding and the Teensy 3.2 for sound generating.
Arduino Nano sends commands (soundfiles to read ) to Teensy 3.2 via serial link (Rx Tx).
(How to smash a fly with a hammer !!!)
 
Status
Not open for further replies.
Back
Top