0

XBee transmitter stops receiving data.
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

XBee transmitter stops receiving data.

by dl_evans on Sat Sep 09, 2017 7:59 pm

Motor controller gets data from an Arduino wired to a Wii Nunchuck. Everything works fine but after a while, the data stops getting sent.

Example:
{123,321,456,654,789,987}
{123,321,456,654,789,987}
{123,321,456,654,789,987}
{123,321,456,654,789,987}
{123,321,456,654,789,987}
{123,321,456,654,789,987}
{123,321,456,654,789,987}
{123,321,456,654,789,987}
{123,321,456,654,789,987}
{,,,,,}
{,,,,,}
{,,,,,}
{,,,,,}
{,,,,,}
{,,,,,}
{,,,,,}

When I look at the receiver just plugged into the XBee XCTU, the data never appears to stop getting sent. I can leave it on for minutes and it will always show what I'm expecting.

Receiver code
Code: Select all | TOGGLE FULL SIZE
#include <string.h>

boolean cfound = false; // complete command found
boolean cstart = false; // start of command

int cp = 0; // char pointer
char stringIn[50]; // commandbuffer
char *parsed[10];   //parsed strings
int counter = 0;   //initialise the counter

#define SOC '{'
#define EOC '}'

void setup() {
Serial.flush();
Serial.begin(9600);
}

void loop() {
int sa;
char bt;
sa = Serial.available(); // count serial buffer bytes

if (sa > 0) { // if buffer not empty process buffer content
  for (int i=0; i < sa; i++){
   bt = Serial.read(); // read one char from the serial buffer
     
   if (cstart ) {
    stringIn[cp] = bt;
    cp++;
     //Serial.print(bt);
   }
   if (bt == SOC) { // got a start of command
    cstart = true;
    //Serial.println("start");
   }
   if (bt == EOC && cstart) { // check for last command char )
    cfound = true;
    stringIn[--cp] = NULL;
    break; // end for-loop
   }
  }
}
if (cfound) {
   for (int i=0; i<cp; i++){
      //Serial.print(stringIn[i]);   //data is correct at this point
    }
  counter = 0; //initialise the counter
  char *token = strtok(stringIn, ",");
 
  if(token)
  {
   //Serial.println("Token!");
   parsed[counter++] = strdup(token); // You've got to COPY the data pointed to
   token = strtok(NULL, ","); // Keep parsing the same string
   while(token)
   {parsed[counter++] = strdup(token); // You've got to COPY the data pointed to
       token = strtok(NULL, ",");
    if(counter == 6)
    {
       Serial.print("{");
       Serial.print(parsed[0]);
       Serial.print(",");
       Serial.print(parsed[1]);
       Serial.print(",");
       Serial.print(parsed[2]);
       Serial.print(",");
       Serial.print(parsed[3]);
       Serial.print(",");
       Serial.print(parsed[4]);
       Serial.print(",");
       Serial.print(parsed[5]);
       Serial.println("}");
    }
   }
   cp = 0;
   stringIn[cp] = '\0';
   parsed[0] = '\0';
   token = "";
   counter = 0;
   cstart = false;
   cfound = false;
   }
  }
}


Transmit code:
Code: Select all | TOGGLE FULL SIZE
#include <Nunchuk.h>
#include <Wire.h>

int RPWM_Output = 5; // Arduino PWM output pin 5; connect to IBT-2 pin 1 (RPWM)
int LPWM_Output = 6; // Arduino PWM output pin 6; connect to IBT-2 pin 2 (LPWM)

int r_en = 8;
int l_en = 9;
int16_t x_right, x_left, y_forward, y_reverse, tZ, tC;
int m, fwd,rvs,lft,rght,u,dwn;

void setup() {
   
  //Serial
  Serial.begin(9600);
 
  //Nunchuck
  Wire.begin();
  nunchuk_init();
  rst();
  delay(1000);
}

