Home \ Help \ Search \ Login RSS

Welcome, Guest. Please Login

This forum is now READ-ONLY! Please visit http://forum.wiring.co/ for the new forum.

Wiring ForumProgramming Questions & HelpPrograms › Wiring Board locking up

Pages: 1 2 
Wiring Board locking up (Read 16032 times)
12/22/09 at 23:36:22

Andy   Offline
YaBB Newbies
Terre Haute, Indiana

Posts: 45
*
 
Hello All!  I have a problem where the wiring board locks up and I can't for the life of me figure it out!  I determined the board is locking up by adding the Heartbeat function (onboard LED that flashes every 500ms.  it freezes on or off when the board locks), please take a quick look.

I am writing a serial string of "01,5,5," every 300ms to the wiring board. 

In the code below I also tried removing the while loop thinking it was stuck inside the loop, that was not the case.  One thing to note, it never locks at the same point, some times it runs for 50 seconds, then others for several minutes.  The board is being run from the USB port power.  If I eliminate the data/serial writes to the wiring board does not lock up just sending data.

Many thanks!

Code:
// Analog inputs are 0-5v and scalled 0-1024, 0.004882812
// Correct scalling for 0-3.3 Voltage/Current module is 0.0073982
// Last update 12/22/09 Andy L
#include <Servo.h>
unsigned long previousTime;       //Heartbeat
int interval = 500;               //interval for Heartbeat
int status = LOW;                 //status var for Heartbeat
long time = 0;
long time1 = 0;
long totaltime = 0;
int strval = 1;
long current = 0;
long voltage = 0;
Vector < int > intVector;  // String Vector

Servo myservo;  // create servo object to control a servo 
Servo myservo1;
int pos = 0;    // variable to store the servo position

String buffer = "";        // buffer to read data from the PC
int ready = 0;             // used to mark when we have a complete string to process
int val;                   // use to read a byte from the serial
int HeadLR=90, HeadUD=90;

void setup()
{
  Serial.begin(115200);   
  myservo.attach(24); 
  myservo1.attach(25);
  pinMode(48, OUTPUT); //Heartbeat LED
}
void loop()
{
  time = millis();
  HeartBeat();
  while(Serial.available() > 0) {  // if data vailable
    val = Serial.read();  // read it
    if((val != '\n')) {  // if no end of line
      buffer += val;
    }
    else {  // if end of line reached, ready to parse the buffer
      ready = 1;
      break;
    } 
  }
  //if(buffer.startsWith("#R")){
    //ready = 0;
    //buffer = String("");
  //}
  if(ready == 1) {  // parse the buffer
    if(buffer.startsWith("0")) {  // verify if it is aggod reading
      splitdata();
    }
    buffer = String("");  // clean up the buffer for next reading
    ready = 0;
  }
  time1 = millis() - time;
  SendSerialData();
}

void SendSerialData()
{
  voltage = analogRead(0);// * 0.004882812) * .06369;          // read analog - Pin 0 is raw Battery Voltage
  current = analogRead(1);// * 0.004882812) * .03660;          // read analog - Pin 1 is raw current drain
  Serial.print(voltage, DEC);       //Battery Voltage
  Serial.print(",");
  Serial.print(time1, DEC); //main loop duraton
  Serial.print(",");
  totaltime = millis() / 60000;    //Turn milliseconds to minutes
  Serial.print(totaltime, DEC);    //Minutes booted
  Serial.print(",");
  Serial.print(strval);            //Inputted Text
  Serial.print(",");
  Serial.print(current, DEC);      //Battery current draw
  Serial.print(",");
  Serial.print(HeadLR, DEC);
  Serial.print(",");
  Serial.print(HeadUD, DEC);
  delay(80);   
}

void splitdata(){
  splitString(buffer,',', intVector);
  if (intVector.get(1) > 4 & intVector.get(1) < 176){HeadLR = intVector.get(1);}
  if (intVector.get(2) > 4 & intVector.get(2) < 176){HeadUD = intVector.get(2);}
  myservo.write(HeadLR);
  myservo1.write(HeadUD);
}
void HeartBeat(){
    if((millis() - previousTime) > interval) {
    // invert the LED status
    if (status == LOW) {
      status = HIGH;
    }
    else {
      status = LOW;
    }
    digitalWrite(48, status);
    previousTime = millis();   // mark the time
  }
} 

 
IP Logged
 
