0
\$\begingroup\$

I have an arduino, accelerometer and a simple audio synthesizer circuit. My goal is to receive data over I2C from accelerometer to control the synthesizer. However I cannot get both the things to work in a single sketch.

I looked at the library for my synthesizer circuit. Here's the code :-

#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    

My guess is that I2C is interrupted when I initialize the synthesizer circuit. I am not sure though. How do I get around this problem?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Sounds like time for an oscilloscope on the interface pins to see exactly what is going on. Sometimes this is the only good way to debug problems like this.

\$\endgroup\$
5
  • \$\begingroup\$ I just tried that, I get a waveform on the oscilloscope alright but it goes flat after a while. Also, I see the pulse coming from the data line when I touch it with the probe. But when I touch the scl my program halts immediately. \$\endgroup\$
    – Ajit
    Nov 5, 2014 at 8:41
  • \$\begingroup\$ Do you have pullup resistors on your I2C bus lines? \$\endgroup\$ Nov 5, 2014 at 13:59
  • \$\begingroup\$ Yes I have pull up resistors 4.7k \$\endgroup\$
    – Ajit
    Nov 5, 2014 at 14:01
  • \$\begingroup\$ Finally got it working. I used an accelerometer by a different manufacturer(adxl345) and the program now seems to work fine. However I am still curious why the previous accelerometer mma 8452Q had the issue. I tried atleast 5 of them and all of them had the same problem. \$\endgroup\$
    – Ajit
    Nov 5, 2014 at 17:16
  • \$\begingroup\$ @Ajit Maybe it's actually your logic that does something wrong then? Update the original post with your MMA8452Q code so we can see what the problem might be. Also, describe your error: does the program crash, enter infinite loop, wrong acceleration values? Let us know. \$\endgroup\$
    – FRob
    May 7, 2015 at 20:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.