From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Arduino Nano does not respond to serial over USB from LabVIEW but works with terminal programs

Solved!
Go to solution

I have a new Nano bought from arduino.cc.

I have written a simple program which will return the state of all digital pins and values from the analog pins when a character is received over the USB serial connection.  When I use the Arduino environment terminal, Realterm, or Max's terminal all works as expected.  When I try to use VISA in a VI to do the job, the Nano comm lights flash but no data is returned.

Debugging reveals that the test "if (Serial.available() > 0)" always results in false (TxAllPins() never runs).  I used a software sniffer on the port.  The attached files Max Session.html (all works as expected) and VI Session.html (no response from Nano) show the activity during the write-read cycle.  I have also attached the LV2015 test VI I have been using.

I have tried another new Nano board and also tried running this on an Intel Compute stick (as exe) and another Windows 10 machine with a default install of LV2015 development env.  All run results were the same, no data from the Nano when using the attached VI.

I am aware of the LIFA toolkit, I do not want to use it.

 

Nano Code:

// Communication
#define BAUD_RATE 9600

// Digital pins
#define DIGITAL_PIN_COUNT 12
#define DIGITAL_PINS_START 5
#define DIGITAL_PINS_END 16

// Analog pins
#define ANALOG_PIN_COUNT 8
#define ANALOG_PINS_START 19
#define ANALOG_PINS_END 26

// Analog Reference
// 10-bit analog to digital converter.
float analogScale = 5 / 1024;

// Forward declarations
void TxAllPins(); // Set note in implementation

void setup()
{
	// Set all digital pins to INPUT and initialize the serial communication system
	for (int i = DIGITAL_PINS_START; i <= DIGITAL_PINS_END; ++i)
	{
		pinMode( i, INPUT);
	}
	Serial.begin(BAUD_RATE);
	while (!Serial)
	{
		// Wait for the serial port
	}
}

void loop()
{
	while (true)
	{
		// Read serial if available
		if (Serial.available() > 0)
		{
			delay(50);
			while( Serial.available() ) Serial.read();
			TxAllPins();
		}
		delay(1);
	}
}

void TxAllPins()
{
	// Writes to serial the comma separated values in pin order starting with pin 5 and ending with pin 26,
	// skipping pins 17 and 18, a digital pin value of 1 equates with true and a 0 with false.
	// Digital read pins 5 - 16. Analog read pins 19 - 26
	for (int i = DIGITAL_PINS_START; i <= DIGITAL_PINS_END; ++i)
	{
		Serial.print( digitalRead( i ) );
		Serial.print( ',' );
	}

	for (int i = ANALOG_PINS_START; i <= ANALOG_PINS_END; ++i )
	{
		Serial.print( (analogRead(i) * analogScale), 4 ); // 4 digits of precision
		if( i < ANALOG_PINS_END ) Serial.print( ',' ); // Do not print a comma after the last number sent
	}
	Serial.println();
	//BEGIN DEBUG
	pinMode(LED_BUILTIN, OUTPUT );
	int temp = 0;
	while(temp++ < 10 )
	{		
		digitalWrite(LED_BUILTIN, HIGH );
		delay(500);
		digitalWrite(LED_BUILTIN, LOW );
		delay(500);
	}	
	pinMode(LED_BUILTIN, INPUT );
	// END DEBUG
}





Download All
0 Kudos
Message 1 of 6
(4,173 Views)
  1. Why have the Com port select a numeric then convert it to a string, then coerce that string to a VISA resource? Rube Goldberg much? 
    1. Just create a control for the VISA resource 
    2. vvCapture.PNG
  2. DON'T USE BYTES AT PORT! 
    1. Enable the Termination character in the VISA Serial setup  
    2. Rewrite your Arduino code to send the term char
    3. Set your VISA read to read a higher number of byte than you expect to receive
    4. Now the VISA read will read until is sees the term char or times out
  3. You don't have a loop!
    1. How do you expect to run this when you have no loop?
    2. It is going to run once and stop if it missed the data too bad.
    3. Don't tell us you are using the Continuous Run button 
      1. If so stop doing that and put a loop around everything and a stop button

 

 

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 2 of 6
(4,168 Views)

RTSLVU:

That is an example VI to perform the required action a single time.  That is the purpose of an example VI, to be simple.

Who cares how I develop my instrument resource descriptor as long as it is correct?  This method works great when reading setup from a configuration file.

