внешнее прерывание

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Добрый!

Есть программа измерения температуры и есть программа включения полива от кнопки через реле. При совмещении программ работает только температура. Реле срабатывает только когда долго держишь кнопку. Как сделать внешнее прерывание без delay. Не могу найти толкового описания функции.

/ * ReadSHT1xValues
 * Термогигрометр на базе датчика SHT10
 * Библиотека SHT1x
  */

#include <SHT1x.h>

// Data and Сlock датчика  SHT1x повесили на пины 10 и 11
#define dataPin  10 //желтый провод
#define clockPin 11 //голубой провод
//а черный (Gnd) и  коричневый -питание
SHT1x sht1x(dataPin, clockPin);

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // установка  LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
 
  lcd.init();                      // Инициализируем lcd
 
  // Печать приветствия на  LCD.
  lcd.backlight();
  lcd.print("TEMP and VLAZHN");
   lcd.setCursor(0, 1);
  lcd.print("PVV Arduino ");
  delay(2000);
  lcd.clear();
 
}

void loop()
{
  float temp_c;

 float humidity;
 
 // Читаем показания датчика SHT10
  temp_c = sht1x.readTemperatureC();
  humidity = sht1x.readHumidity();
  // Выводим данные на LCD
  lcd.setCursor(0, 0);
  lcd.print("Temperat: ");
  lcd.print(temp_c-3.0); //Коррекция температуры на 3 градуса
  lcd.print("C  ");
  lcd.setCursor(0, 1);// вывод второй строки
  lcd.print("Vlazhnst: ");
  lcd.print(humidity);
  lcd.println("% ");

  delay(1000);
}

и второй скетч:


#define pin_valve (6)//цепляем реле R2 
#define pin_btn   (7) //цепляем кнопку на палатях, второй 5В


void setup(){
   // режимы выводов
 
  pinMode(pin_valve,OUTPUT);
  pinMode(pin_btn,INPUT_PULLUP);
  
}

void loop(){
    if(digitalRead(7)==HIGH)//если кнопка нажата ...
   {
  digitalWrite(pin_valve, HIGH);//включаем водичку
      delay(3000);//водичка льется 3сек.
      digitalWrite(pin_valve, LOW);
 } 
}

Жду толковой лекции по прерыванию :)

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012
Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Все эти мигалки через определенное время, а надо  в произвольный момент. По внешнему прерыванию- по нажатию кнопки. И дребезга чтобы не было. Пишется, что delay  в интерапте не работает. Не могу проверить, тк не знаю как прописать время сработки клапана.

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015
Будет работать такой скетч и как в нем запустить время сработки?


[code]
#define pin_valve (6)//цепляем реле R2 

int buttonInt = 0; //цепляем кнопку на pin2
volatile int state = LOW;


void setup()
{
   // режимы выводов
 
  pinMode(pin_valve,OUTPUT);
 
  attachInterrupt(buttonInt, blin, CHANGE);
}

 

void loop()
{
    
  digitalWrite(pin_valve, state);//включаем водичку
      
} 
 
void blin()
{
  state = !state; 
}

[/code]

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
Если Вам, к примеру, надо  чтобы полив длился 2 минуты надо зафиксировать время начала полива
Для этого добавляем 2 переменные
unsigned long currentTime; 
bool fl_start; //Флаг

//все ниже добавляем в "void loop()"
if (state==0) fl_start=0; //Если отключите кнопкой или по времени - стаем в исходное
if (state==1 && fl_start==0)
{
 currentTime = millis(); //Фиксируем время Один раз благодаря флагу
 fl_start = 1;//
}
 //отключаем через 2 минуты
if (fl_start==1)
{
  if (millis() - currentTime >= 120000) state = 0;
}

 

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Вячеслав 151 пишет:

Все эти мигалки через определенное время, а надо  в произвольный момент. По внешнему прерыванию- по нажатию кнопки. И дребезга чтобы не было. Пишется, что delay  в интерапте не работает. Не могу проверить, тк не знаю как прописать время сработки клапана.


Все решения, где убирается delay нужны для того чтобы примерно в любое время выполнить любое действие, при это без использования delay, т.е. именно то, что Вам нужно.
Нет так нет, ищите другой способ.

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Добрый всем!

Собрал вместе скетчи - термогигрометр и подача воды. Проблема с кнопкой. Может сразу сработать, может через секунду и время сработки -3секунды не выдерживается. Как гарантировать и стабилизировать работу кнопки?

