Hi I'm new with arduino world, and need some help for a project that I'm working on.
How can I parse, an incoming data frame from an xbee?
I mean, lets think that we have two xbee, one as a router(API mode) and one as an end device(AT mode) wich is connected to arduino. The router xbee send a frame wich contain 3 bytes for example [B3 C2 A1], and the arduino with the end device have to save them in different cell to do some thing like this, the 3 byte get converted to binary, and then they have to get shifted out from 3 different pin, the first byte from the pin 13, the second byte from the pi 12 and the third byte from the pin 11. How can i do that?
i have tried different way but none of them worked, when i try with an iteration of 3 (one per byte) it gives me something like:
B3
FF
FF
C2
FF
FF
A1
FF
FF
How can i sove this problem? and get 3 different byte that i can use differently?
Please can anybody help me? its an important thing
Are there no delimiters, just those 3 bytes? If it will always be 3 bytes, then use a simple counter to keep track of how many came in, store said byte into an array and once you have all three bytes, send them to your LEDs.
What is the purpose of sending the binary, is this something similar to morse code or is this just the brightness of the LEDs?
yeah here is the programme that i created, but that doesn't work how i want.
the purpose of using the binary: i have 21 led divided in 3 groups of 7 leds
what i want to do is that when the router sends me the frame of 3 bytes 01 02 03 i want that 3 groups of led to light up like this:
000001
000010
this is valid for all the other combinations of hex values that can come from the router xbee.
You test to see if one character is available, and then you input three. How do you know that the second two are actually available? I think that is a serious problem.
A string is a NULL terminated array of chars. Since your char array is never null terminated (and doesn't appear t need to be), it is not a string. Naming the array string is, therefore, stupid.
Since you wrote the code yourself why not add a delimiter to the beginning and end of the data, this way you know you have everything.
Your data is only comprised of 7 bits per LED strand, so you can use 0x80 as the first delimiter and 0x81 as the end delimiter.
Ex: {128, LED1, LED2, LED3, 129}
With this, you can also add more LED strands, if you ever want to.
On the receiving side you look to see if 0x80 has come in and you keep reading until you see 0x81, this will signal that everything came in and now you can distribute the bits to their corresponding LEDs
Generally it is easier to develop your receiving code first, then develop the sending code to match. Below is some receiving code for servo control. The commands have a numeric position value, a servo designator, and an end of data packet marker. You might use something similar for your LEDs.
//zoomkat 11-22-12 simple delimited ',' string parse
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added
// Powering a servo from the arduino usually *DOES NOT WORK*.
String readString;
#include <Servo.h>
Servo myservoa, myservob, myservoc, myservod; // create servo object to control a servo
void setup() {
Serial.begin(9600);
//myservoa.writeMicroseconds(1500); //set initial servo position if desired
myservoa.attach(6); //the pin for the servoa control
myservob.attach(7); //the pin for the servob control
myservoc.attach(8); //the pin for the servoc control
myservod.attach(9); //the pin for the servod control
Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}
void loop() {
//expect single strings like 700a, or 1500c, or 2000d,
//or like 30c, or 90a, or 180d,
//or combined like 30c,180b,70a,120d,
if (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
if (readString.length() >1) {
Serial.println(readString); //prints string to serial port out
int n = readString.toInt(); //convert readString into a number
// auto select appropriate value, copied from someone elses code.
if(n >= 500)
{
Serial.print("writing Microseconds: ");
Serial.println(n);
if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
}
else
{
Serial.print("writing Angle: ");
Serial.println(n);
if(readString.indexOf('a') >0) myservoa.write(n);
if(readString.indexOf('b') >0) myservob.write(n);
if(readString.indexOf('c') >0) myservoc.write(n);
if(readString.indexOf('d') >0) myservod.write(n);
}
readString=""; //clears variable for new input
}
}
else {
readString += c; //makes the string readString
}
}
}
The fact is that the datas come directly from an xbee, from xctu, that sends frames like this :
7E 00 08 01 01 FF FF 00 (3B C1 B2) 51
7E : start delimiter
00 05: length
01: frame type
01: frame ID
FF FF: 16-bit destination address
00: options none[00]
3B C1 B2: RF data
51: check sum
those 3 bytes are the datas that i need to use differently, to light up 3 different led groups, each group are composed by 7 leds.
I think that there aren't any delimiter in the transimitted data packet, obviuosly the arduino and its exbee recieve, and displays only the rf data.
for example if i use only this code:
void set up(){
Serial.begin(9600);
}
void loop(){
while(Serial.available()>0)
{
byte data=Serial.read();
Serial.println(data)
}
}
on the serial monitor it gives me exactly :
3B
C1
B2
like if its reading it in 3 times, not the whole data packet in a row.
But i cant use them in 3 different way,(Sending them in output from 3 differents pin)
while if i use the other sketch that i've uploaded before, it gives me:
3B
FF
FF
C1
FF
FF
B2
FF
FF
in this case when I send them in output I have the first 2 led groups that have all the leds lighted up, while the third one has the last byte(in this case B2), the other two byte?
Hope that you got the problem. And I hope that I have been descriptive and clear enough.
zoomkat:
I agree, but it does not answer the question if data packet terminated with a cr/lf.
Yes it does. Look at it and tell me if it has 0d0a in it.
Anyway, what happens here, when Serial.available() == 1?
while (Serial.available() > 0) { // Do nothing until serial input is received
for (byte d = 0; d <= 2; d++) { //try to load the 3 bytes in the array
string[d] = Serial.read();
aarg:
That was my point exactly. It lacks a crlf. Wasn't that the question?
Think a little more about what you are looking at. Aka, the line you are looking at will not display the cr/lf hex representations if a cr/lf are in what is sent, just as the spaces in the line are not represented by hex 20. The op needs to evaluate the sent data to determine if a cr/lf is at the end. A simple method would be to see if the data strings being sent appear on the same line or in a new line when viewed in the the serial monitor or similar terminal program.
The OP appears to be giving an example of a data packet, based on some documentation on the radio hardware that they have. Why do you think there are any other characters involved?
Why do you think there are any other characters involved?
Most applications that sends serial data will have an end of data marker, traditionally a cf/lf byte combo. My point being you can't tell if a cr/lf is in the line sent or not just by your looking for the hex values in the data line supplied by the op, yet you appear to indicate you can.
i tried doing this way:
while (Serial.available() > 0) { // Do nothing until serial input is received
for (byte d = 0; d <= 2; d++) { //try to load the 3 bytes in the array
string[d] = Serial.read();
but it gives me 9 readings not 3