I'm reading a PIR sensor on ADC1. If I write a simple test app with nothing going on including wifi I can get consistent readings that are logged to the terminal at 10 per second. When I integrate into an app with lots of stuff going on I start to see issues with reading that are wrong.
I noticed a 5 sec cyclic pattern of odd readings that I was able to eliminate when I turned off a module processing lots of data in ext SPI ram. The PIR was pinned to the APP core and the other module was pinned to the PRO core at a lower priority. So the only thing I could think of that was system wide was the reading of data in the SPI ram.
The second issue occurred when the module mentioned above was commented out. The PIR readings looked mostly fine except every now and then the logging to the terminal would pause and the ADC read zero. Thinking that logging to the terminal might be an issue I commented out the ADC read and replaced with a fixed value. I didn't see that occasional pause. This lead me to believe that the ADC read was momentarily sticking. Since the ADC! read has no status return I can't checked for an error.
My next thing to try is to measure the time it takes to read and assume if it's above a certain level that the read was invalid.
So my question is does this ring any bells with anyone. Maybe there is some things that interact. I'm using I2S and I2C.
Also does anyone know how long it should take to read the ADC?
John A
ADC Behavior Issue
-
- Posts: 76
- Joined: Tue Sep 12, 2017 11:25 am
Re: ADC Behavior Issue
Hi,
I use PIR sensors in several of my projects, but never as you say (with ADC) simply tie them to an interruption and increase a counter.
Greetings,
I use PIR sensors in several of my projects, but never as you say (with ADC) simply tie them to an interruption and increase a counter.
Greetings,
Re: ADC Behavior Issue
We designed it to use the ADC so that in future development we can use the detail to characterize the motion. But at this point I just want to detect motion. I'm the SW guy so I'm trying to get the HW designer to look at things like too much gain on the amplifier circuit and stability of the PS voltage. My testing is with USB power, which makes it easy to log data that I can plot. So perhaps the actual product PS is more stable.
We have an earlier version of the design that uses ADC2, but had to change to ADC1 because of wifi conflict. The earlier version on ADC2 demonstrates stable readings using the same test program, which eliminates the other activities talked about in the first post. That's one reason I think the amp circuit might have changed to create too much gain. The earlier version had usb right on the board. The later version uses a separate debug board with usb to power the main board.
John A
We have an earlier version of the design that uses ADC2, but had to change to ADC1 because of wifi conflict. The earlier version on ADC2 demonstrates stable readings using the same test program, which eliminates the other activities talked about in the first post. That's one reason I think the amp circuit might have changed to create too much gain. The earlier version had usb right on the board. The later version uses a separate debug board with usb to power the main board.
John A
Re: ADC Behavior Issue
It's possible that I2S will interfere with the ADCs (see the i2s_adc_enable() and i2s_adc_disable() functions).fly135 wrote:So my question is does this ring any bells with anyone. Maybe there is some things that interact. I'm using I2S and I2C.
To check if the ADC read is taking longer than usual (assuming you are using adc1_get_raw()) you can try add calls to portGET_RUN_TIME_COUNTER_VALUE() before and after the ADC read to get the CPU cycles count then divide by your CPU frequency to get the duration of the ADC read.fly135 wrote:This lead me to believe that the ADC read was momentarily sticking.
I ran the following code
Code: Select all
void app_main()
{
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC_CHANNEL_6, ADC_ATTEN_DB_0);
while (1) {
uint32_t before = portGET_RUN_TIME_COUNTER_VALUE();
int adc_reading = adc1_get_raw(ADC_CHANNEL_6);
uint32_t after = portGET_RUN_TIME_COUNTER_VALUE();
uint32_t clk_cycles = (after - before) + ((after > before) ? 0 : 0xFFFFFFFF);
printf("Reading: %d\tTime Taken us: %d\n", adc_reading, (clk_cycles/160)); //CPU running at 160MHz
vTaskDelay(pdMS_TO_TICKS(500));
}
}
Code: Select all
I (0) cpu_start: App cpu up.
I (211) heap_init: Initializing. RAM available for dynamic allocation:
I (217) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (223) heap_init: At 3FFB3300 len 0002CD00 (179 KiB): DRAM
I (230) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (236) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (242) heap_init: At 40088C30 len 000173D0 (92 KiB): IRAM
I (249) cpu_start: Pro cpu start user code
I (267) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
Reading: 942 Time Taken us: 134
Reading: 91 Time Taken us: 51
Reading: 38 Time Taken us: 51
Reading: 26 Time Taken us: 47
Reading: 16 Time Taken us: 51
Reading: 0 Time Taken us: 48
Reading: 5 Time Taken us: 51
Reading: 0 Time Taken us: 47
Reading: 0 Time Taken us: 51
Reading: 0 Time Taken us: 47
Reading: 0 Time Taken us: 51
Reading: 0 Time Taken us: 47
Reading: 9 Time Taken us: 51
Reading: 0 Time Taken us: 47
Reading: 0 Time Taken us: 51
Reading: 0 Time Taken us: 47
Reading: 18 Time Taken us: 51
Reading: 2 Time Taken us: 47
Reading: 16 Time Taken us: 51
Reading: 53 Time Taken us: 47
Reading: 74 Time Taken us: 51
Reading: 93 Time Taken us: 47
Re: ADC Behavior Issue
Thanks for the tip on the i2s_adc_enable function. I'm using an i2s pcm mic running continuously on app startup, so I don't think that is an issue. We are doing a lot of processing on the mic and I found that reading the mic data into memory caused less of an issue than the processing on the data. At this point I'm leaning towards a board layout causing induced noise in the PIR ampl circuit.
John A
John A
-
- Posts: 11
- Joined: Mon Nov 13, 2017 1:28 pm
Re: ADC Behavior Issue
Hello,
I may change the subject but I have an issue that I don't understand: I have an LCD TFT Touch 320*240 on which I am looking for the coordonates of a touch zone. I can read the X position alone and the Y position alone but when I want to get both the ADC doesn't work anymore:
int abscis() {
int X=0;
gpio_set_direction(GPIO_NUM_26, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_26, 1);
gpio_set_direction(GPIO_NUM_25, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_25, 0);
gpio_set_direction(GPIO_NUM_33, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_33, 0);
gpio_set_direction(GPIO_NUM_32, GPIO_MODE_INPUT);
adc1_config_width(3);
adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_11db);
X=adc1_get_raw(ADC1_CHANNEL_4)/(4096/240);
return X;
}
int ordon() {
int Y=0;
gpio_set_direction(GPIO_NUM_32, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_32, 1);
gpio_set_direction(GPIO_NUM_25, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_25, 0);
gpio_set_direction(GPIO_NUM_33, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_33, 0);
gpio_set_direction(GPIO_NUM_26, GPIO_MODE_INPUT);
adc2_config_channel_atten( ADC2_CHANNEL_9, ADC_ATTEN_11db );
adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &Y);
return (Y/(4096/320));
}
while (1){
int X=abscis();
int Y=ordon();
printf ("X=%d Y=%d\r\n",X, Y);
}
X and Y always egal to 0, but when only one of them it works.
Any idea on the topic? I have been reading all I could find on the web but nothing helped.
Thanks and regards
I may change the subject but I have an issue that I don't understand: I have an LCD TFT Touch 320*240 on which I am looking for the coordonates of a touch zone. I can read the X position alone and the Y position alone but when I want to get both the ADC doesn't work anymore:
int abscis() {
int X=0;
gpio_set_direction(GPIO_NUM_26, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_26, 1);
gpio_set_direction(GPIO_NUM_25, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_25, 0);
gpio_set_direction(GPIO_NUM_33, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_33, 0);
gpio_set_direction(GPIO_NUM_32, GPIO_MODE_INPUT);
adc1_config_width(3);
adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_11db);
X=adc1_get_raw(ADC1_CHANNEL_4)/(4096/240);
return X;
}
int ordon() {
int Y=0;
gpio_set_direction(GPIO_NUM_32, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_32, 1);
gpio_set_direction(GPIO_NUM_25, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_25, 0);
gpio_set_direction(GPIO_NUM_33, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_33, 0);
gpio_set_direction(GPIO_NUM_26, GPIO_MODE_INPUT);
adc2_config_channel_atten( ADC2_CHANNEL_9, ADC_ATTEN_11db );
adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &Y);
return (Y/(4096/320));
}
while (1){
int X=abscis();
int Y=ordon();
printf ("X=%d Y=%d\r\n",X, Y);
}
X and Y always egal to 0, but when only one of them it works.
Any idea on the topic? I have been reading all I could find on the web but nothing helped.
Thanks and regards
-
- Posts: 11
- Joined: Mon Nov 13, 2017 1:28 pm
Re: ADC Behavior Issue
I have cheked ADC1 and ADC2, they both work alone but when called in the same function, I have an odd behaviour, I mean no results (X=Y=0). Delays don't change anything. It works only when I don't set the accuracy neither the voltage level:
//adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_11db); // if set no answer for X
//adc2_config_channel_atten( ADC2_CHANNEL_9, ADC_ATTEN_11db ); // if set no answer for Y
adc1_config_width(3); // accuracy for ADC1 ok, results for Y posiiton are quite good
gpio_set_direction(GPIO_NUM_26, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_26, 1);
gpio_set_direction(GPIO_NUM_25, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_25, 0);
gpio_set_direction(GPIO_NUM_33, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_33, 0);
gpio_set_direction(GPIO_NUM_32, GPIO_MODE_INPUT);
X=adc1_get_raw(ADC1_CHANNEL_4);//Reads X axis touch ]position
gpio_set_direction(GPIO_NUM_32, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_32, 1);
gpio_set_direction(GPIO_NUM_26, GPIO_MODE_INPUT);
gpio_set_direction(GPIO_NUM_33, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_33, 0);
gpio_set_direction(GPIO_NUM_25, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_25, 0);
adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &Y);
X/=(4096/320);
Y/=(4096/240);
I don't have any clue on how the both functions actually work, since I don't know where to find the prototype and the related registers.
Has anyone observed same problem?
//adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_11db); // if set no answer for X
//adc2_config_channel_atten( ADC2_CHANNEL_9, ADC_ATTEN_11db ); // if set no answer for Y
adc1_config_width(3); // accuracy for ADC1 ok, results for Y posiiton are quite good
gpio_set_direction(GPIO_NUM_26, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_26, 1);
gpio_set_direction(GPIO_NUM_25, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_25, 0);
gpio_set_direction(GPIO_NUM_33, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_33, 0);
gpio_set_direction(GPIO_NUM_32, GPIO_MODE_INPUT);
X=adc1_get_raw(ADC1_CHANNEL_4);//Reads X axis touch ]position
gpio_set_direction(GPIO_NUM_32, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_32, 1);
gpio_set_direction(GPIO_NUM_26, GPIO_MODE_INPUT);
gpio_set_direction(GPIO_NUM_33, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_33, 0);
gpio_set_direction(GPIO_NUM_25, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_25, 0);
adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &Y);
X/=(4096/320);
Y/=(4096/240);
I don't have any clue on how the both functions actually work, since I don't know where to find the prototype and the related registers.
Has anyone observed same problem?
Re: ADC Behavior Issue
Not sure where the bug is as the code you posted above works for me.
I suggest you remove all calls to gpio functions they are not necessary. adc1_config_channel_atten() and adc2_config_channel_atten() will already configure the necessary GPIOs.
Please see the adc example for the correct usage of the ADC API
I suggest you remove all calls to gpio functions they are not necessary. adc1_config_channel_atten() and adc2_config_channel_atten() will already configure the necessary GPIOs.
Please see the adc example for the correct usage of the ADC API
Links to adc header files and source filesilly@scharco.de wrote:I don't know where to find the prototype and the related registers.
Who is online
Users browsing this forum: Baidu [Spider] and 87 guests