[code]
/**
 * Брызгалка с термогигрометром 
 * Термогигрометр на базе датчика SHT10 
 * Библиотека SHT1x
  */
//Объявляем библиотеки
#include <SHT1x.h> 
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
//декларируем переменные для брызгалки с прерыванием
#define button 2    // кнопка
#define relay  6    // реле 2
volatile bool flag=0;
volatile unsigned long prevmillis;

// Для датчика термогигрометра
//Data and Сlock датчика  SHT1x повесили на пины 10 и 11
#define dataPin  10 //желтый провод
#define clockPin 11 //голубой провод 
//а черный (Gnd) и  коричневый -питание
SHT1x sht1x(dataPin, clockPin);

LiquidCrystal_I2C lcd(0x27,16,2);  // установка  LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  
  lcd.init();  // Инициализируем lcd 
 
  // Печать приветствия на  LCD.
  lcd.backlight();
  lcd.print("TEMP and VLAZHN");
   lcd.setCursor(0, 1);
  lcd.print("PVV Arduino ");
  delay(2000);
  lcd.clear();
  //режимы pin
 pinMode(button,INPUT_PULLUP);    // кнопка на вход  вкл.подтягивающий резистор. 
pinMode(relay,OUTPUT);           // реле на брызгалку 
attachInterrupt(0, my_func, CHANGE); //прерывание на изменение логич. уровня
  
}

void loop()
{
  float temp_c;

 float humidity;
  
 // Читаем показания датчика SHT10
  temp_c = sht1x.readTemperatureC();
  humidity = sht1x.readHumidity();
  // Выводим данные на LCD
  lcd.setCursor(0, 0);
  lcd.print("Temperat: ");
  lcd.print(temp_c-3.0); //Коррекция температуры на 3 градуса
  lcd.print("C  ");
  lcd.setCursor(0, 1);// вывод второй строки
  lcd.print("Vlazhnst: ");
  lcd.print(humidity);
  lcd.println("% ");
  delay(1000);
  
  if (flag==1) { // если кнопку нажали
  digitalWrite(relay,HIGH); //включаем реле
        if ( millis()-prevmillis >=3000){   //если счёт 3 секунд вышел, то
        digitalWrite(relay,LOW);   //отключаем воду
         flag=0; //сбрасываем флаг работы
              }
       }
}

void my_func() { //отжали
flag=1; //ставим флаг что работа идёт..
prevmillis= millis(); //запомним время
}

[/code]

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

строка 41 - пин кнопки подтянут , зачем CHANGE ? нужно FALLING - сработает по нажатию или RISING - по отпусканию кнопки
строки 65...71 - реле включать миллион раз зачем ? поменяй порядок ифов, т.е. логику проверки когда выключить

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
/**
 * Брызгалка с термогигрометром 
 * Термогигрометр на базе датчика SHT10 
 * Библиотека SHT1x
  */
//Объявляем библиотеки
#include <SHT1x.h> 
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
//декларируем переменные для брызгалки с прерыванием
#define button 2    // кнопка
#define relay  6    // реле 2
volatile byte flag=0;
volatile unsigned long prevmillis;

// Для датчика термогигрометра
//Data and Сlock датчика  SHT1x повесили на пины 10 и 11
#define dataPin  10 //желтый провод
#define clockPin 11 //голубой провод 
//а черный (Gnd) и  коричневый -питание
SHT1x sht1x(dataPin, clockPin);

LiquidCrystal_I2C lcd(0x27,16,2);  // установка  LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  
  lcd.init();  // Инициализируем lcd 
 
  // Печать приветствия на  LCD.
  lcd.backlight();
  lcd.print("TEMP and VLAZHN");
   lcd.setCursor(0, 1);
  lcd.print("PVV Arduino ");
  delay(2000);
  lcd.clear();
  //режимы pin
 pinMode(button,INPUT_PULLUP);    // кнопка на вход  вкл.подтягивающий резистор. 
pinMode(relay,OUTPUT);           // реле на брызгалку 
attachInterrupt(0, my_func, RISING); //прерывание на изменение логич. уровня
}

