Объединение двух sketch кодов

MrBobr
Offline
Зарегистрирован: 19.01.2022

Добрый день, форумчане!

Недавно начал заниматься ардуино, появилась нужда в объединении скетчей, проблема такова:

Первый скетч считывает температуру и влажность с датчика DHT11 и выводит их на экран, второй скетч заставляет загораться и светодиод по хлопку, по отдельности каждый скетч работает стабильно, но при объединении второй скетч прекращает корректно работать, в чем может быть проблема?

(Скетчи прикрепляю ниже)

 Первый скетч:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <dht11.h>
dht11 sensor;
#define DHT11PIN 2
byte degree[8] = // кодируем символ градуса
{
  B00111,
  B00101,
  B00111,
  B00000,
  B00000,
  B00000,
  B00000,
};

void setup()
{
  lcd.init();
  lcd.backlight();
  lcd.createChar(1, degree); // Создаем символ под номером 1
}
void loop()
{
  int chk = sensor.read(DHT11PIN);
  lcd.setCursor(0, 0);
  lcd.print("vlajnost:      %");
  lcd.setCursor(13, 0);
  lcd.print(sensor.humidity);
  lcd.setCursor(0, 1);
  lcd.print("temperatura:");
  lcd.setCursor(13, 1);
  lcd.print(sensor.temperature);
  lcd.print(char(1));
  delay(500);
}

Второй скетч:

const int MicPin = 6;                                // выбор пина для входа от микрофона
const int RELAY_PIN = 13;                             // выбор пина для выхода на реле 

int flag=0; 
 
void setup () 
{
  pinMode(RELAY_PIN, OUTPUT);                        // Реле. Настраиваем вывод 2 Ардуино на Выход
  digitalWrite(RELAY_PIN, HIGH);                     // Выключаем реле 
}
 
void loop () 
{
  if(digitalRead(MicPin) == HIGH  && flag == 0){
    flag=1;
    digitalWrite(RELAY_PIN, LOW);                   // Включаем реле
    delay (150);
  }
  if(digitalRead(MicPin) == HIGH && flag == 1){            
        flag=0;
        digitalWrite(RELAY_PIN,HIGH);                // Выключаем реле
        delay(50);                                   // Задержка. Для устранения дребезга. 
  } 
}
 

 

b707
Offline
Зарегистрирован: 26.05.2017

зачем нам исходные скетчи? - вы лучше покажите, как обьединяли

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Прежде, чем пытаться объединить скетчи, избавьтесь от delay в каждом из них. (скетчи, содержащие delay не поддаются объединению)

MrBobr
Offline
Зарегистрирован: 19.01.2022

Объеденённый скетч:

const int MicPin = 6;                                // выбор пина для входа от микрофона
const int RELAY_PIN = 13;                             // выбор пина для выхода на реле 

int flag=0;

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <dht11.h>
dht11 sensor;
#define DHT11PIN 2
byte degree[8] = // кодируем символ градуса
{
  B00111,
  B00101,
  B00111,
  B00000,
  B00000,
  B00000,
  B00000,
};

void setup()
{
  pinMode(RELAY_PIN, OUTPUT);                        // Реле. Настраиваем вывод 2 Ардуино на Выход
  digitalWrite(RELAY_PIN, HIGH);                     // Выключаем реле 
  lcd.init();
  lcd.backlight();
  lcd.createChar(1, degree); // Создаем символ под номером 1
}
void loop()
{
 {
  if(digitalRead(MicPin) == HIGH  && flag == 0){
    flag=1;
    digitalWrite(RELAY_PIN, LOW);                   // Включаем реле
  }
  if(digitalRead(MicPin) == HIGH && flag == 1){            
        flag=0;
        digitalWrite(RELAY_PIN,HIGH);                // Выключаем реле                                      
  } 
 }
  int chk = sensor.read(DHT11PIN);
  lcd.setCursor(0, 0);
  lcd.print("vlajnost:      %");
  lcd.setCursor(13, 0);
  lcd.print(sensor.humidity);
  lcd.setCursor(0, 1);
  lcd.print("temperatura:");
  lcd.setCursor(13, 1);
  lcd.print(sensor.temperature);
  lcd.print(char(1));
  
}

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Избавиться от делеев не значит тупо их удалить ))

