Pages: [1] 2 3   Go Down
Author Topic: send array of integers via xBee s1  (Read 3287 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
I have some problems sending 4-5 data via xbee.
I'm using arduino mega 2560, arduino diecimila, 2 xbee s1 and I want to control a RC car using those chips. the data I'm trying to send are: status (car on automatic mode or RC mode, values are 0 or 1), FW/BW ( car moving forward/backward, values from 0 to 255, 125-135 is not moving), direction (richt left, values from 0 to 255, which represent the angle of the wheels), default speed (which is the speed of the car when moving on automatic mode).
Until now I've had lot of troubles, because I don't really know how to send an array trough xbee and every time I write a new code it doesn't work. do someone an help me please? I haven't found anything yet and I'm quite desperate :S
thanks
propilot
Logged

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

Quote
the data I'm trying to send are: status (car on automatic mode or RC mode, values are 0 or 1), FW/BW ( car moving forward/backward, values from 0 to 255, 125-135 is not moving), direction (richt left, values from 0 to 255, which represent the angle of the wheels), default speed (which is the speed of the car when moving on automatic mode).
Do you want to send this as ASCII data or binary data? ASCII data is easy to send, easy to receive, and easy to parse. The drawback is that it can be slow doing all that.

Sending data in binary is fast, but error detection/correction is much more difficult.

Quote
Until now I've had lot of troubles, because I don't really know how to send an array trough xbee
Whether the data is in discrete variables or in an array is irrelevant.

Quote
and every time I write a new code it doesn't work.
Post the code. Explain what it does. Explain how that differs from what you want. We can help you fix it.

Quote
do someone an help me please?
I'm trying.

Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

the code of the car is ctrl_robot_....1_7_2, the one of the ground station is ctrl_xbee_...
short explanation for the car code:
float ping(): read the distance from the objects (used in automatic mode only)
void resetdirezione(angolatura): set and move the wheels to the specified angle
void direzione():decides which is the best direction (R or L)
--> int leggiseriale(): this is where the problem should be: this function has to read the data coming from the xbee and separate them in one array so that i can use the numbers easily
//void cercacasa(): unused at the moment (should seek IR and find home)
void destra() and void sinistra(): turn the wheels right or left (instead of them now i use resetdirezione(angle))
setup()smiley-small..
void loop():read the data from the xbee and set the mode: if spia==0 the car moves on automatic mode (with HC-SR04 sensor), else it should use the numbers it gets from xbee to move)
short explanation for the ground station code:
i read the values from a playstation controller (just from 2 potentiometers and one button), than i send them: sz=car mode, sx=FW/BW,sy=R/L,200= default speed (for automatic mode)
if u need more explanation i will give you every info you need smiley
ps.the code, since leggiseriale()gives me back always 0, so automatic mode, works perfectly, the problme is that i want to use also the other mode
thank you
propilot

* ctrl_robot_HC_SR04_test_serialmov_v1_7_2.ino (9.75 KB - downloaded 6 times.)
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

and sorry but I'm not really good with arduino, specially with serial and with xbee
I'm a noob and this is my first big project smiley

* ctrl_xbee_usbcom_v1_3.ino (1.05 KB - downloaded 2 times.)
Logged

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

Code:
float ping()//questa funzione misura la distanza attraverso il sensore a ultrasuoni HC-SR04 viene usata sia durante la marcia sia durante la scelta della direzione da prendere
{
  long durata,distanza; //dichiarazione variabili per la funzione
  distanza=0.034*durata/2;
  return distanza;
}
distanza is NOT a float. Make the return type and the value returned match.

Code:
  servo1.write(40); //la prima direzione è sinistra a 45°
40 does not equal 45.

Code:
long distL,distR;
  distL=ping(); //viene campionata la distanza a destra
ping() currently returns a float. Why are you storing it in a long?

Code:
  servo1.write(130); //la seconda è fatta a destra a 135°
130 does not equal 135.

Get rid of incorrect comments, or fix them.

Code:
  if(distR<40&&distL<40)
Use the space key!

Code:
    Serial3.flush();
A sure sign that you don't understand serial communication.

Having just the receiver code is not enough. We need to see what the sender is sending. You seem to expect to read an integer value calling Serial3.read(). You will read one byte/character using SerialN.read().

Code:
  if(Serial3.available()>4)
  {
    Serial.print("incomingdata");
    while(Serial3.read()!=char(253)){Serial.read();}
    for(int i=0;i<4;i++)
    {
      serialcom[i]=Serial3.read();
      //Serial.print(Serial3.read());
    }
If there are 5 or more characters to read, read and throw away some number of them. Then, read 4 more. That won't work. You need to read and throw away characters until the 253 arrives, then wait until there are 4 more characters/bytes. Then, read the bytes/characters.

Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok now I'm writing another program...I'm working with strings I'll post it when I'm finished. By the way: i know my comments are quite bad,but it's because you don't have the image of my robot...the problem is that the angles that I write aren't the same as the one of the servo (there is a ~5° difference) smiley
Thank you for the problem with long-float, I hadn't noticed, I'll fix it now.
For the problem with the sending code i've attached it to my third comment (it was with the second one but somenthing hasn't worked)
And for the last problem:I had changed this part of my code but i wanted not to save those changes, but when i've closed arduino i might have saved them by mistake, sorry smiley

Maybe is better just to start with a new code, so it'll be easier for you to help me: I have had a new idea:I "pack" a string with all the data,i send it trough the xbees and than unpack it.
the idea was a string like that: "ST;z=***x=***y=***END", where *** can be numers from 0 to 255. I packed it succesfully and seems to work. now I have to unpack it. the two programs are attached

* ctrl_xbee_usbcom_v1_2.ino (1.05 KB - downloaded 2 times.)
* ctrl_xbee_usbcom_send.ino (0.71 KB - downloaded 5 times.)
Logged

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

Quote
the idea was a string like that: "ST;z=***x=***y=***END", where *** can be numers from 0 to 255. I packed it succesfully and seems to work. now I have to unpack it. the two programs are attached
The z=, x=, and y= parts of the message are unnecessary. Just use commas. That saves three bytes. The ST; and END can be single bytes. I like < and >, myself.

Parsing is easy, after you have collected the data into an array. The following code shows how to do that.
Code:
#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

Use strtok() with inData as the input and comma as the delimiter to get the z value as a string, and use atoi() on the token to get the integer value. Then, call strtok() again with NULL and comma as the arguments to get the x value as a string, and again to get the y value as a string. Use atoi() to convert to numbers.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thank you so much, I was really panicking smiley sorry for the bad code and bad comments :S next time I'll be more careful with them!
I'll try to complete the code and let you know if it worked smiley
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Strange, when using this code the compiler gives me an error on the if and else if statement (expected primary expression before '=' token) but i double checked the whole code and I didn't found anything :S
Logged

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

Quote
Strange, when using this code the compiler gives me an error on the if and else if statement (expected primary expression before '=' token) but i double checked the whole code and I didn't found anything
Post your code, then.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The code was the one you send me, but i fixed the problem, it was simply an error with #define (I've written #Define x=2 as I added you part to my code, then I've seen my huge mistake).
Now, you said me I do not understand Serial communication, it's right, as I wrote Serial.flush() I was trying to clear the buffer, so that the data will be the newest possible. How does I clear the buffer?
Thank you for your help!
Logged

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

Clearing the buffer is generally not a good idea. The old flush() method did that by throwing away random amounts of unread data. I can't see how that is a good idea, unless you are resting code that re-syncs with a sender.

If that is not the goal, then every character sent was sent with the expectation that it would be important, and, therefore, read.

Why would you not want to read that data, if you sent it?

If you don't want the Arduino to have to read the data, don't send it.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I need to have always the more recent data sent, so that the car has the latest command i gave her, If the buffer fills quicker than arduino reading it's data I would have always an encreasing delay from my commands and what the robot does, isn't it?

Now as I'm writing about this I've thought:I could add a part of code that sends an "ok" when it's ready to recive, so the ground station sends it's data and the car recive only those one, leaving the buffer clear when I don't need data and ready to recive as I have to use them. would that work?

My first idea was: ground station continues sending data, car reads the latest sent. I clear the buffer so that the data aren't too old
Now: car needs data, send a byte to the G.station, which sends back the array of data needed. No useless communication, no buffer filling up with data i don't need ,as you said, REALLY the latest data availale.
Right?
Logged

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

Quote
If the buffer fills quicker than arduino reading it's data I would have always an encreasing delay from my commands and what the robot does, isn't it?
Yes. So, don't let that happen. Get rid of any delay()s, so that you spent most of your time checking to see if there is anything to do, rather than doing nothing.

Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a little question: as I use the serial.read() function, does it need some time to delete the readen data or is it immediate? I've had some trouble because as I send something like 1,2,3 with the code you gave me I receive 1111,,,,2222,,,,3333 and I'm wondering if it's a problem with some delay() I should use. I simply read the data and put them in one array, should I use some delay to give my board the time do read and then clear the data?
Logged

Pages: [1] 2 3   Go Up
Jump to: