TMRpcm & ISR(TIMER1_CAPT_vect)

Saludos comunidad... Estoy luchando y no encuentro solución. La idea es unir la lectura de un SMPTE timecode y hacer play de algunos archivos en una SDCard
Al tratar de leer / escribir un vector que almacena el codigo de tiempo, el audio no se reproduce mas.
Aquí, parte del código compilado para Arduino UNO...

#define icpPin                8   // ICP input pin on arduino
#define one_time_max          600  // 600 these values are setup for NTSC video
#define one_time_min          300  // 400 PAL would be around 1000 for 0 and 500 for 1
#define zero_time_max         1200 // 1050 80 bits times 29.97 frames per sec
#define zero_time_min         700  // 950 equals 833 (divide by 8 clock pulses)
                                 
#define end_data_position      63
#define end_sync_position      77
#define end_smpte_position     80

#include <SD.h>               // need to include the SD library
#define SD_ChipSelectPin 10   //using digital pin 4 on arduino nano 328
#include <TMRpcm.h>           //  also need to include this library...
#include <SPI.h>
#include <SoftwareSerial.h>

#define CLR(x, y) (x &= (~(1<<y)))
#define SET(x, y) (x |= (1<<y))

#define d0 2
#define d1 9//3 // 3 es pata 5 - 9 que es pata 15
#define d2 4
#define in A0

#define inh1 A1
#define inh2 A2
#define inh3 A3
#define inh4 A4

#define Tx 7        
#define Rx A5//8      
//********************************************************
volatile char timeCode[11];
volatile unsigned int bit_time;
volatile unsigned int bit_time_min = 1000;
volatile unsigned int bit_time_max = 0;
volatile boolean valid_tc_word;
volatile boolean ones_bit_count;
volatile boolean tc_sync;
volatile boolean write_tc_out;
volatile boolean drop_frame_flag;

volatile byte total_bits;
volatile byte current_bit;
volatile byte sync_count;


SoftwareSerial serie(Rx, Tx);   
  
TMRpcm tmrpcm;
int  lastInput;
byte lastD0 = 0, lastD1 = 0;


void setup()
{
  pinMode(icpPin, INPUT);                  // ICP pin (digital pin 8 on arduino) as input

  bit_time = 0;
  valid_tc_word = false;
  ones_bit_count = false;
  tc_sync = false;
  write_tc_out = false;
  drop_frame_flag = false;
  total_bits =  0;
  current_bit =  0;
  sync_count =  0;

  delay (200);

  TCCR1A = B00000000; // clear all
  TCCR1B = B11000010; // ICNC1 noise reduction + ICES1 start on rising edge + CS11 divide by 8
  TCCR1C = B00000000; // clear all
  TIMSK1 = B00100000; // ICIE1 enable the icp
  TCNT1 = 0; // clear timer1
  pinMode(d0, OUTPUT);
  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(in, INPUT);
  pinMode(inh1, OUTPUT);
  pinMode(inh2, OUTPUT);
  pinMode(inh3, OUTPUT);
  pinMode(inh4, OUTPUT);
 
  tmrpcm.speakerPin = 3;
  
  Serial.begin(115200);
  serie.begin(115200);
  Serial.println("Finished setup... ");
  if (!SD.begin(SD_ChipSelectPin)) 
  {  
    Serial.println("SD fail");  
  }
  tmrpcm.play("UnoF.wav");
  delay(500);
  tmrpcm.play("DosM.wav");
  delay(500);
  tmrpcm.play("DosF.wav");
}
void loop()
{
  if (write_tc_out)
  {
    write_tc_out = false;
    if (drop_frame_flag) Serial.print("TC DROP FRAME");
    if (!drop_frame_flag) Serial.print("TC NO DROP FRAME");
    Serial.print((char*)timeCode);
    Serial.print("\r\n");
    Serial.println("......");
    delay (40);
  }
  if (lastInput != readInput())
  {
    unsigned long inicio = millis();
      cli();sei();
    switch(readInput())
    {
      case 1:
      { 
        lastInput = 1;
        player(1);
        serie.write(lastInput);
        break;
      } 
      case 2:
      { 
        lastInput = 2;
        player(2);
        serie.write(lastInput);
        break;
      } 
    }
  }
  if(serie.available()>0)
  {
    byte dato[3];
    serie.readBytes(dato, 3);
    if(dato[0]<32 && dato[1]<32 && dato[2]<32)
    {
      if(lastD0 != dato[0]) 
      { 
        lastD0 = dato[0];
        player(dato[0]);
      }
      if(lastD1 != dato[1])
      {
        lastD1 = dato[1];
        player(dato[1]+16);
      }
    }
  }
}
int readInput()
{
  CLR(PORTC, 1) ;
  SET(PORTC, 2) ;
  SET(PORTC, 3) ;
  SET(PORTC, 4) ;
  switch (switchIn())
  {
    case 1: return 1; break;
    case 2: return 2; break;
    case 3: return 3; break;
    case 4: return 4; break;
  }
}
//*******************************************************************
int switchIn()
{
  CLR(PORTD, 2) ;
  CLR(PORTB, 1);//CLR(PORTD, 3) ;// Cambia por B1
  CLR(PORTD, 4) ;
  delay(1);
  if (digitalRead(in))  return 1;

  SET(PORTD, 2) ;
  CLR(PORTB, 1);//CLR(PORTD, 3) ;
  CLR(PORTD, 4) ;
  delay(1);
}

