Pages: [1]   Go Down
Author Topic: Merging two XBee receivers into a single serial/usb stream?  (Read 1010 times)
0 Members and 1 Guest are viewing this topic.
Manchester, UK
Offline Offline
Sr. Member
****
Karma: 0
Posts: 293
Rodrigo Constanzo is a performer and composer living in Manchester, England. He is an avid improviser and performs regularly using home made electro acoustic, and modified electronic instruments. He is currently working towards a PhD in Composition at th
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm working on a sensor project that has two 9DOF boards with built-in arduinos, each sending data from an XBee to an XBee receiver (so 2 transmitters and 2 receivers). I initially was trying 2 transmitters to 1 receiver but ended up with all sorts of problems with buffer overflow and the serial stream getting all mashed up.

At the moment I'm just using one 'pair' and the XBee receiver is plugged into an XBee usb explorer. Rather than using two XBee explorers I'd like to just have an Arduino on the receive side with 2 XBees plugged into it.

So to do this, do I need to use a Mega since it has more than one hardware serial port? (So each XBee would plug into an independent hardware serial port). Or can I do this with a regular Arduino?

And then in terms of the software, would it just be a sketch on the receiving Arduino that weaves the two streams into one? If so, how would I keep each stream "intact" so that the parsing on my computer doesn't get broken by out of order stuff.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 640
Posts: 50335
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So to do this, do I need to use a Mega since it has more than one hardware serial port?
No, you could use a UNO and SoftwareSerial. Though, the Mega is not that much more, and hardware serial is more reliable.

Quote
If so, how would I keep each stream "intact" so that the parsing on my computer doesn't get broken by out of order stuff.
Start and end of markers around each packet. Each XBee would need to read from one hardware serial (or software serial) port, and then write to the PC-based hardware serial port when the port is not in use.
Logged

Manchester, UK
Offline Offline
Sr. Member
****
Karma: 0
Posts: 293
Rodrigo Constanzo is a performer and composer living in Manchester, England. He is an avid improviser and performs regularly using home made electro acoustic, and modified electronic instruments. He is currently working towards a PhD in Composition at th
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've got a spare Mega on hand so I can just use that.

In terms of the packets, would I need to put those markers in, or are the XBees doing that anyways (in which case I would just parse/split them on the Mega)?

At the moment I'm doing a serial call-response so each sensor/arduino is sending a clump of 20 bytes (9 sensors at 2 bytes each, then 2 more bytes for two switches), and then that's getting split in Max/MSP based on the 20 byte chunk, rather than having the actual packet or sensor bytes tagged.

This is my sensor/arduino code:

Code:
// i2c Arduino Library
#include <Wire.h>

// 0011110b, i2c 7bit address of HMC5883
#define address 0x1E

// Define sensor variables
int AccX;
int AccY;
int AccZ;
int GyroX;
int GyroY;
int GyroZ;
int SW1 = 9;
int SW2 = 10;

#define aX A0
#define aY A1
#define aZ A2
#define gX A6
#define gY A7
#define gZ A3

// Incoming serial byte
int inByte = 0;

//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  // Start serial port at 57600 bps:
  Serial.begin(57600);
 
  // Set incoming switch mode
  pinMode(SW1,INPUT);
  pinMode(SW2,INPUT);
 
  // Start i2c communication
  Wire.begin();
 
  // Put the HMC5883 IC into the correct operating mode
  Wire.beginTransmission(address); //open communication with HMC5883
  Wire.write(0x02); //select mode register
  Wire.write(0x00); //continuous measurement mode
  Wire.endTransmission();
 
  // Send a byte to establish contact until receiver responds
  establishContact(); 
}

