Tengo un arduino, un acelerómetro y un simple circuito sintetizador de audio. Mi objetivo es recibir datos a través de I2C desde el acelerómetro para controlar el sintetizador. Sin embargo, no puedo hacer que ambas cosas funcionen en un solo boceto.
Busqué en la biblioteca el circuito de mi sintetizador. Aquí está el código: -
#ifndef _SYNTH
#define _SYNTH
//**************************************************************
// Arduino synth V4.1
// Optimized audio driver, modulation engine, envelope engine.
//
// Dzl/Illutron 2014
//
//***********************************************
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "tables.h"
#define DIFF 1
#define CHA 2
#define CHB 3
#define SINE 0
#define TRIANGLE 1
#define SQUARE 2
#define SAW 3
#define RAMP 4
#define NOISE 5
#define ENVELOPE0 0
#define ENVELOPE1 1
#define ENVELOPE2 2
#define ENVELOPE3 3
#define FS 20000.0 //-Sample rate (NOTE: must match tables.h)
#define SET(x,y) (x |=(1<<y)) //-Bit set/clear macros
#define CLR(x,y) (x &= (~(1<<y))) // |
#define CHK(x,y) (x & (1<<y)) // |
#define TOG(x,y) (x^=(1<<y)) //-+
volatile unsigned int PCW[4] = {0, 0, 0, 0}; //-Wave phase accumolators
volatile unsigned int FTW[4] = {1000, 200, 300, 400}; //-Wave frequency tuning words
volatile unsigned char AMP[4] = {255, 255, 255, 255}; //-Wave amplitudes [0-255]
volatile unsigned int PITCH[4] = {500, 500, 500, 500}; //-Voice pitch
volatile int MOD[4] = {20, 0, 64, 127}; //-Voice envelope modulation [0-1023 512=no mod. <512 pitch down >512 pitch up]
volatile unsigned int wavs[4]; //-Wave table selector [address of wave in memory]
volatile unsigned int envs[4]; //-Envelopte selector [address of envelope in memory]
volatile unsigned int EPCW[4] = {0x8000, 0x8000, 0x8000, 0x8000}; //-Envelope phase accumolator
volatile unsigned int EFTW[4] = {10, 10, 10, 10}; //-Envelope speed tuning word
volatile unsigned char divider = 4; //-Sample rate decimator for envelope
volatile unsigned int tim = 0;
volatile unsigned char tik = 0;
volatile unsigned char output_mode;
//*********************************************************************************************
// Audio driver interrupt
//*********************************************************************************************
SIGNAL(TIMER1_COMPA_vect)
{
//-------------------------------
// Time division
//-------------------------------
divider++;
if(!(divider&=0x03))
tik=1;
//-------------------------------
// Volume envelope generator
//-------------------------------
if (!(((unsigned char*)&EPCW[divider])[1]&0x80))
AMP[divider] = pgm_read_byte(envs[divider] + (((unsigned char*)&(EPCW[divider]+=EFTW[divider]))[1]));
else
AMP[divider] = 0;
//-------------------------------
// Synthesizer/audio mixer
//-------------------------------
OCR2A = OCR2B = 127 +(((((signed char)pgm_read_byte(wavs[0] + ((unsigned char *)&(PCW[0] += FTW[0]))[1]) * AMP[0]) >> 8) + (((signed char)pgm_read_byte(wavs[1] + ((unsigned char *)&(PCW[1] += FTW[1]))[1]) * AMP[1]) >> 8) + (((signed char)pgm_read_byte(wavs[2] + ((unsigned char *)&(PCW[2] += FTW[2]))[1]) * AMP[2]) >> 8) +
(((signed char)pgm_read_byte(wavs[3] + ((unsigned char *)&(PCW[3] += FTW[3]))[1]) * AMP[3]) >> 8)
) >> 2);
//************************************************
// Modulation engine
//************************************************
// FTW[divider] = PITCH[divider] + (int) (((PITCH[divider]/64)*(EPCW[divider]/64)) /128)*MOD[divider];
FTW[divider] = PITCH[divider] + (int) (((PITCH[divider]>>6)*(EPCW[divider]>>6))/128)*MOD[divider];
tim++;
}
class synth
{
private:
public:
synth()
{
}
//*********************************************************************
// Startup default
//*********************************************************************
void begin()
{
output_mode=CHA;
TCCR1A = 0x00; //-Start audio interrupt
TCCR1B = 0x09;
TCCR1C = 0x00;
OCR1A=16000000.0 / FS; //-Auto sample rate
SET(TIMSK1, OCIE1A); //-Start audio interrupt
sei(); //-+
TCCR2A = 0x83; //-8 bit audio PWM
TCCR2B = 0x01; // |
OCR2A = 127; //-+
SET(DDRB, 3); //-PWM pin
}
//*********************************************************************
// Startup fancy selecting varoius output modes
//*********************************************************************
void begin(unsigned char d)
{
TCCR1A = 0x00; //-Start audio interrupt
TCCR1B = 0x09;
TCCR1C = 0x00;
OCR1A=16000000.0 / FS; //-Auto sample rate
SET(TIMSK1, OCIE1A); //-Start audio interrupt
sei(); //-+
output_mode=d;
switch(d)
{
case DIFF: //-Differntial signal on CHA and CHB pins (11,3)
TCCR2A = 0xB3; //-8 bit audio PWM
TCCR2B = 0x01; // |
OCR2A = OCR2B = 127; //-+
SET(DDRB, 3); //-PWM pin
SET(DDRD, 3); //-PWM pin
break;
case CHB: //-Single ended signal on CHB pin (3)
TCCR2A = 0x23; //-8 bit audio PWM
TCCR2B = 0x01; // |
OCR2A = OCR2B = 127; //-+
SET(DDRD, 3); //-PWM pin
break;
case CHA:
default:
output_mode=CHA; //-Single ended signal in CHA pin (11)
TCCR2A = 0x83; //-8 bit audio PWM
TCCR2B = 0x01; // |
OCR2A = OCR2B = 127; //-+
SET(DDRB, 3); //-PWM pin
break;
}
}
//*********************************************************************
// Timing/sequencing functions
//*********************************************************************
//*********************************************************************
// Setup all voice parameters in MIDI range
// More Code follows
Mi conjetura es que I2C se interrumpe cuando inicializo el circuito del sintetizador. Aunque no estoy seguro. ¿Cómo puedo solucionar este problema?