¿Reproducción de archivos de audio WAV desde una tarjeta SD en el tablero de cableado?

2

Estoy usando Wiring framework para crear un reloj de alarma personalizado. Hasta ahora, he podido trabajar con varias bibliotecas de Arduino en Wiring, solo por incluir Wiring.h en lugar de Arduino.h, como sugiere el creador de Wiring.

En cuanto al audio, he usado la biblioteca TMRpcm en Arduino Uno con éxito. Uno necesita tener una SD o una micro SD configurada, convertir los archivos de audio a un formato específico (WAV, 8 bits, 16 kHz), opcionalmente hacer un circuito amplificador y similares. Ya he hecho eso. Todos los trabajos en el mencionado Arduino.

Sin embargo, dado que Wiring S me da el doble de memoria que Arduino Uno (mi script ya supera la memoria de Arduino UNO), me gustaría implementar mi proyecto en Wiring. Estoy trabajando con un Wiring S , Wiring v.1.0.1-dev como IDE, y ya he cambiado todo include <Arduino.h> por include <Wiring.h> en todos los archivos de la biblioteca TMRpcm.

Cuando ejecuto el ejemplo básico (ajustando el archivo de audio el nombre y la configuración de SD_ChipSelectPin en 20 y el pin del altavoz en 16) Recibo el siguiente mensaje de error:

core.a(WHardwareTimer.cpp.o): In function '__vector_15':
C:\Users\toshiba\Downloads\wiring-v1.0.1-dev\cores\AVR8Bit/WHardwareTimer.cpp:140: multiple definition of '__vector_15'
TMRpcm\TMRpcm.cpp.o:C:\Users\toshiba\Downloads\wiring-v1.0.1-dev\libraries\TMRpcm/TMRpcm.cpp:650: first defined here
core.a(WHardwareTimer.cpp.o): In function '__vector_12':
C:\Users\toshiba\Downloads\wiring-v1.0.1-dev\cores\AVR8Bit/WHardwareTimer.cpp:145: multiple definition of '__vector_12'
TMRpcm\TMRpcm.cpp.o:C:\Users\toshiba\Downloads\wiring-v1.0.1-dev\libraries\TMRpcm/TMRpcm.cpp:569: first defined here
collect2.exe: error: ld returned 1 exit status

Si comento estas definiciones en la biblioteca (archivo TMRpcm.cpp) o en el archivo WHardwareTimer.cpp incluido en Wiring, el código se compila y puedo subirlo a mi Wiring S, pero el archivo de audio no se reproduce o no puede ser escuchado

Aquí puede obtener un archivo de audio de muestra de 31 KB (ya convertido al formato requerido).

¿Podría por favor ayudarme a resolver este problema? ¿Qué me estoy perdiendo? Puedo proporcionarle más detalles si es necesario.

    
pregunta Germán Carrillo

1 respuesta

1

Para completar, puede averiguar que los errores están relacionados con las interrupciones por el hecho de que los nombres de funciones a los que se hace referencia en el error son __vector_(n) , estos se refieren a vectores de interrupción específicos. Para saber exactamente cuáles debe consultar la tabla de vectores en la hoja de datos de AVR. Para ser torpe, en el código compilado los vectores están indexados a 0, pero en la hoja de datos están indexados a 1, para identificar el vector correcto, agregue 1 al (n) en el mensaje de error y búsquelo en la hoja de datos.

Para el ATMega644 (P):

__vector_15 is ISR(TIMER1_OVF_vect)
__vector_12 is ISR(TIMER1_CAPT_vect)

Por lo tanto, son vectores para el desbordamiento del temporizador 1 y la captura de entrada. Creo en el Arduino Core estándar, esto no está en uso, pero en el núcleo de Wiring S ya debe ser usado por algo.

La buena noticia es que ATMega1284 (p) funcionará con el núcleo estándar de Arduino, aunque de manera no oficial. Como el 644 (p) es de la misma serie, solo uno anterior, el núcleo de Arduino debería funcionar sin modificaciones con el 644. Las únicas dos cosas que se requieren son:

  1. Una entrada Boards.txt
  2. Un archivo pins_arduino.h

Al crear estas entradas, debería poder compilar el código para la placa WiringS utilizando el IDE y el núcleo estándar de Arduino (para el que se diseñó la biblioteca).

Para la entrada boards.txt, lo siguiente debería funcionar:

