VB Comms Failure During Long Jobs

Okay Paul, you've got my attention!

I had no idea that String class was problematic, or I would never have used it. It's quite hard to feel your way around a bug when it takes several hours to manifest.

Here's the Arduino code in FULL: I'll post the servo handler loop in the next post, as the full sketch exceeds the forum's character limit

// MMM_matrix_Plotter3 (pairs with same-named VB)
// tjn 16/10/2012
// 
// Status: Interleaving X, Y1, Y2 and Z(B)
// Note: 78 Steps/mm using B servo in Full-wave mode, slack = 36

#include <Wire.h>
#include <iox.h>

// Setup pins (0 and 1 reserved for serial I/O)
byte xctrl1 = 2;                // X-Axis geartrain control 1
byte xctrl2 = 3;                // X-Axis geartrain control 2
byte yctrl1 = 4;                // South-Y geartrain control 1
byte yctrl2 = 5;                // South-Y geartrain control 2
byte y2ctrl1 = 7;               // North-Y geartrain control 1
byte y2ctrl2 = 8;               // North-Y geartrain control 2
byte xypower = 12;              // XY stepper supply
byte lpower = 13;               // Laser logic supply
byte xsensors = 15;             // X-buffer switches
byte ysensors = 14;             // Y-buffer switches
byte scaleFactor = 1;
byte offset1, offset2, space, cut, gap;
byte xStepIdx, y1StepIdx, y2StepIdx, zStepIdx;
int xSteps, y1Steps, y2Steps, zSteps, totalSteps, subSteps, bitIndex, laserTime, tMult;
int xStore, yStore, zStore, pixCount, iterations, dotCount, max1, max2, iTimeIdx = 0;
String inStr = "";              // Hold incoming data
boolean stringComplete = false; // Data complete flag
boolean xStop = false;
boolean yStop = false;
boolean xDir = false;           // TRUE = Clockwise
boolean yDir = false;
boolean zDir = false;
boolean oxDir = false;
boolean oyDir = false;
boolean ozDir = false;
boolean laserOn = false;
long MsDelay;
unsigned char twoWire[] = {
  B01,B11,B10,B00};             // 2-Wire sequence for X/Y steppers
word fullWaveB[] = {            // Full-wave Slave stepper motor sequence
  0x6000,0x2010,0x18,0x4008};
word lampState = 0x0000;
double m, mx, my1, my2, mz, x, y1, y2, z;

void setup() {
  Serial.begin(9600);         // was 38400, but froze
  inStr.reserve(40);          // easily enough for longest command (ie.x7000y7000z1404o13s0c19g6i270o14)
  pinMode(xctrl1, OUTPUT);    // X stepper pin1
  pinMode(xctrl2, OUTPUT);    // X stepper pin2
  pinMode(yctrl1, OUTPUT);    // Y1 stepper pin1
  pinMode(yctrl2, OUTPUT);    // Y1 stepper pin2
  pinMode(y2ctrl1, OUTPUT);   // Y2 stepper pin1
  pinMode(y2ctrl2, OUTPUT);   // Y2 stepper pin2
  pinMode(lpower, OUTPUT);    // Laser power
  pinMode(xypower, OUTPUT);   // XY stepper power
  pinMode(xsensors, INPUT);   // X-buffer switches
  pinMode(ysensors, INPUT);   // Y-buffer switches
  digitalWrite(xypower, LOW); // Power-down XY motors
  digitalWrite(lpower,LOW);   // Power-down laser
  Wire.begin();               // Start 2-wire communications (Arduino as master device)
  IOX.device(0x74, 16);       // 0x74 is address for Servo A (Pitch)
  IOX.write(0x0080, CFGPORT); // P07=INPUT Set ports LOW to make them OUTPUTS
  IOX.write(0x0000, INVPORT); // Set slave device invert ports to all NON-INVERT
  IOX.write(0x000, OUTPORT);  // Power-down Lamp/Fan
  Serial.println("OK?");
  Serial.flush();
  delay(100);
}

