Ok..this will be lengthy but I need to explain some background first.
This part of my software is for sorting items running down a conveyor belt. I am using Modbus for the conveyor belt. Modbus will open gates at a specific time to let an item go through the gate. Items will go through certain gates based on weight.
I am monitoring a sensor to determine when an item is on a scale. When the sensor is blocked, the item is weighed and sent to the appropriate gate. Timers are set to open/close the gate.
My code will work for this..the problem is, it will not work for multiple items. By that I mean, while a gate is open the sensor is not being monitored until the gate is closed. So while Item A is on the way to the gate, Item B will not get weighed on the scale when it blocks the sensor. I could have up to 8 items on the line at once. Here is the code I am running now:
private void SensorThread_DoWork(object sender, DoWorkEventArgs e)
{
if (SensorThread.CancellationPending == true)
e.Cancel = true;
else
{
ReadSensor();
}
}
private void SensorThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//if sensor is blocked
if (sensorstatus == 0)
{
//the timers just start the thread
scaleTimer.Start();
}
else
{
sensorTimer.Start();
}
}
private void ScaleThread_DoWork(object sender, DoWorkEventArgs e)
{
if (ScaleThread.CancellationPending == true)
{
e.Cancel = true;
}
else
{
ReadScale();
//SaveWeight();
prevgate = gate;
gate = DetermineGate();
SetOpenDelay();
SetDuration();
}
}
private void ScaleThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//if gate = 0, this means the weight of meat on scale
//is not in any weight range. Meat runs off the end.
if (gate == 0)
{
txtStatus.Invoke(new UpdateStatusCallback(UpdateStatus), new object[] { meatweight.ToString() +
"lbs is out of range"});
sensorTimer.Start();
}
else
{
//open gate
//then close gate
}
}
This code works fine, I just need to be able to account for multiple items on the line. Any suggestions????
I've also tried the following:
private void SensorThread_DoWork(object sender, DoWorkEventArgs e)
{
if (SensorThread.CancellationPending == true)
e.Cancel = true;
else
{
ReadSensor();
}
}
private void SensorThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
sensorTimer.Start();
}
private void ScaleThread_DoWork(object sender, DoWorkEventArgs e)
{
if (ScaleThread.CancellationPending == true)
{
e.Cancel = true;
}
else
{
//sensor blocked
if (sensorstatus == 0)
{
ReadScale();
//SaveWeight();
prevgate = gate;
gate = DetermineGate();
SetOpenDelay();
SetDuration();
//if gate = 0, this means the weight of meat on scale
//is not in any weight range. Meat runs off the end.
if (gate == 0)
{
txtStatus.Invoke(new UpdateStatusCallback(UpdateStatus), new object[] { meatweight.ToString() +
"lbs is out of range"});
}
else
{
//open gate
//close gate
}
}
}
private void ScaleThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
scaleTimer.Start();
}
When I did this, I started both threads when the start button was pressed. I get all kinds of exceptions and the program eventually throws the SEHException and crashes. The other errors I get say "Serial port already opened" or "I/O Error".
I think you need something like this. Don't know if the locks are needed but I added them for safety since you are getting errors
private void SensorThread_DoWork(object sender, DoWorkEventArgs e)
{
int sensor = 1;
while(!SensorThread.CancellationPending == true)
{
int newSensor;
lock(this)
{
newSensor = ReadSensor();
}
//sensor state changed
if(newSensor != sensor)
{
//sensor was 1 and changed to 0
if(newSensor==0)
{
scaleTimer.Start();
}
sensor = newSensor;
}
Thread.Sleep(1);
}
e.Cancel = true;
}
private void ScaleThread_DoWork(object sender, DoWorkEventArgs e)
{
//sensor blocked
//if (sensorstatus == 0)
{
lock(this)
{
ReadScale();
}
//SaveWeight();
prevgate = gate;
gate = DetermineGate();
lock(this)
{
SetOpenDelay();
SetDuration();
}
//if gate = 0, this means the weight of meat on scale
//is not in any weight range. Meat runs off the end.
if (gate == 0)
{
txtStatus.Invoke(new UpdateStatusCallback(UpdateStatus), new object[] { meatweight.ToString() +
"lbs is out of range"});
}
else
{
lock(this)
{
//open gate
}
lock(this)
{
//close gate
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With