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 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
}
}
}
}
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. |
#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
}
}
}
}
No comments:
Post a Comment