wiring_s.name=Wiring S @ 16 MHz
wiring_s.upload.tool=avrdude 
wiring_s.upload.protocol=wiring 
wiring_s.upload.maximum_size=63488 
wiring_s.upload.maximum_data_size=4096
wiring_s.upload.speed=115200 

wiring_s.bootloader.tool=avrdude 
wiring_s.bootloader.low_fuses=0xF7 
wiring_s.bootloader.high_fuses=0xD4 
wiring_s.bootloader.extended_fuses=0xFD 
wiring_s.bootloader.unlock_bits=0x3F
wiring_s.bootloader.lock_bits=0x2F 
wiring_s.bootloader.file=Wiring/WiringBoot_WiringS.hex 

wiring_s.build.mcu=atmega644p 
wiring_s.build.f_cpu=16000000L 
wiring_s.build.board=AVR_WIRINGS 
wiring_s.build.core=arduino 
wiring_s.build.variant=wirings

Para el archivo pins_arduino.h, cree una carpeta de 'cableados' dentro de la carpeta 'variantes' del núcleo de Arduino, luego cree un archivo pins_arduino.h con el siguiente contenido:

#ifndef Pins_Arduino_h
#define Pins_Arduino_h

#include <avr/pgmspace.h>

// ATMEL ATMEGA644/644P
//
//                       +---\/---+
//          (D 16) PB0 1 |        | 40 PA0 (D 24) AI 0
//          (D 17) PB1 2 |        | 39 PA1 (D 25) AI 1
//     INT2 (D 18) PB2 3 |        | 38 PA2 (D 26) AI 2
//      PWM (D 19) PB3 4 |        | 37 PA3 (D 27) AI 3
//   PWM/SS (D 20) PB4 5 |        | 36 PA4 (D 28) AI 4
//     MOSI (D 21) PB5 6 |        | 35 PA5 (D 29) AI 5
// PWM/MISO (D 22) PB6 7 |        | 34 PA6 (D 30) AI 6
//  PWM/SCK (D 23) PB7 8 |        | 33 PA7 (D 31) AI 7
//                 RST 9 |        | 32 AREF
//                VCC 10 |        | 31 GND 
//                GND 11 |        | 30 AVCC
//              XTAL2 12 |        | 29 PC7 (D 15) 
//              XTAL1 13 |        | 28 PC6 (D 14) 
//      RX0 (D 0) PD0 14 |        | 27 PC5 (D 13) TDI
//      TX0 (D 1) PD1 15 |        | 26 PC4 (D 12) TDO
// INT0 RX1 (D 2) PD2 16 |        | 25 PC3 (D 11) TMS
// INT1 TX1 (D 3) PD3 17 |        | 24 PC2 (D 10) TCK
//      PWM (D 4) PD4 18 |        | 23 PC1 (D  9) SDA
//      PWM (D 5) PD5 19 |        | 22 PC0 (D  8) SCL
//      PWM (D 6) PD6 20 |        | 21 PD7 (D  7) PWM
//                       +--------+
//


#define NUM_DIGITAL_PINS            32
#define NUM_ANALOG_INPUTS           8
#define analogInputToDigitalPin(p)  ((p < 8) ? (p) + 24 : -1)

#define digitalPinHasPWM(p)         ((p) == 4 || (p) == 5 || (p) == 6 || (p) == 7 || (p) == 19 || (p) == 20 || (p) == 22 || (p) == 23)

#define digitalPinToAnalogPin(p)    ( (p) >= 24 && (p) <= 31 ? (p) - 24 : -1 )
#define analogPinToChannel(p)        ( (p) < NUM_ANALOG_INPUTS ? (p) : -1)

static const uint8_t SS   = 20;
static const uint8_t MOSI = 21;
static const uint8_t MISO = 22;
static const uint8_t SCK  = 23;

static const uint8_t SDA = 9;
static const uint8_t SCL = 8;
static const uint8_t LED = 15;

static const uint8_t A0 = 24;
static const uint8_t A1 = 25;
static const uint8_t A2 = 26;
static const uint8_t A3 = 27;
static const uint8_t A4 = 28;
static const uint8_t A5 = 29;
static const uint8_t A6 = 30;
static const uint8_t A7 = 31;

#ifdef ARDUINO_MAIN

// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] =
{
    NOT_A_PORT,
    (uint16_t) &DDRA,
    (uint16_t) &DDRB,
    (uint16_t) &DDRC,
    (uint16_t) &DDRD,
};

