11-17-2022 07:52 AM
Hello everybody,
I am currently working on a project with my Arduino Mega and want to build a GUI for it using LabVIEW.
In this project I want to control an electromagnet by a boolean button. Depending if the button is in the "true" or "false" position, a 'string' should get send to the arduino switching the magnet on or turning it off. Since I want to use more components, and with that more buttons to control them, later I need to use a 'string' instead of an 'char' in order to be able to send more detailed commands to the arduino.
In the attachments I send you the code for the Arduino and my LabView VI. The Arduino code should be correct since using the serial monitor of the Arduino IDE for the input works perfectly fine, but with LabView I'm a total beginner, therefore I can't really tell what I did wrong there.
Appreciate your help!
11-17-2022 08:44 AM
The chance is higher for people to help you if you save the VI for at least 5 versions back. Most will not use the latest for good reasons.
11-17-2022 08:52 AM
Hello,
I'll attach a copy for older versions.
I also did some improvements from suggestions I found on the internet. The VI now will send the 'string' to my arduino, but only if I delete the while-loop. With the while-loop (as shown in the VI I uploaded) it still won't work. But I guess I need the loop if I don't want to manually start the program again everytime I want to switch the magnet on / off?
Greetings
11-17-2022 09:30 AM - edited 11-17-2022 09:50 AM
Solution A: You are sending too fast. If you increase the 500 msec wait to more than 1000 msec (try 2500), it should work.
Solution B: You are reading too slow. Use Serial.setTimeout to a value smaller than 500 msec (or restructure the arduino code).
Check the documentation for Serial.readString
https://www.arduino.cc/reference/en/language/functions/communication/serial/readstring/
Serial.readString() reads characters from the serial buffer into a String. The function terminates if it times out (see setTimeout()).
and Serial.setTimeout
https://www.arduino.cc/reference/en/language/functions/communication/serial/settimeout/
Serial.setTimeout() sets the maximum milliseconds to wait for serial data. It defaults to 1000 milliseconds.
So what happens is this: You send the command. The Arduino will enter the serial.available() - branch and start the readString() function. After 500 msec, you are sending the next command, which gets collected by readString(). After another 500 msec, two things happen at the same time: You are sending a third command and readString() returns. This leads to a race condition on whether the third command will make it into the result.* Your "labview" string is then either two or three characters long, and compared it to a string that is one character long, e.g. "A" to "AA", which is false.
[Edited, thanks to @pincpanter] readString then restarts the internal timeout. This step will be repeated as long as you are sending command faster then the timeout can occur.
*: You have incidentally created the inverse of the popular "Bytes at Port" race condition.
While it is not immediately relevant to your problem, you might benefit from checking out this presentation: https://labviewwiki.org/wiki/VIWeek_2020/Proper_way_to_communicate_over_serial
Edit: @pincpanter is correct in that readString() never returns at all. I have edited my answer to show that. The Arduino documentation is, sadly, slightly ambiguous at times. Reducing the timeout should still work, though. Possible alternative: https://reference.arduino.cc/reference/de/language/functions/communication/serial/readstringuntil/
11-17-2022 09:33 AM
According to the documentation (not really good) and other info I found in the web, readString keep filing characters until a timeout elapses. I read on https://arduino.stackexchange.com that this timeout is 1 second. Your program sends a character every 500 ms, so we can guess that readString never returns. You should use two buttons, one to switch on the magnet the other to switch it on; put a wait of 1000+ ms with each VISA write. Check the modified code. I used buttons that are automatically released after read.
11-17-2022 09:53 AM
Don't use Serial.readString() in Arduino! It is extremely slow. Arduino natively works with bytes (char). The object String (mind the capital S) requires a lot of overhead to make it work. Generally you read character by character until you reach the end marker. Take a look at the excellent guide over on the Arduino forum: https://forum.arduino.cc/t/serial-input-basics-updated/382007.
It's good to understand the details of Arduino serial reading, but it takes some time to grasp it. Instead you can use a library that does all the work for you. I personally use https://github.com/p-v-o-s/Arduino-SerialCommand.
Remember that in LabVIEW you have to terminate each string with a new line constant (\n).
11-17-2022 10:12 AM
I noticed now that the example given in the library may be confusing for beginners of Arduino. I've attached a simplified code.
Here is also the LabVIEW code. You can switch without any delay and Arduino gives the reponse practically immediately.
11-17-2022 02:36 PM - edited 11-17-2022 02:37 PM
Communicating with an Arduino is no different than communicating with any other instrument over serial.
Watch this video it will probably solve all your problems, unless your Arduino code is the problem...
VIWeek 2020/Proper way to communicate over serial
11-18-2022 09:05 AM
There exists two main Arduino libraries. LIFA and LINX. LIFA is older, but the firmware is more simple and easy to modify. It has all kinds of built in functions for controlling and reading various sensors. There are provisions for adding your own functions too. I added a watchdog that would go low if I stopped servicing it.
But if you are doing this for some learning process, in communicating to some VISA device then you still might be able to learn something seeing how these toolkits handle it.
Unofficial Forum Rules and Guidelines
Get going with G! - LabVIEW Wiki.
17 Part Blog on Automotive CAN bus. - Hooovahh - LabVIEW Overlord