LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Connecting to STM32 Nucleo-L432KC board to LabVIEW

Hello everyone.

 

I wrote a code for my stm32 Nucleo-L432KC board.

 

Now I'm writing code in LabVIEW in order to send instructions (such as: set the User_selection value in the Nucleo board code) and receive data (such as Temperature variable value in the Nucleo board code) from the stm32 Nucleo-l432kc board.

 

My Nucleo code works as follow:

 - there is a variable named "User_selection" and it's a uint8_t type.

 - for any number in the "User_selection" variable, I have a code (for example: for User_selection=1, the  Nucleo board sends a command with an nRF24L01 module to another Nucleo board).

 

 - After the Nucleo board preform the User_selection command, it waits for new User_selection input.

 

 - The Nucleo board can also receive data from the nRF24L01 module and store it in different variables.

 

 

I wrote a code in LabVIEW for a GUI for the Nucleo board, But I don't know how to interface between the LabVIEW GUI and the Nucleo board. I've read that I need to use the VISA commands in LabVIEW, but I don't know if I need to add libraries or some code in the Nucleo board code and if I need to add some code in the Nucleo board code, where do I insert the code?

I use STM32CubeIDE and STM32CubeMX to program my Nucleo-L432KC board.

 

I want to communicate with my board thru USB communication.

 

 

