Go Down

Topic: serial receive issues & freeze (Read 853 times) previous topic - next topic

Pixelwhore

So I'm working on my first real project involving multiple arduinos, Xbee radios, and Processing, and I'm running into some odd behavior with incoming serial data thats causing an arduino to lock up until I open or close the serial monitor.

Basic description:
- arduino #1 has a bevy of sensors and is broadcasting a string of their values (i.e. A496B183C1D1E0F214Z)
- a computer across the room is receiving the broadcast and graphically representing it via Processing
- arduino #2 is receiving the broadcast string (through a NewSoftSerial connection)  and using the values to control three lights via Velleman K8064 boards

Arduino #2 is giving me the problem. After about 3 minutes of clean running, I'll receive a string (the last occurance was '¥496B183C0D1E0F') that doesn't meet the format and locks up board until I either open or close the serial monitor. At that point it will run fine for about another 3 minutes until it runs into the same problem. I know the strings being sent from arduino #1 are fine, because I'm monitoring them on the other computer. Since this is my first project with all this, I'm at a loss for what the problem could be, and would appreciate any help.

Here's the code running on arduino #2. Please forgive the sloppiness, my only other coding experience is with vbscript:

Code: [Select]

// import libraries
#include <NewSoftSerial.h>
#include <WString.h>

// make xbee serial
NewSoftSerial Xbee(2, 3); //new rx/tx for Xbee

// define PWM pins
const int PWM1 = 12;
const int PWM2 = 10;
const int PWM3 = 9;

// define variables
int AVal = 0;
int BVal = 0;
int CVal = 0;
int DVal = 0;
int EVal = 0;
int FVal = 0;

void setup() {
 
 //serial settings
 Serial.begin(9600);
 Serial.flush();
 
 //xbee settings
 Xbee.begin(9600);
 Xbee.flush();
 
 //pin settings
 pinMode(PWM1, OUTPUT);
 pinMode(PWM2, OUTPUT);
 pinMode(PWM3, OUTPUT);
 
}

void loop() {
 
String dataString;
byte inByte = 0;

 //get to beginning
 while (inByte != 'A') {
   if(Xbee.available() > 0) {
     inByte = ((char)Xbee.read());
   }
 }

do
{
  dataString.append((char)inByte);
  if(Xbee.available() > 0){
    inByte = ((char)Xbee.read());
  }
} while (inByte != '\n');

Serial.println(dataString);
 
// find placeholders
int A = dataString.indexOf('A');
int B = dataString.indexOf('B');
int C = dataString.indexOf('C');
int D = dataString.indexOf('D');
int E = dataString.indexOf('E');
int F = dataString.indexOf('F');
int Z = dataString.indexOf('Z');

//assign values
AVal = atoi(dataString.substring((A+1), B));
BVal = atoi(dataString.substring((B+1), C));
CVal = atoi(dataString.substring((C+1), D));
DVal = atoi(dataString.substring((D+1), E));
EVal = atoi(dataString.substring((E+1), F));
FVal = atoi(dataString.substring((F+1), Z));

//set valley of fade

int fadeLow;
if (0 <= AVal <= 1026) {
 fadeLow = map(AVal, 0, 1026, 50, 15);
} else if (AVal > 1026) {
 AVal = 1026;
 fadeLow = map(AVal, 0, 1026, 50, 15);
} else if (AVal < 0) {
 AVal = 0;
 fadeLow = map(AVal, 0, 1026, 50, 15);
}

//set peak of fade
int fadeHigh;
if (0 <= BVal <= 1026) {
 fadeHigh = map(BVal, 0, 1026, 255, 155);
} else if (BVal > 1026) {
 BVal = 1026;
 fadeHigh = map(BVal, 0, 1026, 255, 155);
} else if (BVal < 0) {
 BVal = 0;
 fadeHigh = map(BVal, 0, 1026, 255, 155);
}


//set time between PWR
int gapTime = map(FVal, 0, 336, 1, 30); //copy FVal limits from Processing code


//set spikes
int spike1;
if (DVal > 600) { // copy from Processing code
spike1 = 1;
} else {
spike1 = 0;
}

int spike2 = CVal;

int spike3 = EVal;

//fade the lights up
for (int i = fadeLow; i <= fadeHigh; i++) {
 
 if (spike1 == 1) {
   analogWrite(PWM1, 255);
 } else if (spike1 == 0) {
   analogWrite(PWM1, i);
 }
 
 if (spike2  == 0) {
   analogWrite(PWM2, 255);
 } else if (spike2 == 1) {
   analogWrite(PWM2, i);
 }
 
 if (spike3 == 1) {
   analogWrite(PWM3, 255);
 } else if (spike2 == 0) {
   analogWrite(PWM3, i);
 }
 
 delay(gapTime);
}


//fade the lights down
for (int i = fadeHigh; i >= fadeLow; i--) {
 
 if (spike1 == 1) {
   analogWrite(PWM1, 255);
 } else if (spike1 == 0) {
   analogWrite(PWM1, i);
 }
 
 if (spike2  == 0) {
   analogWrite(PWM2, 255);
 } else if (spike2 == 1) {
   analogWrite(PWM2, i);
 }
 
 if (spike3 == 1) {
   analogWrite(PWM3, 255);
 } else if (spike2 == 0) {
   analogWrite(PWM3, i);
 }
 
 delay(gapTime);
}
   
// wrap it up
dataString = NULL;
Xbee.flush();

delay(5000);
 
 }


TeamMCS

Hmm, this problems are always a pain.

Random dropoffs are sometimes an indication of a memory leak. Have you tried dumping the amount of memory remaining to Serial?

I'd also watch those atoi, I can't be 100% sure but I believe they can write outside of their expected boundaries. If they are receiving data slightly to long they may end up writing to some random bit of memory used by your program.

*thinking*

Coding Badly

Code: [Select]
#include <WString.h>
There's a memory leak in the string library.  Have you applied the fix?

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1241618944

Pixelwhore

Quote

There's a memory leak in the string library.  Have you applied the fix?


Bingo. Thanks for pointing that out - I had done some searches earlier but the forum search hasn't been working for me.

Cheers!

Coding Badly

This is what I use to search the site...
http://www.google.com/search?q=%5Bsearch-terms-go-here%5D+site%3Aarduino.cc

And this to search the forum...
http://www.google.com/search?q=%5Bsearch-terms-go-here%5D+site%3Aarduino.cc/cgi-bin/yabb2/YaBB.pl

Go Up