简体   繁体   中英

how to read integer values from serial port in C#?

I have a Keyence camera which communicates through RS-232. It is configured to output three integer values when triggered. I'm having trouble reading the integer values. I try to use a char array buffer but it only reads the first + sign in the output. I tested it using putty and output is something like this

+346.0,+261.0,098

I want to know if there is anything I need to use to read integer values like these?

    static void Main(string[] args)
    {

        char[] buffer1 = new char[200] ;


        SerialPort port = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);

        port.Open();
        if (port.IsOpen) { Console.WriteLine("port is now open"); } else { Console.WriteLine("port not opened correctly"); }

        port.Write("T"); //triggers the camera

        port.Read(buffer1, 0, 200);

        for (int i = 0; i < 200; i++)
        {
            Console.WriteLine(buffer1[i]);
        }
        Console.ReadLine();
    }

I've had issues before with reading from the serial port and not reading in everything expected.

Turns out I was reading in the response from the device and it wasn't done yet writing. I figured the serial port object would continue trying to fill the buffer until the read timeout was hit, and that was not what was happening.

In my scenario I knew how many characters I was going to be reading from the serial port. So if you know that you could implement a repeat on the read until your character buffer is full. I don't know if the same would apply if you are reading from SerialPort.BaseStream.

SerialPort serialPort; 

char[] buffer = new char[expectedLength];
int totalBytesRead = 0;

//continue to read until all of the expected characters have been read
while (totalBytesRead < expectedLength)
{
    totalBytesRead += serialPort.Read(buffer, totalBytesRead, expectedLength - totalBytesRead); 
}

This is the code I use (simplified):

public class Scanner : SerialPort
{
    private string _word;
    private int _globalCounter;
    private readonly char[] _rxArray = new char[2047];

    public Scanner()
    {
        DataReceived += MyDataReceivedEventHandler;
    }

    public event EventHandler<CodeScannedEventArgs> CodeScanned;
    private void MyDataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e)
    {
        do
        {
            var rxByte = (byte)ReadByte();

            // end of word
            if (rxByte == 10)
            {
                // first byte (02) and last two bytes (13 and 10) are ignored
                _word = new string(_rxArray, 1, _globalCounter - 2);

                DisplayData(_word);

                _globalCounter = 0;
            }
            else
            {
                _rxArray[_globalCounter] = (char)rxByte;
                _globalCounter++;
            }
        } while (BytesToRead > 0);
    }

    private void DisplayData(string receivedText)
    {
        OnCodeScanned(new CodeScannedEventArgs(receivedText));
    }

    protected void OnCodeScanned(CodeScannedEventArgs e)
    {
        EventHandler<CodeScannedEventArgs> handler = CodeScanned;

        if (handler != null)
        {
            handler(this, e);
        }
    }
}

The scanner I use adds byte 02 as a prefix and bytes 13 and 10 as postfix to everything it scans, so it is pretty easy for me to break it up into words. You'll obviously need to change the implementation slightly so it works for you.

Edit - CodeScannedEventArgs class:

public class CodeScannedEventArgs : EventArgs
{
    public CodeScannedEventArgs(string scannedCode)
    {
        ScannedCode = scannedCode;
    }

    public string ScannedCode { get; set; }
}

I used the port.ReadTo("\\r") and it works, as the output ends with a carriage return.

But I want to know what is the advantage of using a data received event?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM