CubeCell-Arduino icon indicating copy to clipboard operation
CubeCell-Arduino copied to clipboard

Interrupt not working reliable

Open eikaramba opened this issue 3 years ago • 16 comments

I have massive Problems making it work to have a clear interrupt signal on the cubecell dev board (HTCC-AB01).

Problem: Interrupt is firing randomly

I tried to:

  • Use internal pullup resp. pulldown modes on different pins (gpio0, 1, even gpio6 or 7) via pinMode(PIN,INPUT_PULLUP);
  • use external pullup resp. pulldown resistors (4.7k or 10k, tried others too)
  • interrupt on RAISING or FALLING (both unreliable)
  • usb powered vs. battery powered

But not a single combination and countless hours of trying gave me a reliable interrupt which is only firing when the reed contact switch triggers. the reed switch triggers correctly, but i am not able to eliminate the "noise" so every few seconds the interrupt is firing and the device wakes up. sure i can check the signal and let it directly sleep again, but still it makes the battery low.

Has anyone a similar problem or can tell me anything what could couse this problem?

eikaramba avatar Jan 26 '21 16:01 eikaramba

Just to be sure your problem is really related to the interrupt handling and not sleep mode:

Are you aware, that the lowPowerHandler() function will not permanently put the chip into sleep mode? Well at least not right away.

#include <Arduino.h>
void setup() {
  Serial.begin(9600);
}
void loop() {
  Serial.print("Sleeping..");
  lowPowerHandler();
  Serial.println(" ..awake!");
}

When you run the above code you will get "Sleeping.. ..awake!" about 5 times before finally only a "Sleeping.." appears.

This could be a source for your problems regarding seemingly random wake-ups of the chip.

To instantly put the CubeCell into deep sleep use this (working for platformio):

#include <Arduino.h>
#include "cyPm.c"
extern uint32_t         systime;   // global system time count

void MCU_deepsleep(void)
{
    UART_1_Sleep;
    pinMode(P4_1, ANALOG); // SPI0 MISO
    CySysPmDeepSleep(); // deep sleep mode    
    systime = (uint32_t)TimerGetCurrentTime();
    pinMode(P4_1, INPUT);
    UART_1_Wakeup;
}

void setup() {
  Serial.begin(9600);
}
void loop() {
  Serial.print("Sleeping..");
//  lowPowerHandler();
  MCU_deepsleep();
  Serial.println(" ..awake!");
}

You will see only the "S" of "Sleeping.." because the MCU_deepsleep() function puts the UART in sleep mode, too. Add a delay(500); after the print to see the complete string.

If your interrupt routine stops working after using the custom deep sleep, try replacing the "CySysPmDeepSleep();" with "CySysPmSleep( );" (according to AN86233 of the PSoc4 documentation the GPIO interrupts should work in deep sleep).

Hope this helps to find a solution for your issues.

tuxphone avatar Jan 26 '21 19:01 tuxphone

thanks for the answer but yeah i know. it takes a few loops. that is not the problem as the problem happens randomly every 6-45 seconds, totally random. i tried it with sleep and without, no difference.

However the cysyspmdeepsleep() is new to me, thanks for that. i will try this out. although i doubt this has anything to do with it, as the problem occurs even if the board is for sure in deep sleep and even if it never sleeps at all.

eikaramba avatar Jan 26 '21 20:01 eikaramba

Can you rule out other sources of magnetic fields? How do you use the reed switch? "Open" and waiting for a passing magnet to close the contact? That would be sensitive to outside influences.

I found a possible debouncing method: https://forum.arduino.cc/index.php?topic=14397.0

tuxphone avatar Jan 26 '21 21:01 tuxphone

Debounce would be helpful if the problem occurs on button press, but that is not the case. it happens if i don't do anything.

I am not using a simple pressdown button for testing, same problem.

See the following video maybe for an explanation. maybe even try this yourself, because having a simple button is like the "hello world" of microcontroller programming and i cannot be the first one wanting to have a simple button with one of the heltec boards :) Something is very weird here:

https://youtu.be/uoEOb4H6rFo

eikaramba avatar Jan 30 '21 17:01 eikaramba

I even have this when i directly connect GPIOX to 3.3V. (X=any gpio pin)

attachInterrupt(INT_GPIOX,onWakeUp,FALLING); still firing randomly.

eikaramba avatar Jan 30 '21 18:01 eikaramba

Unbelievable, it seems to be a common problem with at least the CubeCell AB01 Board! I found this forum thread: http://community.heltec.cn/t/cubecell-ab01-gpio-pins-going-high-intermittently/3152/2

