Back to All
Project

MDM9206 with Pressure Detector

 

Skill Level Area of Focus Operating System Platform/Hardware Cloud Services/Platform
Intermediate IoT, Embedded, Sensors RTOS Qualcomm® MDM920x LTE for IoT Gizwits Cloud Platform

This project is designed to read pressure values from the FSR402 sensor using the Qualcomm® MDM9206 LTE modem, a multimode communication chipset that supports Cat-M1/eMTC, Cat-NB1/NB-IoT, 2G/E-GPRS technologies and more than 15 RF bands, making it ideal for global IoT applications. The LED lights up when pressure values exceed the set threshold.

Objective

The main objective of this project is to connect the FSR402 sensor to the ADC interface of the Qualcomm MDM9206 LTE Modem provided by the GoKit development board and collect pressure values.

Materials Required / Parts List / Tools

Source Code / Source Examples / Application Executable

Additional Resources

Build / Assembly Instructions

Parts used

Below are the items used in this project.

  1. Win7 PC
  2. GoKit4 development board
  3. FSR402 Sensor, used to detect pressure values
  4. LED that lights up when pressure value changes exceed the set threshold
  5. DuPont cable, used to connect other components as wires

 

 

GoKit4

DuPont

FSR402

How does it work?

Below are some usage instructions to test the project.

Now let's introduce the demo-Smart-Pressure-detector’s workflow.

gagentMain---->user_init---->led_init---->tx_timer_create---->userTimerCB

Register a callback in the interface named tx_timer_create,when time is up, call the callback called userTimerCB.

demo-Smart-Pressure-detector/main/main.c
  
  void gagentMain( void )
  {
      getFreeHeap();
      user_init();
  }

The function named gagentMain was called by GAgent, the main role of GAgent is data forwarding, which is a data interaction bridge between device data, Wit Cloud, and the application. Function user_init, does some sensor initialization:

void user_init(void)
  {
      int32 ret = -1;
      
      gizLog(LOG_INFO,"Sensor initialization ...\n"); 
  	led_init();							//led init
      txm_module_object_allocate(&userTimer, sizeof(TX_TIMER));
      ret = tx_timer_create(userTimer, "userTimer", userTimerCB, NULL, 1,
                           20, TX_AUTO_ACTIVATE);			
      if(ret != TX_SUCCESS)
      {
          gizLog(LOG_WARNING,"Failed to create UserTimer.\n");
      }
  }
  
  void led_init()
  {
  	   gizLog(LOG_INFO,"in led init...\n"); 
  	   led_gpio_config();
  	   led_on_off(false,led_green);		//init status is off
  }
  
  demo-Smart-Pressure-detector/driver/gpio.c
  
  void led_on_off(bool on, uint8_t pin_gpio)
  {
  	
  	if (on)
  	{
  	qapi_TLMM_Drive_Gpio(gpio_id_tbl[pin_gpio], gpio_map_tbl[pin_gpio].gpio_id, QAPI_GPIO_LOW_VALUE_E);
  	}
  	else
  	{
  	qapi_TLMM_Drive_Gpio(gpio_id_tbl[pin_gpio], gpio_map_tbl[pin_gpio].gpio_id, QAPI_GPIO_HIGH_VALUE_E);
  	}
  }
  
  
  void ICACHE_FLASH_ATTR userTimerCB(void)
  {
  	gizLog(LOG_INFO,"in userTimerCB.....\n"); 
  	int16_t quality;
  
  	quality = fsr402_pressure_adc_read();	  //get quality value.
  
  	if(quality >= 1000)
  	{
  		led_on_off(true,led_green);
  		qapi_Timer_Sleep(100, QAPI_TIMER_UNIT_MSEC, true);
  		led_on_off(false, led_green);
  	}
  else if(quality == -1)
  {
  		led_on_off(true,led_red);
  		qapi_Timer_Sleep(100, QAPI_TIMER_UNIT_MSEC, true);
  		led_on_off(false, led_red);
  	}
   
  }
  
  demo-Smart-Pressure-detector/driver/adc/fsr402_pressure_adc.c
  
  //used to get quality value
  
  int fsr402_pressure_adc_read(void)
  {
      int ret = -1;
      int32_t m_voltage = 0;
      int16_t quilty = 0;
      qapi_ADC_Read_Result_t result;
  	qapi_Status_t status = QAPI_ERROR;
  
      const char *channel_name_adc0 = ADC_INPUT_ADC0;
      
      qapi_Adc_Input_Properties_Type_t Properties_ADC0;
  
  
  /*get an adc handle*/
  
  status = adc_open_handle();
  
      if(status != QAPI_OK)
      {
          gizLog(LOG_ERROR,"Get ADC Handle ERROR!\n");
          return status;
      }
  
  /*get the adc channel configuration*/
  
      status = adc_get_properties(channel_name_adc0, &Properties_ADC0);
      
  if(status != QAPI_OK)
      {
          gizLog(LOG_ERROR,"Get ADC channel-%s Configuration ERROR!\n", channel_name_adc0);
          return status;
      }   
      
  /*read channel ADC0*/
  
  memset(&result, 0, sizeof(result));
  
      status = qapi_ADC_Read_Channel(adc_handle,  &Properties_ADC0, &result);
      if(QAPI_OK == status)
      {
          if(ADC_RESULT_VALID == result.eStatus)
          {  
             m_voltage = result.nMicrovolts /1000;
                  
             quilty = to_quality(m_voltage);
             if(quilty > 0)
             {
                 gizLog(LOG_INFO,"Input %s  Voltage: %d mV  about %d g\n", channel_name_adc0, m_voltage, quilty);
             }
             else if (quilty == 0)
             {
                 gizLog(LOG_INFO,"no press.\n");
             }
             else
             {
                 gizLog(LOG_INFO,"Out of range!\n");
             }  
          }
      }
  
  status = qapi_ADC_Close(adc_handle, false);
  
      if(QAPI_OK != status)
      {
          gizLog(LOG_ERROR,"Free ADC Handle ERROR!\n");
  }
  
      return quilty;
  }
  
  qapi_Status_t adc_open_handle(void)
  {
  	qapi_Status_t status = QAPI_ERROR;
  
  status = qapi_ADC_Open(&adc_handle, 0);
  
      if (QAPI_OK != status) 
      {
          gizLog(LOG_ERROR, "open adc error!\n");
  }
  
      return status;
  }
  
  qapi_Status_t adc_get_properties(const char *Channel_Name_Ptr,
  	qapi_Adc_Input_Properties_Type_t *Properties_Ptr)
  {
  qapi_Status_t status = QAPI_ERROR;
  
      uint32_t Channel_Name_Size = strlen(Channel_Name_Ptr) + 1;
  
  status = qapi_ADC_Get_Input_Properties(adc_handle, Channel_Name_Ptr, Channel_Name_Size, Properties_Ptr);
  
      if (QAPI_OK != status)
      {   
  		gizLog(LOG_ERROR, "ADC Get Channel-%s Properties ERROR!\n", Channel_Name_Ptr);
  }
  
      return status;
  }
  
  //find quality from an arry based on voltage.
  
  int16_t to_quality(int32 m_voltage)            
  {
      uint8_t i =0;
      int16_t quilty = 0;
  
      for(i = 0; i < V_TO_Q_SIZE; i++)
      {
          if(m_voltage <= voltage_to_quality[i].voltage)
          {
              quilty = voltage_to_quality[i].quality;
              return quilty;
          }  
          i++;
      }
  
      if(i >= V_TO_Q_SIZE)
          return -1;
  }