Can you please help me and tell me what do I need to do (add code in the Nucleo board code (and where to add it), program the Nucleo board in the STM32CubeMX with some function, add some function/code in the LabVIEW GUI, etc')?

 

 

Thanks,

Reshef

0 Kudos
Message 1 of 6
(4,758 Views)

VISA commands sound like a good place to look.

Essentially you need to have your board respond to communications in the way you desire.

Without knowledge of (i.e. having seen) your code (or at least the part relating to communication) it's impossible to guess what you should do.

 

I've attached a (partial) example program I have for an Arduino and LabVIEW communication. Although that's not the same as what you're trying to do, it might highlight one possibility.


GCentral
0 Kudos
Message 2 of 6
(4,711 Views)

Here is my code:

 

The STM32  Nucleo-L432KC code:

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
 * All rights reserved.</center></h2>
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
 */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "spi.h"
#include "usart.h"
#include "usb_device.h"
#include "gpio.h"
#include <stdio.h>
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "nRF24.h"
#include "Comu.h"
#include "GPS.h"
#include "GPSConfig.h"
#include "usbd_cdc_if.h"
//#include "retarget.h"
//#include "HTU21D.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define STATION_ID 0xFF
#define _IO volatile
#define REPORT_TEMP_CMD       0x01
#define REPORT_HUMID_CMD      0x02
#define REPORT_GPSCOOR_CMD    0x03
#define REPORT_TIME_CMD       0x04
#define REPORT_CALSTATUS_CMD  0x05
#define JMP_CMD	              0x06
#define AccPointRepData_CMD   0x07
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
#define ROBOT_INDEX(RobotID)		(RobotID-0x20)
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
typedef struct {
	_IO float Temperature;
	_IO float Humidity;
	_IO char GPS_Coordinates[12];
	_IO char GPS_Time[8];
	_IO uint8_t Calibrated;
} TinyRobot_t;

typedef struct {
	_IO char GPS_Coordinates[12];
	_IO char GPS_Time[8];
	_IO uint8_t Calibrated;
} ControlStation_t;

TinyRobot_t RobotList[20];
 uint8_t dataOut[18];
 uint8_t dataIn[17];
_IO uint8_t RxGotMsg = 0, TxSendData = 0, userSelection = 0, robotID = 0;
_IO static uint8_t nRF24RetStatus, nRFTxCout;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	//char buf[100];
  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI2_Init();
  MX_USART2_UART_Init();
  MX_USB_DEVICE_Init();
  /* USER CODE BEGIN 2 */
	//RetargetInit(&huart2);
	for (int i = 0; i < 17; i++)
		dataIn[i] = 0;
	for (int i = 0; i < 18; i++)
		dataOut[i] = 0;

	/* USER CODE BEGIN 2 */
	TM_NRF24L01_Init(0, sizeof(dataOut));
  /* USER CODE END 2 */
	uint8_t data[6];
	while (1) {
		CDC_Receive_FS(userSelection,1); // Receive the USB data from the LabVIEW GUI
		HAL_Delay(500);
		nRF24RetStatus = TM_NRF24L01_GetStatus();
		if (RxGotMsg == 0) {
			if ((nRF24RetStatus & (1 << NRF24L01_RX_DR)) == (1 << NRF24L01_RX_DR)) {  // rx data
				// need to check pipe
				TM_NRF24L01_GetData(dataIn); // read data and reset flag
				RxGotMsg = 1;
				//nRF24L01SetAckPayload((uint8_t *)&nRF24TxBlock, sizeof(nRF24TxBlock),0);
			}
		}

		if (TxSendData) {

			if ((nRF24RetStatus & (1 << NRF24L01_TX_DS)) == (1 << NRF24L01_TX_DS)) { // data was sent
				// TM_NRF24L01_GetData((uint8_t *) &nRF24JunkRxBlock); // read data
				//nRF24TxBlock.Hight++; // next block to send
				TM_NRF24L01_WriteRegister(NRF24L01_REG_STATUS,1 << NRF24L01_TX_DS); // reset flag
			}
			if ((nRF24RetStatus & (1 << NRF24L01_MAX_RT)) == (1 << NRF24L01_MAX_RT)) {      // max transmition reached
				nRFTxCout = TM_NRF24L01_GetRetransmissionsCount(); // get number of TX counts
				NRF24L01_FLUSH_TX;
				TM_NRF24L01_WriteRegister(NRF24L01_REG_STATUS,(1 << NRF24L01_MAX_RT)); // clear max transmition bit by seting it on
			}
			(void) nRFTxCout;
			TM_NRF24L01_Transmit(dataOut);
			RxGotMsg = 0;
			TxSendData = 0;
		}
		(void) nRF24RetStatus;
		switch (userSelection) {
		case REPORT_TEMP_CMD: {
			sprintf((char*) dataOut, "%d%d", robotID, REPORT_TEMP_CMD);
			TxSendData = 1;
			break;
		}
		case REPORT_HUMID_CMD: {
			sprintf((char*) dataOut, "%d%d", robotID, REPORT_HUMID_CMD);
			TxSendData = 1;
			break;
		}
		case REPORT_GPSCOOR_CMD: {
			sprintf((char*) dataOut, "%d%d", robotID, REPORT_GPSCOOR_CMD);
			TxSendData = 1;
			break;
		}
		case REPORT_TIME_CMD: {
			sprintf((char*) dataOut, "%d%d", robotID, REPORT_TIME_CMD);
			TxSendData = 1;
			break;
		}
		case REPORT_CALSTATUS_CMD: {
			sprintf((char*) dataOut, "%d%d", robotID, REPORT_CALSTATUS_CMD);
			TxSendData = 1;
			break;
		}
		case JMP_CMD: {
			sprintf((char*) dataOut, "%d%d", robotID, JMP_CMD);
			TxSendData = 1;
			break;
		}
		}
		if (RxGotMsg) {
			if (strlen((char*) dataIn) >= 2) {
				if (dataIn[0] == STATION_ID) {
					uint8_t RobotID = ROBOT_INDEX(dataIn[2]);
					switch (dataIn[1]) {
					case REPORT_TEMP_CMD: {
						RobotList[RobotID].Temperature = dataIn[3];
						RxGotMsg = 0;
						break;
					}
					case REPORT_HUMID_CMD: {
						RobotList[RobotID].Humidity = dataIn[3];
						RxGotMsg = 0;
						break;
					}
					case REPORT_GPSCOOR_CMD: {
						strcpyFrom(dataIn,(uint8_t*) RobotList[RobotID].GPS_Coordinates,3);
						RxGotMsg = 0;
						break;
					}
					case REPORT_TIME_CMD: {
						strcpyFrom(dataIn,(uint8_t*) RobotList[RobotID].GPS_Time, 3);
						RxGotMsg = 0;
						break;
					}
					case REPORT_CALSTATUS_CMD: {
						if (strcmpFrom(dataIn, (uint8_t*) "Calibrated", 3))
							RobotList[RobotID].Calibrated = 1;
						else
							RobotList[RobotID].Calibrated = 0;
						RxGotMsg = 0;
						break;
					}
					}
				}
			}

		}

	
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */


/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage 
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 72;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 3;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
	/* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

And here is the LabVIEW GUI (the VISA part):

VISA_LabVIEW.JPG

Note: I'm trying to first only to send a string with the number 1 to run the REPORT_TEMP_CMD in order to see if the LabVIEW GUI communicate with the Nucleo board. But it's not communicating with the Nucleo board. instead, I get this error message when I try to run the LabVIEW GUI:

VISA_LabVIEW_Error_msg.JPG

 

Do you see where is the error in my code? or if I need to add/remove something in the LabVIEW or Nucleo code?

 

 

Thank you very much,

Reshef

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

did you find the solution ,please?

 

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

HELLO dear, i have the same problem we created a program in labview and we want to have it run on STM32 processor with serial port (USB) can u help us please, we would be so thankful, thanks in advance 

0 Kudos
Message 5 of 6
(3,205 Views)

@kaoutarBg wrote:

HELLO dear, i have the same problem we created a program in labview and we want to have it run on STM32 processor with serial port (USB) can u help us please, we would be so thankful, thanks in advance 


You need to be a lot more specific. If you simply want to deploy your LabVIEW program to the STM32, then there are bad news, you simply can't. LabVIEW does not support any STM32 board as a target to deploy its VI code to.

 

If you rather meant, writing a program in C(++) in your favorite STM32 IDE such as the STM32CubeProgrammer software and then communicate to it from a LabVIEW program on your PC through RS-232, Virtual Com USB or TCP-IP, which is what this thread really was about to start with, then you certainly can do that, but then you have to come with a concrete problem you are having. We can't and won't give you a ready made program that does all this.

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 6
(3,197 Views)