//In JAVA justin downs johnhenryshammer.com
// Code that will parse a XBEE API Series2 receive packet started from Rob Faludis/Dan Shiftman API series 1 lib
// It is broken into functions for Debugging and for easier use with a microcontroller time out
// for program flow. It is not needed for raw parsing and
//runs faster without funcs. Just decomment.
//** There is also code for transmitting serial as ASCII you don't have to use those
//funcs for the XBEE, just disregard and don't use the dePackageData func.
//set up and run stuff
import processing.serial.*;
Serial port; // Create object from Serial class
int num[] = new int[3];
int points[]= new int[WIDTH];
int beats=0;
//char[] dataIn = new char[20];
byte id = 10;
void setup()
{
println(Serial.list());
frameRate(30);
// Open the port that the board is connected to and use the same speed (9600 bps)
port = new Serial(this,Serial.list()[2], 9600);
}
void draw()
{
getData();
}
/* Function that receives API2 data which was sent using 16-bit addressing
broken into functions for microcontroler timeout blocks. not needed on pc
runs slower.
*/
void getData() {
//println("a");
int timeout=100;
int packetLength = 0;
packetLength = checkHeader(timeout); // START BYTE AND PACKET LENGTH
// println(packetLength);
if (packetLength > 0 ) { // if we have a packet continue
int apiIdentifier = getIdentifier(timeout); // GET ID
char adress[] = getLongAdress(timeout);//GET LONG ADRESS
/*char addrByte=0;
while( port.available() < 8); // stop for bits
char adress[]= new char[8];// array for address
for (int i = 0; i<8; i++){
addrByte =char( port.read());
adress[i]=addrByte;
// print(hex(addrByte));
}
*/
int localAdress =getLocaladdress(timeout);// GET LOCAL ADDRESS
/* while (port.available() < 2); // wait for at least two bytes to be available
int localAd = port.read(); // read the most significant length byte
int localAd2 = port.read(); // read the least significant length byte
int localAdress = (localAd << 8) + localAd2; // put the two bytes together
*/
char options = getOptions(timeout);//GET OPTION
/* while (port.available() < 1);
char options = char(port.read()); // get the options 1 packet ack returned 2 brodcast
*/
char[] dataIn = getInfo(packetLength,timeout);//GET INFO
/*
//info packet
char[] dataIn = new char[30];
while (port.available() < (packetLength - 12));
// println("packetLength22 "+packetLength);
for (int i= 0; i < (packetLength - 12); i++) { // take out other info in packet + checksu
println("packetLength "+ packetLength);
dataIn[i] = char(port.read()); // get a byte of data
// println(hex(dataIn[i]));
}
*/
char checksum = getCheckSum(timeout); //GET CHECKSUM
/*
while (port.available() < 1);
char checksum = char(port.read());
*/
//printall
println("packetLength "+packetLength);
println("sent long address");
for (int i = 0; i<8; i++){
print(hex(adress[i]));
}
println();
println ("local adress "+hex(localAdress));
println("options "+hex(options));
println("info");
for (int i= 0; i < (packetLength - 12); i++) { // take out other info in packet + checksum
println(hex(dataIn[i]));
}
println("checksum "+hex(checksum));
// For ASCCII ***OPTIONAL
println("data " + ArrayLookChars(dataIn));
//for non ASSCII parse **OPTIONAL
/* char stop=char(127); // hex 7F
println("data " + dePackageData(dataIn,'A',stop));// calls below function
*/
}
}
///Start XBee parse funcs
int checkHeader(int timeout) { // timeout is in milliseconds set this to break from waiting for byte
long startTime = millis();
int Length = 0;
int inByte = 0;
// during the timeout period, if we haven't gotten the start byte yet...
while (((millis() - startTime) < timeout) && (inByte != 0x7E)) {
if (port.available() > 0) { // if a byte is waiting in the buffer
inByte = port.read(); // read a byte from the buffer
}
}
// look at byte
if (inByte == 0x7E) { // if we got the API start byte
while (port.available() < 2); // wait for at least two bytes to be available
int lengthMSB = port.read(); // read the most significant length byte
int lengthLSB = port.read(); // read the least significant length byte
Length = (lengthMSB << 8) + lengthLSB; // put the two bytes together
}
return Length;
}
char getCheckSum(int _timeOut){
char checksum ='Z';
long startTime = millis();
while (port.available() < 1 && ((millis() - startTime) < _timeOut)); // wait for at least two bytes to be available
if (port.available() > 0) { // if a byte is waiting in the buffer
checksum = char(port.read());
return checksum; // returns null if timed out
}
println("checksum");
return '0'; // returns null if timed out
}
// function that checks to see if the API Identifier matches a requested value
char getIdentifier(int _timeOut) {
long startTime = millis();
char apiIdentifier = 'Z'; // set apiIdentifier to an impossible value
while (port.available() < 1 && (millis() - startTime) < _timeOut) ; // wait for a byte or timeout
if (port.available() > 0) { // if a byte is waiting in the buffer
apiIdentifier = char(port.read());
return apiIdentifier; // returns null if timed out
}
println("Identifier");
return 'N'; // returns null if timed out
}
int getLocaladdress(int _timeOut){
int localAdress =0;
long startTime = millis();
while (port.available() < 2 && ((millis() - startTime) < _timeOut)); // wait for at least two bytes to be available
if (port.available() > 0) { // if a byte is waiting in the buffer
int localAd = port.read(); // read the most significant length byte
int localAd2 = port.read(); // read the least significant length byte
localAdress = (localAd << 8) + localAd2; // put the two bytes together
return localAdress; // returns null if timed out
}
println("location");
return '0'; // returns null if timed out
}
char[] getLongAdress(int _timeOut){
long startTime = millis();
char addrByte = 'Z';
while( port.available() < 8 && ((millis() - startTime) < _timeOut)); // stop for bits
char address[]= new char[8];// array for address
if (port.available() > 0) { // if a byte is waiting in the buffer
for (int i = 0; i<8; i++){
addrByte =char( port.read());
address[i]=addrByte;
}
return address; //returns null if timed out
}
println("Adresslong");
return null;
}
char[] getInfo(int _packetLength, int _timeOut){
long startTime = millis();
char addrByte = 'Z';
while (port.available() < (_packetLength - 12) && millis() - startTime < _timeOut); // stop for bits
char[] dataIn = new char[100]; // do malloc here
if (port.available() > 0) { // if a byte is waiting in the buffer
for (int i= 0; i < (_packetLength - 12); i++) { // take out other info in packet + checksu
dataIn[i] = char(port.read()); // get a byte of data
// println("packetLength "+ _packetLength);
println("getinfo "+hex(dataIn[i]));
}
return dataIn; //returns null if timed out
}
println("info packet");
return null;
}
char getOptions(int _timeOut){
char options ='Z';
long startTime = millis();
while (port.available() < 1 && ((millis() - startTime) < _timeOut)); // wait for at least two bytes to be available
if (port.available() > 0) { // if a byte is waiting in the buffer
options = char(port.read()); // get the options 1 packet ack returned 2 brodcast
return options; // returns null if timed out
}
println("Options");
return '0'; // returns null if timed out
}
//*** OPTIONAL **** Serial Packaging functions (optional not needed for xbee)
long dePackageData(char[] _data , char _start, char _stop) { //can return a char int long or array
long data=0; // CHANGE HERE
// println(_data[0]);
// println(_data[1]);
if(_data[1] == _start){
int i = 2;
while(_data[i] != _stop){ // variable will read till whenever you say stop
data = data << 8; // data equals data shifted for place
data += _data[i]; // add new eights place
i++; // inc i to get new place
// println(i);
}
}
return data;
}
//use with serialinput
long SerialLookChars() {
char ASCIIString[] = new char[100]; // in string
char inByte='c';
long number = 0; // return number
int stringPos = 0; // keeps track of places in number
if ('a' == port.read()){ // for id parsing of serial
while(inByte !='b'){
inByte = char(port.read());
// save ASCII numeric characters in string:
if ((inByte >= '0') && (inByte <= '9')){
// Serial.println( inByte);
ASCIIString [stringPos] = inByte;
stringPos++;
// Serial.println( stringPos);
}
}
}
port.clear(); // flush junk
number = SerialToInt( ASCIIString,stringPos ); /// convert captured string to an int
stringPos = 0; //reset count num
//if (number !=0)Serial.println(number);//DEBUG
return number;
}
// use with parsed array array
long ArrayLookChars(char[] _array) {
char ASCIIString[] = new char[100]; // in string
char inByte ='z';
long number = 0; // return number
int stringPos = 0; // keeps track of places in number
int i = 2;
if ('a' == _array[1] ){ // for id parsing of serial
while(_array[i] != 'b'){ /// FIRST ONE IS T FOR TAG byte
inByte =_array[i];
i++;
if (i > 90) break; ///FOR PROCESSING, second run of program always fucks buffer
// save ASCII numeric characters in string:
if ((inByte >= '0') && (inByte <= '9')){
ASCIIString [stringPos] = inByte;
stringPos++;
}
}
}
println( "array"+ASCIIString[0] +ASCIIString[1]+ASCIIString[2]+ASCIIString[3]+ASCIIString[4]);
number = SerialToInt( ASCIIString,stringPos ); /// convert captured string to an int
stringPos = 0; //reset count num
//if (number !=0)Serial.println(number);//DEBUG
return number;
}
/*****************
the important parts of the function conversions
are to have a inverting for loop go
from last in array to first and call the plusBaseTen()function
each time.
*******************/
// hits up the number by base ten powered
long timesBaseTen(int _move){ // the
long place = 1; //base 10
int n = 0;
if( _move < 1){ return 1;}//ones place no change
else{
for( n= 0; n<_move; n++){ place = place*10;}
}return place;
}
// converts a ten digit ASCII to int
long SerialToInt(char[] _input, int _arrayLength){
long number=0;
long total=0;
int arrayLook=0;
int i = 0;
int arrayLength =_arrayLength-1; // need one less than actual length 0 is 1
// call invert string for proper string power order
for(i =arrayLength; i >= 0;i--){
// Serial.println(i);
// Serial.println(_input[i]);
// picks out ASCII numbers for error check
if ((_input[i] >= '0') && (_input[i]<= '9')){
println ("INPUT"+ _input[i]);
// processing does not seem to understand Integer class it is stupid, should have done it in eclipse
switch( _input[i]){
case '0' : number =0;
break;
case '1' : number =1;
break;
case '2' : number =2;
break;
case '3' : number =3;
break;
case '4' : number =4;
break;
case '5' : number =5;
break;
case '6' : number =6;
break;
case '7' : number =7;
break;
case '8' : number =8;
break;
case '9' : number =9;
break;
}
println ("NUMBER"+ number);
number = (number * (timesBaseTen(arrayLook))); // puts number in its place
arrayLook++;
total = number+total;
}
}
return total;
}