LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Labview/Arduino bluetooth connection

Solved!
Go to solution

Hi everyone !

I have to pilot a DC motor with an arduino, and to set the duty cycle with labview 2016. The communication MUST be by bluetooth. The bluetooth æodule is a HC-06. Then, I will use a sensor connected to the arduino, and send back the datas to labview.

Blocs.pngThe problem is that I had never use labview before. For now, I can't exchange datas with the arduino.

The code is very simple :

 

String fromArduino;

void setup() {
  pinMode(5,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if(Serial.available()){
    fromArduino = Serial.readString();
    analogWrite(5,fromArduino.toInt());
    Serial.println(fromArduino);
  }
}

There isn't any problem with it, it works well while using the serial monitor of arduino IDE, and I can control the duty cycle by bluetooth using a selfmade android app. (and the hardware is working well)

 

So I tried to use linx (1) to control the arduino. It works using the usb connection, but not with bluetooth. Anyway, I probably need to use my own code on the arduino so linx isn't a good solution right ?

 

Then I used visa (2) but it doesn't work too. I selected the right com port, the bluetooth module was connected, but nothing happened. 

Here are some of the codes I made.

testsBTdiagrams1.jpgThen I tried to just set a digital output of the arduino by send 1 or 0 with labview but it's the same. The bluetooth module is connected, I send the datas by bluetooth, then nothing.

testBTdiagram2.pngAnand the code is :

int data;

void setup() {
  Serial.begin(9600); 
  pinMode(5,OUTPUT);
  pinMode(9,OUTPUT);
}

void loop() {
  if(Serial.available()){
    data=Serial.read();
    if (data==0){
      digitalWrite(5,LOW);
      digitalWrite(9,LOW);
    }
    if (data==1){
      digitalWrite(pin,HIGH);
      delay(500);
    }
    else digitalWrite(9,HIGH);  
    digitalWrite(5,LOW);  
  }
}

I am sure that it's not a big deal, but I can't figure out why it doesn't work. Can anybody help me ?

Cheers

0 Kudos
Message 1 of 12
(6,015 Views)
Solution
Accepted by topic author nitneuk

One problem I see with your first VISA example is that apparently the Arduino toInt method is expecting the string to contain the ASCII representation of an integer, but what you're sending is the raw binary value of the integer. You need to first convert the integer value into a string using something like the "Number to Decimal String" function. There's the reverse problem with your second VISA example; your Arduino code is expecting to receive an integer, but you send it the ASCII characters "1" and space. You need to understand the differences between numbers and ASCII string representations of those numbers, and make sure your LabVIEW code is sending what the Arduino code is expecting to receive.

0 Kudos
Message 2 of 12
(5,995 Views)
Solution
Accepted by topic author nitneuk

Please post actual code not pictures of code.

 

I say this because there must be something wrong in your code as BT devices like the HC-06 install a virtual serial port and become transparent after you pair them with your computer. So communicating with a device connected through an HC-06 is no different than communicating with any other device on a serial port.

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 3 of 12
(5,989 Views)

Hi, thank you for your answer !

 

That's true, I wasn't using the right conversion functions or types, I corrected it.

It wasn't the only problem. While using the VISA, I never called "VISA open".

 

Also, I had a hard time to establish a correct communication because of the delays between each character and between each iteration of the loop.

 

But now it's working, thank you very much.

I upload the code there, it may help someone later.

 

Cheers

0 Kudos
Message 4 of 12
(5,978 Views)

Hi, thank's for your answer.

 

That's true, there were some problems about my code, but also, the communication wasn't properly established.

I didn't use VISA open.

 

Cheers

0 Kudos
Message 5 of 12
(5,976 Views)

In your new code there's a lot screwy with how you're handling the floating point value of the dial control and converting it into a string. I've never seen a "Format into String" function without a format specifier wired, though you have the output string wire positioned so it looks like it's wired to that terminal, which is confusing. By default it will output six digits of precision after the decimal point, which I'm guessing is not what you want, since your Arduino code is expecting an integer string. Your mention of delays between characters is confusing too, can you attach your "1-at-a-time" VI as well so I can take a look?

0 Kudos
Message 6 of 12
(5,973 Views)

Sorry for the delay.

I don't know anything about the format conversion. I just wanted to convert my integer into a string, send it by bluetooth and then convert it into an int. So I found randomly this subVI. The numeric is wired to input1 and the output is resulting String. Here is the code I am using.

 

String duty;
void setup() {
  Serial.begin(9600);
  pinMode(5,OUTPUT);
}

void loop() {
  if(Serial.available()){
    duty=Serial.readString();
    analogWrite(5,duty.toInt());
  }
}

 

As I will use a PID to control the speed of the motor later, maybe I should try to use a float instead of an integer ?

About the delays, I used the smaller ones I could, trying to reduce them until the program doesn't work anymore.

 

I have a VI called 1-at-a-time, but I found it on the internet and it doesn't do what I want. Here is the only one I use.

 

Thank you for your help

 

0 Kudos
Message 7 of 12
(5,948 Views)

Your Duty Cycle control is configured to be a floating point number (see that it's orange and has "DBL", for "double-precision floating point" on it) instead of an integer. When you connect a floating point wire to the input of the "Format Into String" function without wiring up a format string, by default the string that's generated will include a decimal point and six digits of precision. So it's possible to set the control to any floating point value between 0 and 255, and the generated string will be in the format "123.456789". You then have "1-at-a-time.vi" send each character of that string with 5 ms delay between characters. You also run the Duty Cycle control value through a "to I32" conversion which will drop the fractional part before displaying it in the indicator below the control, though the indicator is also configured to display a floating point number.

 

Your Arduino code uses the "readString" function to read from the serial port. readString expects characters to come in one after the other, adding them to the received string, until it sees a delay of 1000 ms (the default timeout setting, unless you changed it elsewhere in your code) with no characters, at which point it finishes. There should be no need to include delays between the sent bytes of the string; the Arduino should have no problem receiving one immediately after the other. However, unless you wait at least one whole second between the end of one string and the beginning of the next one, it will combine them together into the same string. Next the "toInt" function converts the received string into an integer. The documentation is vague about how it does this, but presumably it's interpreting the ASCII characters in the string as decimal digits. It says that if a non-numeric character is encountered the conversion will finish, which happens when it reaches the decimal point in your string. That means it discards the decimal point and the six digits after it, which were sent and received for no purpose.

 

If you're intending to send an integer (which you are), you should change your Duty Cycle control to an integer type, specifically U8. I would only suggest using a floating point number (which would require changing your Arduino code quite a lot) if you need better resolution than 1/255 = 0.39% steps. Normally "Format Into String" has a format string wired to it which tells it how to format the resulting string; if you don't want to bother with that, I'd again suggest using the "Number to Decimal String" function, as it's simpler to use, and if you're feeding it an integer then you don't have to specify a precision.

 

There should be no need for the 5 ms delay between characters, unless something's seriously wrong with your Arduino code that prevents it from receiving and buffering incoming serial data in a timely fashion. However, to satisfy the requirement of at least 1000 ms delay between strings, you need to wait more than 1000 ms before sending the next string, e.g. 1100 ms to be safe. If you don't wait long enough, then the readString will keep adding to the first string it received and will never finish. That 1000 ms delay means that once per second is the fastest you can ever send updates, and your code must sit at the readString until the 1000 ms timeout elapses, preventing it from doing much else in the meantime. You could use setTimeout to make it shorter (e.g. 100 ms) or with more programming you could implement a proper termination character, meaning that after sending the integer you could send e.g. a carriage return character, and the Arduino would immediately know it had received the whole string and it could proceed.

Message 8 of 12
(5,918 Views)

@arteitle wrote:

 

If you're intending to send an integer (which you are), you should change your Duty Cycle control to an integer type, specifically U8. I would only suggest using a floating point number (which would require changing your Arduino code quite a lot) if you need better resolution than 1/255 = 0.39% steps.


One correction, you don't have to use a floating point number to get greater precision, just use an integer wider than eight bits. A U16 has a range of 0-65535, which would give you precision of 0.0015%.

0 Kudos
Message 9 of 12
(5,916 Views)

Thank you so much, I understand how it works !

The precision of 1/255 is enough for the duty cycle and for now, waiting 1100ms is okay so I kept my code and just followed your recommendations on labview.

I will post my code and the VI anyway, it may help someone.

 

Now I have to send integers from the arduino to labview before sending the pwm value but it's another story and maybe another topic later haha

 

Thank you very much

 

String duty;

void setup() {
  Serial.begin ( 9600 );
  pinMode ( 5, OUTPUT );
}

void loop() {
  if ( Serial.available() ) {
    duty = Serial.readString();
    analogWrite ( 5, duty.toInt() );
  }
}

0 Kudos
Message 10 of 12
(5,880 Views)