5 Replies Latest reply on May 31, 2018 4:43 AM by Gyan Chand

    I can't tell from the examples how to connect various sensors' ADC output to the BLE!

    stevewald_1982846

      I have the example code for using the Environmental Sensing profile in PSoC4 4200 BLE (CY8CKit-042-BLE-A). It messes with simulation of windspeed and other stuff, but doesn't show how to set up a real system with multiple sensor inputs to the ADC. What calls to I make to write new data from ADC into BLE registers? How do I create a main loop that reads all the sensor data, writes it to BLE, then shuts the chip down for a second or two before waking up and starting over? What is the HandleIndication(flags) procedure in ess.c for, and how does it compare with HandleNotification()? How do I find my way around all the CHARACTERISTIC and DESCRIPTION pointer data types?

      I would really appreciate any help here. Thanks!

      Steve

        • 1. Re: I can't tell from the examples how to connect various sensors' ADC output to the BLE!
          e.pratt_1639216

          You would replace the "fake" data in the example with the readings/processed data from the ADC sensors you want to use.

          Most of the BLE examples have the main loop constantly running, and only call the functions to handle events/flags individually.

          HandleIndication() sounds like it is handling the BLE indication events from the remote device, similar to HandleNotification(), but it is a different BLE operation. The CHARACTERISTIC and DESCRIPTION pointer data types are referring to different BLE structures used to send/read BLE values.

          It sounds like you have a list of questions on various aspects of the application, I would suggest breaking it into its constituent parts:

          ADC reading multiple sensors.

          BLE deep sleep (going to sleep and waking up after a period of time, etc)

          BLE communication (notifications, indications, sending the data)

          I would look for an example for each one, starting with the least complicated (at the top).

          Handling multiple analog inputs/polling rates using an Analog Mux/SAR ADC

          http://www.cypress.com/video-library/PSoC/psoc-101-lesson-17-deep-sleep/387641

          PSoC-4-BLE/100_Projects_in_100_Days at master · cypresssemiconductorco/PSoC-4-BLE · GitHub

          • 2. Re: I can't tell from the examples how to connect various sensors' ADC output to the BLE!
            stevewald_1982846

            e.pratt,

            The answer may be correct as far as it goes, but doesn't give many details.

            For now, I just want to run all the sensors at the same polling rate and leave the system awake all the time. Let's just get some data through.

            I replaced the SimulateProfile() calls with HandleNotificaion() <sic> calls from the example. The calls have pointers to characteristic_data structures with the ADC_GetResult16() data filled in, but I'm getting zero's in the data read by CySmart. I can't really tell yet whether the ADC is not producing data properly or the software datapath still isn't fully connected right. At least the ADC and BLE appear to be running. Here are some code fragments... am I missing something?

             

            /*******************************************************************************/

             

            #define ADC_THERMISTOR1_CHAN                (0u)

            #define ADC_HUMIDITY_CHAN                        (1u)

            CYBLE_ESS_CHARACTERISTIC_DATA_T temperature1;

            CYBLE_ESS_CHARACTERISTIC_DATA_T humidity;

             

            /*******************************************************************************

            * Function HandleADC()

            ********************************************************************************/

            void HandleADC(void) {

                ADC_SetChanMask(0x0003);            // using two channels for now

                ADC_Enable();

                ADC_StartConvert();

                CReg_BegSoc_Write(1u);              // Start the ADC when ready

                ADC_IsEndConversion(ADC_WAIT_FOR_RESULT);       // Wait for conversions to finish

                ADC_StopConvert();

             

                temperature1.value = ADC_GetResult16(ADC_THERMISTOR1_CHAN);

                humidity.value = ADC_GetResult16(ADC_HUMIDITY_CHAN);

            }

             

            /*******************************************************************************

            * Function Name: main()

            ********************************************************************************

            int main()

            {

                CYBLE_API_RESULT_T apiResult;

                CyGlobalIntEnable;

                /* Set initial Change Index value */

                CyBle_EsssSetChangeIndex(essChangeIndex);

                /* Start CYBLE component and register generic event handler */

                CyBle_Start(AppCallBack);

                    /* Configure button interrupt */

                Wakeup_Interrupt_StartEx(&ButtonPressInt);

             

                UART_DEB_Start();

                ADC_Init();

                EssInit();

                /* Global Resources initialization */

                ADC_Start();

                Opamp1_Start();

                WDT_Start();

             

                while(1)

                {

                    /* CyBle_ProcessEvents() allows BLE stack to process pending events */

                    CyBle_ProcessEvents();

                   /* To achieve low power in the device */

                    LowPowerImplementation();

                   // Run the ADC for sensor data

                    HandleADC();

                    /* Check if there is updated data -- replace simulation with actual data

                    * SimulateProfile(&temperature1);

                    * SimulateProfile(&humidity);

                    */

                    HandleNotificaion(&temperature1);

                    HandleNotificaion(&humidity);

            ...

                    if(connected &ct.) {

                            /* Check if there are notifications for Thermistor1 and send them */

                            ChkNtfAndSendData(&temperature1);               

                            /* Check if there are notifications for Humidity and send them */

                            ChkNtfAndSendData(&humidity);               

                            /* Check if there are indications need to send to remote Client and send them */

                            if((isIndicationEnabled == YES) && (isIndicationPending == YES))

                            {

                                HandleIndication(indicationValue);

                                isIndicationPending = NO;

                                CyBle_ProcessEvents();

                            }

                        }

                        prevMainTimer = mainTimer;

                    }

            }

             

            /*******************************************************************************

            * Function Name: HandleNotificaion()

            *  -- unaltered from ess.c in the Environmental Sensing example

            ********************************************************************************

            *

            * Summary:

            *  Sends a notification about a descriptor change to the Client.

            *

            * Parameters: 

            *   *sensorPtr: A pointer to the sensor characteristic structure.

            *

            *******************************************************************************/

            void HandleNotificaion(CYBLE_ESS_CHARACTERISTIC_DATA_T *sensorPtr)

            {

                CYBLE_API_RESULT_T apiResult;

                uint8 tmpBuff[CYBLE_ESS_2BYTES_LENGTH];

             

                /* Pack data to BLE compatible format ... */

                CyBle_Set16ByPtr(tmpBuff, sensorPtr->value);

             

                /* ... and send it */

                apiResult = CyBle_EsssSendNotification(connectionHandle,

                                                       sensorPtr->EssChrIndex,

                                                       sensorPtr->chrInstance,

                                                       SIZE_2_BYTES,

                                                       tmpBuff);

                if(apiResult != CYBLE_ERROR_OK)

                {

                    DBG_PRINTF("Send notification is failed: %d \r\n", apiResult);

                } else

                {   DBG_PRINTF("Notification for %s #%d was sent successfully. ", CharIndexToText(sensorPtr->EssChrIndex), sensorPtr->chrInstance + 1u);

                    DBG_PRINTF("Notified value is: %d.%d m/s.\r\n", sensorPtr->value/100u, sensorPtr->value%100u);

                    sensorPtr->sensorNewDataReady = NO;

                    sensorPtr->ntfTimer = sensorPtr->ntfTimeoutVal;

                }

            }

            • 3. Re: I can't tell from the examples how to connect various sensors' ADC output to the BLE!
              Gyan Chand

              Hello,

               

                  Probably ADC_StopConvert(); API is clearing the ADC Data Register. Could you comment out this API or put after reading the register value.

               

              """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

                 ADC_IsEndConversion(ADC_WAIT_FOR_RESULT);      // Wait for conversions to finish

                 ADC_StopConvert(); // Comment Out this Line or Put after reading the ADC Data Register.

                  temperature1.value = ADC_GetResult16(ADC_THERMISTOR1_CHAN);

                  humidity.value = ADC_GetResult16(ADC_HUMIDITY_CHAN);

              """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

               

               

              -Gyan

              • 4. Re: I can't tell from the examples how to connect various sensors' ADC output to the BLE!
                stevewald_1982846

                I don't think so. Here's the code for StopConvert... It does nothing but change the sample_ctrl_reg continuous_en bit.

                void ADC_StopConvert(void)

                {

                    #if(ADC_DEFAULT_SAMPLE_MODE_SEL == ADC__FREERUNNING)

                        ADC_SAR_SAMPLE_CTRL_REG &= (uint32)(~ADC_CONTINUOUS_EN);

                    #endif /* ADC_DEFAULT_SAMPLE_MODE == ADC__FREERUNNING */

                }

                 

                Instead I fiddled with the 'Notifications' checkboxes on the BLE/Env Sensing/Profiles and voila! started getting data with CySmart.

                I want to shut down conversions right away to allow low-power mode to take over, and not have the next set of free-running conversions already in progress. But I am guessing about the proper sequence for doing this... any better ideas out there? I tried messing with ADC Hardware Triggering from a user control register, but only ended up shutting down the ADC completely.

                Steve

                • 5. Re: I can't tell from the examples how to connect various sensors' ADC output to the BLE!
                  Gyan Chand

                  Hello Steve,

                   

                      You are correct. Sorry for the confusion. The ADC output value will  still be there in the ADC data register until overwritten by the next conversion or power cycle/reset.

                   

                  To move forward with Low Power implementation you can refer the code example available as a part of PSoC Creator code examples. Just Go to PSoC Creator-> File-> Code Example-> Search for 'BLE_Battery_Level'.

                   

                  -Gyan