C# and Arduino Timeout function

别说谁变了你拦得住时间么 提交于 2021-01-29 08:50:56

问题


I'm currently working with a Arduino IDE and C# enviroment for a project. The principal idea is write and read values from some variables. I would like implement a Timeout after I change a variable to confirm that the change was done correctly or if happend a communication error. Could Anyone helpme with a Link or PDF info to understan the way to implement this feature? This is a part from the code:

C#

    private void connectToArduino()

    {

        isConnected = true;
        string selectedPort = comboBox1.GetItemText(comboBox1.SelectedItem);
        port = new SerialPort(selectedPort, 115200, Parity.None, 8, StopBits.One);
        port.Open();
        port.Write("#START\n");
        button1.Text = "Disconnect";
        label5.Text = "Ready!";
        label5.ForeColor = Color.Blue;
        label7.Text = "Ready!";
        label7.ForeColor = Color.Blue;
        textBox5.Text = "0";
        textBox6.Text = "0";
        textBox8.Text = "0";
        textBox9.Text = "0";
    }


    private void disconnectFromArduino()
    {

        isConnected = false;
        port.Write("#STOP\n");
        port.Close();
        button1.Text = "Connect";
        label5.Text = "No ready";
        label5.ForeColor = Color.Red;
        label7.Text = "No ready";
        label7.ForeColor = Color.Red;
        textBox5.Text = "0";
        textBox6.Text = "0";
        textBox8.Text = "0";
        textBox9.Text = "0";
    }

    private void button1_Click_1(object sender, EventArgs e)
    {
        if (!isConnected)
        {
            connectToArduino();
        }
        else
        {
            disconnectFromArduino();
        }
    }


    private void Aplicar1_Click(object sender, EventArgs e)
    {
        if (isConnected)
        {
            port.WriteLine("#SP" + textBox5.Text + "#\n");
        }
        else
        {
            MessageBox.Show("Connect COM Port");
        }
    }

Arduino

boolean isConnected = false;
String inputString = "";    
boolean stringComplete = false; 
String commandString = "";

int led1Pin = 10;
int led2Pin = 9;
int led3Pin = 8;
int led4Pin = 7;
int button = 13;
int buttonstate;

String Command, Value, Valuenum, Jump, Request;



void setup() 
{
Serial.begin(115200);

}

int numero1;
int numero2;  
int numero3;
int numero4;

 void loop() {



 if(stringComplete) {

 stringComplete = false;
 getCommand();


                if(commandString.equals("#SP")) {
                
                numero1 = getNumToPrint();
                compareNum(numero1);

                          Command = String ("SP");
                          Value   = String ("OK");
                          Jump    = String ("\n");
                          Serial.print(Command + Value);
                
                }

回答1:


Add some multiline textBox10 to write there messages received from the module. It would be helpful in debugging. MessagBox is not a good solution for debugging.

PortReaderLoop was made with help of SerialPort documentation.

I've excluded not changed methods.

private void connectToArduino()
{
    isConnected = true;
    string selectedPort = comboBox1.GetItemText(comboBox1.SelectedItem);
    port = new SerialPort(selectedPort, 115200, Parity.None, 8, StopBits.One);

    port.ReadTimeout = 500;
    port.WriteTimeout = 500;

    port.Open();
    port.Write("#START\n");
    button1.Text = "Disconnect";
    label5.Text = "Ready!";
    label5.ForeColor = Color.Blue;
    label7.Text = "Ready!";
    label7.ForeColor = Color.Blue;
    textBox5.Text = "0";
    textBox6.Text = "0";
    textBox8.Text = "0";
    textBox9.Text = "0";

    Task.Run(() => PortReaderLoop());
}

private readonly IProgress<string> messageCallback = new Progress<string>(s => 
{
    textBox10.Text += s + "\r\n";
});

private readonly IProgress<string> errorCallback = new Progress<string>(s =>
{
    MessageBox.Show(s);
});

// continuously reads the input and fires callback for each received line
private void PortReaderLoop()
{
    try
    {
        while (isConnected)
        {
            try
            {
                string message = port.ReadLine();
                messageCallback.Report(message);
            }
            catch (TimeoutException) { } // nothing received
        }
    }
    catch (InvalidOperationException) { } // port is not open
}

// the answer to your question is this method and timeouts in connectToArduino()
private async Task PortWriteAsync(string message)
{
    try
    {
        await Task.Run(() => 
        {
            port.WriteLine(message); 
        });
    }
    catch (Exception ex)
    {
        errorCallback.Report(ex.Message);
    }
}

// async to keep UI responsive while writing to Port
private async void Aplicar1_Click(object sender, EventArgs e)
{
    if (isConnected)
    {
        Aplicar1.Enabled = false;
        await PortWriteAsync("#SP" + textBox5.Text + "#\n");
        Aplicar1.Enabled = true;
    }
    else
    {
        errorCallback.Report("Connect COM Port");
    }
}

IProgress helps to execute something in the UI Thread because updating it from the other (pooled) Threads or Tasks is unsafe.

If you're interested in async/await please refer to the documentation

I didn't test the code because I have no such module.



来源:https://stackoverflow.com/questions/62924164/c-sharp-and-arduino-timeout-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!