I now made two head mounted XBee modules with sniff and accelerometer monitoring for a total of 4 ADC channels each. Each module alone sends a sample from each channel at 1000 / 4 = 250 Hz. Each 4 sample packet is 16 bytes in length so the XBee is sending 16*250 = 4000 bytes per second or 32 Kbps.
With two modules, I was not sure if the receiving XBee was going to be able to handle twice the data (though the stated RF data rate is 250 Kbps). A further concern was that my receiving XBee is communicating with an Arduino at 115.2 Kbps so with data from a single remote XBee, we are already one third of the way there.
Surprisingly, everything worked together immediately after a slight tweak of the Arduino code (below).
I can now have two animals with the magnetically connected sensors running around while I monitor sniffing and movement. The total data rate into the receiving XBee is now 64 Kbps. In principle I should only be limited by the serial port speed.
Each XBee has a further 2 on-board ADCs which I am planning to use soon.
Next: Adding an on-board amplifier for recording bio-potentials (EMG, LFP, etc).
Here is the Arduino code:
#include <Wire.h>
#define BUFFER_LEN 64
// constants
#define START_DELIMITER 0x7E
#define API_ID 0x83
// source addresses of two XBee modules
#define SRC1 0x4321
#define SRC2 0x4322
#define PACKET_LEN 0x10
#define N_SAMPLES 0x01
#define MCP4725_ID 0b01100000
int DAC_BUS_PINS[] = {13,12,11,9,8,7,6,5};
int N_DAC = 4;
int i, j;
byte buffer[BUFFER_LEN];
byte L12[2];
byte dac_bits[2];
int dac_off = 0;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(115200);
Wire.begin();
for (i=0;i<(N_DAC*2);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, addr;
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);
addr = (int)word(buffer[1],buffer[2]);
(addr==SRC2) ? dac_off = 4 : dac_off = 0;
// [ 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+dac_off],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+dac_off],LOW); // null DAC address to [0b1100010]
}
// END DAC Communication
}
}
}
}
With two modules, I was not sure if the receiving XBee was going to be able to handle twice the data (though the stated RF data rate is 250 Kbps). A further concern was that my receiving XBee is communicating with an Arduino at 115.2 Kbps so with data from a single remote XBee, we are already one third of the way there.
Surprisingly, everything worked together immediately after a slight tweak of the Arduino code (below).
I can now have two animals with the magnetically connected sensors running around while I monitor sniffing and movement. The total data rate into the receiving XBee is now 64 Kbps. In principle I should only be limited by the serial port speed.
Each XBee has a further 2 on-board ADCs which I am planning to use soon.
Next: Adding an on-board amplifier for recording bio-potentials (EMG, LFP, etc).
Two XBee sensor modules and one receiver module hooked up to an Arduino which outputs a total of 8 DAC channels. |
#include <Wire.h>
#define BUFFER_LEN 64
// constants
#define START_DELIMITER 0x7E
#define API_ID 0x83
// source addresses of two XBee modules
#define SRC1 0x4321
#define SRC2 0x4322
#define PACKET_LEN 0x10
#define N_SAMPLES 0x01
#define MCP4725_ID 0b01100000
int DAC_BUS_PINS[] = {13,12,11,9,8,7,6,5};
int N_DAC = 4;
int i, j;
byte buffer[BUFFER_LEN];
byte L12[2];
byte dac_bits[2];
int dac_off = 0;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(115200);
Wire.begin();
for (i=0;i<(N_DAC*2);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, addr;
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);
addr = (int)word(buffer[1],buffer[2]);
(addr==SRC2) ? dac_off = 4 : dac_off = 0;
// [ 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+dac_off],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+dac_off],LOW); // null DAC address to [0b1100010]
}
// END DAC Communication
}
}
}
}
No comments:
Post a Comment