I'm still bashing away at this fault, I have tried a lot of different fixes (including USB registry tweaks) but as none of them helped I won't bother listing them here. Here are the relevant bits of my code in case I'm doing something superdumb. Both programs (especially the VB side) are quite big, so I've only included the serial sections. Please bear in mind that the code works perfectly FOR A WHILE, anything between 1 and 16 hours, but not indefinitely. The machine stops 'randomly' after executing a command successfully, and fails to get the 'OK' back to VB. Then VB freezes, and on re-running the app I get 'Port is Closed'. Despite applying DisableSelectiveSuspend, the only way I can recover the connection is by un/re-plugging the USB cable. And yes, I have tried many different USB cables too!
Arduino side:
// tjn 16/10/2012
//
// Status: Working! Interleaves 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>
// Variables get declared...
void setup() {
Serial.begin(38400);
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);
}
//Wait for input string and parse it into usable chunks
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(); // Z 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;
}
// Show VB immediate window that variables are good
Serial.print("x=");
Serial.print(xSteps,DEC);
Serial.print(" y=");
Serial.print(y1Steps,DEC);
Serial.print(" z=");
Serial.print(zSteps,DEC);
Serial.print(" l=");
Serial.print(laserTime,DEC);
Serial.print(" o1=");
Serial.print(offset1,DEC);
Serial.print(" s=");
Serial.print(space,DEC);
Serial.print(" c=");
Serial.print(cut,DEC);
Serial.print(" g=");
Serial.print(gap,DEC);
Serial.print(" i=");
Serial.print(iterations,DEC);
Serial.print(" o2=");
Serial.println(offset2,DEC);
// Do various things with motors and lasers...
Serial.println("OK"); // Reset ready to receive next command from vb
inStr = ""; // Clear input string
stringComplete = false;
oxDir = xDir;
oyDir = yDir;
ozDir = zDir;
}
}
VB (Express 2008) side:
'setup form
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If SerialPort1.IsOpen Then
SerialPort1.Close()
End If
Try
With SerialPort1
.PortName = "Com7" 'check your ports!!! (AMD4400 = 5, Duemilanove = 4, UNO = 7)
.BaudRate = 38400
.Encoding = System.Text.Encoding.ASCII
End With
'Open the port and clear the input buffer
SerialPort1.Open()
SerialPort1.DiscardInBuffer()
Catch Ex As Exception
MsgBox(Ex.ToString)
End Try
End Sub
'release resources after form is closed
Private Sub Form1_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
If SerialPort1.IsOpen() Then
SerialPort1.Close()
End If
End Sub
'This sub gets called automatically when the COM port receives data
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
rxBuffer = (SerialPort1.ReadLine) 'Move recieved data into the buffer
If rxBuffer.StartsWith("OK") Then 'Allows diagnostic messages from Arduino without interfering with comms
enableSend = True
End If
Debug.WriteLine("-> " + rxBuffer)
End Sub
Private Function Output(ByVal CurrentImage As Bitmap) As Bitmap
For i = 0 to Whatever ' 1 to 7000-ish
' Build outString
Debug.WriteLine(outString)
SerialPort1.Write(outString & vbCrLf)
enableSend = False
While enableSend = False
End While
outString = ""
next i
End Function