//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {
  // Define variables for magnetometer
  int MagX,MagY,MagZ;

  // Tell the HMC5883 where to begin reading data
  Wire.beginTransmission(address);
  Wire.write(0x03); //select register 3, X MSB register
  Wire.endTransmission();
 
  // If we get a valid byte, read analog ins:
  if (Serial.available() > 0) {
    inByte = Serial.read();
   
    AccX = analogRead(aX);
    AccY = analogRead(aY);
    AccZ = analogRead(aZ);
    GyroX = analogRead(gX);
    GyroY = analogRead(gY);
    GyroZ = analogRead(gZ);
   
  // Read data from each axis of magnetometer, 2 registers per axis
  Wire.requestFrom(address, 6);
  if(6<=Wire.available()){
    MagX = Wire.read()<<8; // X msb
    MagX |= Wire.read(); // X lsb
    MagZ = Wire.read()<<8; // Z msb
    MagZ |= Wire.read(); // Z lsb
    MagY = Wire.read()<<8; // Y msb
    MagY |= Wire.read(); // Y lsb
  }
 
  // Send sensor data out
 
  // Accelerometer X 
  Serial.write(highByte(AccX));
  Serial.write(lowByte(AccX));
 
  // Accelerometer Y
  Serial.write(highByte(AccY));
  Serial.write(lowByte(AccY));
 
  // Accelerometer Z
  Serial.write(highByte(AccZ));
  Serial.write(lowByte(AccZ));
 
  // Gyroscope X
  Serial.write(highByte(GyroX));
  Serial.write(lowByte(GyroX));
 
  // Gyroscope Y
  Serial.write(highByte(GyroY));
  Serial.write(lowByte(GyroY));
 
  // Gyroscope Z
  Serial.write(highByte(GyroZ));
  Serial.write(lowByte(GyroZ));
 
  // Magnetometer X
  Serial.write(highByte(MagX));
  Serial.write(lowByte(MagX));
 
  // Magnetometer Y
  Serial.write(highByte(MagY));
  Serial.write(lowByte(MagY));
 
  // Magnetometer Z
  Serial.write(highByte(MagZ));
  Serial.write(lowByte(MagZ));
 
  // Switch 1
  Serial.write(digitalRead(SW1));
 
  // Switch 2
  Serial.write(digitalRead(SW2));
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.write('A');   // send a capital A
    delay(300);
  }
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 640
Posts: 50335
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
In terms of the packets, would I need to put those markers in, or are the XBees doing that anyways (in which case I would just parse/split them on the Mega)?
The XBees may or may not packetize the data, depending on whether or not you are using API mode packeting is done) or not (no packeting is done). The code you posted does not use API mode, so you need to delimit the packets.
Logged

Manchester, UK
Offline Offline
Sr. Member
****
Karma: 0
Posts: 293
Rodrigo Constanzo is a performer and composer living in Manchester, England. He is an avid improviser and performs regularly using home made electro acoustic, and modified electronic instruments. He is currently working towards a PhD in Composition at th
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Right, should I do that at source (the arduino attached to the sensors) or when combining the streams in the Mega?
I'm worried about data rates/latency if I have to chub up the packets leaving the sensors again (I'm currently using a call-response method between the sensor arduino and the computer as I was getting wicked buffer locking up problems just sending data willy nilly).
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 640
Posts: 50335
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I'm worried about data rates/latency if I have to chub up the packets leaving the sensors again
You need something as simple as
Code:
Serial.print("<");
// Existing prints
Serial.print(">");

Quote
I'm currently using a call-response method between the sensor arduino and the computer as I was getting wicked buffer locking up problems just sending data willy nilly
You are only sending two extra characters - one at the start and one at the end. Should have no real impact on transmission speed, complexity, etc.
Logged

Manchester, UK
Offline Offline
Sr. Member
****
Karma: 0
Posts: 293
Rodrigo Constanzo is a performer and composer living in Manchester, England. He is an avid improviser and performs regularly using home made electro acoustic, and modified electronic instruments. He is currently working towards a PhD in Composition at th
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah that makes more sense. I was picturing sticking a header/footer onto each byte, but I guess the receiving Arduino would get a clump of data, then send that whole clump out before reading/sensor the other clump of data (rather than reading/sending each byte as it comes).
Logged

Pages: [1]   Go Up
Jump to: