Does anybody know the reason why a GPIO Input Pin (any, tried a lot 14,21,22,32,35,5,4) has a double interrupt when using a optocoupler (TLP281)?
The setup used is the following:
One ESP32 will manage the Output connection to the opto, basically setting High/Low so that the opto switches the ground signal coming from another ESP32 that has the Interrupt Routine on a pin (14 on the pictures). GROUNDS are NOT tied together. In any case, when grounds are tied, the result is the same.
As you can see in the pictures, the Sender ESP32 sends a single pulse and counts it and the Receiver ESP32 with the interrupt pin receives the Interrupt and sends to a queue with a task that reads the queue and prints (a) the count, (b) the tickcount when the int happened and (c) if the signal was high or low.
The Interrupt pin is set to NEGEDGE, pullup enabled (also tested with an additional 10k pullup).
Code: Select all
void pinTaskIn(void *pArg)
{
intdef param;
param.count=0;
param.timer=0;
param.lowHigh=0;
intdef param1;
gpio_config_t io_conf;
uint64_t mask=1;
io_conf.intr_type = GPIO_INTR_NEGEDGE;
io_conf.pin_bit_mask = (mask<<whichPin);
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_down_en =GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en =GPIO_PULLUP_ENABLE;
gpio_config(&io_conf);
gpio_install_isr_service(0);
gpio_set_intr_type(whichPin, GPIO_INTR_NEGEDGE);
isrQ = xQueueCreate( 100, sizeof( param ) );
gpio_isr_handler_add((gpio_num_t)whichPin, gpio_isr_handler,(void*)¶m);
printf("Ready Input\n");
while(1)
{
if( xQueueReceive( isrQ, ¶m, portMAX_DELAY ))
{
printf("Count %d lowHigh %d timer %d\n",param.count,param.lowHigh, param.timer);
}
vTaskDelay(100/portTICK_PERIOD_MS);
}
}
The result is that for a Single activation of the optocoupler the Interrupt routine has 2 interrupts, one for a Low and another for a High when it is clearly defined only NEGEDGE.
The worst part is that it is not consistent, most of the times it has two interrupts but randomly it has only one (second print screen Count 3).
I have tried Hardware setups like 1.5 K pullup to 300K pullup. No change. A 1uf Cap. Same result.
The sending routine is simple but i attach it so as to have no doubts about the code.
Code: Select all
void pinTaskStep(void *pArg)
{
mystruct *defs=(mystruct*)pArg;
gpio_config_t io_conf;
uint64_t mask=1;
int sent=0;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.pin_bit_mask = (mask<<defs->elpin);
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pull_down_en =GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en =GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
printf("Ready Output\n");
while(1)
{
if(sendit)
{ sent++;
printf("Sending[%d] %d\n",defs->elpin,sent);
sendit=0;
gpio_set_level((gpio_num_t)defs->elpin, 1);
vTaskDelay(100/portTICK_PERIOD_MS);
gpio_set_level((gpio_num_t)defs->elpin, 0);
}
vTaskDelay(100/portTICK_PERIOD_MS);
}
}
Also from the interrupt we get that there is Low int and then a High int 100ms after the first. No idea how.
This experiment as done to confirm that a Electric Meter which sends a signal via an optocoupler is not a fault. A Logic Analyzer was used with the meter and had the same results as the experiment with only one pulse registered but 2 ints in the ESP32. I originally thought it was a "noise interference" in the Electric Meter but in our "lab" the result is the same with a simple setup.
Any ideas or suggestions are welcomed.