0
votes

I have a serial port waiting for some weight string from an external scale. The problem is that the scale sends multiple readings, about 8 readings per second, all of which are the same weight, for the same product being weighed. I have to print a label once the weight is received, but since I get multiple readings, it printed a a label with every reading received.

I have tried the following solution, and works for the first two products being weighed, and then triggers multiple prints again.

private void SerialReader_Event(object sender, SerialDataReceivedEventArgs e)
    {
        string dataRead = String.Empty;

        try
        {
            SerialPort port = (SerialPort)sender;
            if (port.IsOpen)
            {
                dataRead = port.ReadExisting();
            }

            portDataRead = new DataRead(HandlePortReadData);
            this.Invoke(portDataRead, new object[] { dataRead });
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Reading Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

private void HandlePortReadData(string dataRead)
    {
        int parsedValue;

        if (!String.IsNullOrEmpty(dataRead))
        {
            var stability = dataRead.Substring(1, 1);

            var weight = dataRead.Substring(2, 5);

            if (stability == "0")   //0 is a Stable wieght
            {
                this.RemoveReceivedEventHandler();

                var parsedSuccess = int.TryParse(weight, out parsedValue);
                if (parsedSuccess)
                {
                    if (parsedValue > _weightTrigger) //only trigger print if weight is greater than (n) weight
                    {
                        if (!this.IsDisposed)
                        {
                            AddWeight(parsedValue);
                            PerformPrint();
                        }
                    }
                }
            }
        }
    }

private void RemoveReceivedEventHandler()
    {
        //remove event
        sp.DataReceived -= SerialReader_Event;
        System.Threading.Thread.Sleep(1000);
        sp.DiscardInBuffer();
        sp.DiscardOutBuffer();

        _timer.Enabled = true;
        _timer.Interval = _weighingDelay;
        _timer.AutoReset = false;
        _timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Tick);
        _timer.Start();
    }

void _timer_Tick(object sender, EventArgs e)
    {
        this.AddReceivedEventHandler();
    }

private void AddReceivedEventHandler()
    {
        if (sp != null)
        {
            sp.DataReceived += SerialReader_Event;
            sp.DiscardInBuffer();
        }
        //InitialiseSerialPort();

        if (_timer != null)
        {
            _timer.Stop();
            _timer.Enabled = false;
        }
    }

As can be seen, when I remove the DataReceived event, I start a timer, which after a few seconds, should add the DataReceived event again.

What am I doing wrong here?

1
Whenever the RemoveReceivedEventHandler is called, I start the timer.user1269016
Just print new data only if something changed.Alex F
You cannot make this reliable. The trouble with removing the event handler is just a foreshadowing of what is going to go wrong in practice, there just isn't any reliable way to keep your program in sync with the stream of packages. You need to talk to the plant engineer(s), some kind of mechanism is required to reliably detect a package entering the scale. Could come from a PLC that controls the conveyor, could require a photo detector, etc.Hans Passant
I had a similar issue with a very sensitive scale, whereby readings would be triggered by the breeze created by someone walking past (or a sneeze!). I built in a mechanism to ignore readings that were +/- a threshold of the previous reading (which I think you've tried to do - or are you just using weights over n?), and after that it was bob on. But it's not clear whether your scale just sends 8 readings a second regardless of whether it thinks the weight has changed.Gareth
I get multiple readings, regardless of the value changed or not. I try and eliminate +- readings by checking for stable weight (0), but even if the weight is stable, I get multiple readings, the scale is constantly sending the data. The print should only happen if the weight exceeds n.user1269016

1 Answers

1
votes

Personally I wouldn't bother trying to remove the events. I'd let the events trigger and find a way to filter the data.

I don't know much about your hardware, but perhaps you could print a label each time the reading goes from being unstable to stable when the weight is greater than zero? Or print a label when you have received a couple of stable values with the same weights, then ignore subsequent weights of the same value. Once a value is stable you could average all of the values you receive and print the label once the reading goes unstable or deviates by a certain margin.