Вопрос про внешние прерывания
- Войдите на сайт для отправки комментариев
Пнд, 19/03/2018 - 23:33
Подскажите, уважаемые.
Пытаюсь доделать под свои нужды проект.
https://ongroup.ru/energoeffektivnaya_gsm-signalizaciya_na_osnove_arduino_sborka_proshivka_test.html
У него есть большой недостаток - нет обратной связи, т.е. модем не может разбудить ардуину.
Я не долго думая подключил датчик к INT0, а INT1 к TX-у модема, задействовал 0-е и 1-е) прерывание.
...
void wakeUp0(){//обработчик прерывания
waked0=true;
}
void wakeUp1(){//обработчик прерывания
waked1=true;
}
....
....
attachInterrupt(0, wakeUp0, CHANGE );/ // включить прерывание 0
attachInterrupt(1, wakeUp1, CHANGE ); // включить прерывание 1
НО
Почему-то при любом дёргании за любую из двух ног ардуины, срабатывают ОБА обработчика прерываний.
Что не так ?
а дергаете за какие ноги? Вы в курсе, что цифра 0 в коде
attachInterrupt(0, wakeUp0, CHANGE );
это номер прерывания, а не номер ноги ардуино?
а дергаете за какие ноги? Вы в курсе, что цифра 0 в коде
attachInterrupt(0, wakeUp0, CHANGE );
это номер прерывания, а не номер ноги ардуино?
Ноги D2 = INT0 и D3 = INT1
Кто ж знает что у вас там в коде? Скажем датчик будит, ардуина обменивается , срабатывает ТХ. Или наоборот - ТХ будит , ардуина опрашивает датчик и.т.д.
Попробуйте отключить все прерывания внутри прерываний ( не запретить ), перед засыпанием опять проинициализируйте прерывания.
Код секретный? Тогда разбирайтесь с ним сами. Хрустальные шары здесь запрещены. И что за датчик Вы тоже забыли написать.
Ок. благодаря вашим советам была найдена ошибка.
при пробуждении, я выключал подтяжки и из за этого срабатывало второе прерывание.
Теперь другой вопрос.
Если во время бодрствования (прерывания выключены), была активность модема, то после ухода в сон и пробуждения по прерыванию от датчика, срабатывает и обработчик активности модема.
Т.е похоже, что при бодрствовании устанавливается какой-то флаг, который обрабатывается только после ухода в сон и последующего пробуждения.
Код по-прежнему секретный? Ну, тогда по-прежнему разбирайтесь сами.
Код по-прежнему секретный? Ну, тогда по-прежнему разбирайтесь сами.
Ну почему бы не помочь.
b612, похоже, что при бодрствовании устанавливается какой-то флаг, который обрабатывается только после ухода в сон и последующего пробуждения.
Ну почему бы не помочь.
Потому что хрустальные шары запрещены. И нарушая запрет Вы рискуете.
Google, как удалить запись на форуме Arduino.ru?
Гугл активируется через "OKay, Google. <сюда пишите что надо>"
#include <avr/sleep.h> #include <SoftwareSerial.h> // библиотека программного UART SoftwareSerial gsm(7, 6); // RX(7), TX(6) volatile bool waked0=false; volatile bool waked1=false; volatile bool tosleep=false; volatile bool doDial=false; volatile int8_t incomingByte = 0; volatile int8_t rejim = 0; #define _Rejim0 0 // исходный режим #define _ATcommand 1 // режим прямого ввода AT-команд #define _SetPinTo 2 #define _SetLEDTo 3 /*ISR (INT0_vect) {waked0=true;} ISR (INT1_vect) {waked1=true;}*/ void wakeUp0(){//обработчик прерывания waked0=true; } void wakeUp1(){//обработчик прерывания waked1=true; } /////////////////////////////////////////// void toRejim0(){ rejim = _Rejim0; Serial.println(""); Serial.print(">"); } void gsmOFF(){ // Serial.println("gsm OFF"); PORTD|=B00010000; // ВЫКЛЮЧЕНИЕ МОДУЛЯ (поднимаем DTR) _delay_ms(10); // // gsm.println("AT+CPWROFF"); // ПЕЧАТАЕМ КОМАНДУ OFF gsm.println("AT+CSCLK=2"); // усыпляем модем while(1){ // if (gsm.find("OK")) { Serial.println("AT+CSCLK=2 ok"); break; //выходим из цикла } } PORTB &=~ B00100000; // выключить LED 13 } // //========================================= void gsmON(){ // //PORTD|=B01000000; // 6-му порту (TX) назначить 1 PORTD &= ~(B00010000); // ЗАПУСК МОДУЛЯ (опускаем DTR) _delay_ms(110); // PORTB |= B00100000; // включить LED 13 !!! Serial.println(F("gsm ON")); // while(!gsm.find("+PBREADY")); // ждём прочтения тел. книги // Serial.println("PBREADY"); gsm.println(F("AT+CSCLK=0")); // устанавливаем управление питанием через без DTR while(1){ // if (gsm.find("OK")) { Serial.println(F("AT+CSCLK=0 ok")); break; //выходим из цикла } } while(1){ // gsm.println(F("AT+CREG?")); // проверяем в сети ли модуль if (gsm.find("0,1")) { Serial.println(F("on line? Ok.")); break; // если сеть есть, выходим из цикла } _delay_ms(400); // проверка раз в 0,4 сек Serial.println(F("off line")); } // } // /////////////////////////////////////////// // void sleepNow(){ // функция засыпания Serial.println("sleep"); _delay_ms(100); // Serial.end(); ADCSRA = 0x00; // отключить подсистему АЦП (экономия 140 мкА) //UCR = 0x00; // отключить UART //PORTD &=~ B01000000; // в вывод TX поставить 0 PORTD = 0; // в вывод TX поставить 0 DDRD |= B00010000; // 4-й вывод - выход на DTR модема), 6-й софтварный TX //digitalWrite(2, HIGH);//включим подтяжку //digitalWrite(3, HIGH);//включим подтяжку PORTB &=~ B00100000; // выключить LED 13 set_sleep_mode(SLEEP_MODE_PWR_DOWN); // режим сна PWR_DOWN attachInterrupt(0, wakeUp0, CHANGE );// FALLING ); // включить прерывание 0 attachInterrupt(1, wakeUp1, CHANGE ); // включить прерывание 1 sleep_enable(); // включение возможности сна sleep_mode(); // сон //проснулись sleep_disable(); // detachInterrupt(0); // отключить прерывания detachInterrupt(1); // отключить прерывания //digitalWrite(2, LOW);//вЫключим подтяжку //digitalWrite(3, LOW);//вЫключим подтяжку PORTB |= B00100000; // включить LED 13 !!! Serial.begin(9600); gsm.begin(9600); // скорость работы UART Serial.println("Wake"); } void setup(){ gsm.begin(9600); // скорость работы UART Serial.begin(9600); DDRD |= B01010000; // 4-й выводы на выход (DTR модема) 6-й софтварный TX PORTD &= ~(B00010000); // ЗАПУСК МОДУЛЯ (опускаем DTR) PORTB |= B00100000; // включить LED 13 !!! //pinMode(2, INPUT_PULLUP); //pinMode(3, INPUT_PULLUP); digitalWrite(2, HIGH);//включим подтяжку digitalWrite(3, HIGH);//включим подтяжку DDRB |= B00100010; // вывод 13 на выход (светик) и на звук //pinMode(9, OUTPUT); //звук //gsmON(); // запуск модуля для теста //gsmOFF(); // выключаем модуль } void loop(){ if (waked0){ // если сработало прерывание waked0=false; Serial.println("INT0"); //gsmON();//будим модем for (uint8_t i=0;i<10;i++) { digitalWrite(9, HIGH); delay(50); digitalWrite(9, LOW); delay(50); } } else if (waked1) { // если сработало прерывание waked1=false; Serial.println("INT1"); //пискнем digitalWrite(9, HIGH); delay(100); digitalWrite(9, LOW); } else if (doDial){ doDial=false; Serial.println("Dial"); //gsmON(); gsm.println("ATD+79514558448;"); // отзваниваемся, в ответ приходит OK и CONNECT _delay_ms(100); if (gsm.find("OK")) while(1){ // ожидание сброса вызова gsm.println("AT+CPAS"); // при каждой итерации опрашиваем модуль if (gsm.find("0")) break; // если 0, то выходим из цикла while _delay_ms(100); // проверка раз в 0,1 сек } for (char i=0; i<14; i++){ PORTB|=B00100000; // LED 13 ON _delay_ms(200); PORTB&=~(B00100000); // LED 13 OFF _delay_ms(200); } //gsmOFF(); // выключить модуль _delay_ms(10); //while(1); // блокируем программу*/ } else if (tosleep){ tosleep=false; //gsmOFF(); //усыпляем модем sleepNow(); // укладываем контроллер спать } else { if (gsm.available()) // Ожидаем прихода данных (ответа) от модема... {Serial.write(gsm.read());} // ...и выводим их в Serial if (Serial.available()) // Ожидаем команды по Serial... {incomingByte=Serial.read(); switch (rejim) { case _Rejim0: {switch (incomingByte) {case 's': {tosleep=true; toRejim0(); break; } case 'f': //"f" {Serial.println(F("gsm to sleep")); gsmOFF(); break; } case 'g': //"g" {Serial.println(F("gsm to wake")); gsmON(); break; } case 'a': {rejim=_ATcommand; Serial.print(F("AT>")); break; } case 'd': {rejim=_SetPinTo; Serial.print(F("set pin 4 to>")); break; } case 'l': //"L" {rejim=_SetLEDTo; Serial.print(F("set LED 13 to>")); break; } case 'R': //"R" {doDial=true; break; } case 'q': //"q" { Serial.print(F("portD2 = ")); Serial.println(digitalRead(2)); break; } case 'w': //"w" { Serial.print(F("portD3 = ")); Serial.println(digitalRead(3)); break; } case 'h': //"h" { Serial.println(F("a - at commands")); Serial.println(F("s - arduino to sleep")); Serial.println(F("R - do dial")); Serial.println(F("f - gsm to sleep")); Serial.println(F("g - gsm to wake")); Serial.println(F("f - gsm to sleep")); Serial.println(F("l(L) - set LED 13 to ..")); Serial.println(F("q - read POTTd2")); Serial.println(F("w - read POTTd3")); break; } default: {break;} } break; } case _ATcommand: { gsm.write(incomingByte); // ...и отправляем полученную команду модему //Serial.write(incomingByte); if (incomingByte == 0x0D) { toRejim0(); } break; } case _SetPinTo: { if (incomingByte == '1') { digitalWrite(4, HIGH); toRejim0(); } else if (incomingByte == '0') { digitalWrite(4, LOW); toRejim0(); } else { toRejim0(); } break; } case _SetLEDTo: { if (incomingByte == '1') { digitalWrite(13, HIGH); toRejim0(); } else if (incomingByte == '0') { digitalWrite(13, LOW); toRejim0(); } else { toRejim0(); } break; } default: {break;} } }//switch (rejim) }//if (Serial.available()) }Так все и не надо.
КОгда вопрос нормально готовится, из кода выбрасывается всё лишнее, оставляется только то, что работает и демонстрирует проблему.
В коротком коде люди разберутся и подскажут.
Как-то так.