I need twoADC channels. I tried to configure using :
CONFIG_ADC= y in prj file,
&adc{
#io-channel-cells = < 0x2 >;
}; in overlay file .. the compile error appears as shown in atteched iamge.
Gulzar Singh
I need twoADC channels. I tried to configure using :
CONFIG_ADC= y in prj file,
&adc{
#io-channel-cells = < 0x2 >;
}; in overlay file .. the compile error appears as shown in atteched iamge.
Gulzar Singh
Hello,
SAADC supports 8 channels- One cannel per single-ended input and two channels per differential input. So, If you want two single-ended inputs- you need to create two separate channel configurations; one for AIN0 and one for AIN1 for instance. It has to be defined from the main.c file. Also if you intend to do periodic sample using PPI or collect the sample as part of interrupt handling like this example I linked before https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/reference/peripherals/adc.html?highlight=adc_channel_cfg#c.adc_channel_cfg ; you have to define this in C file.
Best Regards,
Kazi Afroza Sultana
Hi, I created an application for testng the sampling of 2 channels on AIN0 and AIN1. The files are attached. I have few doubts.
1. In the adc.h, is #define BUFFER_SIZE 2 right or wrong to sample 2 analog channels ? If in future, 3 chhannels are required, may I set #define BUFFER_SIZE 3.
2. In the main file, I adc instantiated by binding and then, set up channels using err = adc_channel_setup() .. function. Is it proper way ?
3. As, I copied the most coe from sample program, what is meaning of following ?
#if defined (CONFIG_BOARD_BMS_NRF5340_CPUAPP)
NRF_SAADC->TASKS_CALIBRATEOFFSET = 1;
4. I wrote two sample functions, as in adc.c. Is this proper way to add to sequence ? If, wrong any where, may you make changes and attache corrected code file ?
5. I called adc sampling functions in repeatitive timer. Is the result of adc from AIN0 and AIN1 be avaialble at same index or at different indices in p_sample_buffer[].
void my_work_handler(struct k_work *work) {int err; /* do the processing that needs to be done periodically */ //********** AIN0 Sample part ************** err = adc_sample1(); if (err) { // printk("Error in adc sampling: %d\n", err); } Var1 = p_sample_buffer[0]; err = adc_sample2(); if (err) { // printk("Error in adc sampling: %d\n", err); } Var2 = p_sample_buffer[0]; } K_WORK_DEFINE(my_work, my_work_handler); void my_timer_handler(struct k_timer *dummy) { k_work_submit(&my_work); } K_TIMER_DEFINE(my_timer, my_timer_handler, NULL); //**************** void main() { //ADC setup adc_dev = device_get_binding(ADC_DEVICE_NAME); if (!adc_dev) { printk("device_get_binding ADC (=%s) failed\n", ADC_DEVICE_NAME); } err = adc_channel_setup(adc_dev, &m_1st_channel_cfg); if (err) { printk("Error in adc AIN0 setup: %d\n", err); } err = adc_channel_setup(adc_dev, &m_2nd_channel_cfg); if (err) { printk("Error in adc AIN1 setup: %d\n", err); } #if defined (CONFIG_BOARD_BMS_NRF5340_CPUAPP) NRF_SAADC->TASKS_CALIBRATEOFFSET = 1; #else #error "Choose supported board or add new board for the application" #endif }
// ADC.C File //**************** static int adc_sample1(void) { int ret; const struct adc_sequence sequence = { .channels = BIT(ADC_1ST_CHANNEL_ID), .buffer = p_sample_buffer, .buffer_size = sizeof(p_sample_buffer), .resolution = ADC_RESOLUTION, }; if (!adc_dev) { return -1; } ret = adc_read(adc_dev, &sequence); if (ret) { // printk("adc_read() failed with code %d\n", ret); } for (int i = 0; i < BUFFER_SIZE; i++) { // printk("ADC raw value: %d\n", p_sample_buffer[i]); } return ret; } static int adc_sample2(void) { int ret; const struct adc_sequence sequence = { .channels = BIT(ADC_2ND_CHANNEL_ID), .buffer = p_sample_buffer, .buffer_size = sizeof(p_sample_buffer), .resolution = ADC_RESOLUTION, }; if (!adc_dev) { return -1; } ret = adc_read(adc_dev, &sequence); if (ret) { // printk("adc_read() failed with code %d\n", ret); } for (int i = 0; i < BUFFER_SIZE; i++) { // printk("ADC raw value: %d\n", p_sample_buffer[i]); } return ret; } //****************
Gulzar Singh
Hello Gulzar,
I have started looking at your files. Could you please send me the whole project so I can try to reproduce it?
Best Regards,
Kazi Afroza Sultana
Hi, here is the code in attached file.
//********************** #include <hal/nrf_saadc.h> //********** #define ADC_DEVICE_NAME DT_LABEL(DT_INST(0, nordic_nrf_saadc)) #define ADC_RESOLUTION 10 #define ADC_GAIN ADC_GAIN_1_6 #define ADC_REFERENCE ADC_REF_INTERNAL #define ADC_ACQUISITION_TIME ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10) #define ADC_1ST_CHANNEL_ID 0 #define ADC_1ST_CHANNEL_INPUT NRF_SAADC_INPUT_AIN0 #define ADC_2ND_CHANNEL_ID 1 #define ADC_2ND_CHANNEL_INPUT NRF_SAADC_INPUT_AIN1 #define BUFFER_SIZE 2 int err; static int p_sample_buffer[BUFFER_SIZE]; const struct device *adc_dev; static const struct adc_channel_cfg m_1st_channel_cfg = { .gain = ADC_GAIN, .reference = ADC_REFERENCE, .acquisition_time = ADC_ACQUISITION_TIME, .channel_id = ADC_1ST_CHANNEL_ID, #if defined(CONFIG_ADC_CONFIGURABLE_INPUTS) .input_positive = ADC_1ST_CHANNEL_INPUT, #endif }; static const struct adc_channel_cfg m_2nd_channel_cfg = { .gain = ADC_GAIN, .reference = ADC_REFERENCE, .acquisition_time = ADC_ACQUISITION_TIME, .channel_id = ADC_2ND_CHANNEL_ID, #if defined(CONFIG_ADC_CONFIGURABLE_INPUTS) .input_positive = ADC_2ND_CHANNEL_INPUT, #endif }; static int adc_sample1(void) { int ret; const struct adc_sequence sequence = { .channels = BIT(ADC_1ST_CHANNEL_ID), .buffer = p_sample_buffer, .buffer_size = sizeof(p_sample_buffer), .resolution = ADC_RESOLUTION, }; if (!adc_dev) { return -1; } ret = adc_read(adc_dev, &sequence); if (ret) { // printk("adc_read() failed with code %d\n", ret); } for (int i = 0; i < BUFFER_SIZE; i++) { // printk("ADC raw value: %d\n", p_sample_buffer[i]); } return ret; } static int adc_sample2(void) { int ret; const struct adc_sequence sequence = { .channels = BIT(ADC_2ND_CHANNEL_ID), .buffer = p_sample_buffer, .buffer_size = sizeof(p_sample_buffer), .resolution = ADC_RESOLUTION, }; if (!adc_dev) { return -1; } ret = adc_read(adc_dev, &sequence); if (ret) { // printk("adc_read() failed with code %d\n", ret); } for (int i = 0; i < BUFFER_SIZE; i++) { // printk("ADC raw value: %d\n", p_sample_buffer[i]); } return ret; } //**************** void my_work_handler(struct k_work *work) {int err;unsigned int k; /* do the processing that needs to be done periodically */ //********** AIN0 Sample part ************** err = adc_sample1(); if (err) { // printk("Error in adc sampling: %d\n", err); } var1 = p_sample_buffer[0]; err = adc_sample2(); if (err) { // printk("Error in adc sampling: %d\n", err); } var2 = p_sample_buffer[0];// should it be index 0 or 1 ????? } K_WORK_DEFINE(my_work, my_work_handler); void my_timer_handler(struct k_timer *dummy) { k_work_submit(&my_work); } K_TIMER_DEFINE(my_timer, my_timer_handler, NULL); //******************************************************** void main(){ //ADC setup adc_dev = device_get_binding(ADC_DEVICE_NAME); if (!adc_dev) { printk("device_get_binding ADC (=%s) failed\n", ADC_DEVICE_NAME); } err = adc_channel_setup(adc_dev, &m_1st_channel_cfg); if (err) { printk("Error in adc AIN0 setup: %d\n", err); } err = adc_channel_setup(adc_dev, &m_2nd_channel_cfg); if (err) { printk("Error in adc AIN1 setup: %d\n", err); } #if defined (CONFIG_BOARD_BMS_NRF5340_CPUAPP) NRF_SAADC->TASKS_CALIBRATEOFFSET = 1; #else #error "Choose supported board or add new board for the application" #endif k_timer_start(&my_timer, K_SECONDS(4), K_SECONDS(30)); while(1) { // do something } }
I mean the project folder which contain build file, configure file, cmakelist text file and source file. like the following screenshot:
I mean the project folder which contain build file, configure file, cmakelist text file and source file. like the following screenshot:
Hi, I just need answer of three queries as shown in attached image.