1

The data that I am getting on Putty

I am currently working on a personnal project and I would like at the moment to understand the basics of ADC using DMA and transmitting values using UART to my computer. I am working on STM CubeIDE and I did the right configuration of the ADC using pin A0 linked to a potentiometer, thus transmitting analog values between 0 and 4096 depending on its resistance.

I am using a circular buffer and ping pong configuration with UART callback and Putty in order to check that I am receiving the right integers. The problem is that I am receiving special caracters but integers which is a real problem since I will need to use these integers to compute the temperature of a sensor using an algorithm. This is what I have tried to do at the moment. With the configuration of TIM2 I am getting in real values using the ADC but I am not able to link the UART DMA and stream those values on my PC.

#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "uart.h"
/* USER CODE END Includes */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

#define BUFFER_SIZE 128
int i;                        // AO!
char msgbuf[BUFFER_SIZE];     // AO!

/* USER CODE END PD */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc;
DMA_HandleTypeDef hdma_adc;

TIM_HandleTypeDef htim2;

UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_tx;
DMA_HandleTypeDef hdma_usart2_rx;

/* USER CODE BEGIN PV */

uint16_t ADC_buffer[BUFFER_SIZE];
uint16_t DAC_buffer[BUFFER_SIZE];

static volatile uint16_t *inBufPtr = &ADC_buffer[0];
static volatile uint16_t *outBufPtr = &DAC_buffer[0];

uint8_t dataReadyFlag; // flag in order to process the data
uint16_t adcdata[1];

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_ADC_Init(void);
static void MX_USB_PCD_Init(void);
static void MX_TIM2_Init(void);
/* USER CODE BEGIN PFP */

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc);
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc);

/* USER CODE END PFP */
HAL_DMA
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart2)
{
    inBufPtr = &ADC_buffer[0];
    outBufPtr = &DAC_buffer[0];
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
    dataReadyFlag = 1;
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart2)
{
    inBufPtr = &ADC_buffer[BUFFER_SIZE / 2];
    outBufPtr = &DAC_buffer[BUFFER_SIZE / 2];
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
    dataReadyFlag = 1;
}

void processData()
{
    static uint16_t leftIn, leftOut;
    static uint16_t rightIn, rightOut;

    for (uint8_t n = 0; n < (BUFFER_SIZE / 2) - 1; n += 2) {
        /*
         * Left Channel
         */
        /* Get ADC input and convert to float */
        leftIn = (uint16_t)inBufPtr[n];
        if (leftIn > 1)
            leftIn -= 2;
        /*Compute new output sample */
        leftOut = leftIn;

        /* Convert back to signed int and set DAC output*/
        outBufPtr[n] = (uint16_t)leftOut;

        /*
         * Right Channel
         */
        /* Get ADC input and convert to float */
                rightIn = (uint16_t)inBufPtr[n + 1];
                if (rightIn > 1)
                    rightIn -= 2;
                /* Compute new output sample */
                rightOut = rightIn;

                /* Convert back to signed int and set DAC output */
                outBufPtr[n + 1] = (uint16_t)rightOut;
    }
    dataReadyFlag = 0;
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/

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

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

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART2_UART_Init();
  MX_ADC_Init();
  MX_USB_PCD_Init();
  MX_TIM2_Init();

  /* USER CODE BEGIN 2 */

  HAL_UART_Receive_DMA(&huart2, (uint16_t *)DAC_buffer, BUFFER_SIZE);
  HAL_UART_Transmit_DMA(&huart2, (uint16_t *)ADC_buffer, BUFFER_SIZE);
  HAL_ADC_Start_DMA(&hadc, (uint32_t *)adcdata, 1);
  HAL_TIM_Base_Start(&htim2);

  // HAL_UART_Transmit_DMA(&huart2, (uint8_t *)ADC_buffer, BUFFER_SIZE);

  // uart_Init(&huart2);

  /* USER CODE END 2 */

  /* Infinite loop */
  while (1)
  {
      if (dataReadyFlag)
          processData();
  }
}
Jonas
  • 121,568
  • 97
  • 310
  • 388
Arthur
  • 11
  • 2
  • So your issue is that you are sending the binary buffer but you want readable text representation instead? – KIIV Mar 21 '23 at 18:57
  • Exactly I would like to transfer analogic values of the voltage using the dma. – Arthur Mar 21 '23 at 20:24
  • Then you'll have to make another much bigger buffer and convert all the values to readable text. As the values are only 0..4095, you can spare one character per sample and count only BUFFER_SIZE*(4+1) (or +2 if you are using \r\n) and then nice little loop over the samples and filling usart buffer. – KIIV Mar 21 '23 at 22:06
  • The thing is that I do not want to use the CPU to perform conversions for instance. Just to stream my integers that my ADC is getting to UART without the CPU. But I see your point with sprintf() – Arthur Mar 22 '23 at 14:12
  • You can send it binary, but you'll have to make the other side to display it correctly (= write your own serial monitor) and you have to hope it won't skip a byte – KIIV Mar 23 '23 at 08:58

0 Answers0