Session 9: Light Weight ADC Driver

Document created by Gabriela Godinez Employee on Jun 29, 2016Last modified by Gabriela Godinez Employee on Jun 29, 2016
Version 2Show Document
  • View in full screen mode

This video presentation is the ninth installment of the Essentials of MQX RTOS Application Development training course. In this session, you will be introduced to the LWADC Driver, and will learn to configure and read ADC input.

This training was created by Embedded Access Inc., a Freescale sponsored training provider and proven partner.


Session 9 Course LineLab Outline
  • Analog signals and uses cases for ADCs
  • How ADCs work
  • Driver walk through
  • Attributes of ADCs
  • Configuring ADCs
  • Reading the ADC
  • Scaling the ADC output
  • Initializing an ADC device
  • Initializing an ADC input
  • Reading an ADC input
  • Scaling an ADC reading
  • Reading an average of the ADC input


First, watch the video for Session 9: LWADC Driver.

Then, follow through with the interactive lab assignment below.



In our previous lab we used a light weight timer to set an event bit every 100 msec and whenever this event bit was set the Input Task would send a message to the Health Task with the reading from the potentiometer. The problem however was that we hadn't yet covered the ADC and so the potentiometer value sent was 0.Now that you know how to initialize an ADC device and it's input it's now time to update this part of our application to include the actual potentiometer value in the message that is sent by the Input Task.


The objective of this lab is to learn about the lwadc driver by adding code to read the potentiometer and send the value to the health task.This objective will be accomplished by:

  • Initializing the ADC driver
  • Initializing the ADC input
  • Periodical reading of the ADC
  • Changing the scaling so a voltave between 0 and 12000 millivolts is displayed
  • Using _lwadc_read_average

New functions/ structures you will use:
     LWADC_STRUCT, LWADC_VALUE, __lwadc_init(), _lwadc_init_input(), _lwadc_read(),_lwadc_set_attribute(),_lwadc_read_average()



    1. We saw in the video that there is a separate structure of type LWADC_INIT_STRUCT for each of the ADC Devices. These are located in init_lwadc.c which is in the 'BSP_Files' folder of the BSP project. It would be a good idea to review this file to get familiar with this structure.
      Whiteboard 9-1.jpg
    2. Just below where you initialized the switches (with the init_switch() function) in InitTask.c use the lwadc_init() function to initialize ADC 1. ADC 1 will be used because the potentiometer is connected to ADC 1 on the tower K70 board. We'll see this in a moment. ADC 1 is the default ADC controller in this BSP and there is a define for this in the board specific BSP file (twrk70f120m.h) called BSP_DEFAULT_LWADC_MODULE. So you can use this define to point to the ADC1 init structure or more directly use 'lwadc1_init'. Note that the extern for BSP_DEFAULT_LWADC_MODULE is missing in some versions of MQX so you may need to add an 'extern const LWADC_INIT_STRUCT BSP_DEFAULT_LWADC_MODULE' at the top of InputTask.c.
      Cheat 9-1.png
    3. This will initialize the ADC device but the next step is to initialize the data structure for the input to this ADC Device. This is done with the lwadc_init_input() function. Don't forget to declare a structure of type LWADC_STRUCT. As with all inputs, you will find in twrk70f120m.h, a define for the ADC input from the potentiometer. It is called BSP_ADC_POTENTIOMETER and it is set it to (ADC1_SOURCE_AD20). This defines the ADC Device that it is connected to and the pin muxing.
      Whiteboard 9-2.jpg
      Cheat 9-2a.png
      Cheat 9-2b.png


    1. Now we're ready to read the input. You will recall that in the endless loop of our Init Task it will wait indefinitely for either a switch or ADC event bit to be set, and once one of these bits has been set the appropriate action is taken. We added the setting of the ADC event bit in the last lab with the use of a timer. Currently when this bit is set the Input Task will send a message to the Health Task but we don't have any real data to send so our job is to add that data now. Before sending the message the Input Task should use the _lwadc_read() function to get the setting of the potentiometer. You will need a variable of type LWADC_VALUE for the reading from the ADC to be written to.
      Cheat 9-3a.png
      Cheat 9-3b.png
    2. Update the data field in the message to the Health Task to be the read value from the ADC.
    3. Since the _lwadc_read() function returns TRUE if the read is successful and FALSE if the read was unsuccessful it would make sense to update your code to only send a message if the read from the ADC was successful.
      Cheat 9-4.png


    1. Compile and run your code.
    2. On the print out you should see the Health Task and Display Task message ADC messages being displayed continuously (officially once every 100 msec because that's the period of our timer that triggers the reading of the ADC). If you change the setting of the potentiometer on the K70 tower card the value printed out should change and the readings should range from 0 (or close to it) to 3300 (or close to it) to represent 3300 millivolts.
      Results 9-1.png


    1. As you saw the input wasn't scaled at all, it simply showed you the voltage (in millivolts) that the ADC was reading. But you may want to scale the input to a range that is more meaningful. Instead of having the input range from 0 to 3300 we want to scale this so it ranges from 0 to 12000. This could represent a temperature that goes up to 1,200 degrees (in tenths of a degree) or a voltage range that goes up to 12 volts (measured in millivolts). Use the _lwadc_set_attribute() function to change the scaling. Try this on your own, if you need a hint use the whiteboard.
      Whiteboard 9-3.jpg
    2. Change the reading of the ADC to return an average value over 8 reads. This requires the _lwadc_read_average() function.


  1. Compile and run your code.
  2. Confirm on the output that the range of the potentiometer is now from 0 to 12000.
    Results 9-2.png

Need more help? The full source code for this lab can be found in the 'Lab Source Code' folder here.