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);
}
Filtering caps (1n ?) can also help.
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
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
This an interesting thread, I would like to know if you get it resolved.
I’ll add a large and a very small capacitor to the BluePill GND/VCC and see if it helps.
Best
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
Same bluepill with the same sketch? no changes in circuit, powersupply, usb cable…?
If so, we may never know ![]()
But it’s weaker–meaning less max. current–than the previous one. Hence, I would expect more problem
[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.
Unfortunately, the setup of my home office changed a lot yesterday. Anyway, we’ll see
Thanks & best

