0

I want my HC05 Bluetooth Module to trigger an interrupt when it receives a signal. So I've followed suggestions from the Arduino Forum and connected the Bluetooth TXD pin to the Arduino RX Pin and the Interrupt Pin (2), which I set to high. It is set to detect a FALLING voltage, presumably when BT transfers data. When I connected it this way a funny thing happens. I can clearly see that the interrupt is being called because power consumptions goes way up when Android sends a message to BT module, meaning the device wakes up. However the serial port no longer appears to work on the Nano. I think I narrowed down the possible cause to me damaging the board by removing lineage regulator or damaging serial port somehow with the interrupt. Is the way I wired up the interrupt pin as described correct? Your help would really help me narrow down my problem.

#include <avr/sleep.h>

#define ledPin 7
#define intPin 3
int state = 0;
int stateData = 0;
int ultraPin = 10;
int trigPin = 11;    // Trigger
int echoPin = 12;    // Echo
long duration, cm;
unsigned char inches;
unsigned long timer;

void setup() {
  pinMode(ultraPin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);  
  pinMode(intPin, INPUT);
  digitalWrite(intPin, HIGH);
  attachInterrupt(digitalPinToInterrupt(intPin), interrupt, FALLING);
  digitalWrite(ultraPin, LOW);
  Serial.begin(9600); // Default communication rate of the Bluetooth module
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu();
}

void interrupt(){
  Serial.println("interrupted");
  sleep_disable();
  Serial.write(50);
  delay(500);
  timer = millis();
  digitalWrite(ultraPin, HIGH);
  while (true){
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      pinMode(echoPin, INPUT);
      duration = pulseIn(echoPin, HIGH);
      cm = (duration / 2) / 29.1;   // Divide by 29.1 or multiply by 0.0343
      inches = (duration / 2) / 74; // Divide by 74 or multiply by 0.0135
      Serial.write(inches);
      delay(50);           
      stateData = Serial.read();     
      if (stateData != 49){
        // receipt from android
        unsigned long timeElapse = millis() - timer;
        if (timeElapse > 5000) {
          break; // exit and SLEEP
        } 
      }
      else {
          // reset the timer
          timer = millis();
        }
      }
    sleep_enable();
    sleep_cpu();  
}

void loop() {

}
4
  • 1
    setting pin to high works only in output mode
    – jsotola
    Sep 18 '20 at 17:01
  • For an input digitalWrite HIGH will turn on the internal pull-up.
    – Delta_G
    Sep 18 '20 at 17:06
  • @jsotola not necessarily true: arduino.cc/reference/en/language/functions/digital-io/…
    – I Like
    Sep 21 '20 at 5:14
  • @ILike that us somewhat correct ... but enabling the pullup resistor is not the same as driving the pin high ... driving the pin high could destroy a sensor output, or the arduino pin, if the sensor drove the pin low ... the pullup resistor would not cause damage because the resulting current would be limited by the pullup resistor ... after all, pullup resistors are used with switches that short the pin to ground when pressed
    – jsotola
    Sep 21 '20 at 5:18
1

I'm not sure, if you can rule out the hardware damage (you wrote, that you removed the linear voltage regulator, but didn't explain more there). But with that code you won't get what you want.

I see multiple issues, all boiling down to the same problem: You cannot do that inside of an ISR:

  • delay() relies on interrupts to happen during its execution. As of my knowledge this leads to delay() never ending, blocking your code. Also it is very bad design to have a long running ISR. So much is depending on interrupts to work and when you have something long running, you can just easily do that inside the main code, triggered by an interrupt flag variable.
  • millis() will not increment during the run of the ISR.
  • delayMicroseconds() will work, but you still should keep the ISR very short. Reading an ultrasonic sensor is a no-go.
  • Serial.write() will fill the libraries internal TX buffer, but the actual transmission of the data also relies on interrupts. You won't get your data that way.

Instead of doing all that inside the ISR, you should just let the Arduino wake up, then set a (single byte) flag variable. In your main code you need to check for that flag with an if statement. In that if statement, you are doing all what you need to do and at the end you are resetting the flag and going to sleep again.

2
  • I see, so the main issue is that I am using interrupt inside an interrupt routine, which doesn't work?
    – I Like
    Sep 18 '20 at 20:12
  • 1
    You are using code, which relies on interrupts, in an interrupt. You are not using interrupts inside of an interrupt, that is a phrase, that does not make sense. For example the function Serial.write() does not use an interrupt, it just places the data in the TX buffer. But the rest of Serial uses interrupts to actually send the data out
    – chrisl
    Sep 18 '20 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.