[SOLVED] IRQ handling problem (updated: electronic interference?)

terraduino
Sat Jul 08, 2017 12:13 pm
Hi,

I attached a reed switch (PA4 and 3V3) to a BluePill that is powered by dedicated 5V USB power supply through micro USB. I activated IRQ on PA4 to get a notice when the window is opened or closed.
It did work well, I thought. But eventually I get false notifications although the window was far open, hence, definitely no change of magnetic field around the reed switch. First occurrence after maybe 10-60 minutes then every now and then, sometimes 5 times in 10 seconds.

Probably I got something wrong with my code. This is the IRQ relevant code. Note that I’m using arrays to define multiple IRQs. However, only one IRQ is used at the moment. volatile uint8_t toggle = 1;
volatile uint8_t event = false;
uint8_t bIRQIgnore = true;

const uint8_t irq_pins[] = IRQ_PINS;
const ExtIntTriggerMode irq_mode[] = IRQ_MODE;
const uint16_t irq_ids[] = IRQ_IDS;
const WiringPinMode irq_pull[] = IRQ_PULL;
uint16_t irq_event = 0; // each bit one irq, max 16
uint16_t irq_state = 0; // each bit one irq, max 16
uint16_t irq_stateA = 0; // each bit one irq, max 16
uint16_t irq_stateB = 0; // each bit one irq, max 16
uint16_t irq_stateC = 0; // each bit one irq, max 16

// minimal activity in irqhandler
void irqhandler(void) {
if (bIRQIgnore || event) return;
irq_stateA = GPIOA->regs->IDR;
irq_stateB = GPIOB->regs->IDR;
irq_stateC = GPIOC->regs->IDR;
event = true;
}

// enable IRQ for specified pins
void setupIRQ() {
for (int i = 0; i < arrlen(irq_pins); i++) {
pinMode(irq_pins[i], irq_pull[i]);

// give time to settle, before that initial state was false.
delay(10);

// read current pin states
irq_stateA = GPIOA->regs->IDR;
irq_stateB = GPIOB->regs->IDR;
irq_stateC = GPIOC->regs->IDR;

// set "old" IRQ states
for (uint8_t i = 0; i < arrlen(irq_pins); i++) {
if (getIRQPinState(irq_pins[i])) {
sbi(irq_state, i);
} else {
cbi(irq_state, i);
}
}
attachInterrupt(irq_pins[i], irqhandler, irq_mode[i]);
}
bIRQIgnore = false;
}

void checkIRQ() {
if (event) {

// check all PINs to see which changed/triggered
for (uint8_t i = 0; i < arrlen(irq_pins); i++) {
uint8_t pnew = getIRQPinState(irq_pins[i]);
uint8_t pold = gbi(irq_state, i);

if (pnew != pold) {
// set new value
if (irq_mode[i] == CHANGE) {
if (pnew) sbi(irq_state, i);
else cbi(irq_state, i);
}
// set to high, does not check for falling edge
if (irq_mode[i] == RISING) {
cbi(irq_state, i);
}
// set to low, does not check for rising edge
if (irq_mode[i] == FALLING) {
sbi(irq_state, i);
}

Serial.println(pnew ? "CLOSED" : "OPENED");

}
}
event = false;
}
}

// helper to get single pin status
uint8_t getIRQPinState(uint8_t irq) {
if (irq < 16) {
return gbi(irq_stateA, irq);
}
if (irq < 32) {
return gbi(irq_stateB, irq - 16);
}

return gbi(irq_stateC, irq - 32);
}


stevestrong
Tue Jul 11, 2017 2:31 pm
The internal pull-up/down resistors are very weak (30k or larger), so it is suggested to use extra ones, with 10k or less.
Filtering caps (1n ?) can also help.

terraduino
Tue Jul 11, 2017 6:30 pm
Thanks for your suggestions.
I tried a 10k pulldown but it didn’t help.

I’m not sure where to put your filtering cap. In parallel to the switch? It will work as a physical de-bounce circuit, right?

Best


terraduino
Wed Jul 12, 2017 11:29 pm
Today, I observed that pulling the plug of my printer caused the BluePill to trigger the interrupt. The printer and dedicated USB power supply, which is powering my BluePill, share the same main line.
I’m really surprised that this triggered the interrupt. Is it normal behavior that such voltage changes “pierce through” two voltage regulator (i.e. the spikes were not smoothed out)?
Moreover, how can I stabilize it? Solder a big capacitor on the BlueBill close to the micro USB plug?

Thanks & best


victor_pv
Wed Jul 12, 2017 11:54 pm
Perhaps adding a small debounce capacitor in the input helps?
This an interesting thread, I would like to know if you get it resolved.

terraduino
Sat Jul 22, 2017 1:01 pm
Dear @victor_pv, sorry for the late response. I’ll update this thread as soon as I have news.
I’ll add a large and a very small capacitor to the BluePill GND/VCC and see if it helps.
Best

terraduino
Fri Aug 04, 2017 11:40 pm
Electronics is … weird. I tried to reproduce the error that I stumbled across some weeks ago. However, the BluePill runs stable now and no IRQ is triggered. No idea what changed but if I can reproduce the error I’ll let you know.

Best


victor_pv
Sat Aug 05, 2017 1:19 am
[terraduino – Fri Aug 04, 2017 11:40 pm] –
Electronics is … weird. I tried to reproduce the error that I stumbled across some weeks ago. However, the BluePill runs stable now and no IRQ is triggered. No idea what changed but if I can reproduce the error I’ll let you know.

Best

Same bluepill with the same sketch? no changes in circuit, powersupply, usb cable…?
If so, we may never know :(


terraduino
Mon Aug 07, 2017 10:17 pm
Actually, I did change the USB cable.
But it’s weaker–meaning less max. current–than the previous one. Hence, I would expect more problem ;)

victor_pv
Tue Aug 08, 2017 4:03 am
[terraduino – Mon Aug 07, 2017 10:17 pm] –
Actually, I did change the USB cable.
But it’s weaker–meaning less max. current–than the previous one. Hence, I would expect more problem ;)

Do you still have the old cable around to test again with it?
Strange, but who knows if perhaps one cable is better shielded than the other, or the old one had some bad contact that caused the voltage to drop… who knows, but perhaps testing again you can rule that out.


terraduino
Thu Aug 10, 2017 11:14 am
Good question. Don’t know which it was but maybe I find some time to test a bunch of them. Would be interesting to know.
Unfortunately, the setup of my home office changed a lot yesterday. Anyway, we’ll see :)

RogerClark
Thu Aug 10, 2017 9:56 pm
Thin wires in the cheap cable may be an advantage in this case, as it forms the L or R part of a filter in line with the supply.

terraduino
Sat Aug 12, 2017 8:14 pm
Interesting, didn’t know that.

Thanks & best


Leave a Reply

Your email address will not be published. Required fields are marked *