PIC16F18446 Curiosity Nano and QT7 Touch Board Example
Introduction
This article guides you from start to finish on how to use the MPLAB® Code Configurator (MCC) mTouch® Sensing Solutions module to create two touch buttons and one slider and enable the Universal Asynchronous Receiver Transmitter (UART) debugging interface on the PIC16F18446 Curiosity Nano Board, Curiosity Nano Touch Adapter, and QT7 Xplained Pro Extension Kit.
Materials
Hardware
Software
Procedure
Create an MPLAB X IDE Project for the PIC16F18446
- Choose Project: Standalone Project
- Select Device: PIC16F18446
- Select Tool: PIC16F18446 Curiosity Nano (PKOB nano)
- Select Compiler: XC8
- Select Project Name and Folder
Open MCC in MPLAB X IDE
If you don't see the MCC logo, please check that you have installed the MCC plugin. More information on MCC installation can be found on the "MPLAB Code Configurator (MCC)" page.
Configure the System Clock
Open the System Module from the Project Resources menu. Select HFINTOSC with 2x PLL from the Oscillator Select drop-down box, and select 16_MHz from the HF Internal Clock drop-down box. This will result in a 32 MHz system clock.
To ensure the performance of the mTouch button/proximity, the system clock is required to be at least 8 MHz. If you select a system clock slower than 8 MHz, the mTouch module will generate a warning in the notification window.
Load the mTouch Module
Double click on the mTouch button in the Libraries list inside the Device Resources window.
After loading the module, the mTouch button will appear in the Project Resources pane.
Select the mTouch Sensors
After loading the mTouch module, all available mTouch sensor pins will be shown in the Pin Manager: Grid View pane. You will need to select the physical sensors and shield based on the sensor pinout information in Table 1.
Pin Name | Function |
---|---|
RA5 | Button0 |
RA1 | Button1 |
RC2 | Slider1_Seg0 |
RC3 | Slider1_Seg1 |
RC6 | Slider1_Seg2 |
RC5 | Driven Shield |
Table 1
Add mTouch Buttons and Link to the Sensors
Go to the Buttons configuration view, and click Create New Button. Type "2" into the Number of Button text box, then click Add.
Then, click each button name to go to the Button Settings view and select the corresponding sensors shown in Table 1.
Add mTouch Slider and Link to the Sensors
Similar to the process of adding the mTouch buttons, go to the Sliders configuration view and click Create New Slider. Keeping 1 as the Number of Slider and 3 as the Number of Segments, click Add.
Then, click the slider name to go to the Slider Settings view, and select the corresponding sensors shown in Table 1.
Enable Debugging with Data Visualizer and Configure Enhanced Universal Synchronous Asynchronous Receiver Transmitter (EUSART) Module
Go to the Debug tab within the mTouch module. Check the Enable Debug box, select EUSART1 to be the EUSART module, and select Data Visualizer as the debug method. The EUSART module will be automatically added to the project and should appear in the project resources window.
Click on the EUSART module in the project resources window to check that it is configured correctly.
Check that the RX and TX pins are properly selected in the Pin Manager: Grid View. The RX pin should be RB6 and the TX pin should be RB4.
Setup I/O Pins to Control LEDs
There are eight LEDs on this board, and we want to use them to indicate the button and slider states. The pinout is shown in Table 2.
Pin | Name | Function |
---|---|---|
RA4 | LED0 | Button0 Touch Indicator |
RB5 | LED1 | Button1 Touch Indicator |
RC4 | LED2 | Slider1 Position Indicator |
RB7 | LED3 | Slider1 Position Indicator |
RC7 | LED4 | Slider1 Position Indicator |
RC0 | LED5 | Slider1 Position Indicator |
RA2 | LED6 | Slider1 Position Indicator |
RC1 | LED7 | Slider1 Position Indicator |
Table 2
Use the Pin Manager: Grid View to select the LED pins based on the pinout table.
Go to the Pin Module, and rename the pins as "LEDx". Because the LEDs are active low, we need to set up the pin starting high to turn off the LEDs.
Generate Code
Click on the Generate button.
Call mTouch Service and Enable Interrupts in main.c
Open up the generated main.c file. Place MTOUCH_Service_Mainloop() into the while loop as shown in the following code block and uncomment the functions that enable interrupts.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
// initialize the device
SYSTEM_Initialize();
// When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
// Use the following macros to:
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
// Disable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptDisable();
while (1)
{
// Add your application code
MTOUCH_Service_Mainloop();
}
}
Set Up Your Own Callback Functions
We have seen how to use the polling method to obtain the button state in the Curiosity Development Board Example. In this example, we will use callback functions. The mTouch library allows you to set your own callback function when a press/release event happens to bypass the function pointer to the setter function.
First, we implement the press/release callback functions for the button and proximity sensors and then pass these function pointers to the setter functions for each event as shown in the following code block (highlighted):
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
void processButtonTouch(enum mtouch_button_names button)
{
}
void processButtonRelease(enum mtouch_button_names button)
{
}
void processSliderPressed(enum mtouch_slider_names slider)
{
}
void processSliderRelease()
{
}
void processSliderPositionChange(enum mtouch_slider_names slider)
{
}
/*
Main application
*/
void main(void)
{
// initialize the device
SYSTEM_Initialize();
// When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
// Use the following macros to:
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
// Disable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptDisable();
MTOUCH_Button_SetPressedCallback(processButtonTouch);
MTOUCH_Button_SetNotPressedCallback(processButtonRelease);
MTOUCH_Slider_SetPressedCallback(processSliderPressed);
MTOUCH_Slider_SetPositionChangedCallback(processSliderPositionChange);
MTOUCH_Slider_SetReleasedCallback(processSliderRelease);
while (1)
{
// Add your application code
MTOUCH_Service_Mainloop();
}
}
Use the mTouch Buttons and Slider to Control LEDs
Once you have setup the callback functions, you will need to implement the logic to control the LEDs based on different events from the buttons/slider. The complete main.c code is shown in the following code block:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
void processButtonTouch(enum mtouch_button_names button)
{
switch(button)
{
case Button0: LED0_SetLow();break;
case Button1: LED1_SetLow();break;
default: break;
}
}
void processButtonRelease(enum mtouch_button_names button)
{
switch(button)
{
case Button0: LED0_SetHigh();break;
case Button1: LED1_SetHigh();break;
default: break;
}
}
void processSliderPressed(enum mtouch_slider_names slider)
{
uint16_t position = MTOUCH_Slider_Position_Get(slider);
if (position < 42)
LED2_SetLow();
else if (position < 85)
LED3_SetLow();
else if (position < 128)
LED4_SetLow();
else if (position < 171)
LED5_SetLow();
else if (position < 214)
LED6_SetLow();
else
LED7_SetLow();
}
void processSliderRelease()
{
LED2_SetHigh();
LED3_SetHigh();
LED4_SetHigh();
LED5_SetHigh();
LED6_SetHigh();
LED7_SetHigh();
}
void processSliderPositionChange(enum mtouch_slider_names slider)
{
processSliderRelease();
processSliderPressed(slider);
}
/*
Main application
*/
void main(void)
{
// initialize the device
SYSTEM_Initialize();
// When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
// Use the following macros to:
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
// Disable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptDisable();
MTOUCH_Button_SetPressedCallback(processButtonTouch);
MTOUCH_Button_SetNotPressedCallback(processButtonRelease);
MTOUCH_Slider_SetPressedCallback(processSliderPressed);
MTOUCH_Slider_SetPositionChangedCallback(processSliderPositionChange);
MTOUCH_Slider_SetReleasedCallback(processSliderRelease);
while (1)
{
// Add your application code
MTOUCH_Service_Mainloop();
}
}
Program the Board
After you connect the board to the PC with a USB cable, click the Program button to program the board.
Connect to Data Visualizer
Open Data Visualizer and select the appropriate COM port in the drop-down box in the Serial Port Control Panel window. Then click on the Autodetect protocols link to select the folder within the project where the protocol files are located.
The protocol files should be located in the mtouch folder within the mcc_generated_files folder. You can check this by locating the files of type *DB, DS, and SC.
Now click the Connect button. When a successful connection is established you will see the live touch data appear in the mTouch Data Visualizer window. This data can be useful for debugging and tuning a touch project.