void player(byte num)
{
  switch (num)
  {
    case 1: 
    {
      tmrpcm.play("UnoM.wav");    
      delay(10);
      break;
    }
    case 2: 
    {
      tmrpcm.play("DosM.wav"); 
      delay(10);
      break;
    }
  }
}

ISR(TIMER1_CAPT_vect)
{
  byte tc[8];
  int lastTime = 0;
  int time = micros();
  TCCR1B ^= _BV(ICES1);
  bit_time = ICR1;
  TCNT1 = 0;  //resetTimer1
  if(bit_time < bit_time_min && bit_time > one_time_min) bit_time_min = bit_time;
  if(bit_time > bit_time_max && bit_time < zero_time_max) bit_time_max = bit_time;
  if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // 
  {
    total_bits = 0;
  }
  else
  {
    if (ones_bit_count == true) ones_bit_count = false;
    else
    {
      if (bit_time > zero_time_min)
      {
        current_bit = 0;
        sync_count = 0;
      }
      else //if (bit_time < one_time_max)
      {
        ones_bit_count = true;
        current_bit = 1;
        sync_count++;
        if (sync_count == 12)
        { 
          sync_count = 0;
          tc_sync = true;
          total_bits = end_sync_position;
        }
      }
      if (total_bits <= end_data_position) // timecode runs least to most so we need
      {                                    // to shift things around
        tc[0] = tc[0] >> 1;
        for(int n=1; n<8; n++)
        {
          if(tc[n] & 1) tc[n-1] |= 0x80;
          tc[n] = tc[n] >> 1;
        }
        if(current_bit == 1)tc[7] |= 0x80;
      }
      total_bits++;
    }
    if (total_bits == end_smpte_position)
    {
      total_bits = 0;
      if (tc_sync)
      {
        tc_sync = false;
        valid_tc_word = true;
        lastTime = time;
      }
    }
    if (valid_tc_word)
    {
      valid_tc_word = false;
      timeCode[10] = (tc[0]&0x0F)+0x30;      
      timeCode[9]  = (tc[1]&0x03)+0x30;
      timeCode[8]  =  ':';
      timeCode[7]  = (tc[2]&0x0F)+0x30;
      timeCode[6]  = (tc[3]&0x07)+0x30;
      timeCode[5]  =  ':';
      timeCode[4]  = (tc[4]&0x0F)+0x30;
      timeCode[3]  = (tc[5]&0x07)+0x30;
      timeCode[2]  = ':';
      timeCode[1]  = (tc[6]&0x0F)+0x30;
      timeCode[0]  = (tc[7]&0x03)+0x30;
      
      if(tc[1]&0x04) drop_frame_flag = true;
      else drop_frame_flag = false;
      write_tc_out = true;
    }
  }
}

Este es el código ... cuando hago algo con el array timeCode[XX] el sonido desaparece ...
Estoy perdido ... ¿Podrían darme una mano ???

Lee las Normas del foro.
Luego ve a More (abajo a la derecha), click, luego Modify y estas en modo EDICION.
Selecciona todo el código y click en </> arriba del emoticon

Cuando el código se lea debidamente te respondo.

ariel_ba:
Estoy perdido ... ¿Podrían darme una mano ???

Lo mismo digo yo.

Primero: si es un código de ejemplo, de dónde lo sacaste?
Segundo: ni me compila por lo siguiente:

if (lastInput != readInput())
  {
    unsigned long inicio = millis();
    cli(); sei(); // WTF???
    {
      case 1:
        {
          lastInput = 1;
          player(1);
          serie.write(lastInput);
          break;
        }
      case 2:
        {
          lastInput = 2;
          player(2);
          serie.write(lastInput);
          break;
        }
    }
  }

Esto debería sea una sentencia switch, pero... se compara qué con qué?

Cuatro razones por las cuales la reproducción con TMRpcm parece detenerse:

  • Intentar reproducir un archivo mientras se está reproduciendo otro.
  • Intentar acceder a un archivo de la tarjeta SD, mientras algo se está reproduciendo.
  • Intentar utilizar speakerPin para otros propósitos, sin haber llamado a disable anteriormente.
  • Alguna interrupción que tarde más que el periodo de la frecuencia de muestreo a la que se reproduce el archivo; aunque en teoría continúa una vez la interrupción acabe.

Todo gira en torno a esta librería de TMRh20 TMRpcm
Acá hay un código bastante similar con explicaciones.