How do you feel about this article? Help us to provide better content for you.
Thank you! Your feedback has been received.
There was a problem submitting your feedback, please try again later.
What do you think of this article?
Parts list
Qty | Product | Part number | |
---|---|---|---|
1 | Microchip AVR128DA48 Curiosity Nano Evaluation Kit GPIO Evaluation Board DM164151 | 204-2690 | |
1 | Microchip AC164162 for use with Mikrobus Click Modules, Xplained Pro Extension Boards | 193-6490 | |
1 | MikroElektronika MIKROE-1881, 4x4 RGB LED Matrix Display mikroBus Click Board | 136-0725 | |
1 | MikroElektronika Force Click mikroBus Click Board for Implement Force Pressure Measurement MIKROE-2065 | 136-0788 | |
1 | MikroElektronika RN4871 Click Bluetooth Development Kit MIKROE-2544 | 168-3003 | |
The Curiosity Nano development platform from Microchip is a small-sized, easily customizable rapid prototyping solution that provides developers with everything they might need to bring their project ideas to life. This article introduces the main features of the platform focusing specifically on a target microcontroller from AVR DA family. Together with our DesignSpark members, we will investigate one of the example codes from Microchip’s GitHub repository, while also discussing the basic operation of peripherals that were used in the demo, such as GPIOs, ADC and USART.
Peripheral Configuration - GPIO (Part1)
Peripheral Configuration - USART (Part 2)
Peripheral Configuration - ADC
The applied force is detected using Interlink Electronics’ force sensing resistor (FSR) implemented with a help of add-on circuitry on the Force click board. The analog output voltage from Force click board is then fed to the ADC of the AVR128DA48.
Force sensor
Force click board with force sensing resistor
The FSR is a type of piezoresistive sensor, which consists of two membranes that are separated by a spacer adhesive. The bottom membrane is a conductor substrate with two sets of interdigitated traces that are electronically isolated from one another, whereas the other membrane is coated with carbon-based conductive ink. In a neutral state, there is a distance between the top and bottom layers due to a small separation created by the spacer, thus resulting in an open circuit configuration with no electricity passing between the layers. When external force or pressure is applied, the gap between two membranes gets closer changing the resistance to be proportional to applied force. The analog output voltage of the FSR is then converted to the corresponding digital value using the in-built ADC.
Typical construction of force sensing resistor
SAR ADC
The AVR128DA48 microcontroller features a 12-bit successive approximation register (SAR) ADC, with a sampling rate of up to 130 ksps (kilosamples per second). This type of ADCs uses binary search algorithm to convert the analog value to a digital equivalent. Consider an example of 4-bit SAR ADC below.
4-bit SAR ADC
The SAR ADC typically consists of a sample and hold circuit, a comparator, a digital to analog converter, a successive approximation register along with the control circuit. When the new conversion period starts, the sample and hold circuit samples the input signal. The comparator then compares that signal with the output signal of the DAC. Based on the result of the comparison, the output of the SAR changes one bit at a time. The complete explanation of SAR ADC’s working is available in this article.
The AVR128DA48 microcontroller has one instance of ADC peripheral accessible through PORTD pins (PD0 to PD7). It supports single-ended and differential inputs implemented using analog input multiplexers. The former allows measurements between selected input level and 0V, whereas the latter measures the voltage between two input channels.
ADC Block Diagram
The ADC can be configured to specific voltage reference (VREF) levels coming from various sources such as internally generated voltages, AVDD supply voltage as well as external VREF pin (VREFA).
The summary of given ADC registers is given in the table below. We will discuss the initialization steps for setting up the ADC to convert the analog signal from the FSR sensor.
ADC Registers Summary
ADC initialization
Reference voltage
In the demo, we will be relying on a single-ended 12-bit conversion with the result of the conversion to be stored in the ADCn.RES register given by the following equation:
Here, VAINP is the positive ADC input and the VADCREF is the selected ADC voltage reference. The VADCREF is equal to AVDD = 3.3V in our setup, which can be set by accessing VREF register.
The analog values in the range between 0 and VADCREF are mapped to the 12-bit representation (although the register has a 16-bit capacity). You will notice that the maximum value of VAINP can vary from one setup to another. When maximum force is applied on the Force sensor the voltage on ADC pin is 3.261V which gives ADC count ~ 0xFCF.
The relationship between input range and binary output representation
Clock generation & Prescaler
The ADC converts analog signal into digital signal at regular intervals determined by its operation range, usually in order of kHz frequencies. However, the CPU clock frequency is significantly higher (up to 24 MHz for AVR® DA family). Therefore, the microcontrollers usually have a prescaler circuit to perform a frequency division operation with predefined division factors, such as 2, 4, 8, 12, …,256. For example, defining a prescaler factor of 96 in PRESC bit field of ADCn.CTRLC register will result in fADC = fCPU/96 = 125kHz for fCPU = 12MHz.
ADC Prescaler
Single vs Accumulated Sampling
There are two operation modes supported depending on the accumulator setting: a single sample or an accumulation of samples. The timing diagrams for these modes are shown below. As you might notice, there are a number of operations with specific timing that happen within the conversion cycle for both modes. Those include start-up (2*fCPU cycles), sampling (2*fADC cycles), conversion (13.5*fADC cycles) and result formatting (2*fCPU cycles). Total conversion time will depend on whether the result of the conversion is taken after a single sample or an accumulation of n samples. The SUMPNUM bit field within the ADCn.CTRLB register can be used to set how many samples should be accumulated (if any).
Single sample conversion
Accumulated conversion for two samples
Free-running mode
If the Free-Running mode is enabled in the ADCn.CTRLA register, a new conversion is started as soon as the previous conversion has completed. The timing diagram for the ADC in Free Running mode for a single conversion is shown below.
ADC in Free Running mode
Pin selection & enable
In the demo, the pin PD4, which corresponds to the AIN4 channel of the ADC, has been selected to feed the input signal through the positive terminal by writing to the MUXPOS bit field of the ADCn.MUXPOS register. Lastly, the selected pin is enabled by writing “1” to the ENABLE bit in the ADCn.CTRLA register.
void adc_init()
{
VREF.ADC0REF = VREF_REFSEL_VDD_gc;
ADC0.CTRLA = ADC_FREERUN_bm;
ADC0.CTRLB = ADC_SAMPNUM_ACC128_gc;
ADC0.CTRLC = ADC_PRESC_DIV96_gc; /* MAX FCLK_ADC 1.25 Khz */
ADC0.MUXPOS = ADC_MUXPOS_AIN4_gc; /* ADC channel AIN4->PD4 */
ADC0.CTRLA |= ADC_ENABLE_bm ;
}
Code implementation – Starting a conversion
To start the conversion, it is necessary to write a “1” to the Start Conversion (STCONV) bit in the ADCn.COMMAND register. The STCONV bit will be set during a conversion and cleared once the conversion is complete.
ADC conversion in the main function
int main(void)
{
ccp_write_io((void *)&(CLKCTRL.OSCHFCTRLA), CLKCTRL_FREQSEL_12M_gc); /* CPU clock is configured to 12 Mhz in clock_config.h */
io_init();
adc_init();
usart_ble_init();
usart_cdc_init();
sei();
rgb_init();
rgb_pattern_MixColor();
rgb_pattern_Red_Green_White();
RN4871_Setup_Transparent_UART_service();
ADC0.COMMAND |= ADC_STCONV_bm;
while (1)
{
if(adc_result_is_ready())
{
adc_t.adc_result = (uint16_t)adc_get_result();
adc_t.adc_average_result = (uint16_t)adc_t.adc_result >> DIV_OR_SHIFT;
strength_percentage = (float)(adc_t.adc_average_result * MAX_FORCE_PERCENT) / ADC_MAX_VALUE_for_FORCE_CLICK;
transmit_to_BLE(strength_percentage);
transmit_to_terminal(strength_percentage);
rgb_display_pattern_per_force();
}
}
}
The result of the conversion is accessible through the ADCn.RES register, and the RESRDY interrupt flag is set in the ADCn.INTFLAGS register.
Getting the ADC result from RES register
uint16_t adc_get_result(void)
{
return (ADC0.RES);
}
bool adc_result_is_ready(void)
{
return (ADC0.INTFLAGS & ADC_RESRDY_bm);
}
Summary
In this (rather long) article, we collated the detailed explanation of three main peripherals that were used to implement the Stress Ball demo from Microchip. Even if this is your first time working with 8-bit microcontrollers from AVR® family, you should able to follow the instructions and get started with building applications easily. The complementary application documents and code examples will be included in the Resources section.
If you have any other tutorials you want to see on DesignSpark, leave us a comment below!
Resources
Rapid Prototyping with the Curiosity Nano Platform – Microchip University
AVR1000b: Getting Started with Writing C-Code for AVR® - TB3262
How to Use Force Sensitive Resistor with 12-bit ADC - AN3408
AVR® DA Family Datasheet - Microchip
AVR128DA48 USART Hello World Example – GitHub
USART Serial Terminal – Microchip Developer
WS2812 Tutorial – Friendly Wire
Successive Approximation ADC Explained – ALL ABOUT ELECTRONICS
Differential ADC Using the AVR128DA48 Curiosity Nano - GitHub