void loop() {

    if (nunchuk_read())
    {
        // Work with nunchuk_data
          //Left / Right
          x_right = nunchuk_joystickX();
         
          if(x_right < 0)
          {
            x_left = x_right*-1;
          }
                 
          if(x_right >= 10)
          {
            right();
          }
          else
          {
            //Serial stop
            rght = 0;
            //analogWrite(LPWM_Output, 0);
          }
 
          if(x_left >= 10)
          {
            left();
          }
          else
          {
            //Serial stop
            lft = 0;
            //analogWrite(RPWM_Output, 0);
          }
 
          //Forward / Reverse
          y_forward = nunchuk_joystickY();
         
          if(y_forward < 0)
          {
            y_reverse = y_forward *-1;
          }
                 
          if(y_reverse >= 30)
          {
            reverse();
          }
          else
          {
            //Serial stop
            rvs = 0;
            //analogWrite(LPWM_Output, 0);
          }
         
          if(y_forward >= 30)
          {
            forward();
          }
          else
          {
            //Serial stop
            fwd = 0;
            //analogWrite(RPWM_Output, 0);
          }

        tC = nunchuk_buttonC();
        if(tC == 1)
        {
          up();
        }
        else
        {
          u = 0;
        }
       
        tZ =nunchuk_buttonZ();
        if(tZ == 1)
        {
          down();
        }
        else
        {
          dwn = 0;
        }
       
        if((tZ == 1) && (tC == 1))
        {
           rst();
        }
    }
    delay(5);
    Serial.print("{");
    Serial.print(fwd);
    Serial.print(",");
    Serial.print(rvs);
    Serial.print(",");
    Serial.print(lft);
    Serial.print(",");
    Serial.print(rght);
    Serial.print(",");
    Serial.print(u);
    Serial.print(",");
    Serial.print(dwn);
    Serial.println("}");
}

void forward()
{
  m = map(y_forward, 10, 110, 0, 1024);
  fwd = m;
  //analogWrite(RPWM_Output, m);
  //Serial.print("F,");
  //Serial.println(y_forward, DEC);
}
void reverse()
{
  m = map(y_reverse, 10, 110, 0, 1024);
  rvs = m;
  //analogWrite(LPWM_Output, m);
  //Serial.print("B,");
  //Serial.println(y_reverse, DEC);
}
void left()
{
  m = map(x_left, 10, 110, 0, 1024);
  lft = m;
  //analogWrite(RPWM_Output, m);
  //Serial.print("L,");
  //Serial.println(x_left, DEC);
}
void right()
{
  m = map(x_right, 10, 110, 0, 1024);
  rght = m;
  //analogWrite(LPWM_Output, m);
  //Serial.print("R,");
  //Serial.println(x_right, DEC);
}
void up()
{
  //Serial.println("U");
  u = 255;
}

void down()
{
  //Serial.println("D");
  dwn = 255;
}
void rst()
{
  x_right = 0;
  x_left = 0;
  y_forward = 0;
  y_reverse = 0;
}

dl_evans
 
Posts: 71
Joined: Mon Apr 18, 2011 11:21 pm
Location: McPherson, KS

Re: XBee transmitter stops receiving data.

by dl_evans on Sun Sep 10, 2017 2:10 am

I think I'm getting closer...

I found something to free up the strdup() function from:
https://stackoverflow.com/questions/25010853/c-freeing-memory-after-strdup

Code: Select all | TOGGLE FULL SIZE
  if(token)
  {
   //Serial.println("Token!");
   parsed[counter++] = strdup(token); // You've got to COPY the data pointed to
   token = strtok(NULL, ","); // Keep parsing the same string
   while(token)
   {
    parsed[counter++] = strdup(token); // You've got to COPY the data pointed to
    token = strtok(NULL, ",");
    if(counter == 6)
    {
       Serial.print("{");
       Serial.print(parsed[0]);
       Serial.print(",");
       Serial.print(parsed[1]);
       Serial.print(",");
       Serial.print(parsed[2]);
       Serial.print(",");
       Serial.print(parsed[3]);
       Serial.print(",");
       Serial.print(parsed[4]);
       Serial.print(",");
       Serial.print(parsed[5]);
       Serial.println("}");
    }
//added code to free up the strdup() function
   free(parsed[counter]); 
   }
   cp = 0;
   stringIn[cp] = '\0';
   parsed[0] = '\0';
   token = "";
   counter = 0;
   cstart = false;
   cfound = false;
   }


This works a lot longer but eventually, the output looks like this:

{123,321,456,654,789,987}
{123,321,456,654,789,987}
{123,321,456,654,789,987}
{123,321,456,654,789,987}
{123,21,456,654,789,987}
{123,,456,654,789,987}
{,,456,654,789,987}
{,,456,654,789,987}
{,,456,654,789,987}
{,,456,654,789,987}
{,,456,654,789,987}
{,,456,654,789,987}


Not even sure how that's happening. I keep copying / pasting the same string {123,321,456,654,789,987} as a test.

dl_evans
 
Posts: 71
Joined: Mon Apr 18, 2011 11:21 pm
Location: McPherson, KS

Re: XBee transmitter stops receiving data.

by dl_evans on Sat Sep 23, 2017 4:15 am

Found a guy on Hackaday doing the same thing to make a Star Wars Gonk droid move. That code helped a lot.

