LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Joystick Read + Serial Write to Arduino with LabVIEW

Hello all!

 

I am a new member using LabVIEW for work, school and personal projects (yikes I'd better becomes proficient!) and was hoping to get some advice on the best way to send serial commands from a joystick.

 

I already posted requesting help on how to send string commands to an Arduino using the Basic Serial Read and Write example (http://forums.ni.com/t5/LabVIEW/Problem-with-serial-port-readings-from-LabVIEW-to-Arduino/m-p/177837... and was able to get that issue resolved. As it stands I currently need some help devising my game plan with regard to how the commands are set.

 

Essentially the joystick control will be divided into 2 parts; the buttons, off which there are elevel, and the axis. With regard to the buttons I have so far added a modified Serial Read and Write that includes only the 'Write' with a constant string character 'A' which is triggered when Button 2 is pressed. This has successfully triggered an LED I had hooked up to an Arduino which had a Serial.read() function that was instructed to send power to a pin when it matched 'A'.

 

First question: What is the best way to set up the buttons so they do not clutter up the Serial Port? Is there a switch case function in LabVIEW that I could wire to a single Serial Write where different buttons will trigger corresponding string constants? Or do I have to attach a Serial Write to every button? This seems like it would take up more space and complicate things expecially when two buttons are pressed simultaneously.

Second question: What is the best way to time this? The Serial Read and Write is meant for one write at a time (manually triggered) while I want it to check every X milliseconds so I can send a stream of commands. I tried a timed loop but am unsure what it needs to encompass and what an appropriate time frame should be.

Third question: My idea for dealing with the joystick is to set up a grid for the axis based on the readings they output and use numerical comparisons to isolate commands. For example if the X and Y axis are from 1-10 each, I would say when X>7 & Y>& (top right corner), send 'B'. Again looking for advice on timing.

 

All advice is appreciated, I apologize in advance for any errors I make due to my experience level.

 

Yusif Nurizade

0 Kudos
Message 1 of 36
(4,748 Views)

Hi Akello,

 

To answer your questions:

 

1) Use a Case Structure. You can create each new case by right clicking on the top and adding a new case. You should add a new case for every different button input to achieve this I believe.

 

2) If you already know you want to read/write at certain intervals, a timed loop would probably be your best bet. You would have a loop (while loop or for loop) with a wait for ms inside of it. The loop will execute all of the code inside and will not move on until everything is executed including your wait. The time frame that you need to consider are the latencies of your joystick and the Arduino. Possibly a better way to achieve communication is with a hand-shaking system so that you only send data to the Arduino when it is ready.

 

3) For your comparisons, you should be find if you just use logic. This part will be easier if you already know the cuttoff ranges. Use the logic generated from the inputs to feed into a case structure that determines which code should be executed.

 

Good luck!

 

Jason L.

Product Support Engineer
National Instruments
0 Kudos
Message 2 of 36
(4,718 Views)

Thanks for the response Jason!

 

I actually made some progress today before seeing your message so let me give a little update:

 

1) I got the case structure working although I have some issues with it. First of all, when the boolean button values go through the array and are converted to numeric, they appear in powers of 2. Is there any way I can keep them in the digits range? I will probably avoid this since there would be a risk of overlap (pressing button 1 + button 2 would trigger the numeric equivalent of button 3 in digits) but I am curious if and how it is doable. More importantly, as you will see from my attached VI, the case structure was built without a timed loop and includes a serial write in each case. This works but it is messy and feels like bad programming. I was thinking of keeping the Serial Write outside of the case structure and leaving only strings there. The Serial Write would be outside of it and in a timed loop, any thoughts? I might just be pulling this out of nowhere.

 

2) Could you please elaborate on a hand-shaking system? I am unfamiliar with the term.

 

3) Logic works, I'll begin implementing once I am done with the buttons.

 

Thanks again for your help,

Yusif Nurizade

0 Kudos
Message 3 of 36
(4,712 Views)

I did not see the other discussions but I have some suggestions.

First see this basic example and try to make your code much better.

 

1) You are not closing the port after you abort the program. This makes error when you run again you code. So, close the serial port always when ever your reading and writing completes.

2) Drag out the serial initialization out to the while loop. Don't initialize the port for every new iteration. BTW, You not closing the port and opening many times in while loop.Smiley Mad

3) See the below example and make your changes according to that and also use some delay time when you are reading or writing to serial device.

