Get ADC and send through BLE qn9080-DK

cancel
Showing results for 
Search instead for 
Did you mean: 

Get ADC and send through BLE qn9080-DK

3,296 Views
ashkanrezaee
Contributor III

Hi,
I want to use and change wireless uart program to get some data from ADC and send it through BLE to phone. Is there anyone to help me? I do not know what I should change in the program.
Thanks

qn9080-dk‌ blutooth‌ ADC uart

Labels (3)
37 Replies

1,297 Views
michalisantonio
Contributor I

Hi,

When run qn908xcdk_wireless_examples_bluetooth_private_profile_server_bm and include delay inside 

case gConnEvtConnected_c:  

The code doesnt execute correctly if delay over 20s and no ADC data appear on QPP app. All works fine if delay less than 10s.

How can i fix this so i can use any delay i want?

static void BleApp_ConnectionCallback (deviceId_t peerDeviceId, gapConnectionEvent_t* pConnectionEvent)
{
BleConnManager_GapPeripheralEvent(peerDeviceId, pConnectionEvent);

switch (pConnectionEvent->eventType)
{
case gConnEvtConnected_c:
{

mPeerInformation[peerDeviceId].deviceId = peerDeviceId;
mAdvState.advOn = FALSE;

delay(20000000);//delay 20s 

0 Kudos

1,297 Views
gerardo_rodriguez
NXP Employee
NXP Employee

Hi,

The baremetal scheduler is non-preemptive, so if your delay is implemented with a for loop, all the other essential tasks from the bluetooth stack will not be executed during this time. You could avoid this by using the freertos scheduler. However, a better approach would be to avoid using blocking delays and use the SW timers provided by the framework. You can see how these timers are used by the demo examples, e.g.:

   TMR_StartLowPowerTimer(mBatteryMeasurementTimerId, gTmrLowPowerIntervalMillisTimer_c,
   TmrSeconds(mBatteryLevelReportInterval_c), BatteryMeasurementTimerCallback, NULL);

0 Kudos

1,297 Views
ashkanrezaee
Contributor III

Hi,

I want to use all of the ADC pins at once. I configured pins like this:

static void ADC_CONF4(void)
{
adc_config_t adcConfigStruct4;
adc_sd_config_t adcSdConfigStruct4;

ADC_GetDefaultConfig(&adcConfigStruct4);
adcConfigStruct4.channelEnable = (1U << ADC_CHANNEL_4);
adcConfigStruct4.channelConfig = (ADC_CFG_IDX << ADC_CHANNEL_4);
adcConfigStruct4.triggerSource = ADC_TRIGGER;
adcConfigStruct4.clock = kADC_Clock2M;
adcConfigStruct4.convMode = kADC_ConvModeSingle;
ADC_Init(ADC, &adcConfigStruct4);

ADC_GetSdDefaultConfig(&adcSdConfigStruct4);
adcSdConfigStruct4.downSample = kADC_DownSample32;
ADC_SetSdConfig(ADC, ADC_CFG_IDX, &adcSdConfigStruct4);
g_AdcBandgap4 = ADC_GetBandgapCalibrationResult(ADC, ADC_CFG_IDX);

g_AdcVinn4 = ADC_GetVinnCalibrationResult(ADC, &adcConfigStruct4);

ADC_Enable(ADC, true);
}

and then activate the channels like this:

static void ADC_CH_4(void)
{
//Activate ADC4
POWER_EnableADC(true);
ADC_CONF4();
ADC_Enable(ADC, true);
ADC_DoSoftwareTrigger(ADC);
while (!(ADC_GetStatusFlags(ADC) & kADC_DataReadyFlag))
{
}
adcConvResult4 = ADC_GetConversionResult(ADC);
fresult4 = ADC_ConversionResult2Mv(ADC, ADC_CHANNEL_4, ADC_CFG_IDX, g_AdcBandgap4, g_AdcVinn4,
adcConvResult4);
}

I used channel 4 till channel 11 (8 channels)

But channel 8 values are related to channel 4 and channel 9!

I separated every parameter but it still related and changed with these 2 pins. I checked with 5 different QN9080 board.

What is the problem?

0 Kudos

1,297 Views
xing_chang
NXP Employee
NXP Employee

Hi Ashkan,

Do you mean that the result of channel 8 conversion is related not only to PA08 but also to PA00 and PA09?

Have you set the corresponding pin to ADC function?
Like this,
IOCON_PinMuxSet (IOCON PORTA_IDX, PIN8_IDX portA_pin8_config);/* PORTA PIN8 (coords: 46) is configured as ADC4 */
Const uint32_t portA_pin16_config = (
IOCON_FUNC4 | /* Selects pin function 4 */
IOCON_MODE_HIGHZ | /* Selects high-z function */
IOCON_DRIVE_LOW /* Enable low drive strength */
);

0 Kudos

1,297 Views
ashkanrezaee
Contributor III

Hi,

How can I use a Timer to indicate a delay between two ADC receiving/sending through BLE data?

0 Kudos

1,297 Views
michalisantonio
Contributor I

Hi, you can try this:

static void delay(uint32_t dly)  
{
   volatile uint32_t i = 0;
   for (i = 0; i < dly; ++i)
   {
       __asm("NOP"); /* delay */
   }
}

0 Kudos

1,297 Views
ashkanrezaee
Contributor III

Hi,

I don't want to use a delay. I want to use CTIMER instead of delay.

CTIMER start, ADC measure and send values, for example, every 30 ms.

0 Kudos

1,297 Views
xing_chang
NXP Employee
NXP Employee

Hi Ashkan,

You can refer to the following function in SDK project:

TMR_StartLowPowerTimer(mBatteryMeasurementTimerId, gTmrLowPowerIntervalMillisTimer_c,
TmrSeconds(mBatteryLevelReportInterval_c), BatteryMeasurementTimerCallback, NULL);

0 Kudos

1,297 Views
michalisantonio
Contributor I

Thanks. Just need send ADC data over SPI. Can I use  SPI_MasterTransferNonBlocking(EXAMPLE_SPI_MASTER, &masterHandle, &xfer); in qn908xcdk_driver_examples_spi_interrupt_transfer to send ADC data?

0 Kudos

1,297 Views
xing_chang
NXP Employee
NXP Employee

Yes,it is ok.

0 Kudos

1,297 Views
michalisantonio
Contributor I

Hi, How save ADC data on QN9080DK internal memory for later use?

0 Kudos

1,297 Views
xing_chang
NXP Employee
NXP Employee

Hi, you can use the Non Volatile Data Storage (NVDS) driver to store user information. It supports nvds_get and nvds_get() interfaces.

0 Kudos

1,297 Views
michalisantonio
Contributor I

thanks! Also how to send data to external SD card using QN9080DK SPI pins?

0 Kudos

1,298 Views
xing_chang
NXP Employee
NXP Employee

Hi Michalis,

Our SDK is only available to the SPI driver. For SD card operation, you should refer to the SD card spec to implement it yourself, or find some open source code on the Internet.

SPI drivers are located at: SDK\boards\qn908xcdk\driver_examples\ SPI

0 Kudos

1,298 Views
ashkanrezaee
Contributor III

Hi,

In ADC results, the float value shows data in mV. Is there any conversion to show the results more accurate? For example, convert data to microV. 

0 Kudos

1,298 Views
xing_chang
NXP Employee
NXP Employee

Hi ashkanrezaee‌,

No, we don't have a formula for converting to microvolts

0 Kudos

1,298 Views
ashkanrezaee
Contributor III

In the ADC example, ADC should measure voltages between 0~2.8, however, it can measure between 0~2.7. is there any way to increase this range to for example 0~3.3? 

Can you explain that?

And something else, what is the range of the ADC in bytes? it should be 0000~FFFF, but FFFF shows 3.3v and the maximum values of the ADC pin is 2.7!

0 Kudos

1,298 Views
xing_chang
NXP Employee
NXP Employee

Hi Ashkan,

   You can modify the reference source voltage (refSource) and use an external reference source (kADC_RefSourceExtWithDriver)  so that the measurement range is up to 3.3v.

About the range of the ADC in bytes, you can refer to the 30.5.8.2 Output data format section of document UM11023.

0 Kudos

1,298 Views
michalisantonio
Contributor I

Yes, I use QN9080DK. So how can I merge 2 SDK examples in one ? I just need read ADC data and send over Bluetooth.

0 Kudos

1,298 Views
ashkanrezaee
Contributor III

Hi,

I had a problem like you.

At first, You need to define ADC pins as ADC in your board.c in the specific function. Then you have to call back this function in your "wireless_uart.c"  then you should activate ADC.

now it's related to your plan. If you need to respond to the command from application, you need to go to BleApp_GattServerCallback and change pServerEvent->eventData.attributeWrittenEvent.aValue and send back data with this BleApp_SendUartStream function.

**(You can not send more than 12 characters in this part and I don't know why! If someone knows, please tell me)**

If you need to send your data whenever serial read something (pressing Keyboard keys) you need to go to BleApp_FlushUartStream function and add your data in BleApp_SendUartStream  when bytesRead != 0.

Remember that BleApp_SendUartStream function sends a memory. so you need to put your ADCs data in the memory with FLib_MemCpy.

0 Kudos