Датчик PIR и сон (прерывание) на Mega2560
Итак, я начал получать некоторые знания о ИК-датчике и о том, как позволить Arduino «заснуть», пока ИК-датчик не обнаруживает движения.
Я нашел где-то следующий код, и он выглядел довольно просто. Поэтому я решил попробовать и взял свой Mega2560, светодиод и датчик PIR.
Хотя на первый взгляд казалось, что это работает, Arduino делает противоположное тому, что я ожидал. Он выключает светодиод и Arduino, когда есть движение, вместо того, чтобы выключать Arduino, когда движения НЕТ. Как я уже говорил, все происходит наоборот.
Возможно, это простое решение, но я не могу найти его самостоятельно.
Код:
#include <avr/sleep.h>
int wakePin = 2; // пин, используемый для пробуждения
int led = 13;
void wakeUpNow() {
}
void setup() {
pinMode(wakePin, INPUT_PULLUP);
pinMode(led, OUTPUT);
attachInterrupt(0, wakeUpNow, LOW); // используем прерывание 0 (вывод 2) и запускаем функцию wakeUpNow, когда вывод 2 получает НИЗКИЙ уровень
}
void sleepNow() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // здесь устанавливается спящий режим
sleep_enable(); // включает бит сна в регистре mcucr
attachInterrupt(0,wakeUpNow, LOW); // используем прерывание 0 (вывод 2) и запускаем функцию
digitalWrite(led,LOW);
sleep_mode(); // здесь устройство действительно усыплено!!
// ПРОГРАММА ПРОДОЛЖАЕТСЯ С ЭТОГО ПОСЛЕ ПРОБУЖДЕНИЯ
sleep_disable(); // первое, что нужно сделать после пробуждения от сна: отключить сон...
detachInterrupt(0); // отключает прерывание 0 на выводе 2, поэтому код wakeUpNow не будет выполняться в обычное время работы.
digitalWrite(led,HIGH);
}
void loop() {
sleepNow(); // здесь вызывается функция сна
}
Заранее спасибо.
Код адаптирован к следующему, и теперь он работает. Когда движение обнаруживается ИК-датчиком, он включает светодиод на контакте 13; когда движение не обнаружено, светодиод выключается.
Остались два вопроса:
1) Как я могу быть уверен, что Arduino действительно сейчас спит?
2) Когда Arduino только что перешел в спящий режим, требуется несколько секунд (+/- 6 с), прежде чем он сможет уловить другое движение. Могу ли я получить более быстрое обнаружение или другой метод «сна» или «энергосбережения», который позволит Arduino быстрее реагировать на движение?
#include <avr/sleep.h>
const int wakePin = 2; // пин, используемый для пробуждения
const int led = 13;
int wakeVal = 0;
int wakeState = LOW;
void wakeUpNow() {
}
void setup() {
Serial.begin(9600);
pinMode(wakePin, INPUT_PULLUP);
pinMode(led, OUTPUT);
//attachInterrupt(0, sleepNow, LOW); // используем прерывание 0 (вывод 2) и запускаем функцию wakeUpNow, когда вывод 2 получает НИЗКИЙ уровень
}
void sleepNow() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // здесь устанавливается спящий режим
sleep_enable(); // включает бит сна в регистре mcucr
attachInterrupt(0,wakeUpNow, LOW); // используем прерывание 0 (вывод 2) и запускаем функцию
sleep_mode(); // здесь устройство действительно усыплено!!
}
void disSleep(){
// ПРОГРАММА ПРОДОЛЖАЕТСЯ С ЭТОГО ПОСЛЕ ПРОБУЖДЕНИЯ
sleep_disable(); // первое, что нужно сделать после пробуждения от сна: отключить сон...
detachInterrupt(0); // отключает прерывание 0 на выводе 2, поэтому код wakeUpNow не будет выполняться в обычное время работы.
}
void loop() {
wakeVal = digitalRead(wakePin);
if (wakeVal == HIGH){
disSleep();
digitalWrite(led,HIGH);
delay(1000);
if (wakeState == LOW){
Serial.println("Motion detected");
wakeState = HIGH;
}
}
else{
digitalWrite(led,LOW);
delay(1000);
if (wakeState == HIGH){
Serial.println("Motion stopped - Going to Sleep Mode !");
wakeState = LOW;
delay(1000);
sleepNow(); // здесь вызывается функция сна
}
}
}
@Y.Terz, 👍2
Обсуждение1 ответ
Это проблема платы Arduino Mega. На Mega D2 не INT0, как на Uno. Это INT4. В спецификации есть сноска, в которой говорится, что поддерживается только прерывание уровня. Это означает, что вы не можете использовать RISING, FALLING или CHANGE. Ваш единственный выбор — использовать LOW. Таким образом, Arduino проснется, когда движение выключится, а не включится. Вот почему это отстало. Если вы используете Uno вместо Mega, вы можете использовать RISING, и он будет работать так, как вы думаете.
- Программа arduino выдаёт ошибку expected //primary-expression before ')' token error: //expected ';' before '}' token E
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Что выбрать между датчиками температуры и влажности: AM230x или DHT22?
- Выводы прерываний Arduino Mega 2560 и отображение портов с помощью поворотного энкодера
- Взаимодействие с датчиком SSI?
- ArduinoMEGA: 64 цифровых входа вызывают случайные значения digitalRead
- Возникла проблема с переобъявлением символа другого типа
- ATtiny85 AC Phase Control для регулировки яркости лампочки
Вы предполагаете, что ваш датчик дает низкий выходной сигнал, когда обнаруживает движение? Возможно, все наоборот?, @uint128_t
@uint128_t прав. Большинство ИК-датчиков переходят в ВЫСОКИЙ уровень, когда обнаруживают движение., @dinotom
attachInterrupt(0,wakeUpNow, HIGH);
может быть?, @GerbenДа, я знаю, что движение = высокое, и ни одно движение не должно быть низким. Я уже пробовал присоединить Interrupt(0,wakeUpNow,HIGH). Вроде не решает., @Y.Terz