Не повредит ли установка пин прерывания модуль Bluetooth?

Я хочу, чтобы мой Bluetooth-модуль HC05 вызывал прерывание при получении сигнала. Поэтому я последовал предложениям с форума Arduino и подключил контакт Bluetooth TXD к контакту Arduino RX и контакту прерывания (2), который я установил на высокий уровень. Он настроен на обнаружение ПАДАЮЩЕГО напряжения, предположительно, когда BT передает данные. Когда я подключил его таким образом, происходит забавная вещь. Я ясно вижу, что прерывание вызывается, потому что энергопотребление сильно возрастает, когда Android отправляет сообщение модулю BT, что означает, что устройство просыпается. Однако последовательный порт больше не работает на Nano. Я думаю, что сузил возможную причину повреждения платы, удалив регулятор линейности или каким-то образом повредив последовательный порт с помощью прерывания. Правильно ли я подключил вывод прерывания, как описано? Ваша помощь действительно поможет мне сузить круг моей проблемы.

#include <avr/sleep.h>

#define ledPin 7
#define intPin 3
int state = 0;
int stateData = 0;
int ultraPin = 10;
int trigPin = 11;    // Курок
int echoPin = 12;    // Эхо
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); // Скорость связи модуля Bluetooth по умолчанию
  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;   // Делим на 29,1 или умножаем на 0,0343
      inches = (duration / 2) / 74; // Делим на 74 или умножаем на 0,0135
      Serial.write(inches);
      delay(50);           
      stateData = Serial.read();     
      if (stateData != 49){
        // квитанция от андроида
        unsigned long timeElapse = millis() - timer;
        if (timeElapse > 5000) {
          break; // выходим и СПИМ
        } 
      }
      else {
          // сбросить таймер
          timer = millis();
        }
      }
    sleep_enable();
    sleep_cpu();  
}

void loop() {

}

, 👍0

Обсуждение

установка вывода на высокий уровень работает только в режиме вывода, @jsotola

Для входа digitalWrite HIGH включается внутренняя подтяжка., @Delta_G

@jsotola не обязательно верно: https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/, @I Like

@IКак будто мы несколько правы ... но включение подтягивающего резистора - это не то же самое, что приведение штыря в высокий уровень ... перевод штыря в высокий уровень может разрушить выход датчика или штырь arduino, если датчик установил штырь в низкий уровень .. ... подтягивающий резистор не вызовет повреждений, потому что результирующий ток будет ограничен подтягивающим резистором ... в конце концов, подтягивающие резисторы используются с переключателями, которые при нажатии замыкают контакт на землю, @jsotola


1 ответ


Лучший ответ:

1

Я не уверен, что вы можете исключить повреждение оборудования (вы написали, что удалили линейный стабилизатор напряжения, но не объяснили там больше). Но с этим кодом вы не получите того, что хотите.

Я вижу несколько проблем, и все они сводятся к одной проблеме: вы не можете сделать это внутри ISR:

  • delay() полагается на прерывания, возникающие во время его выполнения. Насколько мне известно, это приводит к тому, что delay() никогда не заканчивается, блокируя ваш код. Кроме того, очень плохой дизайн - иметь долго работающий ISR. Так много зависит от работы прерываний, и когда у вас что-то долго работает, вы можете просто сделать это внутри основного кода, запустив переменную флага прерывания.
  • millis() не будет увеличиваться во время выполнения ISR.
  • delayMicroseconds() будет работать, но вы все равно должны делать ISR очень коротким. Считывать показания ультразвукового датчика нельзя.
  • Serial.write() заполнит внутренний буфер TX библиотеки, но фактическая передача данных также зависит от прерываний. Вы не получите свои данные таким образом.

Вместо того, чтобы делать все это внутри ISR, вы должны просто позволить Arduino проснуться, а затем установить (однобайтовую) переменную флага. В вашем основном коде вам нужно проверить этот флаг с помощью оператора if. В этом операторе if вы делаете все, что вам нужно, и в конце вы сбрасываете флаг и снова засыпаете.

,

Понятно, основная проблема в том, что я использую прерывание внутри процедуры прерывания, которая не работает?, @I Like

Вы используете код, который полагается на прерывания, в прерывании. Вы не используете прерывания внутри прерывания, это фраза, которая не имеет смысла. Например, функция Serial.write() не использует прерывание, она просто помещает данные в буфер TX. Но остальная часть Serial использует прерывания для фактической отправки данных., @chrisl