2

Have an STM32 device, that send over Serial port an AES encrypted Hex data any 2 seconds. All messages are finished with newline. My program (with User Interface, not a console one) is able to read from serial and to decrypt the data, even in loop still working good, but the problem is that in loop i can't use the disconnect function, so my program stay in "infinite loop". Here is a code:

public void button1_Click(object sender, EventArgs e)
{
    try 
    {
        serialPort1.PortName = cBoxComPort.Text;
        serialPort1.BaudRate = 9600;
        serialPort1.DtrEnable = true;
        serialPort1.ReadTimeout = 5000;
        serialPort1.WriteTimeout = 500;
        serialPort1.Open();
        lblStatusCom.Text = "Connected";
        lblMessage.Text = "I am on!";

        while (serialPort1.IsOpen)
        {
            string mgs1 = serialPort1.ReadLine();
            byte[] key = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
            byte[] enc = StringToByteArray(mgs1);
            byte[] dec = Decrypt(enc, key);
            lblMessage.Text = getString(dec);
        }
    }
    catch(Exception err)
    {
        MessageBox.Show(err.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        //lblStatusCom.Text = "Disconnected";
    }
}

How can i "put to background" this loop process, so that a user can click to disconnect, if he wish to quit the reading?

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
Peter Boldt
  • 73
  • 11
  • is the device sending data periodically?, You could also use the [DataReceived](https://learn.microsoft.com/en-us/dotnet/api/system.io.ports.serialport.datareceived?view=netframework-4.8) event for such a thing. One important thing here is that if you put it on another thread you cannot simply manipulate GUI controls like `lblMessage.Text = getString(dec);` since they are on another thread. You would need to use [Invoke as in this example](https://stackoverflow.com/a/2562959/5174469) – Mong Zhu Feb 20 '20 at 08:50
  • @Mong Zhu The program sends in any 2 second a long line (around 200 characters) finalized with newline. The time of "printing to serial" is some milliseconds. Do the DataReceived can be used in this case or is better to put it in background? – Peter Boldt Feb 20 '20 at 08:59
  • "The program sends in any 2 second " does it send **every** 2 seconds a string? like at 1:10 then at 1:12 then at 1:14 and so on ?=! – Mong Zhu Feb 20 '20 at 09:04
  • @Mong Zhu Yes, correct every 2 second. – Peter Boldt Feb 20 '20 at 09:06
  • I think 2 seconds is a good interval to use the event. It will fire automatically as soon as data arrives from the device. Remember the cross thread problem! see my first comment – Mong Zhu Feb 20 '20 at 09:16
  • 1
    @Mong Zhu, Thank Yuo will now read first the DataReceived part then the Invoke ducumentation You sent me. Many thanx for Your time and help! – Peter Boldt Feb 20 '20 at 09:21
  • ok, I wrote also an answer of how you could use the event. Good luck! and happy coding – Mong Zhu Feb 20 '20 at 09:23

1 Answers1

2

Here is a version that would use the DataReceived event:

With the button click you would open the port and register the event

public void button1_Click(object sender, EventArgs e)
{
    try 
    {
        serialPort1.PortName = cBoxComPort.Text;
        serialPort1.BaudRate = 9600;
        serialPort1.DtrEnable = true;
        serialPort1.ReadTimeout = 5000;
        serialPort1.WriteTimeout = 500;
        serialPort1.Open();
        lblStatusCom.Text = "Connected";
        lblMessage.Text = "I am on!";

        serialPort1.DataReceived += portDataReceived;

    }
    catch(Exception err)
    {
        MessageBox.Show(err.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        //lblStatusCom.Text = "Disconnected";
    }
}

private void portDataReceived(object sender, EventArgs args)
{
    SerialPort port = sender as SerialPort;

    if (port == null)
    {
        return;
    }

    string mgs1 = port.ReadLine();
    byte[] key = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
    byte[] enc = StringToByteArray(mgs1);
    byte[] dec = Decrypt(enc, key);
    if (lblMessage.InvokeRequired)
    {
        lblMessage.Invoke(new Action(()=> lblMessage.Text = getString(dec)));
    }
    else
    {
        lblMessage.Text = getString(dec);
    }
}
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76