Reply #1 - 12/23/09 at 05:48:51

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
What happens if you add
previousTime = millis(); to the setup()?
 
IP Logged
 
Reply #2 - 12/23/09 at 20:37:59

Andy   Offline
YaBB Newbies
Terre Haute, Indiana

Posts: 45
*
 
barragan, thanks!  Not sure I understand, but I added it to setup.  Same problem, the board locked up after about 4-5 minutes.

Code:
// Analog inputs are 0-5v and scalled 0-1024, 0.004882812
// Correct scalling for 0-3.3 Voltage/Current module is 0.0073982
// Last update 12/22/09 Andy L
#include <Servo.h>
unsigned long previousTime;       //Heartbeat
int interval = 500;               //interval for Heartbeat
int status = LOW;                 //status var for Heartbeat
long time = 0;
long time1 = 0;
long totaltime = 0;
int strval = 1;
long current = 0;
long voltage = 0;
Vector < int > intVector;  // String Vector

Servo myservo;  // create servo object to control a servo
Servo myservo1;
int pos = 0;    // variable to store the servo position

String buffer = "";        // buffer to read data from the PC
int ready = 0;             // used to mark when we have a complete string to process
int val;                   // use to read a byte from the serial
int HeadLR=90, HeadUD=90;

void setup()
{
  Serial.begin(115200);
  myservo.attach(24);
  myservo1.attach(25);
  pinMode(48, OUTPUT); //Heartbeat LED
  previousTime = millis();
}
void loop()
{
  time = millis();
  HeartBeat();
  while(Serial.available() > 0) {  // if data vailable
    val = Serial.read();  // read it
    if((val != '\n')) {  // if no end of line
      buffer += val;
    }
    else {  // if end of line reached, ready to parse the buffer
      ready = 1;
      break;
    }
  }
  //if(buffer.startsWith("#R")){
    //ready = 0;
    //buffer = String("");
  //}
  if(ready == 1) {  // parse the buffer
    if(buffer.startsWith("0")) {  // verify if it is aggod reading
      splitdata();
    }
    buffer = String("");  // clean up the buffer for next reading
    ready = 0;
  }
  time1 = millis() - time;
  SendSerialData();
}

void SendSerialData()
{
  voltage = analogRead(0);// * 0.004882812) * .06369;          // read analog - Pin 0 is raw Battery Voltage
  current = analogRead(1);// * 0.004882812) * .03660;          // read analog - Pin 1 is raw current drain
  Serial.print(voltage, DEC);       //Battery Voltage
  Serial.print(",");
  Serial.print(time1, DEC); //main loop duraton
  Serial.print(",");
  totaltime = millis() / 60000;    //Turn milliseconds to minutes
  Serial.print(totaltime, DEC);    //Minutes booted
  Serial.print(",");
  Serial.print(strval);            //Inputted Text
  Serial.print(",");
  Serial.print(current, DEC);      //Battery current draw
  Serial.print(",");
  Serial.print(HeadLR, DEC);
  Serial.print(",");
  Serial.print(HeadUD, DEC);
  delay(80);
}

void splitdata(){
  splitString(buffer,',', intVector);
  if (intVector.get(1) > 4 & intVector.get(1) < 176){HeadLR = intVector.get(1);}
  if (intVector.get(2) > 4 & intVector.get(2) < 176){HeadUD = intVector.get(2);}
  myservo.write(HeadLR);
  myservo1.write(HeadUD);
}
void HeartBeat(){
    if((millis() - previousTime) > interval) {
    // invert the LED status
    if (status == LOW) {
      status = HIGH;
    }
    else {
      status = LOW;
    }
    digitalWrite(48, status);
    previousTime = millis();   // mark the time
  }
} 

 
IP Logged
 
Reply #3 - 12/24/09 at 19:20:27

Andy   Offline
YaBB Newbies
Terre Haute, Indiana

Posts: 45
*
 
I have moved my two servo pins to 16 and 17 on port 2 because they do not share with any other.  I also moved to a different computer, just to be sure.  Still after a couple minutes the Wiring board locks.  I believe either I have hit a firmware bug or my Wiring board is somehow defective.

barragan, is it possible for you to confirm or provide a replacement IO board?

Many thanks, please feel free to Email me directly.
dr.diesel@gmail.com
Andy

EDIT:  I also commented out the splitdata() function eliminating the new function and the servo write command.  The board still locks up.
 
IP Logged
 
Reply #4 - 12/26/09 at 03:02:34

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
Please provide the minimum program that reproduces the error.
 
IP Logged
 
Reply #5 - 12/26/09 at 03:08:00

Andy   Offline
YaBB Newbies
Terre Haute, Indiana

Posts: 45
*
 
Hello!
Code:
// Analog inputs are 0-5v and scalled 0-1024, 0.004882812
// Correct scalling for 0-3.3 Voltage/Current module is 0.0073982
// Last update 12/22/09 Andy L
#include <Servo.h>
unsigned long previousTime;       //Heartbeat
int interval = 500;               //interval for Heartbeat
int status = LOW;                 //status var for Heartbeat
long time = 0;
long time1 = 0;
long totaltime = 0;
int strval = 1;
long current = 0;
long voltage = 0;
long distance = 0;
Servo myservo;  // create servo object to control a servo 
Servo myservo1;

String buffer = "";        // buffer to read data from the PC
int ready, whilebreak = 0;             // used to mark when we have a complete string to process
int val;                   // use to read a byte from the serial
int HeadLR=90, HeadUD=90;

void setup()
{
  Serial.begin(19200);   
  myservo.attach(24); 
  myservo1.attach(25);
  pinMode(48, OUTPUT); //Heartbeat LED
}
void loop()
{
  time = millis();
  delay(80);
  HeartBeat();
  while(Serial.available() > 0) {  // if data vailable
    val = Serial.read();  // read it
    if(val != '\n') {  // if no end of line
      buffer += val;
      whilebreak ++;
      if (whilebreak > 200){
        whilebreak = 0;
        buffer= String("");
        break;
      }
    }
    else {  // if end of line reached, ready to parse the buffer
      ready = 1;
      whilebreak = 0;
      break;
    } 
  }
  if(ready == 1) {  // parse the buffer
    if(buffer.startsWith("0")) {  // verify if it is aggod reading
      splitdata();
    }
    buffer = String("");  // clean up the buffer for next reading
    ready = 0;
  }
  time1 = millis() - time;
  SendSerialData();
  buffer = "";
}

void SendSerialData()
{
  voltage = analogRead(0);                // * 0.004882812) * .06369;          // read analog - Pin 0 is raw Battery Voltage
  current = analogRead(1);                // * 0.004882812) * .03660;          // read analog - Pin 1 is raw current drain
  distance = analogRead(2);
  Serial.print(voltage, DEC);             //Battery Voltage
  Serial.print(",");
  Serial.print(time1, DEC);               //main loop duraton
  Serial.print(",");
  totaltime = millis() / 60000;           //Turn milliseconds to minutes
  Serial.print(totaltime, DEC);           //Minutes booted
  Serial.print(",");
  Serial.print(strval);            
  Serial.print(",");
  Serial.print(current, DEC);             //Battery current draw
  Serial.print(",");
  Serial.print(HeadLR, DEC);
  Serial.print(",");
  Serial.print(HeadUD, DEC);
  Serial.print(",");
  Serial.print(availableMemory());
  Serial.print(",");
  Serial.print(distance, DEC);
}

