C#和Arduino使用Stopwatch类在WinForm中显示时间

时间:2017-08-06 15:31:28

标签: c# multithreading arduino serial-port

我是Arduino的新手并使用线程进行编程。 我在Arduino中编写了5个按钮 - 当你按下按钮时会发生一些事情。 我想在C#中接收数据(C#从Adruino发送的端口读取数据。 这使我们能够知道要启动哪个秒表。 按下按钮时,秒表启动并显示经过的时间。 问题是我无法使用多个按钮,例如:我有5个按钮可以随时按下, 但是当前的代码只能处理1个按钮。 我非常感谢你的帮助,因为我已经挣扎了好几天。

Arduino代码:

const int button1 = 3;
const int button2 = 5;

int counter1 = 0;
int counter2 = 0;

int buttonState1 = 0;
int buttonState2 = 0;


void setup() 
{
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  Serial.begin(9600);
}

void loop() 
{
  buttonState1 = digitalRead(button1);
  buttonState2 = digitalRead(button2);

  // *** BUTTON 1 ***
  if (buttonState1 == LOW && counter1==0)
  {
    //Serial.println("connected");
    counter1++;
    delay(100);
  }
  else if (buttonState1 == HIGH && counter1==1) 
  {
    //Serial.println("ready");
    counter1++;
    delay(100);
  }
  else if(buttonState1 == LOW && counter1==2)
  {
    Serial.println("start");
    counter1++;
    delay(100);
  }
  else if(buttonState1 == HIGH && counter1==3)
  {
    Serial.println("stop");
    counter1++;
    delay(100);
  }


  // *** BUTTON 2 ***
  if (buttonState2 == LOW && counter2 == 0)
  {
    //Serial.println("connected");
    counter2++;
    delay(100);
  }
  else if (buttonState2 == HIGH && counter2 == 1) 
  {
    //Serial.println("ready");
    counter2++;
    delay(100);
  }
  else if(buttonState2 == LOW && counter2 == 2)
  {
    Serial.println("start2");
    counter2++;
    delay(100);
  }
  else if(buttonState2 == HIGH && counter2 == 3)
  {
    Serial.println("stop2");
    counter2++;
    delay(100);
  }
}

C#代码:

Stopwatch stopwatch = new Stopwatch();
Stopwatch stopwatch2 = new Stopwatch();

// display time from first stopwatch
private void timer1_Tick(object sender, EventArgs e)
{
   lblSec.Text = stopwatch.Elapsed.Minutes.ToString() + ":" + 
   stopwatch.Elapsed.Seconds.ToString() + "." + 
   stopwatch.Elapsed.Milliseconds.ToString();
}

// display time from second stopwatch
private void timer2_Tick(object sender, EventArgs e)
{
   label1.Text = stopwatch2.Elapsed.Minutes.ToString() + ":" + 
   stopwatch2.Elapsed.Seconds.ToString() + "." + 
   stopwatch2.Elapsed.Milliseconds.ToString();
}  

编辑:有效。 我打开端口并按下按钮时启动一个新线程。循环检查来自端口的值并启动/停止秒表。

public void PortReadLine()
{
    for (int i = 0; i < 4; i++)
    {
        string portValue = myPort.ReadLine();
        switch (portValue)
        {
            case "start\r":
                stopwatch.Start();
                break;

            case "start2\r":
                stopwatch2.Start();
                break;

            case "stop\r":
                stopwatch.Stop();
                break;

            case "stop2\r":
                stopwatch2.Stop();
                break;
        }
    }
}

private void button1_start_Click(object sender, EventArgs e)
{
    myPort.BaudRate = 9600;
    myPort.PortName = "COM3";
    myPort.Open();

    Thread threadPort = new Thread(PortReadLine);
    threadPort.Start();
}

1 个答案:

答案 0 :(得分:0)

第一次按下按钮并调用ThreadMethodStop()时,看起来好像您正在禁用串口:

if (data == "stop\r")
{
    stopwatch.Stop();
    myPort.Close();  // <== here
}
if (data == "stop2\r")
{
    stopwatch2.Stop();
    myPort.Close();  // <== and here
}

尽量不要关闭注释行上的端口。

接下来,您的counter变量似乎跟踪状态,但在释放按钮后超出范围,loop()中的任何内容都不会将它们返回到满足您&&的值1}}条件:

else if(buttonState2 == LOW && counter2 == 2)
{
   Serial.println("start2");
   counter2++;
   delay(100);
}
else if(buttonState2 == HIGH && counter2 == 3)
{
   Serial.println("stop2");
   counter2++;
   delay(100);
}

例如,在增加counter2之后,看看它的值是4,因此永远不再满足if语句中的条件?我认为你需要

else if(buttonState2 == HIGH && counter2 == 3)
{
  Serial.println("stop2");
  counter2 = 2; // make ready to return to start2 condition OR
  counter2 = 0; // return to initial state, do one of these...
  delay(100);
}

当然对另一个按钮也一样。