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() {
}
asked Sep 18, 2020 at 16:27
4
  • 1
    setting pin to high works only in output mode Commented Sep 18, 2020 at 17:01
  • For an input digitalWrite HIGH will turn on the internal pull-up. Commented Sep 18, 2020 at 17:06
  • @jsotola not necessarily true: arduino.cc/reference/en/language/functions/digital-io/… Commented Sep 21, 2020 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 Commented Sep 21, 2020 at 5:18

1 Answer 1

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.

answered Sep 18, 2020 at 18:05
2
  • I see, so the main issue is that I am using interrupt inside an interrupt routine, which doesn't work? Commented Sep 18, 2020 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 Commented Sep 18, 2020 at 21:06

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.