简体   繁体   中英

c# key down command to arduino

hello I have troubles with my robotic wheelchair controlled by c# app. I can cotrol car by button which is doing good. Problem is controling by keyboard letter. When i pres and hold W, A, S, D c# constantlly send commands to arduino and that can produce motor freeze and continious drive. Question is have I can modifiy c# code to send just one command(not continus sending about 10 times per second same command) like when I pressed button.

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        switch (e.KeyCode)
        {
            case Keys.W:
                Arduino.Write("R");
                break;
            case Keys.S:
                Arduino.Write("A");
                break;
            case Keys.A:
                Arduino.Write("I");
                break;
            case Keys.D:
                Arduino.Write("S");
                break;
        }
    }

Have you thought about implementing a timer to cause a delay between the writing to the Arduino? You can compare the time at which the key was pressed, with a function that returns whether a specific time period has passed (returning true or false if it has), which if true can call your Arduino.Write function. Although the function will call continuously, the writing to the Arduino will be delayed depending on your timer.

Question is formatted differently, but I believe this may help you: How can I get rid of character repeat delay in C#?

Try this:

// Add this before all the methods
private bool canSend = true;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    var timer = new Timer();
    timer.Interval = 5000; // Example value, multiply number of seconds by 1000 to get a value
    timer.Tick += new EventHandler(TimerTick);
    if (!canSend) return;
    switch (e.KeyCode)
    {
        case Keys.W:
            Arduino.Write("R");
            break;
        case Keys.S:
            Arduino.Write("A");
            break;
        case Keys.A:
            Arduino.Write("I");
            break;
        case Keys.D:
            Arduino.Write("S");
            break;
    }
    canSend = false;
    timer.Start();
}
private void TimerTick(object sender, EventArgs e)
{
    canSend = true;
}  

What this does is check if it can send the command. If it can, it will start a new timer (for 5 seconds in the example i made) and reset the bool so it can send it again.

The best solution is to set a timeout or locking resource during a specific time (using Mutex / Lock)

private bool isArduinoFree=true;
private int _timeOut=500; //equal to half second
 private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (isArduinoFree)
           {
            isArduinoFree=false;
            switch (e.KeyCode)
            {
                case Keys.W:
                    Arduino.Write("R");
                    break;
                case Keys.S:
                    Arduino.Write("A");
                    break;
                case Keys.A:
                    Arduino.Write("I");
                    break;
                case Keys.D:
                    Arduino.Write("S");
                    break;
            }
            Thread.Sleep(_timeOut);
            _isArduinoFree=true;
           }
   }

Caution: if you use a Sleep it will freeze you can creat a task and start it.

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