0

I'm working on a project in ASP.NET and the code behind is in C#. I've been reading data from a scale that sends me "YES" or "NOT" if the weight displayed on the scale is within two numbers that you set on the actual scale. As far as I know those two strings are the only data the scale can send. Right now, A button on the page reads data and changes a label to "good job" or "wrong" (Pretty simply just working on functionality right now). But I've been getting older data when I click the button, for example I'll click it twice with nothing on the scale and get "NOT" and the label will change to "wrong" but once I put something on the scale that is within the limit instead of getting "YES" I'll get something like "NOTYES".

I've got a ReadTimeout on the serial port and I have a thread, but I'm not to familiar with threads this is my first time doing something like this. I added a DiscardInBuffer() to the serial port and it seemed to help a bit, but not too much, I also wasn't too sure where to put it.

I've also been printing to the console so I can see what data is actually getting read. It constantly sends data so I'll have a huge string that is somewhat unpredictable like "NOT\nNOT\nNot\n..." so that's why I cleaned the data.

The button has auto post back and the label is in an update panel, so it runs loadPage(), and then read() and then the buttonClick() - which is essentially useless at this point.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;

namespace ScaleTest
{

    public partial class WebForm1 : System.Web.UI.Page
    {
        public SerialPort port;
        public string scaleData = "";

        protected void Page_Load(object sender, EventArgs e)
        {

            if (IsPostBack)
            {
                Thread readThread = new Thread(Read);
                port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
                port.ReadTimeout = 1000;
                if (port.IsOpen == false)
                    try
                    {
                        port.Open();
                    }
                    catch (Exception oex)
                    {
                        Debug.WriteLine(oex);
                    }
                readThread.Start();
                readThread.Join();
                port.Close();
            }
        }

        public void Read()
        {
            try
            {
                string message;
                string scaleData = port.ReadLine();
                port.DiscardInBuffer();
                Debug.WriteLine(scaleData);
                scaleData = scaleData.Trim().Replace("\r", string.Empty).Replace("\n", string.Empty);
                scaleData = String.Join("", scaleData.Distinct());


                Debug.WriteLine(scaleData);


                if (scaleData == "YES")
                {
                    message = "Good Job!";
                }
                else if (scaleData == "NOT")
                {
                    message = "WRONG!";
                }
                else
                {
                    message = "Try Again.";
                }
                ScaleLabel.Text = message;

            }
            catch (TimeoutException) { }
        }

        protected void ButtonClick(object sender, EventArgs e)
        {
        }

    }
}

If I start with nothing on the scale, run the program and press the button, scaleData will be "NOT" and the label will change to wrong which is correct. But if I put something on the scale within the limit and press the button again, I'll usually have to press the button a few times to get "YES" because it is getting old data and giving me stuff like "NOTYES".

  • 1
    The data is buffered and you have to read until you clear the buffer. – jdweng Jul 05 '19 at 22:06
  • Try using the `DataReceived` event. https://learn.microsoft.com/en-us/dotnet/api/system.io.ports.serialport.datareceived?view=netframework-4.8 – Baddack Jul 08 '19 at 21:55
  • check this out https://stackoverflow.com/a/13755084/891715 – Arie Jul 25 '19 at 10:15

1 Answers1

0

You can try this sample code in this link, which use ReadLine() Method

public static void Main()
{
     _serialPort = new SerialPort();
     _serialPort.BaudRate = 115200;
     _serialPort.PortName = "COM7";
     _serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
}

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        SerialPort sp = (SerialPort)sender;
        if (!sp.IsOpen) return;

        string indata = _serialPort.ReadLine();
        Console.WriteLine(indata);
    }
    catch (Exception) {};
}