Aaron Hanson
allaboutcircuits.com
Learn how to hook up an analog input (potentiometer) and output (LED) using a Microchip BLE module.
This is the four installment in my project series created to demonstrate using Microchip's RN487x Bluetooth module.
We are creating functional Bluetooth-connected peripherals for each of the four tasks; a digital sensor, a digital control, an analog sensor, and an analog control. Each example includes a nominal circuit, and the configuration necessary on the RN487x. A simple application script for exercising the peripheral is also provided.
In Part 1, I gave an important design overview for all the peripherals. We've already covered example peripherals in Part 3, which dealt with two projects for a digital input and a digital control.
Here, in Part 4, we will go directly to the third and fourth examples, an analog sensor and an analog control.
Project 3: Analog Sensor
Our analog sensor will be represented by a potentiometer (Figure 9).
Figure 9. | Analog sensor will be represented by a potentiometer. |
Our design pattern has three components we will need to provide:
- Hardware: Task-specific hardware to provide an analog input signal
- Configuration: RN487x module commands to allocate a variable in a database, and to map the signal to the variable
- Application: Script on a workstation, to request the sensor value and display the digitized values
What follows is the component breakdown.
Analog Input Hardware
The role of ‘analog input’ is simply provided by a potentiometer; RV1. The RN487x module datasheet indicates that the full A/D range is from VCC to GND, so we wire the potentiometer accordingly (Figure 10).
Figure10. | The schematic for the analog input peripheral project. |
Since we are only managing one signal and we aren't using PWM, we’ve chosen the RN4871. The circuit can be powered by a pair of AAA batteries or even a coin-cell.
The remaining circuit elements are:
- C1: A bypass capacitor to stabilize power
- R1, C2: A delay for the processor reset at power-on
- J1: A serial port for configuration
Analog Input Configuration
Before creating the configuration for this example, make sure the module is in a known state. This is described in the appendix section on common initialization. Do not skip this step!
We only need one characteristic in the database to represent our digitized value. So we create one service and one characteristic in that service.
The two corresponding commands are:
PS,59c88760536411e7b114b2f933d5fe66
PC,59c889e0536411e7b114b2f933d5fe66,02,02
The first command, PS, creates the service. The second command, PC, creates the characteristic.
In both commands, the first parameter is the identifier that allows our peripheral to exist in the universe of other Bluetooth peripherals and still be accessed uniquely. This parameter must conform to the UUID standard. You can use the example values shown. It is also easy to create any number of standard UUIDs.
In the PC command, the second parameter tells the Bluetooth layer how changes in the database will get to the client. In this case, the parameter (02), says that the application will just read this value as needed.
Finally, in the PC command, the third parameter defines the size of the value in bytes; "02" in this case because the A/D ports provide a 16-bit result (full range is 0x0000-0x0E10).
The script part of our configuration looks like this:
@CONN
SM,2,0010
@DISCON
SM,2,0000
@TMR2
$VAR1=@,2
SHW,0072,$VAR1
SM,2,0010
This script causes the A/D converter to sample the signal pin every 10 ms, and put the digitized value in the database. The scripting feature that we use that is unique to this example is timers.
By method:
- @CONN: Runs when a client connects. It starts the timer.
- @DISCON: Runs when a client disconnects. It stops the timer.
- @TMR2: Runs when the timer expires. It transfers a sample to the database. The RN487x timers are ‘one shot’ timers, so we need to restart the timer as well.
This script keeps the module busy as long as the client is connected, and the power requirements will be high. It is best to consider this in the client design. The client should only connect to the peripheral when it is necessary to acquire samples.
Analog Input Application
The Python script is meter.py and can be found here. Edit the script and replace the sample MAC address with the MAC address of your device. Then, to exercise the example, simply apply power to the peripheral, then run the script on a system with the appropriate Bluetooth capabilities. (As I mentioned above, you can refer to the appendix for help with this setup in Linux.)
The script will issue messages to indicate progress while connecting to the peripheral. After the peripheral is connected, the script will read and display a new sample every half-second.
The script is short and includes comments for all the function blocks and GATT API calls.
Next, we'll follow the same design pattern to create an analog control.
Project 4: Analog Control
As with Project 2 in the previous article, the output will be represented by an LED. Our design pattern has three components we will need to provide:
- Hardware: Task-specific hardware to express the analog signal
- Configuration: RN487x module commands to allocate a variable in a database, and to map the variable to the analog signal
- Application: Script on a workstation, to supply a varying 16-bit value that specifies the desired analog signal level
What follows is the component breakdown.
Analog Control Hardware
The role of ‘analog output’ is provided by an LED; D1. The RN4870 module will generate a PWM (pulse-width-modulated) square wave output on this pin (Figure 11). This is a common single-wire method of expressing an analog value and can also be converted to an analog voltage with a simple low-pass filter.
Figure11. | The schematic for the analog output peripheral project. |
The RN4871 has no analog output options, which is why we use the 4870 for this example. Connecting the PWM signal directly to an LED gives us a way to see an analog range; a dim LED for low values, a bright LED for high values, and so on. Like the other three projects, this circuit can also be powered by a simple pair of AAA batteries a coin-cell.
The remaining circuit elements are:
- C1: A bypass capacitor to stabilize power
- R1, C2: A delay for the processor reset at power-on
- J1: A serial port for configuration
Analog Control Configuration
Before creating the configuration for this example, make sure the module is in a known state. This is described in the appendix section on common initialization. Do not skip this step!
We only need one characteristic in the database to represent our sensor state. So we create one service and one characteristic in that service. The two corresponding commands are:
PS,59c88760536411e7b114b2f933d5fe66
PC,59c889e0536411e7b114b2f933d5fe66,08,14
The first command, PS, creates the service. The second command, PC, creates the characteristic. In both commands, the first parameter is the identifier that allows our peripheral to exist in the universe of other Bluetooth peripherals and still be accessed uniquely. This parameter must conform to the UUID standard. You can use the example values shown. As I mentioned above, you can also create however many standard UUIDs you need.
In the PC command, the second parameter tells the Bluetooth layer how changes in the value should get to the client. In this case, the parameter (08), says that the peripheral must send a confirmation to the client when a value is changed.
Finally, in the PC command, the third parameter defines the size of the value in bytes; "14" bytes in this case. Although the full PWM command can be expressed with only 4 bytes, we are using a remote-function call in this example which requires more space. This is further explained in the application script.
The script part of our configuration looks like this:
@PW_ON
72=?FUNC1
?FUNC1
[,2,2,$PM1,$PM2
There are two methods in this script, the first prefixed with ‘@’ and the 2nd with ‘?’. Each method runs on a specific system event, and has just one command:
- @PW_ON: Runs at power-on. The method associates a function, ?FUNC1, with a database variable. The associated DB variable is specified by the characteristic handle, 72.
- ?FUNC1: Runs whenever a client writes a value to the DB variable identified by handle 0072. The parameters to the method are determined by the values that the client writes to the DB variable. The method takes those two variables, $PM1 and $PM2, and uses them to control the frequency and duty-cycle of the PWM signal. This is the signal connected to the LED.
Analog Control Application
The Python script is volume.py and can be found here. Edit the script and replace the sample MAC address with the MAC address of your device. Then, to exercise the example, simply apply power to the peripheral, then run the script on a system with the appropriate Bluetooth capabilities. (See the appendix in Part 1 for help with this setup in Linux.)
The script will issue messages to indicate progress while connecting to the peripheral. After the peripheral is connected, the script will send a range of values to the peripheral. The values will slowly increase, then decrease. As a result, the LED will gradually brighten, then fade.
The script is short and includes comments for all the function blocks and GATT API calls. The BLE feature we use that is unique to this example is remote function calls.
Project Video
Now that we've assembled all four of our peripherals projects, you can check out my video below to see them in action:
Fabrication Options
The Microchip RN487x development board can be used for any of these examples as-is but it also has many features that are not necessary for the systems we are creating.
Hand soldering the device and the test circuits onto a prototyping PCB is probably the least expensive option. The modules are intended for surface-mount, so small-component skills and temperature-management are critical for this approach. All the examples in this series were validated with a prototype of this form.
Public vs Private Characteristics
The 128-bit UUIDs we used to identify characteristics in this series are referred to as private characteristics in the Bluetooth standard. A private characteristic is typically only useful within the domain of a client application and a peripheral that are both developed by a single hardware/software vendor. The alternative is a 16-bit characteristic which has a publicly understood definition and is registered with the Bluetooth SIG.
You can see more established public characteristic definitions in [1]. It is also possible to register new definitions with the SIG. Where public characteristics are used, interoperability between different hardware and software vendors becomes possible. The RN487x module supports public characteristics.
Concurrent Control and Sense Signals
Although these examples are each concerned with only a single hardware signal, this is not a limitation of the module. As discussed earlier, both RN487x modules have multiple GPIO pins and they can be used concurrently. The pin binding scripts can be concatenated for multiple pins. The module NVRAM has space for multiple service and characteristic definitions. And, of course, the client application can manage multiple characteristics and related events, all within the scope of one device connection.