вытяжка на кухне

restiv
Offline
Зарегистрирован: 03.01.2016

доброго времени суток уважаемые форумчане!

Прошу Вас помочь наладить скетч. Установил на кухонную вытяжку датчик температуры, чтобы она включалась если на плите что то начинали готовить. Все хорошо работало. Но тут некоторое ввремя назад сынок начал подбегать и открывать газ. Чтобы предотвратить отравление газом или взрыв решил добавить датчик MQ2. Но после подключения и доработки скетча возникли проблемы. Микроконтроллер перестал запускать вытяжку. Если по отдельности либо датчик температуры, либо датчик газа прописываю, то все работает. А вместе не хотят. Подскажите пожалуйста в чем моя ошибка?

#include <OneWire.h>
int buzzer = 7;        // Пин подключения биззера:
int smokeA0 = A0;      // Пин подключения MQ2:
int sensorThres = 10;  // Пороговое значение уровня газа:
int reley = 6;         // Пин подключения реле:


OneWire  ds(8);  // подключен к 8 пину (резистор на 4.7к обязателен)

void setup(void) {
  pinMode(buzzer, OUTPUT);
  pinMode(smokeA0, INPUT);
  pinMode(reley, OUTPUT);   
  digitalWrite(reley, LOW);  // Включаем вентилятор
  Serial.begin(9600); 
}

void loop(void) {
  int analogSensor = analogRead(smokeA0);
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  for( i = 0; i < 8; i++)
  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // начало коммуникации
  
  delay(1000);
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // читаем значение

  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // смотрим 9 байтов
    data[i] = ds.read();
    Serial.print(" ");
  }
  // Преобразуем получненный данные в температуру
  // Используем int16_t тип, т.к. он равен 16 битам
  // даже при компиляции под 32-х битный процессор
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3;
    if (data[7] == 0x10) {
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw & ~7;
    else if (cfg == 0x20) raw = raw & ~3;
    else if (cfg == 0x40) raw = raw & ~1;
  }
  celsius = (float)raw / 16.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" C, ");
  Serial.print("Gas sensor: ");
  Serial.print(analogSensor);
  
  if (celsius > 37 || analogSensor > sensorThres) // устанавливаем значение температуры или уровня газа при котором включается реле
  {
    digitalWrite(reley, HIGH); 
    tone(buzzer, 1000, 200);
  }
   if (celsius < 33  || analogSensor < sensorThres) // устанавливаем значение температуры  или уровня газа при котором отключается реле
  { 
    digitalWrite(reley, LOW);
    notone(buzzer, 1000, 200);
  }
  delay (1000);
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А чего печатает в строка 65-69. Скопипастите сюда

restiv
Offline
Зарегистрирован: 03.01.2016

sadman41
Offline
Зарегистрирован: 19.10.2016

Реле-то щёлкает хотя бы? После стр.75 временно delay(3000) поставьте.

restiv
Offline
Зарегистрирован: 03.01.2016

Нет. Реле вообще никак не реагирует. стоит из условия убрать один из датчиков, как все начининает работать без проблем.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

После стр.75 временно delay(3000) поставьте.

С языка сняли. Только хотел сказать - может он не успевает за такое время включить?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

delay-то поставьте, чего получается?

restiv
Offline
Зарегистрирован: 03.01.2016

Попробовал поставить после строки 75 delay(3000). Реле стало срабатывать, но только на эти 3 сек задержки. После этого отключается.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

Возьмите фен и погрейте температурный датчик долно быть включено пока греете.

sadman41
Offline
Зарегистрирован: 19.10.2016

Диагноз ясен. Первое условие включает, второе - сразу выключает. Нужно их перепридумать.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Чёрт!!!!!!!

В строке 76 && надо! Какого чёрта там  || делает?

Выключаем кода температура в порядке И газ тоже в порядке.

restiv
Offline
Зарегистрирован: 03.01.2016

Я кажется понял свою ошибку.

 if (celsius > 37 || analogSensor > sensorThres) // устанавливаем значение температуры или уровня газа при котором включается реле
  {
    digitalWrite(reley, HIGH);
    tone(buzzer, 1000, 200);
  }
 
   if (celsius < 33 && analogSensor < sensorThres) // устанавливаем значение температуры  или уровня газа при котором отключается реле
  {
    digitalWrite(reley, LOW);

 

Во втором условии поставил логическое "И" и все заработало. получается второе условие выполняется при выполнении обоих условий.

Спасибо всем за помощь!

sadman41
Offline
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:

Ну, правильно, у Вас за эти три секунды уменьшился analogSensor

Сомнительно, что переменная сама по себе стала уменьшаться.

Просто условия у него написаны так, что первое по OR врубает (если любой из параметров вышел за предел), а второе - вырубает (если вышел за предел только один параметр, а второй ОК).

Нужно обладателю вытяжки немного подумать.

restiv
Offline
Зарегистрирован: 03.01.2016

Спасибо!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

Сомнительно, что переменная сама по себе стала уменьшаться.

Ну, да, конец рабочего дня, я что-то не заметил, что он её снова не читает.

Но уже разобрались.

sadman41
Offline
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:

Но уже разобрались.

Я вот вам хотел по const в параметрах функции вопрос задать, но тему не могу найти, в которой спор был.

Вопрос незамысловатый и, наверное, больше к эстетике относится. Есть, например, void func(byte *data, byte lenght); И внутри этой функции мне надо всю эту data совать куда попало, т.е. самое удобное делать length-- и  data++. Вопрос вот в чем: есть ли профит в передаче const lenght и копировании значения в локальную переменную или же можно просто брать и по рабоче-крестьянски декрементировать ее и делу конец? Ведь память под нее всё равно выделена, как я понимаю.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Я бы делал по рабоче-крестьянски.

С const там же рекомендация простая: "не собираешься менять - не скрывай этого от компилятора". Но нет ведь рекомендации "ради слова const создавай себе головную боль".