textString/WString hangs my Arduino?

I replaced some low level char-array code with textString http://www.arduino.cc/en/Tutorial/TextString today after some frustration trying to get a time string formatted. Now my arduino hangs after looping several times. I suspect a buffer overflow or that I’m exceeding my available RAM but I don’t know enough about this stuff to know.

Forgive me for pasting the entire code block - it’s a little trashed from troubleshooting. Since the problem could be somewhere other than the string handling, though…

This is code for a lap counter. There is a PIR attached to the sensor pin. On every lap I’m printing the lap number and last lap time to a sparkfun LCD. There are also the requisite blinkenlights. It used to count to 120+ now it only goes to 10 before hanging or resetting.

#include <SoftwareSerial.h>
#include <WString.h>

#define rxPin 2
#define txPin 3
#define LCDdelay 75
#define blinkDelay 150
#define warmup 8
#define lastlap 49

SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

int state = HIGH;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = LOW;    // the previous reading from the input pin

unsigned long time = 0;         // the last time the output pin was toggled
long debounce = 8000;

long loopCount = 0;
long lastLapTime = 0;

int sensorPin = 8;
int switchPin = 9;
int redPin = 13;
int ylwPin = 12;
int grnPin = 11;
int buzPin = 10;

String pBuffer = "";

char message[17];
int i = 0;
char lastMessage[17];
char b[2];

void setup()
{
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);  
  Serial.begin(9600);

  pinMode(sensorPin, INPUT); 
  pinMode(redPin, OUTPUT); 
  pinMode(redPin, OUTPUT); 
  pinMode(ylwPin, OUTPUT); 
  pinMode(grnPin, OUTPUT); 
  pinMode(buzPin, OUTPUT);

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  backlightOn();
  delay(500);
  sPrint("CountBot v1.1");
  sPrint("Sporks R Us Ltd.");
  delay(1500);
  clearLCD();
  sPrint("Warming up PIR..");
  
  for (i=warmup;i>=0;i--){
    delay(1000);
    pBuffer.append(i);
    sPrint(pBuffer.append("..."));
  }
  
  delay(1000);
  clearLCD();
  sPrint("Ready!");
  
  time = millis();

}

void loop()                     // run over and over again
{
  reading = digitalRead(sensorPin);
  
  //digitalWrite(grnPin, reading);
  
  // if we just pressed the button (i.e. the input went from LOW to HIGH),
  // and we've waited long enough since the last press to ignore any noise...  
  if (reading == LOW && previous == HIGH && millis() - time > debounce) {
    
    // ... invert the output

    state = !state;
    
    lastLapTime = millis() - time;
    
    time = millis();  // ... and remember when the last button press was
    
    loopCount++;
    
    // Serial.println(timeFormat(lastLapTime));
    printLap(loopCount,lastLapTime);
    
    blinkLED(buzPin,1); 
  }

  if (loopCount >= lastlap){
     blinkLED(redPin,2);
     blinkLED(ylwPin,2);
     blinkLED(grnPin,2);
  }

  previous = reading;
  
}

void printLap(int lap, long lapTime){
    String buffer = "# ";
  
    // pBuffer.append(loopCount<10 ? "0" : "");
    buffer.append(lap);
   // pBuffer.append(" LL: ");
   // pBuffer.append(timeFormat(lastLapTime));
    sPrint(buffer);
}

/*********************************************************
 * 
 * General functions
 * 
 **********************************************************/

void blinkLED(int targetPin, int numBlinks) {
  // this function blinks the status LED light as many times as requested
  for (int i=0; i<numBlinks; i++) {
    digitalWrite(targetPin, HIGH);   // sets the LED on
    delay(blinkDelay);                     // waits for a second
    digitalWrite(targetPin, LOW);    // sets the LED off
    delay(blinkDelay);
  }
}

String timeFormat(long inTime){
    inTime = inTime / 1000;
    
    String output = "";
    int seconds = (int)(inTime % 60);
    int minutes = (int)((inTime/60) % 60);
    int hours = (int)((inTime/3600) % 24);
    output.append(minutes<10 ? "0" : "");
    output.append(minutes);
    output.append(":");
    output.append(seconds<10 ? "0" : "");
    output.append(seconds);
    return output;
 }




/*********************************************************
 * 
 * LCD functions
 * 
 **********************************************************/
 
void sPrint(String localMessage) {
  clearLCD();
  delay(LCDdelay);
  selectLineOne();
  delay(LCDdelay);
  mySerial.print(lastMessage);     
  delay(LCDdelay);
  selectLineTwo();
  delay(LCDdelay);
  mySerial.print(localMessage);
  strcpy(lastMessage,localMessage);
}

void selectLineOne(){  //puts the cursor at line 0 char 0.
  mySerial.print(0xFE, BYTE);   //command flag
  mySerial.print(128, BYTE);    //position
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
  mySerial.print(0xFE, BYTE);   //command flag
  mySerial.print(192, BYTE);    //position
}
void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
  if (position<16){ 
    mySerial.print(0xFE, BYTE);   //command flag
    mySerial.print((position+128), BYTE);    //position
  }
  else if (position<32){
    mySerial.print(0xFE, BYTE);   //command flag
    mySerial.print((position+48+128), BYTE);    //position 
  } 
  else { 
    goTo(0); 
  }
}

void clearLCD(){
  mySerial.print(0xFE, BYTE);   //command flag
  mySerial.print(0x01, BYTE);   //clear command.
  delay(LCDdelay);
}
void backlightOn(){  //turns on the backlight
  mySerial.print(0x7C, BYTE);   //command flag for backlight stuff
  mySerial.print(157, BYTE);    //light level.
  delay(LCDdelay);
}
void backlightOff(){  //turns off the backlight
  mySerial.print(0x7C, BYTE);   //command flag for backlight stuff
  mySerial.print(128, BYTE);     //light level for off.
  delay(LCDdelay);
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  mySerial.print(0xFE, BYTE);
  delay(LCDdelay);
}

After a quick look at the code behind WString, it seems that it allocates memory on initialization. This means you'll need to specifically declare the maximum length of a string upon initialization.

String output = "";

becomes:

String output = String(10);//will initialize a string with 10char capacity and length 0

I do not know, just guessing.