For more details regarding the FSR402 data conversion, please see the blog below:

https://blog.csdn.net/weixin_38498942/article/details/86680506

Usage Instructions

  1. Download code from GitHub repository: https://github.com/ThunderSoft-XA/demo-Smart-Pressure-detector
  2. Compile the code and flash the image to GoKit4 development kit
  3. Connect the FSR402 sensor to the ADC interface of the GoKit development board
  4. Connect one pin of the LED to the D9 pin of the development board, and the other pin is connected to the Vcc
  5. Connect the USB data cable between the PC and GoKit development board
  6. Open the serial debugging assistant
  7. Put your finger on the pressure receiving surface of the sensor, you can see that the data has changed.When pressure values change beyond the set threshold, the LED will be lit.
Parts

Contributor Info

Name Email Title/Company
Zhen [email protected] Thundersoft
Rong [email protected] Thundersoft
Jie [email protected] Thundersoft
Kou [email protected] Thundersoft
Eric [email protected] Thundersoft

Qualcomm MDM9206 is a product of Qualcomm Technologies, Inc. and/or its subsidiaries.

Opinions expressed in the content posted here are the personal opinions of the original authors, and do not necessarily reflect those of Qualcomm Incorporated or its subsidiaries ("Qualcomm"). The content is provided for informational purposes only and is not meant to be an endorsement or representation by Qualcomm or any other party. This site may also provide links or references to non-Qualcomm sites and resources. Qualcomm makes no representations, warranties, or other commitments whatsoever about any non-Qualcomm sites or third-party resources that may be referenced, accessible from, or linked to this site.

Project Authors
Thunder Software Technology (Shenzhen) Co., Ltd.
Shenzhen

Sign up for the Developer Newsletter.

Get software and hardware tool resources to help optimize your development delivered to your inbox weekly.

Qualcomm relentlessly innovates to deliver intelligent computing everywhere, helping the world tackle some of its most important challenges. Our leading-edge AI, high performance, low-power computing, and unrivaled connectivity deliver proven solutions that transform major industries. At Qualcomm, we are engineering human progress.

Stay connected

Get the latest Qualcomm and industry information delivered to your inbox.

Subscribe
Manage your subscription

© Qualcomm Technologies, Inc. and/or its affiliated companies.

Snapdragon and Qualcomm branded products are products of Qualcomm Technologies, Inc. and/or its subsidiaries. Qualcomm patented technologies are licensed by Qualcomm Incorporated.

Note: Certain services and materials may require you to accept additional terms and conditions before accessing or using those items.

References to "Qualcomm" may mean Qualcomm Incorporated, or subsidiaries or business units within the Qualcomm corporate structure, as applicable.

Qualcomm Incorporated includes our licensing business, QTL, and the vast majority of our patent portfolio. Qualcomm Technologies, Inc., a subsidiary of Qualcomm Incorporated, operates, along with its subsidiaries, substantially all of our engineering, research and development functions, and substantially all of our products and services businesses, including our QCT semiconductor business.

Materials that are as of a specific date, including but not limited to press releases, presentations, blog posts and webcasts, may have been superseded by subsequent events or disclosures.

Nothing in these materials is an offer to sell or license any of the services or materials referenced herein.