Skip to main content
Visitor II
April 24, 2020
Question

Sending float voltage value via USB CDC.

  • April 24, 2020
  • 4 replies
  • 1591 views

Hello,

I want to send the float type voltage value that I read with stm32f429I discovery card using adc reference voltage via usb cdc. My problem is this; I read the adc reference voltage and voltage value, and I can assign it to a float type variable. But when I want to send this variable via usb, the voltage value is read infinitely and I cannot send it. Can you help with this problem? The codes I use are below;

#include "main.h"

#include "usb_device.h"

#include "usbd_cdc_if.h"

#include <string.h>

#include <stdio.h>

#define VREFIN_CAL ((uint16_t*)((uint32_t)0x1FFF7A2A))

uint16_t adc_value[2];

float Vadc = 0, Vdda = 0;

int count = 0;

char volt_array[16];

void Read_ADC()

{

if(HAL_ADC_PollForConversion(&hadc1, 1000000) == HAL_OK)

{

adc_value[count] = HAL_ADC_GetValue(&hadc1);

count++;

if(count == 2)

count = 0;

Vdda = (float) 3.3 * (*VREFIN_CAL) / adc_value[1];

Vadc = Vdda * adc_value[0] / 4095;

}

}

int main(void)

{

 HAL_Init();

 SystemClock_Config();

 MX_GPIO_Init();

 MX_ADC1_Init();

 MX_I2C1_Init();

 MX_SPI1_Init();

 MX_TIM2_Init();

 MX_USB_DEVICE_Init();

HAL_ADC_Start(&hadc1);

 while (1)

 {

Read_ADC();

sprintf(volt_array, "%.4f\n\r", Vadc);

CDC_Transmit_HS((uint8_t*)volt_array, strlen(volt_array));

 }

}

Thank you for your help.

    This topic has been closed for replies.

    4 replies

    Super User
    April 24, 2020

    You're sending it as a string, not a float.

    > But when I want to send this variable via usb, the voltage value is read infinitely and I cannot send it.

    What does this mean?

    The first time you call Read_ADC(), you'll have adc_value[1] = 0, so your value is infinite. Is that what you mean?

    You're calling CDC_Transmit_HS repeatedly, which isn't going to work if it's already busy. Should still send data occasionally though.

    BTaşk.1Author
    Visitor II
    April 24, 2020

    Hello there,

    Thank you for your answer. When I watch the Vadc value as below, the value is read infinitely. (You can see in the first picture in the Annex-1.)

    while (1)

     {

    Read_ADC();

    sprintf(volt_array, "%.4f\n\r", Vadc);

    CDC_Transmit_HS((uint8_t*)volt_array, strlen(volt_array));

     }

    Vadc value can be read if I don't use the sprintf function. So if I call in the following way, Vadc value can be read. (You can see the second picture in the Annex-2.)

     while (1)

     {

    Read_ADC();

    //sprintf(volt_array, "%.4f\n\r", Vadc);

    CDC_Transmit_HS((uint8_t*)volt_array, strlen(volt_array));

     }

    Super User
    April 24, 2020

    On the first call, adc_value[1] = 0, thus

    Vdda = (float) 3.3 * (*VREFIN_CAL) / adc_value[1];

    is infinity. Thus,

    Vadc = Vdda * adc_value[0] / 4095;

    is infinity as well.

    It looks like you're trying to convert two channels with the same ADC in the same conversion group. This requires DMA to handle effectively. Otherwise, the values will overwrite one another since they share the same output register ADC->DR. What you're trying can work, but only if your CPU is fast enough to handle every single interrupt and if your conversion rate is slow enough.

    From the reference manual:

    13.8.1 Using the DMA

    Since converted regular channel values are stored into a unique data register, it is useful to

    use DMA for conversion of more than one regular channel. This avoids the loss of the data

    already stored in the ADC_DR register.

    BTaşk.1Author
    Visitor II
    April 24, 2020

    Hello,

    Thank you for your answer. Should the use of DMA be for this application as follows?

    #include "main.h"

    #include "usb_device.h"

    #include "usbd_cdc_if.h"

    #include <string.h>

    #include <stdio.h>

    #define VREFIN_CAL ((uint16_t*)((uint32_t)0x1FFF7A2A))

    uint32_t adc_value[2];

    float Vadc = 0, Vdda = 0;

    int count = 0;

    char volt_array[16];

    void Read_ADC()

    {

    if(HAL_ADC_PollForConversion(&hadc1, 1000000) == HAL_OK)

    {

    adc_value[count] = HAL_ADC_GetValue(&hadc1);

    count++;

    if(count == 2)

    count = 0;

    Vdda = (float) 3.3 * (*VREFIN_CAL) / adc_value[1];

    Vadc = Vdda * adc_value[0] / 4095;

    }

    }

    int main(void)

    {

     HAL_Init();

     SystemClock_Config();

     MX_GPIO_Init();

     MX_ADC1_Init();

     MX_I2C1_Init();

     MX_SPI1_Init();

     MX_TIM2_Init();

     MX_USB_DEVICE_Init();

    HAL_ADC_Start_DMA(&hadc1, adc_value, 2); <------- UPDATED

     while (1)

     {

    Read_ADC();

    sprintf(volt_array, "%.4f\n\r", Vadc);

    CDC_Transmit_HS((uint8_t*)volt_array, strlen(volt_array));

     }

    }