void loop()
{
  float temp_c;

 float humidity;
  
 // Читаем показания датчика SHT10
  temp_c = sht1x.readTemperatureC();
  humidity = sht1x.readHumidity();
  // Выводим данные на LCD
  lcd.setCursor(0, 0);
  lcd.print("Temperat: ");
  lcd.print(temp_c-3.0); //Коррекция температуры на 3 градуса
  lcd.print("C  ");
  lcd.setCursor(0, 1);// вывод второй строки
  lcd.print("Vlazhnst: ");
  lcd.print(humidity);
  lcd.println("% ");
  delay(1000);
  
  if (1 == flag)
  { // если кнопку отпустили
    prevmillis = millis();
    digitalWrite(relay,HIGH); //включаем реле
    flag = 2;
  }
  
  if (2 == flag)
  {
    if ( millis()-prevmillis >=3000)
    {   //если счёт 3 секунд вышел, то
      digitalWrite(relay,LOW);   //отключаем воду
      flag=0; //сбрасываем флаг работы
    }
  }
}

void my_func() { //отжали
flag=1; //ставим флаг что работа идёт..
}

при вставке кода жми ещё "свернуть"
и волатильность у превмиллис надо убрать.....

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

мой очередной скетч. 

[code]
/**
 * Брызгалка с термогигрометром 
 * Термогигрометр на базе датчика SHT10 
 * Библиотека SHT1x
  */
//Объявляем библиотеки
#include <SHT1x.h> 
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
//декларируем переменные для брызгалки с прерыванием
#define button 2    // кнопка
#define relay  6    // реле 2
volatile bool flag=0;
volatile unsigned long prevmillis;
long previousMillis = 0;        // храним время последнего измерения
long interval = 3000; //интервал измерения
// Для датчика термогигрометра
//Data and Сlock датчика  SHT1x повесили на пины 10 и 11
#define dataPin  10 //желтый провод
#define clockPin 11 //голубой провод 
//а черный (Gnd) и  коричневый -питание
SHT1x sht1x(dataPin, clockPin);

LiquidCrystal_I2C lcd(0x27,16,2);  // установка  LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  
  lcd.init();  // Инициализируем lcd 
 
  // Печать приветствия на  LCD.
  lcd.backlight();
  lcd.print("TEMP and VLAZHN");
   lcd.setCursor(0, 1);
  lcd.print("PVV Arduino ");
  delay(2000);
  lcd.clear();
  //режимы pin
 pinMode(button,INPUT_PULLUP);    // кнопка на вход  вкл.подтягивающий резистор. 
pinMode(relay,OUTPUT);           // реле на брызгалку 
attachInterrupt(0, my_func, CHANGE); //прерывание на изменение логич. уровня
  
}

void loop()
{
  // здесь будет код, который будет работать постоянно
  // и который не должен останавливаться на время между переключениями свето
  unsigned long currentMillis = millis();
    //проверяем не прошел ли нужный интервал, если прошел то
  if(currentMillis - previousMillis > interval) 
  {
    // сохраняем время последнего переключения
    previousMillis = currentMillis;  
  float temp_c;
  float humidity;
  
 // Читаем показания датчика SHT10
  temp_c = sht1x.readTemperatureC();
  humidity = sht1x.readHumidity();
  // Выводим данные на LCD
  lcd.setCursor(0, 0);
  lcd.print("Temperat: ");
  lcd.print(temp_c-3.0); //Коррекция температуры на 6 градусов
  lcd.print("C  ");
  lcd.setCursor(0, 1);// вывод второй строки
  lcd.print("Vlazhnst: ");
  lcd.print(humidity);
  lcd.println("% ");
  }
  if (flag==1) { // если кнопку нажали
  digitalWrite(relay,HIGH); //включаем реле
        if ( millis()-prevmillis >=3000){   //если счёт 3 секунд вышел, то
        digitalWrite(relay,LOW);   //отключаем воду
         flag=0; //сбрасываем флаг работы
              }
       }
}

void my_func() { //отжали
flag=1; //ставим флаг что работа идёт..
prevmillis= millis(); //запомним время
}

[/code]

Здесь поправьте



 

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

нет, тоже тормоз при нажатии батона. А мой последний вроде нормально  заработал

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

код из #8 пробовал ?

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

SU-27-16 пишет:

код из #8 пробовал ?

Это что?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

один из вариантов ответа на вопрос - Как гарантировать и стабилизировать работу кнопки?

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

не нашел

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

что не нашёл ?!!!!!!!!!!!!!!!!!!!!
в посте #8 нажми показать код и копируй.....

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

я понимаю что delay из температурной программы тормозил срабатывание кнопки

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

да я его попробовал. он тормозит

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

просмотрел :(
в #8 убери строку 61......

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Ну молодец!

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Спасибо!

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

пожста....
строки 50...60 лучше вызывать 1...2 раза в секунду, чтобы не мучить датчик и экран

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

стоит 3сек