void loop() {
  if (stringComplete) {
    if(inStr.indexOf("x") >=0) xSteps = inStr.substring(inStr.indexOf("x")+1,inStr.indexOf("y")).toInt();
    else xSteps = 0;  // X Transit
    if(inStr.indexOf("y") >=0) {
      if(inStr.indexOf("z") >=0) y1Steps = inStr.substring(inStr.indexOf("y")+1,inStr.indexOf("z")).toInt();
      else y1Steps = inStr.substring(inStr.indexOf("y")+1).toInt(); // Y Transit
    }
    else y1Steps = 0;
    if(inStr.indexOf("z") >=0) {
      if(inStr.indexOf("l") >=0) zSteps = inStr.substring(inStr.indexOf("z")+1,inStr.indexOf("l")).toInt();
      else zSteps = inStr.substring(inStr.indexOf("z")+1).toInt(); // Y Transit
    }
    else zSteps = 0;
    if(inStr.indexOf("l") >=0) laserTime = inStr.substring(inStr.indexOf("l")+1).toInt();
    else laserTime = 0;  // Laser On/Off
    if(inStr.indexOf("o") >=0){
      laserTime = inStr.substring(inStr.indexOf("l")+1,inStr.indexOf("o")).toInt();      // Laser On Time
      offset1 = inStr.substring(inStr.indexOf("o")+1,inStr.indexOf("s")).toInt();        // Offset1
      space = inStr.substring(inStr.indexOf("s")+1,inStr.indexOf("c")).toInt();          // Space
      cut = inStr.substring(inStr.indexOf("c")+1,inStr.indexOf("g")).toInt();            // Cut
      gap = inStr.substring(inStr.indexOf("g")+1,inStr.indexOf("i")).toInt();            // Gap
      iterations = inStr.substring(inStr.indexOf("i")+1,inStr.lastIndexOf("o")).toInt(); // Iterations
      offset2 = inStr.substring(inStr.lastIndexOf("o")+1).toInt();                       // Offset2
    } 
    else {
      offset1 = 0;
      space = 0;
      cut = 0;
      gap = 0;
      iterations = 0;
      offset2 = 0;
    }

    if (xSteps < 0) xDir = true;
    if (xSteps > 0) xDir = false;
    if (xSteps == 0) xDir = oxDir;
    if (y1Steps < 0) yDir = true;
    if (y1Steps > 0) yDir = false;
    if (y1Steps == 0) yDir = oyDir;
    if (zSteps < 0) zDir = false;
    if (zSteps > 0) zDir = true;
    if (zSteps == 0) zDir = ozDir;
    if (xStop = true && xDir != oxDir) xStop = false;
    if (yStop = true && yDir != oyDir) yStop = false;
    xSteps = abs(xSteps);
    y1Steps = abs(y1Steps);
    zSteps = abs(zSteps);
    y2Steps = y1Steps;

    if (zDir != ozDir) { // Vertical Slack Handler
      zSteps += 37;      // Z-Slack value (from laser deflection test)
    }

    totalSteps = max(xSteps, y1Steps);
    subSteps = min(xSteps, y1Steps);
    m = (double)subSteps/(double)totalSteps;

    if (m > 0.7) { // vector splitter/dog-legger to avoid bad harmonics between X&Y
      digitalWrite(lpower,LOW);
      if (xSteps > y1Steps) {
        xStore = xSteps;
        yStore = y1Steps;
        xSteps = xStore - y1Steps;
        y1Steps = 0;
        y2Steps = 0;
        digitalWrite(xypower, HIGH);
        xyzServos();
        xSteps = yStore;
        y1Steps = yStore;
        y2Steps = y1Steps;
      }
      if (xSteps < y1Steps) {
        xStore = xSteps;
        yStore = y1Steps;
        y1Steps = yStore - xSteps;
        xSteps = 0;
        digitalWrite(xypower, HIGH);
        xyzServos();
        xSteps = xStore;
        y1Steps = xStore;
        y2Steps = y1Steps;
      }
      // else not used (no adjustment needed when X & Y are equal!  
    }

    if (xSteps != 0 || y1Steps != 0 || zSteps != 0) {
      digitalWrite(xypower, HIGH);
      xyzServos(); // rem-out while testing
    }
    else {
      if (laserTime == 1) {
        digitalWrite(lpower, HIGH); // Laser ON
        IOX.write(0x0200, OUTPORT); // Lamp & Fan ON
      }
      else{
        digitalWrite(lpower,LOW);   // Laser OFF
        IOX.write(0x000, OUTPORT);  // Lamp & Fan OFF
      }
    }

    if (xSteps  == 0 && y1Steps == 0) { // switch OFF motors on end vector
      //digitalWrite(xypower, LOW); // Machine loses registration on power-down!
      if (laserTime == 0) IOX.write(0x0000, OUTPORT); // Turn lamp & fan OFF
    }

    if (xStop == true) Serial.println("X-buffer Hit");
    if (yStop == true) Serial.println("Y-buffer Hit");
    Serial.println("OK"); // Tell VB Arduino's ready to receive next command
    Serial.flush();
    inStr = "";           // Clear input string
    stringComplete = false;
    oxDir = xDir;
    oyDir = yDir;
    ozDir = zDir;
  }
  //else{
    //Serial.println("OK!"); // Tell VB Arduino's ready to receive next command from vb    
    //Serial.flush();
    //delay(1000); 
  //}
}

void serialEvent() {
  while (Serial.available()) { // get new byte
    char inChar = (char)Serial.read(); 
    inStr += inChar;           // add to the inStr
    if (inChar == '\n') {      // Flag if char is vbcrlf
      stringComplete = true;
    } 
  }
}

Any ideas/suggestions would be greatly appreciated.