void splitdata(){
  Vector < int > intVector;  // String Vector
  splitString(buffer,',', intVector);
  if (intVector.get(1) > 4 & intVector.get(1) < 176){HeadLR = intVector.get(1);}
  if (intVector.get(2) > 4 & intVector.get(2) < 176){HeadUD = intVector.get(2);}
  myservo.write(HeadLR);
  myservo1.write(HeadUD);
}
void HeartBeat(){
    if((millis() - previousTime) > interval) {
    // invert the LED status
    if (status == LOW) {
      status = HIGH;
    }
    else {
      status = LOW;
    }
    digitalWrite(48, status);
    previousTime = millis();   // mark the time
  }
}
int availableMemory() { //Returns the amount of free RAM in bytes
  int size = 1024; // Use 2048 with ATmega328
  byte *buf;
  while ((buf = (byte *) malloc(--size)) == NULL)
    ;
  free(buf);
  return size;
} 



If I write "01,94,90," about 300 times from my PC it will lock the board.  I write it at an interval of 100ms.  The duration between writes does not matter, it seems to be the quantity.

I put my Scope on the DTR pin (Pin 2 of the USB to 232 chip) just to make sure it was not being drug low for some unforeseen reason and it was a solid 5v the entire time.

Also forgot to mention, this is Wiring v23.

Many Thanks.
« Last Edit: 12/26/09 at 14:56:23 by Andy »  
IP Logged
 
Reply #6 - 12/26/09 at 23:53:54

Andy   Offline
YaBB Newbies
Terre Haute, Indiana

Posts: 45
*
 
In case it helps.  I modified my program (on the PC side) to count the number of writes before the wiring board locks up.  This is 100% repeatable, the wiring board locks up after 517 writes, this could be a few less as it takes my PC a couple scans to realize the board is locked up.

Thanks
 
IP Logged
 
Reply #7 - 12/27/09 at 00:41:32

Andy   Offline
YaBB Newbies
Terre Haute, Indiana

Posts: 45
*
 
Ok, major discovery!  It appears there is some bug clearing a string with:

Code:
buffer = ""; 



If I change the above to:

Code:
buffer = "0"; 



The problem goes away!  I think clearing the string with "" is causing a memory leak.

barragan, any thoughts on this observation?

Thanks,
Andy
 
IP Logged
 
Reply #8 - 12/27/09 at 07:59:29

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
got it, that's it, thanks Andy, I assume your code is not locking anymore right? I added this to the list. I am running tests now for Wiring running on atmega1281 and atmega2561 microcontrollers, things seem going well Smiley
 
IP Logged
 
Reply #9 - 12/27/09 at 14:07:08

Andy   Offline
YaBB Newbies
Terre Haute, Indiana

Posts: 45
*
 
Correct, the board is not locking up.

Thanks!
 
IP Logged
 
Reply #10 - 01/01/10 at 17:08:20

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
hi Andy, I've been running this sketch and seems to work fine, can you test it? http://wiring.org.co/learning/libraries/readstring.html
 
IP Logged
 
Reply #11 - 01/01/10 at 21:23:24

Andy   Offline
YaBB Newbies
Terre Haute, Indiana

Posts: 45
*
 
Happy New Year barragan!

Yes, the board continues to lockup with the example you provided above and is 100% repeatable. 

I am writing "This is a test" then "L", after 730 cycles the board locks.

Thanks!
 
IP Logged
 
Reply #12 - 01/01/10 at 21:58:56

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
thanks Andy.
 
IP Logged
 
Reply #13 - 01/02/10 at 00:00:50

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
Found it Smiley!!! finally. It was a bug on WString.h in the virtual destructor: it should be:

virtual ~String() { delete [] _buffer; }

instead of:

virtual ~String() { if( _capacity > 0 ) delete [] _buffer; }


it is on svn now if you want to give it a try, or send me a mail and I'll send you the modified files.
Thanks again Andy.
 
IP Logged
 
Reply #14 - 01/02/10 at 00:25:42

Andy   Offline
YaBB Newbies
Terre Haute, Indiana

Posts: 45
*
 
Any chance this is related?

/home/george/wiring/build/linux/work/libraries/Servo/Servo.cpp:46:23: error: WProgram.h: No such file or directory

Good news on the find!
 
IP Logged
 
Pages: 1 2