MrBobr
Offline
Зарегистрирован: 19.01.2022

Ну, так получилось)

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

И что, работает? Светодиод зажигается? ))

MrBobr
Offline
Зарегистрирован: 19.01.2022

В самом начале, сам по себе зажигается, на хлопки не реагирует, но если подкрутить потенциометр на плате микрофона до состояния постоянной работы от любого шума, то состояние светодиода меняется

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Ну, раз все устраивает, то умолкаю... )

MrBobr
Offline
Зарегистрирован: 19.01.2022

Так в том и дело, что не устраивает, он должен срабатывать по хлопку, а не тогда, когда я кручу потенциометр на плате

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

Я встречал два вида "микрофонных" модулей: непосредственно микрофон и детектор шума. И работают они по-разному.

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Значит не работает. А все почему? Да потому что

v258 пишет:

Избавиться от делеев не значит тупо их удалить ))

Светодиод у тебя срабатывает, но слишком быстро, глаз заметить не успевает. Чтобы успевал, там делеи и были вставлены. Но для объединенного скетча это не вариант. Тут по хорошему все полностью переписывать нужно

b707
Offline
Зарегистрирован: 26.05.2017

MrBobr пишет:

Так в том и дело, что не устраивает, он должен срабатывать по хлопку, а не тогда, когда я кручу потенциометр на плате

проблема микрофона не имеет ни малейшего отношения к обьединению скетчей

vrd
Offline
Зарегистрирован: 20.01.2022

Начну с физики.

Хлопок имеет свою длительность.

В первом скетче длительность хлопка ограничивают дэлеи 150 и 50.

От первого можно избавится, перенеся второй ИФ в конец цикла ЛУП.

Вывод данных на экран займёт необходимые милисы.

А последний дэлей 50 верните на место.

Скобки убрать на 33 и 42.

MrBobr
Offline
Зарегистрирован: 19.01.2022

И даже так, всё равно не работает

b707
Offline
Зарегистрирован: 26.05.2017

MrBobr, изучите пример BlinkWithoutDelay в шапке форума и перепишите программу по его образцу

vrd
Offline
Зарегистрирован: 20.01.2022
uint32_t t1 = 0;
int check = 1000;

if (millis() - t1 >= check) {
  if (digitalRead(MicPin) == HIGH  && flag == 0) {
    flag = 1;
    t1 = millis();
    digitalWrite(RELAY_PIN, LOW);                   // Включаем реле
  }
}

if (millis() - t1 >= check) {
  if (digitalRead(MicPin) == HIGH && flag == 1) {
    flag = 0;
    t1 = millis();
    digitalWrite(RELAY_PIN, HIGH);               // Выключаем реле
  }

}

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

b707 пишет:

MrBobr, изучите пример BlinkWithoutDelay в шапке форума и перепишите программу по его образцу

Ты думаешь твои слова в его голове в предложение складываются?)

vrd
Offline
Зарегистрирован: 20.01.2022

Чаще секунды НЕ хлопать :)

b707
Offline
Зарегистрирован: 26.05.2017

vrd, вы - MrBobr? нафига подсказывать, пусть человек найдет сам.

А тупые подсказки ему не помогут, он через час придет тоже самое спрашивать, мы здесь такое уже проходили много раз

MrBobr
Offline
Зарегистрирован: 19.01.2022

Благодарю, это действительно помогло, но заставить работать корректно два скетча вместе я смог только после того, как сделал второй скетч через if, в данный момент скетч выглядит так:

const int MicPin = 6;                                // выбор пина для входа от микрофона
const int RELAY_PIN = 13;                             // выбор пина для выхода на реле 
uint32_t t1 = 0;
int check = 1000;
int flag = 0;
uint32_t t = 0;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <dht11.h>
dht11 sensor;
#define DHT11PIN 2
byte degree[8] = // кодируем символ градуса
{
  B00111,
  B00101,
  B00111,
  B00000,
  B00000,
  B00000,
  B00000,
};

void setup()
{
  pinMode(RELAY_PIN, OUTPUT);                        // Реле. Настраиваем вывод 2 Ардуино на Выход
  digitalWrite(RELAY_PIN, HIGH);                     // Выключаем реле 
  lcd.init();
  lcd.backlight();
  lcd.createChar(1, degree); // Создаем символ под номером 1
}
void loop()
{
  if (millis() - t1 >= check) {
    if (digitalRead(MicPin) == HIGH && flag == 1) {
      flag = 0;
      t1 = millis();
      digitalWrite(RELAY_PIN, HIGH);               // Выключаем реле
    }
  }
  if (millis() - t1 >= check) {
    if (digitalRead(MicPin) == HIGH  && flag == 0) {  
      flag = 1;
      t1 = millis();
      digitalWrite(RELAY_PIN, LOW);                   // Включаем реле
    }
  }
  
  if (millis() - t >= check) {    
   int chk = sensor.read(DHT11PIN);
   lcd.setCursor(0, 0);
   lcd.print("vlajnost:      %");
   lcd.setCursor(13, 0);
   lcd.print(sensor.humidity);   
   lcd.setCursor(0, 1);
   lcd.print("temperatura:");
   lcd.setCursor(13, 1);
   lcd.print(sensor.temperature);
   t = millis();
   lcd.print(char(1));
   
  }

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Не через if, а через millis(). Собственно, как и нужно было делать ))

MrBobr
Offline
Зарегистрирован: 19.01.2022

Хотелось бы задать еще один вопрос, почему до тех пор пока я не ввёл новый тип для второй части скетча (uint32_t t = 0), а использовал старый (uint32_t t1 = 0), датчик работал некорректно (то работает, то нет)?

MrBobr
Offline
Зарегистрирован: 19.01.2022

Принял)

b707
Offline
Зарегистрирован: 26.05.2017

вообще, два условия в строчках 34 и 41 почти совпадают. их можно обьединить в одно и записать короче

b707
Offline
Зарегистрирован: 26.05.2017

MrBobr пишет:

Хотелось бы задать еще один вопрос, почему до тех пор пока я не ввёл новый тип для второй части скетча (uint32_t t = 0), а использовал старый (uint32_t t1 = 0), датчик работал некорректно (то работает, то нет)?

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

Чтобы работали обе части, таймеры в каждой должны иметь свои отдельные переменные

 

MrBobr
Offline
Зарегистрирован: 19.01.2022

Благодарю теперь понял, прозвучит ещё один банальный вопрос, но какую функцию выполняет millis в 37, 44 и 59 строке?

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

millis() - http://arduino.ru/Reference/Millis

Цитата:
Возвращает количество миллисекунд с момента начала выполнения текущей программы на плате Arduino. Это количество сбрасывается на ноль, в следствие переполнения значения, приблизительно через 50 дней.

В указанных строчках запоминается текущий момент времени, от которого в последствии пляшут строчки 34, 41 и 49

MrBobr
Offline
Зарегистрирован: 19.01.2022

Я думал над этим, но разве тогда не будет получаться отрицательное значение?

lilik
Offline
Зарегистрирован: 19.10.2017

MrBobr пишет:

Я думал над этим, но разве тогда не будет получаться отрицательное значение?

От большего вычитают меньшее, почему и где отрицательное?

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

MrBobr пишет:

Я думал над этим, но разве тогда не будет получаться отрицательное значение?

uint32_t - беззнаковый тип, отрицательным быть не может. При переполнении просто сбрасывается в нуль и начинает увеличиваться заново.

MrBobr
Offline
Зарегистрирован: 19.01.2022

Я про то, что если, как вы и говорите, строки 37, 44 и 59 влияют на строки 34, 41, 49, то получается, что когда мы отнимаем t1 у нас будет либо 0 либо отрицательное значение

Feofan
Offline
Зарегистрирован: 28.05.2017
v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

MrBobr пишет:

Я про то, что если, как вы и говорите, строки 37, 44 и 59 влияют на строки 34, 41, 49, то получается, что когда мы отнимаем t1 у нас будет либо 0 либо отрицательное значение

Еще раз - uint32_t НЕ может быть отрицательным. Почитай про беззнаковые типы.

И еще - millis() постоянно увеличивается, т.е. меньше t1 оно не может быть по определению. Только через 50 дней, но, если все сделано правильно ( а в твоем коде таки все сделано правильно), то и это не страшно ))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

MrBobr пишет:

 когда мы отнимаем t1 у нас будет либо 0 либо отрицательное значение