http://zone.ni.com/devzone/cda/epd/p/id/2669

0 Kudos
Message 4 of 36
(4,704 Views)

1) How did you want the boolean values to be convered if not in powers of two? In other words, can you give an example of what numbers you want based off what buttons are pressed?

 

Like what shjukheter says, I would agree in that you should pull the configure serial port out of the while loop as you only need to configure your serial port once. Also make sure that you are closing your serial port (VISA close) at the end of the process when you are done writing.

 

2) By hand-shaking I meant that you would make the Arduino send a response back to your machine when it receives the command, and you only send commands back to it after you recieve this "OK" message. This way you are garaunteed that you are sending commands to the Arduino only when it is ready for it. It may take a little bit more programming, but you're program will be more streamlined in the end. It also causes little bit more latency, I don't know if this will be an issue for your application goals though.

Product Support Engineer
National Instruments
0 Kudos
Message 5 of 36
(4,690 Views)

Thank you for the responses friends! Let me first respond to the point you brought up before moving on to my own concerns:

 

shjukheter:

1) I added the serial port close inside the while loop but the program would not run until I took it out of the while loop. Is this an issue? Seems like it will only close when all the writing is done not everytime.

2) Done.

3) I originally started with this example but took off the things I did because it worked without them and I didn't understand why I needed them. The code seems to work better now and I've added the delay time to the while loop as well.

 

Jason:

1) I am fine with the powers of two, in fact it makes life easier and avoids the potential problems that a 1-11 would cause. My question was more theoretical, for my general LabVIEW knowledge; could this been done?

 

2)My application goals are for the joystick to stick to send single letter strings to the Arduino which will manipulate pins based accordingly. I started out speaking back and forth between them; the LabVIEW VI would send a string and the Arduino would send a string back to be read. The actual communication is working fine now, do I still need this handshaking?

 

 

Whew, OK so I am including my design so far. The final step will be to tigger similar strings based on the axis which will be divided among N, S, E, W, NW, NE, SW, SE and the degrees of intensity each. There will be a visual LED on the VI that displays what what triggered and I am currently trying to figure out how to get the individual values to be compared and submitted into the same boolean drop down. Hopefully I can unbundle the axis block just like the button block and then set up logic gates for boolean cases and use the same switch case I was using. Any suggestions?

 

Thanks again for the help,

Yusif 

0 Kudos
Message 6 of 36
(4,669 Views)

Guys I finished the for the directional sensors as we had discussed and ran into a problem I cannot figure out:

 

1. Only some of my LEDs are lighting while some are unresponsive even when I see their required values getting reached on the axis.

2. The LEDs are not turning off when the joystick moves out of their position.

3. The number indicator that I added to my array displays odd numbers which makes no sense since it should only be in powers of 2.

 

Please help!

 

Yusif

0 Kudos
Message 7 of 36
(4,646 Views)

Hi Akello,

 

The serial port close inside the loop will attempt to close the port every iteration. You just need to do so once after the loop. This is the same for the open serial port. If it is inside the loop, the program will attempt to open the port every iteration, which is impossible unless you are closing it in the iteration. You're two options is to have both in the loop or both out of the loop, the latter being more optimal.

 

I don't think you need handshaking as long as the communication is fine 🙂

Product Support Engineer
National Instruments
0 Kudos
Message 8 of 36
(4,610 Views)

Yusif,

 

Try Creating another (simpler) program to test the functionalities of your LED's. Make sure you are writing the bits to go low to turn off the LED. The digital outputs will most likeley remain in the last state received.

 

Jason

Product Support Engineer
National Instruments
0 Kudos
Message 9 of 36
(4,608 Views)

Jason,

 

I thought of a way to break the directional problem into two pieces; the joystick has a trigger and I was going to rewrite so that while the trigger is not pressed (F,) the directional pad will represent N,S,E,W while when it is pressed the pad represents NW, NE, SW, SE thus avoiding the problem of overlap. Will implement within the next two days an update on my progress.

 

Could you elaborate on what you mean by "writing the bits to go low to turn off the LED"? They are remaining on after switching to a different position. My thought was to negate all other cases in a certain case's position; for example when the N1 is true, all others are set to false, but I wonder if there is an easier way to achieve this. Any advice?

 

As always, your help is greatly appreciated!

 

Yusif

0 Kudos
Message 10 of 36
(4,591 Views)