...and yes, GPIO4 seems to be a little bit more stable in regard to interrupts! very sad that this seems to be a hardware failure, but at least one pin is working and i know the problem. it was literally driving me nuts because it did not make ANY sense.

There is even more information in this thread, with possible hardware solutions to mitigate this on other pins. will try this too, but everyone should be aware of this problem on the dev boards http://community.heltec.cn/t/phantom-interrupts-while-asleep-on-ab-01/2242

it still is not 100% working, but we are a little closer to the problem

eikaramba avatar Jan 31 '21 16:01 eikaramba

We tested no problem as you described and also http://community.heltec.cn/t/cubecell-ab01-gpio-pins-going-high-intermittently/3152/2. Have a try this code. The int GPIO can't be hanging. 图片

#include "Arduino.h"

#define INT_GPIO GPIO5

void onWakeUp() { delay(10); if(digitalRead(INT_GPIO) == 0) { Serial.printf("Woke up by GPIO.\r\n"); delay(10); } }

void setup() { // put your setup code here, to run once: Serial.begin(115200); pinMode(INT_GPIO,INPUT); attachInterrupt(INT_GPIO,onWakeUp,FALLING); }

void loop() { Serial.print("sleep\r\n"); lowPowerHandler(); // put your main code here, to run repeatedly: }

Heltec-Aaron-Lee avatar Feb 01 '21 06:02 Heltec-Aaron-Lee

not sure why you connected VS with GPIO5 but if i connect 3.3V with GPIO5 it does not work. the board wakes up from sleep every so often and the digitalRead still gives 1, so no "Wake up by GPIO" in the console.

see this picture:

as i said i tried different boards, different cables, the connections are all good

IMG_20210311_224243

eikaramba avatar Mar 11 '21 21:03 eikaramba

ok if i connect to VS instead of V3.3 the random interrupts seem to be wrong (finger crossed). i thought VS is only for input for solar panel? not for output. at least that's what the diagram says https://resource.heltec.cn/download/CubeCell/HTCC-AB01/HTCC-AB01_PinoutDiagram.pdf

update: ok if i put the reed contact directly to VS it also fires randomly, i guess a pullup resistor is still needed. while try that

update2: nope it just does not work. please i welcome you, try to connect a reed contact to the board and try to make the interrupt only fire and wake up the board if the reed contact opens or closes. i tried everything...

eikaramba avatar Mar 11 '21 22:03 eikaramba

Hey, I saw strange interrupt behaviour as well: I have configured a falling flank interrupt to measure the time between. It will be triggered randomly as well. The signal connected to any GIOP-pin will be clean (checking it with logic analyser at the same time). the time between falling flanks differs. the Cubecell is NOT WORKING RELIABLE.

Using the same code on heltec's esp32 wifi lora v2 the mentioned bug didn't not occur at all. it looks like an hardware issue.

nordblick2 avatar Sep 27 '21 14:09 nordblick2

Was there any solution found? Thanks.

mahesh2000 avatar Feb 25 '22 14:02 mahesh2000

unfortunately not, i still have this behaviour with all cubecell i have. a workaround is to use GPIO4 for the switch and use pinMode(SWITCH_PIN,INPUT_PULLDOWN);

However because the rgb is on gpio4 you get a lot of nasty side effects. they can be handled but i would rather just use a regular gpio pin and not have any noise there.

eikaramba avatar Feb 25 '22 15:02 eikaramba

I encountered a similar, but not identical problem: Every time I used the getBatteryVoltage() function the interrupt I had activated for the USER_KEY input fired. My workaround is to set a flag before calling getBatteryVoltage() and reset it afterwards. The interrupt handler checks if the flag is set and returns without an action if so. This setup seems to work, even in combination with deep sleep using LoRaWAN.cycle(sleep_ms) and LoRaWAN.sleep().

Kater--S avatar Jun 03 '22 17:06 Kater--S

I am experiencing exactly the same as @eikaramba , any update on this?

antoniomolram avatar Oct 22 '22 14:10 antoniomolram

unfortunately it was never solved. what i did is to use PIN 4 which is also used by the LED. It somehow is the only stable PIN, which when set to INPUT_PULLDOWN can reliable fire an interrupt on a rising signal and never when not.

eikaramba avatar Oct 24 '22 00:10 eikaramba

A few tips:

  • Disable external ISRs on tx
  • Expose rx fn's to toggle your external isr when rx rxDutyCycle and OnRxDone http://community.heltec.cn/t/asr6502-lora-interrupt-on-receive/13475
  • Make good use of filter caps

bigFin avatar Apr 19 '24 18:04 bigFin