А я вот, когда отнимаю от часа ночи (1:00) два часа взат, у меня всегда получается не -1:00, а 23:00, не знаешь почему?

lilik
Offline
Зарегистрирован: 19.10.2017

ТС, вот вам ещё пример соединения двух скетчей и более...

// 1 поток
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
delay(500);// кадр 1 
digitalWrite(13,HIGH);
delay(100);// кадр 2
digitalWrite(13,LOW);
  
}
// 2 поток
void setup()
{
pinMode(12, OUTPUT);
}
void loop()
{
delay(666);// кадр 1   
digitalWrite(12,HIGH);
delay(222);// кадр 2
digitalWrite(12,LOW);
}
// слитые 1 и 2 поток
long Y1=0;
long Y2=0;
int K1=1;//счётчик кадров в псевдопотоке 1
int K2=1;//счётчик кадров в псевдопотоке 2

void setup()
{
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
}
void loop()
{
loop_1();//
loop_2();//
}
//////////////////////////////
void loop_1(){
if(K1==1&&millis()-Y1>=100){Y1=millis();K1=2;digitalWrite(13,LOW);}
if(K1==2&&millis()-Y1>=500){Y1=millis();K1=1;digitalWrite(13,HIGH);}    
}
void loop_2(){
if(K2==1&&millis()-Y2>=222){Y2=millis();K2=2;digitalWrite(12,LOW);}
if(K2==2&&millis()-Y2>=666){Y2=millis();K2=1;digitalWrite(12,HIGH);}    
}
//////////////////////////////

 

MrBobr
Offline
Зарегистрирован: 19.01.2022

Я понимаю, что он не может быть отрицательным, просто я не могу понять за что конкретно в строках 34 и т.п. отвечают строки 37 и т.п., если за "millis(), то зачем тогда мы дали ему название такое же, как и типу, а если за t1, то как ему вообще тогда удаётся работать?

MrBobr
Offline
Зарегистрирован: 19.01.2022

Ну, во первых, потому что так принято в наших странах, что до 01:00 находится 00:00, а до него 23:00, во вторых, мы с вами на ты не переходили, если вас что-то не устраивает, или что-то не нравится, прошу не писать и, банально, пройти мимо

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Слушаю и повинуюсь, барин. 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

MrBobr пишет:
Ну, во первых, потому что так принято в наших странах, что до 01:00 находится 00:00, а до него 23:00

Нет. Это потому, что время отрицательным быть не может. Это тоже "беззнаковый тип". Потому подчиняется той же арифметике, что и uint32_t

lilik
Offline
Зарегистрирован: 19.10.2017

ТС, вы поняли хоть что то из моего 35 сообщения?Или не понятно как работает строка типа:

if(millis()-Y1>=100){Y1=millis();}

???

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

MrBobr пишет:
Я понимаю, что он не может быть отрицательным, просто я не могу понять за что конкретно в строках 34 и т.п. отвечают строки 37 и т.п., если за "millis(), то зачем тогда мы дали ему название такое же, как и типу, а если за t1, то как ему вообще тогда удаётся работать?

Коллеги! Почему этот позорный детсад еще не перенесен в "Песочницу"?

----------------

2 ТС: Наш Форум для общения по интересам, для ответов на вопросы и обучения есть форумы формата "Q&A" (например СтекОверфлоу), поисковики и обучающие платформы. Учитывая двузначный IQ у тебя, учебники не предлагаю.

MrBobr пишет:
Ну, во первых, потому что так принято в наших странах, что до 01:00 находится 00:00, а до него 23:00, во вторых, мы с вами на ты не переходили, если вас что-то не устраивает, или что-то не нравится, прошу не писать и, банально, пройти мимо

А тут ты решил поучить жизни модератора. Как думаешь сам, теперь тебе станет легче получить помощь? ;)))))

------------------

Вообще, поддерживать разговор в тысячный раз об "объединении двух скетчей" - это уже психиатрия какая-то, нет? Не нужно так уж ронять планку форума. Но это уже не призыв, а просто Май Хамбл Опиньён.  Один раз пациенту сказали убрать "делеи" и читать "блинк-без-делей" до просветления. Зачем еще что-то, если диагноз ясен?