const uint16_t PROGMEM port_to_output_PGM[] =
{
    NOT_A_PORT,
    (uint16_t) &PORTA,
    (uint16_t) &PORTB,
    (uint16_t) &PORTC,
    (uint16_t) &PORTD,
};

const uint16_t PROGMEM port_to_input_PGM[] =
{
    NOT_A_PORT,
    (uint16_t) &PINA,
    (uint16_t) &PINB,
    (uint16_t) &PINC,
    (uint16_t) &PIND,
};

const uint8_t PROGMEM digital_pin_to_port_PGM[NUM_DIGITAL_PINS] =
{
  PD, // D0
  PD, // D1
  PD, // D2
  PD, // D3
  PD, // D4
  PD, // D5
  PD, // D6
  PD, // D7
  PC, // D8
  PC, // D9
  PC, // D10
  PC, // D11
  PC, // D12
  PC, // D13
  PC, // D14
  PC, // D15
  PB, // D16
  PB, // D17
  PB, // D18
  PB, // D19
  PB, // D20
  PB, // D21
  PB, // D22
  PB, // D23
  PA, // D24
  PA, // D25
  PA, // D26
  PA, // D27
  PA, // D28
  PA, // D29
  PA, // D30
  PA, // D31
};

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[NUM_DIGITAL_PINS] =
{
  _BV(0), // D0 PD0
  _BV(1), // D1 PD1
  _BV(2), // D2 PD2
  _BV(3), // D3 PD3
  _BV(4), // D4 PD4
  _BV(5), // D5 PD5
  _BV(6), // D6 PD6
  _BV(7), // D7 PD7
  _BV(0), // D8 PC0
  _BV(1), // D9 PC1
  _BV(2), // D10 PC2
  _BV(3), // D11 PC3
  _BV(4), // D12 PC4
  _BV(5), // D13 PC5
  _BV(6), // D14 PC6
  _BV(7), // D15 PC7
  _BV(0), // D16 PB0
  _BV(1), // D17 PB1
  _BV(2), // D18 PB2
  _BV(3), // D19 PB3
  _BV(4), // D20 PB4
  _BV(5), // D21 PB5
  _BV(6), // D22 PB6
  _BV(7), // D23 PB7
  _BV(0), // D24 PA0
  _BV(1), // D25 PA1
  _BV(2), // D26 PA2
  _BV(3), // D27 PA3
  _BV(4), // D28 PA4
  _BV(5), // D29 PA5
  _BV(6), // D30 PA6
  _BV(7), // D31 PA7
};

const uint8_t PROGMEM digital_pin_to_timer_PGM[NUM_DIGITAL_PINS] =
{
  NOT_ON_TIMER, // D0 PD0
  NOT_ON_TIMER, // D1 PD1
  NOT_ON_TIMER, // D2 PD2
  NOT_ON_TIMER, // D3 PD3
  TIMER1B,      // D4 PD4
  TIMER1A,      // D5 PD5
  TIMER2B,      // D6 PD6
  TIMER2A,      // D7 PD7
  NOT_ON_TIMER, // D8 PC0
  NOT_ON_TIMER, // D9 PC1
  NOT_ON_TIMER, // D10 PC2
  NOT_ON_TIMER, // D11 PC3
  NOT_ON_TIMER, // D12 PC4
  NOT_ON_TIMER, // D13 PC5
  NOT_ON_TIMER, // D14 PC6
  NOT_ON_TIMER, // D15 PC7
  NOT_ON_TIMER, // D16 PB0
  NOT_ON_TIMER, // D17 PB1
  NOT_ON_TIMER, // D18 PB2
  TIMER0A,      // D19 PB3
  TIMER0B,      // D20 PB4
  NOT_ON_TIMER, // D21 PB5
  NOT_ON_TIMER, // D22 PB6
  NOT_ON_TIMER, // D23 PB7
  NOT_ON_TIMER, // D24 PA0
  NOT_ON_TIMER, // D25 PA1
  NOT_ON_TIMER, // D26 PA2
  NOT_ON_TIMER, // D27 PA3
  NOT_ON_TIMER, // D28 PA4
  NOT_ON_TIMER, // D29 PA5
  NOT_ON_TIMER, // D30 PA6
  NOT_ON_TIMER, // D31 PA7
};

#endif // ARDUINO_MAIN
#endif // Pins_Arduino_h
    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas