freeze when receiving multi values on serial data, overflow issue?

Hi guys,

I'm fighting with this code by two days, read and tried to edit many things but nothing..

The project consists of sending multi values (ps3 controller) from the the first Arduino and send them to the second arduino via Serial wireless using 2 xbee modules.

There is a part that seems to work fine where the first TX Arduino can send the multi values and the RX Arduino can receive them correctly, but thanks to the serial monitor of the RX it seems that the problem begin when the values exceed three digits, for example all work fine when the value are


94
58
0
0
0

but when they reach three digits like here


87
235
0
0
0

the RX arduino freeze and back to work and respond to commands only after some seconds that i don't press any button of the controller.

I'm still a newbie but it seems a buffer issue what do you think?

These are my two sketches:

TX

/*
 Edited version of the sketch for the PS3 Bluetooth library - developed by Kristian Lauszus
 For more information visit my blog: http://blog.tkjelectronics.dk/ or
 send me an e-mail:  kristianl@tkjelectronics.com
 */

#include <PS3BT.h>
#include <usbhub.h>

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#include <SPI.h>
#endif

USB Usb;
//USBHub Hub1(&Usb); // Some dongles have a hub inside

BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
/* You can create the instance of the class in two ways */
PS3BT PS3(&Btd); // This will just create the instance
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch

bool printTemperature;
bool printAngle;
const uint8_t LED_tx = 2;

char dataPacket[64];

int Servo1 = 0; // 2 char
int Servo2 = 0; // 3 char
int Servo3 = 0; // 3 char
int led1 = 0;
int led2 = 0;

void setup() {
  pinMode(LED_tx, OUTPUT);

  Serial.begin(57600);
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));


}
void loop() {
  Usb.Task();

  if(PS3.PS3Connected || PS3.PS3NavigationConnected) {
    Servo1 = map(PS3.getAnalogHat(LeftHatX), 0, 255, 0, 180);
    Servo2 = PS3.getAnalogButton(L2);
    Servo3 = PS3.getAnalogButton(R2);
      if (PS3.getButtonClick(TRIANGLE)) {
          led1 = 1;
      } else {
          led1 = 0;
            }
      if (PS3.getButtonPress(CIRCLE)) {
          led2 = 1;
      } else {
          led2 = 0;
            }
        sprintf(dataPacket,"<%d,%d,%d,%d,%d>",Servo1, Servo2, Servo3, led1, led2);              //sprintf(dataPacket, "X%d" ,gx);
          Serial.println(dataPacket);
    delay(10);
  }



  if (PS3.PS3Connected || PS3.PS3NavigationConnected) {

    if (PS3.getButtonClick(PS)) {
      Serial.print(F("\r\nPS"));
      PS3.disconnect();
    }
    else {
//      if (PS3.getButtonClick(TRIANGLE))
//        Serial.print("\r\nH");
//      if (PS3.getButtonPress(CIRCLE))
//        Serial.print(F("\r\nH"));
        
      if (PS3.PS3Connected)
        digitalWrite(LED_tx, PS3.getButtonPress(CROSS));
      else
        digitalWrite(LED_tx, LOW);
        
      if (PS3.getButtonClick(SQUARE))
        Serial.print(F("\r\ndigitalWrite(ledPin, HIGH);"));

      if (PS3.getButtonClick(UP)) {
        Serial.print(F("\r\nUp"));
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED4);
        }
      }

    }

  }

}

RX

#include <Servo.h>

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[64];
byte index;

const int ledPin = 12;                      // the pin that the LED is attached to
int incomingByte;                           // a variable to read incoming serial data into
int valo = 0;

Servo myservo;

void setup() {
  Serial.begin(57600);                      // initialize serial communication
  Serial.println( "Serial Start" );
  pinMode(ledPin, OUTPUT);                  // initialize the LED pin as an output
  myservo.attach(7);
}

void loop() {
  if (Serial.available() > 0) {             // see if there's incoming serial data:
    delay(1);  //small delay to allow input buffer to fill
/*
    incomingByte = Serial.read();           // read the oldest byte in the serial buffer
    
    if (incomingByte == 'H') {          // if it's a capital H (ASCII 72), turn on the LED
      digitalWrite(ledPin, HIGH);
//      delay(10);
      digitalWrite(ledPin, LOW);
    }
    if (incomingByte == 'L') {              // if it's an L (ASCII 76) turn off the LED
      digitalWrite(ledPin, LOW);
    }
*/

    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       return;
    }
    else
    {
      if(index < 63)
      {
        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
 int values[5]; // Array to hold the values
byte index = 0; // index into array

char *token = strtok(inData, ","); // Get the first token
while(token)
{
   values[index] = atoi(token); // convert the token to an int and store it in the array
   index++; // Increment the index

   token = strtok(NULL, ","); // Keep parsing the same string
}
Serial.println("---------");
Serial.println(values[0]);
Serial.println(values[1]);
Serial.println(values[2]);
Serial.println(values[3]);
Serial.println(values[4]);

    valo = values[0];
       myservo.write(valo);

    if (values[3] == 1) {
       digitalWrite(ledPin, HIGH);      
      } else {
        digitalWrite(ledPin, LOW);
        }
    if (values[4] == 1) {
       digitalWrite(ledPin, HIGH);      
      } else {
        digitalWrite(ledPin, LOW);
        }



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

  }
}

Have a look at the 3rd example in Serial Input Basics. It is similar to what you are doing but I think it will work reliably for you. Note that it does not have any use for delay().

...R

Thanks Robin, your thread was already an open window in my browser, and i've try to read it again, but i can't find the right point that need to fix mine, and what you mean that it doesn't have any use for delay()? because when i tried to remove the one in my sketch it simply broke even the part that was working fine.. please any further help on where i messed up would be appreciated

jonnys90:
Thanks Robin, your thread was already an open window in my browser, and i've try to read it again, but i can't find the right point that need to fix mine,

Because there isn't any one right point. You have to understand the whole thing.

and what you mean that it doesn't have any use for delay()? because when i tried to remove the one in my sketch it simply broke even the part that was working fine.. please any further help on where i messed up would be appreciated

Without seeing your code, how could anybody know? Please post the updated version, in code tags.

aarg:
Without seeing your code, how could anybody know? Please post the updated version, in code tags.

Hi, aarg, what you mean? i've already included my both sketches TX and RX in my first post and it's updated.

@jonnys90, use the complete recvWithStartEndMarkers() function from my demo and use it in the way it is used in the demo.

...R

hi robin, now that i'm starting to understanding your functions it seems a little bit more simple :smiley:

now i can send the values with Serial.print() but i would just to read the ParsedData on the serial monitor possibily without to have to use softwareserial cause i've tried it and give me problems

another thing: i notice that someone that use your functions has added this part "strcpy(tempChars, receivedChars);" and say that is necessary to protect the original data, it's really neccessary?

jonnys90:
now i can send the values with Serial.print() but i would just to read the ParsedData on the serial monitor possibily without to have to use softwareserial cause i've tried it and give me problems

Sorry, I don't understand.

another thing: i notice that someone that use your functions has added this part "strcpy(tempChars, receivedChars);" and say that is necessary to protect the original data, it's really neccessary?

I think I added that. The parse process uses strtok() which changes the string it is working on. If you need to be able to use the unchanged string you need to make a copy of it first.

...R

I'm sending several values of a joystick from the arduino A to the arduino B using Serial.print() but i would also to read on Serial Monitor those value received by recvWithStartEndMarkers();
because the only problem is that to see these it also use the Serial.print so it create like a loop and so an overload of info that broke all

cause now in the serial monitor of the Arduino A that sends the value i see just the value that it send and not see them on the arduino B, and vice versa, in the B I don't see (read, because it receive them and can use them anyway) them

jonnys90:
I'm sending several values of a joystick from the arduino A to the arduino B using Serial.print() but i would also to read on Serial Monitor those value received by recvWithStartEndMarkers();
because the only problem is that to see these it also use the Serial.print so it create like a loop and so an overload of info that broke all

What Arduinos are you using?

If you are using a Mega you can use Serial1 for communication with the other Arduino and leave Serial free for debugging.

If you are using an Uno you can use SoftwareSerial to create an extra serial port on each Arduino and, again, leave Serial free for debugging.

...R

I use two Arduino Uno

because le't say that i don't need to debug, and need to exchange several values among 2 arduino with 2 xbee can i do it using just Serial.print or i need to use SoftwareSerial?

see here this is the problem that i've now:

TX (PS3 Controller) OUTPUT:

<hello PS3,3,2.1,0>
<hello PS3,3,2.1,0>
Message: hello CAR Integer: 1 Float: 2.30 Servo: 90 Led1: 0 Led2: 0
<hello PS3,3,2.1,0>
Message: hello CAR Integer: 1 Float: 2.30 Servo: 90 Led1: 0 Led2: 0
<hello PS3,3,2.1,0>
Message: hello CAR Integer: 1 Float: 2.30 Servo: 90 Led1: 0 Led2: 0

RX (Rc Car) OUTPUT:

<hello CAR,1,2.3,90,0,0>
<hello CAR,1,2.3,90,0,0>
Message hello PS3 Integer 3 Float 2.10 Shock 0
<hello CAR,1,2.3,90,0,0>
<hello CAR,1,2.3,90,0,0>
Message hello CAR Integer: 1 Float: 2.3 Integer 0 Float 0.00 Shock 0

You need to post a diagram showing how you have everything connected. A photo of a pencil drawing is much better than a Frizting thing.

I am not familiar with XBEEs but if they connect to Pins 0 and 1 then you could also connect them to two other pins using SoftwareSerial. Then Pins 0 and 1 would be free for debugging.

...R

yeah, here are an image, sorry if it's Frizting but i had it already as i done it before to start the project :-[

anyway i've just commented the ShowParsedData() to test a simple blink led when i press a button in my controller but even when i try to blink but the controller can't even connect and from what i see on Serial Monitor it's not fluide and it seems also that continue being restarted because on both Serial Monitor sometimes i get:

<hello PS3,3,2.1,77>
<hello PS3,3,2.1,77>
<hello PS3,3,2.1,77S³®+±�Start
This demo expects 3 pieces of data - text, an integer and a floating point value

<hello PS3,3,2.1,77>
<hello PS3,3,2.1,77>
<hello PS3,3,2.1,77>

and

<hello CAR,1,2.3,90,0,0>77
<hello CAR,1,2.3,90,0,0>77
<hello CAR,1,2.3,90,0,0>0
<hello CAR,1,2.3,90,0,0>77
<hello CAR
Š55±Õ•Ñ½½Ñ¡�Library StartedThis demo expects 3 pieces of data - text, an integer and a floating point value
Enter data in this style <text,12,24.7>

<hello CAR,1,2.3,90,0,0>0
<hello CAR,1,2.3,90,0,0>0
<hello CAR,1,2.3,90,0,0>0
<hello CAR,1,2.3,90,0,0>0
<hello CAR,1,2.3,90,0,0>0

i've added the value of 77 be sent by the RX (Car) so i can know when they are connected and are exchanging the data

It may be a nice artistic looking picture but there is not a single connection shown on it. Just do a simple pencil drawing and post a photo of it.

Have you tried SoftwareSerial ?

...R

sorry what you mean with pencil drawing? have you saw the picture in my last reply? there it being show how they are connected, because i don't have nothing more different than:

Arduino Uno TX --> USB Host shield --> Xbee shield --> Xbee (with a led connected)

Arduino Uno RX -----------------------> Xbee shield --> Xbee (with a led connected)

i tried SoftwareSerial and it's very slow, anyway i don't need more debug, i'm just try to turn on the led on pin 12 but it continue to freeze or not respond even if i try to add several delay

I want to see wires drawn from each connection to each other connection. A text description of wiring is too easy to misunderstand.

I'm sure you know how to use a pencil (or a pen if you are braver than I am) to make a drawing.

...R

maybe i forgot to tell you that they are both connetected with the USB cable to the pc, what i need to draw? the 2 arduino with the 2 shields connected over? there are not any wires, as the controller use the bt dongle connected on the USB Host shield.. have you understand?

OK. I had not realized the XBees are on shields - I had assumed there would be wires between them and the Arduino.

Maybe there is a schematic that shows how the XBee shield uses the Arduino pins?

...R

Ok, don't worry no problem.

The XBee shield it's named "Xbee module sheild V3.0" and a site is linkin to this schematic: Here

From what i've understand the xbee shield use just the Tx and Rx to allow to 2 arduino to comunicate like normal using Tx and Rx but in wireless way, and just replicate the other arduino pins, so i think the connections isn't the problem here...

it's over a week with today that i'm looking everywhere to do this SIMPLE task, i just need to send 4-5 values wireless from Arduino to another one, but it's seems to be more complicated than what i was expecting :frowning:

I don't see Arduino pin numbers in that diagram. I'm guessing from what you say "the xbee shield use just the Tx and Rx to allow to 2 arduino to comunicate like normal using Tx and Rx but in wireless way" that the shield uses HardwareSerial (pins 0 and 1) which is fine as long as you don't want to communicate with the SerialMonitor as well as with the other Arduino.

It seems to me that being able to communicate separately with the SerialMonitor is essential to prove that the wireless system work.

I do think the code in Serial Input Basics will work - it's just that I don't know how to demonstrate that.

Sorry, I am not familar with the XBee system. I have use nRF24L01+ modules which are not on shields and use SPI rather than serial to communicate with the Arduino.

...R