LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Send a keyboard event from labview to C#

Hi,

 

We currently have a program in c# that takes keyboard inputs from a user and will fly a quadrotor. We aim to have a LabView .vi generate keyboard commands based on our experiment and send the commands to the c# code creating a feedback loop where the .vi will keep track of sensor and experimental data.

 

Our problem is that we have tried many different methods to send the keyboard commands in LabView. 

1) http://zone.ni.com/devzone/cda/epd/p/id/3711

2) http://forums.ni.com/t5/LabVIEW/Send-keyboard-commands-to-another-windows-program/td-p/330670/page/2

 

as well as other variations and similar .vi's that do the same thing. Here is an example of a .vi used to press the letter "t" once.

 

http://i.imgur.com/hwmjZ.png

 

 

All of them can write the string to a text (open notepad put cursor in blank window) file but none can do it in such a way that it is detected by the c# code. On my own I can open and run the c# code and press keyboard buttons myself and the commands are recognized, so I think it could be an issue with how LabView sends the keyboard events and how c# reads them. Here is the c# code segment that we are using to read the input commands:

 

public override List<String> GetPressedButtons()
{
          KeyboardState state = device.GetCurrentKeyboardState();

          List<String> buttonsPressed = new List<String>();
          foreach (Key key in Enum.GetValues(typeof(Key)))
          {
                    if (state[key])
                    {
                              if (!buttonsPressed.Contains(key.ToString()))
                              {
                                        buttonsPressed.Add(key.ToString());
                              }
                    }

          }

          return buttonsPressed;

}

 

Can anyone help trying to figure out why using the keybd_event function in LabView can not interface correctly with the above detection code in c#? I can provide any code and clarification if you think it can be helpful.

 

Thanks,

Andy

0 Kudos
Message 1 of 6
(3,956 Views)

A little outside my range of experience here, but are you calling that C# code in a loop and polling the keyboard, or are you responding to events?  To me, it looks like that C# code queries the actual state of the keyboard, whereas keybd_event sends an event.  If your C# code doesn't handle the event, or polls the state of the keyboard in response to the event instead of determining which keys are pressed from the event data, you won't get any keypresses.

 

Also, the MSDN help for keybd_event suggests using SendInput instead.

0 Kudos
Message 2 of 6
(3,952 Views)

Hi,

 

The C# code views the keyboard state. However, LabView only registers and sends keyboard events using keybd_event. I have a class that will listen to keyboard events and then change the keyboard state accordingly. The class I added is here:


https://gist.github.com/471698

 

and I added this to the keyboard input class. I am sure this gets called when the program runs. This basically sets up the listener and it waits for keyup and keydown events. When an event occurs the three functions below this one should be called.

 

public KeyboardInput(Device device) : base()
{
this.device = device;
DetermineMapping();
listener = new KeyboardListener();

listener.KeyDown += new RawKeyEventHandler(OnKeyDown);
listener.KeyUp += new RawKeyEventHandler(OnKeyUp);
}

 

 

However, this never gets called even if I push buttons myself on the keyboard. But I think pushing buttons on the keyboard changes the state directly and there is no event heard from Labview.

 

 

public void OnKeyDown(object sender, RawKeyEventArgs e)
{
Console.WriteLine("Key down. VK Code: " + e.VKCode);
SetKeyState(e.VKCode, 1);
}

 

public void OnKeyUp(object sender, RawKeyEventArgs e)
{
Console.WriteLine("Key up. VK Code: " + e.VKCode);
SetKeyState(e.VKCode, 0);
}

 

private void SetKeyState(int VKCode, byte state)
{
byte[] kbsArray = new byte[255];
if (GetKeyboardState(kbsArray))
{
kbsArray[VKCode] = state;
}
Console.WriteLine("State Changed");
SetKeyboardState(kbsArray);
}

 

Because the above functions are not ever called I think that the events are never heard by the C# code. Has anyone ever established a link between Labview and C#? This is definitely something that my project needs. I can provide both the Labview .vi and the C# solution file if you think that can help.

 

Thanks,

Andy

0 Kudos
Message 3 of 6
(3,898 Views)

awtudor2 wrote:

However, this never gets called even if I push buttons myself on the keyboard. But I think pushing buttons on the keyboard changes the state directly and there is no event heard from Labview.

 

Because the above functions are not ever called I think that the events are never heard by the C# code. Has anyone ever established a link between Labview and C#? This is definitely something that my project needs. I can provide both the Labview .vi and the C# solution file if you think that can help.


I don't quite understand.  You wrote "this never gets called even if I push buttons myself" - so why do you think this is a LabVIEW problem?

It would help to have your C# code and your LabVIEW code.  However, usually when one wants to establish a connection between LabVIEW and C# one uses .NET directly, not some unusual scheme of sending keyboard events as messages through the operating system.

0 Kudos
Message 4 of 6
(3,894 Views)
0 Kudos
Message 5 of 6
(3,890 Views)

Hi,

 

I can't say with certainty where the problem is or even how many there are. I do know that the KeyboardListener.cs class should work according to what I have read online. I also know that if I press the keyboard myself then the state is changed and the correct action is taken. If I try to issue an event from Labview then the event is not captured. Here is the code, it is rather large ~20 MB.

 

https://www.dropbox.com/s/vsvcje1ro364otu/ARDrone.zip

https://www.dropbox.com/s/p3h3tj8bcqc29gk/Forward_backward0924.vi

 

The key listener is in ARDroneInput>Utils>KeyboardListener.cs and the polling takes place in ARDroneInput>KeyboardInput.cs

 

The reason I wanted to use keyboard inputs is because the quadrotor we are using takes keyboard commands W,A,S,D,T and L. Initially I thought having Labview issue these commands would be the simplest method. That may not be the case.

 

I was just thinking that it is not necessary that key events are sent from Labview. Instead, one could send an array representing the frequency of each button press rather than the button press directly. In that case an array that is updated continuously from Labview will just have to be kept track of in the C# code. The C# can then convert that to whatever control input we want. Can it be easier to send a vector of numbers in real time to C#?

 

If you think it is better to establish a connection between Labview and C# using .NET to send keyboard commands (rather than the vector idea above) can you explain that a little more? How does one go about doing that? If you think the vector idea is simpler how should the interface be set-up?

 

I just talked with my collegue and we think that maintaing a .txt file in Labview and having C# read it is the best option. We will begin working on that and will update you tomorrow.

 

Thanks,

Andy 

0 Kudos
Message 6 of 6
(3,884 Views)