Showing posts with label circuit. Show all posts
Showing posts with label circuit. Show all posts

Sunday, February 24, 2013

Arduino I2C DAC Array Using MCP4725

The XBee in line passing mode would output signals via PWM.  However, this method is not very good because of the low PWM frequency of the XBee and the need to filter signals introducing additional phase delays on top of transmission times.

To remove this problem, I use an Arduino to receive signals from XBee and send appropriate values to an array of MCP4725 DAC chips.

The MCP4725 chips come with a set address on I2C with just one address bit selectable by the user.  To implement the DAC array, connected the selectable address bits of the DACs on the I2C to digital outputs of the Arduino.  To select one DAC for writing, the Arduino sets its address bit high.  The Arduino is programmed to write to that specific address.

Here is the datasheet for the MCP4725:
http://www.sparkfun.com/datasheets/BreakoutBoards/MCP4725.pdf

All schematic etc can be found here: https://docs.google.com/folder/d/0Byu6zHhzDPqVQlEtMFBaeHRZUlE/edit?usp=sharing

Here is my breakout board for an array of four MCP4725s and a picture of the array on top of the XBee shield from sparkfun:
The green colored board is the DAC breakout.  Blue is the XBee and red is the SparkFun XBee Shield.

The PCB Layout.

The circuit schematic.
The Arduino code is as follows:


#include <Wire.h>

#define BUFFER_LEN 64

// constants
#define START_DELIMITER 0x7E
#define API_ID          0x83

#define PACKET_LEN      0x10
#define N_SAMPLES       0x01

#define MCP4725_ID      0b01100000  

int DAC_BUS_PINS[] = {9,11,12,13};
int N_DAC = 4;

int i, j;

byte buffer[BUFFER_LEN];
byte L12[2];
byte dac_bits[2];

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);
  Wire.begin();
  
  
  for (i=0;i<N_DAC;i++)
  {
    pinMode(DAC_BUS_PINS[i],OUTPUT);
    digitalWrite(DAC_BUS_PINS[i],LOW);
  }
  
  dac_bits[0] = 0;
  dac_bits[1] = 0;
}

// the loop routine runs over and over again forever:
void loop() {
  
  int len;
  unsigned char firstByte;
    
  int value, X, Y, Z;
  word adc_val;

  if (Serial.available()) {
  
    firstByte = Serial.read();

    if (firstByte==START_DELIMITER) // start of a packet
    {
      Serial.readBytes((char*)L12,2);
      len = word(L12[0],L12[1]);

      if (len==PACKET_LEN) { // check for API packet of right length
        
        Serial.readBytes((char*)buffer,len);  
       
        //      [ sniff |   X   |   Y   |   Z   ]
        //buffer[  8, 9, 10, 11,  12,13,  14,15 ]
       
        // DAC Communication
        for (j=0;j<N_DAC;j++)
        {
          // adc value
          value=word(buffer[(j*2)+8],buffer[(j*2)+9]);
          //value=word(buffer[8],buffer[9]);
          adc_val = value*4;
   
          digitalWrite(DAC_BUS_PINS[j],HIGH); // address a DAC chip [0b1100011]
          Wire.beginTransmission(99); //99
          Wire.write(0b01000000); // write dac register command [c2 c1 c0 x x pd1 pd0 x]  for write dac c2 = 0, c1 = 1, c0 = 0
          for (i=0;i<8;i++) bitWrite(dac_bits[0],i,bitRead(adc_val,i+4)); // shift bits around for making i2c compatible
          for (i=0;i<4;i++) bitWrite(dac_bits[1],i+4,bitRead(adc_val,i));
          Wire.write(dac_bits[0]);
          Wire.write(dac_bits[1]);
          Wire.endTransmission();
          digitalWrite(DAC_BUS_PINS[j],LOW); // null DAC address to [0b1100010]
        } 
        // END DAC Communication  
      }          
    }
  }
  
}

Thursday, May 24, 2012

Beware Logic Levels

I had a very annoying time tracking down a problem with my poke detector circuit.  For some reason, it recently started acting up.  Now, the circuit is basically just a phototransistor feeding into an AND logic gate.  The weird behavior was that occasionally the output of the logic would get lots of noise on it and there would be strong crosstalk between different channels, i.e. different pokes.

After poking around with a scope for a while and re-reading documentation on the AND gate, I figured out the problem:  the phototransistor did not activate fully in the "no poke" condition and this caused a small voltage drop across the transistor.  This voltage drop was right about 0.8 volts, the TTL low level (TTL levels are 0.8V-=LOW and 2V+=HIGH).  Apparently if the voltage is between LOW and HIGH, strange things happen.

I fixed the problem by installing a higher value resistor prior to the phototransistor.  This served to drop more volts before the phototransistor.  Now the reading is only 0.3 volts when there is no poke and the system is working just fine.

Wednesday, May 23, 2012

Circuit Simulation

My electronics projects have gotten complicated enough to give me a headache.  To surrender to this complexity I started using a circuit simulator application.  The one I downloaded is FREE and seems pretty good.  It is called LTspice (spice stands for Simulation Program with Integrated Circuit Emphasis).  The program is available for download by anyone at: http://www.linear.com/designtools/software/.

I also found a Java-based program available as a web applet here for very simple things: http://www.falstad.com/circuit/