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

Post here first, or if you can't find a relevant section!
terraduino
Posts: 11
Joined: Tue Jun 27, 2017 6:34 pm

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

Post by 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.

Code: Select all

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);
}

checkIRQ() is called in loop all the time.

To make things little more complicated, the BluePill also collects sensor data (i.e. DS18B20, ADC readings, and its own voltage), receives data via nRF24L01+ on interface SPI2, and sends and receives data via Serial1 to a Raspberry Pi 3.
In general, the setup is working well. I'm not sure but in case it is related to the IRQ problem, the nRF24 seems to "crash" for unknown reasons after arbitrary intervals. "Crash" means it does not receive data anymore. When this happens, I call its setup routine again and it works. Here is the setup

Code: Select all

void setupTRX() {
  radio.begin();
  radio.setAutoAck(1); 
  radio.setChannel(TRX_CHANNEL);
  radio.setDataRate( TRX_DATARATE );
  radio.setPALevel(TRX_POWER);
  radio.setRetries(TRX_DELAY, TRX_RETRIES); // delay, count

  radio.enableDynamicAck();
  radio.enableDynamicPayloads();

    for (byte b = 0; b < 6; b++) {
      radio.openReadingPipe(b, pipes[b]);
    }
    radio.startListening();
}
EDIT: As I'm still doing tests on a second BluePill, it hit me. The board I mentioned above is still configured with the interrupt but I disconnected the reed switch. Instead, I connected it to a second board that does nothing but sit and wait for an interrupt. The point is, the BluePill 1 does not generate false notifications as long as no wire is attached to PA4.
Well, what can this mean?
1. The reed switch is faulty somehow and "floats".
2. Is it possible that the thin wires (AWG28) connecting the BluePill and the reed switch are causing the problem? Maybe wire capacitance or other interference? I'm using internal pulldown resistor on the BluePill. Could a stronger external pulldown resistor help?


Would be great if someone has an idea.
Thanks & best

stevestrong
Posts: 1520
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: IRQ handling problem (updated: electronic interference?)

Post by 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
Posts: 11
Joined: Tue Jun 27, 2017 6:34 pm

Re: IRQ handling problem (updated: electronic interference?)

Post by 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
Posts: 11
Joined: Tue Jun 27, 2017 6:34 pm

Re: IRQ handling problem (updated: electronic interference?)

Post by 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
Posts: 1607
Joined: Mon Apr 27, 2015 12:12 pm

Re: IRQ handling problem (updated: electronic interference?)

Post by 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
Posts: 11
Joined: Tue Jun 27, 2017 6:34 pm

Re: IRQ handling problem (updated: electronic interference?)

Post by 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
Posts: 11
Joined: Tue Jun 27, 2017 6:34 pm

Re: IRQ handling problem (updated: electronic interference?)

Post by 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
Posts: 1607
Joined: Mon Apr 27, 2015 12:12 pm

Re: IRQ handling problem (updated: electronic interference?)

Post by victor_pv » Sat Aug 05, 2017 1:19 am

terraduino wrote:
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
Posts: 11
Joined: Tue Jun 27, 2017 6:34 pm

Re: IRQ handling problem (updated: electronic interference?)

Post by 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
Posts: 1607
Joined: Mon Apr 27, 2015 12:12 pm

Re: IRQ handling problem (updated: electronic interference?)

Post by victor_pv » Tue Aug 08, 2017 4:03 am

terraduino wrote:
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.

Post Reply