Gyver умная мусорка V2 и аппаратное прерывание по сенсорной кнопке

tobsik

✩✩✩✩✩✩✩
2 Апр 2019
18
0
34
Новороссийск
Всем привет. Повторил проект умного мусорного ведра, но не могу добавить одну функцию: при нажатии на сенсорную кнопку ардуино выходит из сна и открывает крышку, а при следующем нажатие - опускает. Понимаю, что это основы и всего в пару строчек кода, но не могу реализовать. Прошу помощи)
 

tobsik

✩✩✩✩✩✩✩
2 Апр 2019
18
0
34
Новороссийск
C++:
#include <Arduino.h>
#include "LowPower.h" 
#include <VarSpeedServo.h>

//--------------------НАСТРОЙКИ----------------------
#define maxH 60        // высота срабатывания
#define cap_time 15     // время открытой крышки в секундах
#define open_angle 80   // угол открытия
#define close_angle 0 // угол закрытия
#define debug 0        // вывод информации в порт для отладки (0 выкл, 1 вкл)
//--------------------НАСТРОЙКИ----------------------

// ---ПОДКЛЮЧЕНИЕ---
#define trigPin 11
#define echoPin 12
#define sensorVCC 10
#define MOSFETpin 5
#define servoPin 6
// ---ПОДКЛЮЧЕНИЕ---

VarSpeedServo servo;
volatile boolean intFlag = false;

long duration;
byte distance;
unsigned long open_timer;
volatile boolean open_flag;

void open_cap() {
  if (debug) Serial.println("open cap");
  digitalWrite(MOSFETpin, 1);     // подать питание на серво
  delay(10);
  servo.write(open_angle, 30, true );        // открыть крышку
  delay(1000);                    // ждать серво
  digitalWrite(MOSFETpin, 0);     // отключить серво
  open_flag = 1;                  // флаг что крышка открыта
}

void close_cap() {
  digitalWrite(MOSFETpin, 1);
  if (debug) Serial.println("close cap");// подать питание на серво
  delay(10);
  servo.write(close_angle, 20, true);   // закрыть крышку
  delay(1000);                    // ждать серво
  digitalWrite(MOSFETpin, 0);     // отключить серво
  open_flag = 0;                    // флаг что крышка закрыта
}
// блок, измеряющий расстояние
byte measure() {
  digitalWrite(trigPin, 0);
  delayMicroseconds(5);
  digitalWrite(trigPin, 1);
  delayMicroseconds(15);
  digitalWrite(trigPin, 0);
  duration = pulseIn(echoPin, HIGH);
  return (duration / 2) / 29.1;        // получаем расстояние с датчика
}

void Interrupt() {
  if (intFlag == true) {intFlag = false;}
  if (intFlag == false) {intFlag = true;}
 
}



void setup() {
  Serial.begin(9600);
  if (debug) Serial.println("system start");
  attachInterrupt(0, Interrupt, RISING  ); // аппаратное прерывание на 2 пине
  servo.attach(servoPin);         // серво на 5 порту
  pinMode(trigPin, OUTPUT);       // пин триггера в режиме выхода
  digitalWrite(trigPin, 0);
  pinMode(MOSFETpin, OUTPUT);     // пин мосфета в режиме выхода
  digitalWrite(MOSFETpin, 0);
  pinMode(echoPin, INPUT);        // пин эхо в режиме входа
  pinMode(sensorVCC, OUTPUT);     // пин питания как выход
  digitalWrite(sensorVCC, 0);     // выключить датчик
  open_cap();                     // открытие крышки при запуске 

}



void loop() {


LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF);  // спать 1 секунду

  digitalWrite(sensorVCC, 1); // включить дальномер
  delay(500);
  measure();                   // первый "холостой" проход, иначе датчик не алло
  distance = measure();                 // получить расстояние
  digitalWrite(sensorVCC, 0);           // выключить дальномер
  if (debug) {
    Serial.println(distance);
    delay(500);
  }

if (distance > 5 && distance < maxH && open_flag == 0) { // если расстояние попадает в диапазон
        open_timer = 0;                     // сбросить таймер
    if (!open_flag) {                   // если крышка закрыта
      
      open_cap();                       // открыть крышку
      
    }
  } else {
    if (open_flag) {                    // если крышка открыта
      open_timer++;   // прибавить таймер
       if (debug) {Serial.print("Open: "); Serial.println(open_timer);}       
      if (open_timer > cap_time) {      // если с момента открытия прошло больше 5сек
        close_cap();                    // закрыть крышку
      }
    }

 
  }
}
Вот код. Привязываем прерывание на 2 пин. По прерыванию вызывается Interrupt. Подскажите, как можно реализовать что бы по нажатию на кнопку крышка открывалась независимо от показаний датчика расстояния.
 

tobsik

✩✩✩✩✩✩✩
2 Апр 2019
18
0
34
Новороссийск
@tobsik, Простой поиск по коду даёт следующее:

open_cap(); // открыть крышку