Did you notice that I am only reading bytes at port for display purposes?  My VISA read is set to 81 bytes which is my packet size including the term chars.  Yes, I could set it higher but this is not related to the problem I am experiencing.  VISA configure serial port with default options gives you 0xA term character and Enable Termination true.  My Nano code sends \n as the final character.

I do not claim to be an expert but I am not new to serial communications, and have done so extensively with instruments and Arduinos in various programming languages including LV.  I would appreciate constructive feedback.  Your comments are not helpful or constructive but appear to be mostly copy/paste of boiler plate responses.

 

0 Kudos
Message 3 of 6
(4,152 Views)

Sorry for the boilerplate responses, you did not say what error you were receiving just 

no data is returned." and those are the most common reasons why serial communications just "don't work".

 

What about that 50mS delay? Maybe you are missing the first few bytes.

 

What is error 1073676294 you are ignoring, VISA Timeout?

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 4 of 6
(4,145 Views)
Solution
Accepted by topic author randol

You are probably unaware that when the COM port is opened to communicate with the Arduino, the Arduino waits to see if firmware is being downloaded or not. It is the behavior of the bootloader.

 

You must account for this behavior !

 

The rule of thumb is for LabVIEW to wait to receive a "I am ready" from the Arduino before sending anything to the Arduino.

 

If you have had prior experience with Arduinos and serial ports with LabVIEW as you write, then why do you have a problem now? ? ?

 

 

As for your Arduino code, there is no need to have while (true) in your loop () .

Loop( )  runs continuously!

 

.

 

0 Kudos
Message 5 of 6
(4,141 Views)

The first thing I noticed when I opened the VI this morning is that there was no VISA Open call.  I accidently removed it while reducing the VI to "simplest form to demonstrate the problem".  Reduction into obscurity, oops.

 


@nyc_(is_out_of_here) wrote:

You are probably unaware that when the COM port is opened to communicate with the Arduino, the Arduino waits to see if firmware is being downloaded or not. It is the behavior of the bootloader.

 

You must account for this behavior !

 

The rule of thumb is for LabVIEW to wait to receive a "I am ready" from the Arduino before sending anything to the Arduino.

 

If you have had prior experience with Arduinos and serial ports with LabVIEW as you write, then why do you have a problem now? ? ?

I have a problem now because this is a test VI.  In general, unless there is a reason not to, I obtain a lock on all COM resources at program init which has resulted in the coincidence that this Arduino behavior has not impacted me.

 

Revised sketch:

// Communication
#define BAUD_RATE 9600

// Digital pins
#define DIGITAL_PIN_COUNT 12
#define DIGITAL_PINS_START 5
#define DIGITAL_PINS_END 16

// Analog pins
#define ANALOG_PIN_COUNT 8
#define ANALOG_PINS_START 19
#define ANALOG_PINS_END 26

// Analog Reference
// 10-bit analog to digital converter.
float analogScale = 5 / 1024;

// Forward declarations
void TxAllPins(); // Set note in implementation

void setup()
{
	// Set all digital pins to INPUT and initialize the serial communication system
	int i = 0;
	for (i = DIGITAL_PINS_START; i <= DIGITAL_PINS_END; ++i)
	{
		pinMode( i, INPUT);
	}
	Serial.begin(BAUD_RATE);
	while (!Serial)
	{
		// Wait for the serial port
	}
}

void loop()
{
	// Initialization stuff that did not belong in setup() goes outside the while loop
	while (true)
	{
		// Read serial if available
		if (Serial.available() > 0)
		{
			switch(Serial.read())
			{
				case 'i' : Serial.println("READY"); break; // initialization complete
				case 'r' : TxAllPins(); break;
				default : ;// do nothing
			}
		}
		delay(1);
	}
}

void TxAllPins()
{
	// Writes to serial the comma separated values in pin order starting with pin 5 and ending with pin 26,
	// skipping pins 17 and 18, a digital pin value of 1 equates with true and a 0 with false.
	// Digital read pins 5 - 16. Analog read pins 19 - 26
	// Digital output pins return
	for (int i = DIGITAL_PINS_START; i <= DIGITAL_PINS_END; ++i)
	{
		Serial.print( digitalRead( i ) );
		Serial.print( ',' );
	}

	for (int i = ANALOG_PINS_START; i <= ANALOG_PINS_END; ++i )
	{
		Serial.print( (analogRead(i) * analogScale), 4 ); // 4 digits of precision
		if( i < ANALOG_PINS_END ) Serial.print( ',' ); // Do not print a comma after the last number sent
	}
	Serial.println();
}





Download All
0 Kudos
Message 6 of 6
(4,096 Views)