Transceiver / motor driver (not 100% done but I'm sure anyone having a problem could fill in the rest)
Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>

// SoftwareSerial is used to communicate with the XBee
//#include <SoftwareSerial.h>

//SoftwareSerial XBee(2, 3); // Arduino RX, TX (XBee Dout, Din)

int inByte = 0;         // incoming serial byte
String inString = "";    // string to hold input
byte joyx, joyy, zbtn, cbtn, aux1, aux2, aux3;
int MoveCounter = 0;

void setup() {

  // initialize Serial port
  Serial.begin(9600);
 
  Serial.println("Ready.");
}

void loop() {
 
  // 10 times per second
  while (Serial.available() > 0) {
    int inChar = Serial.read();
    //Serial.print(inChar);
    inString += (char)inChar;
    // if you get a newline, parse and print the data
    if (inChar == '\n') {
      if (ParseInput(inString) == 0) {
        TakeAction();
      }
      else {
        Serial.println("Input Error");
      }
      //Serial.println(inString);
      inString = "";
    }
  }
  delay(100);
}

int ParseInput(String inString) {
  String tempString = "";
  int i = 0;

  if (isDigit(inString[0]) == false)  return 1;   //First character must be a digit

  while (i < inString.length() && inString[i] != ',')
  {
    tempString += inString[i];
    i++;
  }
  joyx = tempString.toInt();
  if (joyx > 255) return 1;
  tempString = "";
  i++;

  while (i < inString.length() && inString[i] != ',')
  {
    tempString += inString[i];
    i++;
  }
  joyy = tempString.toInt();
  if (joyy > 255) return 1;
  tempString = "";
  i++;

  while (i < inString.length() && inString[i] != ',')
  {
    tempString += inString[i];
    i++;
  }
  zbtn = tempString.toInt();
  if (zbtn > 1) return 1;
  tempString = "";
  i++;

  while (i < inString.length() && inString[i] != ',')
  {
    tempString += inString[i];
    i++;
  }
  cbtn = tempString.toInt();
  if (cbtn > 1) return 1;
  tempString = "";
  i++;
 
  return 0;
}

void TakeAction() {

    if(joyy >= 200)
    {
      fwd();
    }
    if(joyy <= 50)
    {
      rvs();
    }
    if(joyx >= 200)
    {
      rgt();
    }
    if(joyx <= 50)
    {
      lft();
    }
    if((joyy < 200) && (joyy > 50) && (joyx < 200) && (joyx > 50))
    {
      stp();
    }
}

void fwd()
{
  Serial.println("fwd");
}
void rvs()
{
  Serial.println("rvs");
}
void rgt()
{
  Serial.println("rgt");
}
void lft()
{
  Serial.println("lft");
}
void stp()
{
  Serial.println("stp");
}


Remote / Wii-Mote
Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include "nunchuck_funcs.h"

// SoftwareSerial is used to communicate with the XBee
#include <SoftwareSerial.h>

SoftwareSerial XBee(2, 3); // Arduino RX, TX (XBee Dout, Din)

int RPWM_Output = 5; // Arduino PWM output pin 5; connect to IBT-2 pin 1 (RPWM)
int LPWM_Output = 6; // Arduino PWM output pin 6; connect to IBT-2 pin 2 (LPWM)

int r_en = 8;
int l_en = 9;

int loop_cnt = 0;
String outString = "";    // string to hold output
byte joyx, joyy, zbtn, cbtn;

void setup() {
   
  // Initialize XBee Software Serial port. Make sure the baud
  // rate matches your XBee setting (9600 is default).
  XBee.begin(9600);
  printMenu(); // Print a helpful menu:
 
  //Nunchuck
  //Wire.begin();
  nunchuck_init(); // send the initilization handshake
}

void loop() {
  if ( loop_cnt >= 100 ) { // every 100 msecs get new data
    loop_cnt = 0;
    outString = "";

    nunchuck_get_data();
    //nunchuck_print_data();

    joyx  = nunchuck_joyx();  // ranges from 30 - 226;  131 center
    joyy  = nunchuck_joyy();  // ranges from 38 - 231;  135 center
    zbtn = nunchuck_zbutton();
    cbtn = nunchuck_cbutton();

    outString += (byte)joyx;
    outString += ",";
    outString += (byte)joyy;
    outString += ",";
    outString += (byte)zbtn;
    outString += ",";
    outString += (byte)cbtn;

    XBee.println(outString);
  }
  loop_cnt++;
  delay(1);
}

// printMenu
// A big ol' string of Serial prints that print a usage menu over
// to the other XBee.
void printMenu()
{
  // Everything is "F()"'d -- which stores the strings in flash.
  // That'll free up SRAM for more importanat stuff.
  XBee.println();
  XBee.println(F("SteamPunk Trunk Transmitter"));
  XBee.println(F("============================"));
}


Get the nunchuck_funcs.h here:
[url]
https://github.com/bithead942/GonkPower ... ck_funcs.h
[/url]

dl_evans
 
Posts: 71
Joined: Mon Apr 18, 2011 11:21 pm
Location: McPherson, KS

Please be positive and constructive with your questions and comments.