close_cap(); // закрыть крышку
Вы, видимо, меня не поняли....
Подскажите, как можно реализовать что бы по нажатию на кнопку крышка открывалась независимо от показаний датчика расстояния.
при нажатии на сенсорную кнопку ардуино выходит из сна и открывает крышку, а при следующем нажатие - опускает
 

Wan-Derer

★★★★★✩✩
Команда форума
31 Июл 2018
2,006
406
Москва
wan-derer.ru
@tobsik,
поймать нажатие кнопки
если крышка закрыта - открыть крышку
иначе - закрыть крышку

Готовые процедуры для того и другого уже есть в скетче
 

tobsik

✩✩✩✩✩✩✩
2 Апр 2019
18
0
34
Новороссийск
C++:
#include <Arduino.h>
#include "LowPower.h" // библиотека сна
//#include <Servo.h>    // используем библиотеку для работы с сервоприводом
#include <VarSpeedServo.h>

//--------------------НАСТРОЙКИ----------------------
#define maxH 60        // высота срабатывания
#define cap_time 15     // время открытой крышки в секундах
#define open_angle 80   // угол открытия
#define close_angle 0 // угол закрытия
#define debug 1        // вывод информации в порт для отладки (0 выкл, 1 вкл)
//--------------------НАСТРОЙКИ----------------------

// ---ПОДКЛЮЧЕНИЕ---
#define trigPin 11
#define echoPin 12
#define sensorVCC 10
#define MOSFETpin 5
#define servoPin 6
// ---ПОДКЛЮЧЕНИЕ---

VarSpeedServo servo;
volatile boolean intFlag = false;
volatile boolean Flag = false;

long duration;
byte distance;
unsigned long open_timer;
volatile boolean open_flag;

void open_cap() {
  if (debug) Serial.println("open cap");
  digitalWrite(MOSFETpin, 1);     // подать питание на серво
  delay(10);
  servo.write(open_angle, 30, true );        // открыть крышку
  delay(1000);                    // ждать серво
  digitalWrite(MOSFETpin, 0);     // отключить серво
  open_flag = 1;
  intFlag = false;             // флаг что крышка открыта
}

void close_cap() {
  digitalWrite(MOSFETpin, 1);
  if (debug) Serial.println("close cap");// подать питание на серво
  delay(10);
  servo.write(close_angle, 20, true);   // закрыть крышку
  delay(1000);                    // ждать серво
  digitalWrite(MOSFETpin, 0);     // отключить серво
  open_flag = 0;
  intFlag = false;         // флаг что крышка закрыта
}
// блок, измеряющий расстояние
byte measure() {
  digitalWrite(trigPin, 0);
  delayMicroseconds(5);
  digitalWrite(trigPin, 1);
  delayMicroseconds(15);
  digitalWrite(trigPin, 0);
  duration = pulseIn(echoPin, HIGH);
  return (duration / 2) / 29.1;        // получаем расстояние с датчика
}

void buttonTick() {
  intFlag = true; Serial.println("Interrupt");
 
 
 
}



void setup() {
  Serial.begin(9600);
  if (debug) Serial.println("system start");
  attachInterrupt(0, buttonTick, FALLING   ); // аппаратное прерывание на 2 пине
  servo.attach(servoPin);         // серво на 5 порту
  pinMode(trigPin, OUTPUT);       // пин триггера в режиме выхода
  digitalWrite(trigPin, 0);
  pinMode(MOSFETpin, OUTPUT);     // пин мосфета в режиме выхода
  digitalWrite(MOSFETpin, 0);
  pinMode(echoPin, INPUT);        // пин эхо в режиме входа
  pinMode(sensorVCC, OUTPUT);     // пин питания как выход
  digitalWrite(sensorVCC, 0);     // выключить датчик
  open_cap();                     // открытие крышки при запуске 

}



void loop() {
if (intFlag == true) {
Serial.println("intFlag == true");
if (open_flag == 1) {Serial.println("open_flag == 1"); close_cap();}
if (open_flag == 0) {Serial.println("open_flag == 0"); open_cap();}
}

//LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF);  // спать 1 секунду

  digitalWrite(sensorVCC, 1); // включить дальномер
  delay(500);
  measure();                   // первый "холостой" проход, иначе датчик не алло
  distance = measure();                 // получить расстояние
  digitalWrite(sensorVCC, 0);           // выключить дальномер
  if (debug) {
    Serial.println(distance);
    delay(500);
  }



if (distance > 5 && distance < maxH && open_flag == 0) { // если расстояние попадает в диапазон
        open_timer = 0;                     // сбросить таймер
    if (!open_flag) {                   // если крышка закрыта
      
      open_cap();                       // открыть крышку
      
    }
  } else {
    if (open_flag & (intFlag)) {                    // если крышка открыта
      open_timer++;   // прибавить таймер
       if (debug) {Serial.print("Open: "); Serial.println(open_timer);}       
      if (open_timer > cap_time) {      // если с момента открытия прошло больше 5сек
        close_cap();                    // закрыть крышку
      }
    }

 
  }
}
Сделал так, но работает не совсем так: если крышка закрыта, нажимаем кнопку - открывается и тут же закрывается, а если открыта - закрывается и открывается)

Не могу понять, что я делаю не так)