Два условия - одна релюшка

medossa
Offline
Зарегистрирован: 10.07.2012

Друзья. Есть релюшка, которая включается по заданному условию (показания датчика). Как организовать код, чтобы можно было еще по сериал соединению вкл/отключать? Например, релюшка включилась при температуре 15 градусов. Но возникла необходимость выключить принудительно. Как сделать два условия?

maksim
Offline
Зарегистрирован: 12.02.2012

Ну так вы покажите код.

medossa
Offline
Зарегистрирован: 10.07.2012

Да собственно и кода-то пока нет из-за недопонимания. Вот стандартный. Т.е. если считываемое значение аналогового пина меньше 400, то релюшка включится, больше - выключится. При значении меньше 400, необходима возможность отключения реле путём посылки байта в порт, а в else наоборот включения.

int relay = 9;
int ldr = 2;
int val = 0;

void setup()
{
Serial.begin(9600);
pinMode(relay, OUTPUT);
}

void loop()
{
val = analogRead(ldr);
if (val < 400)
{
digitalWrite(relay, HIGH);
}
else
{
digitalWrite(relay, LOW);
}

}
maksim
Offline
Зарегистрирован: 12.02.2012
#define relay 9
#define ldr A2
#define porog 400

bool state = 0, f = 0;


void setup()
{
  Serial.begin(9600);
  pinMode(relay, OUTPUT);
}

void loop()
{
  if(Serial.available()) state = Serial.read() - '0';
  int val = analogRead(ldr);
  if (val < porog && !f) 
  {
    state = HIGH;
    f = 1;
  }
  if (val >= porog && f)
  {
    state = LOW;
    f = 0;
  }
  digitalWrite(relay, state);
}

В монитор отправляете 1 или 0.

medossa
Offline
Зарегистрирован: 10.07.2012

Максим, благодарствую. Сейчас к сожалению не проверю, завтра с утра отпишусь.

С меня стакан)

step962
Offline
Зарегистрирован: 23.05.2011

maksim пишет:

В монитор отправляете 1 или 0.

Нет, такое решение, я думаю, не удовлетворит топикстартера, ведь для того, чтобы релюшка срабатывала при переходе через порог в ту или иную сторону, придется каким-то образом устанавливать управляющий бит в "правильное" состояние. А как его узнать, не имея информации от датчика? Мерлина привлекать?

Решением может быть управляющий сигнал, имеющий три состояния:
0 - принудительное выключение реле
1 - принудительное включение реле
ну и третье состояние ("2"?), когда Мерлин не колдует и реле работает в соответствии с логикой обработки аналогового сигнала.

То есть, вместо двух if-блоков напрашивается вложенный "трехэтажный" if:

if(controlState==0) {
  // выключаем реле
}
else if(controlState==1) {
  // включаем реле
}
else {
  // первоначальная логика
} 

 

medossa
Offline
Зарегистрирован: 10.07.2012

а кто такой Мерлин? :)

step962
Offline
Зарегистрирован: 23.05.2011

Ну как же - Мерлин это же такой Мерлин

maksim
Offline
Зарегистрирован: 12.02.2012

step962 пишет:

Нет, такое решение, я думаю, не удовлетворит топикстартера, ведь для того, чтобы релюшка срабатывала при переходе через порог в ту или иную сторону, придется каким-то образом устанавливать управляющий бит в "правильное" состояние. А как его узнать, не имея информации от датчика? Мерлина привлекать?

О чем вы? Не нужно ничего узнавать, если реле было включено, то при отправке 0 оно отключиться, если было выключено ,то при отправке 1 включится, в то же время при переходе через порог реле будет так же вкючаться или выключаться независимо от того в каком состоянии оно было установленно принудительно. То есть это как обычный выключатель в комнате и два человека - каждый может включить свет и каждый может его выключить.

step962
Offline
Зарегистрирован: 23.05.2011

maksim пишет:

О чем вы? 

Оценивал структуру, не вглядываясь в детали.

Пригляделся повнимательнее - увидел дополнительный триггер. Таки да - работать будет, однако подход к решению несколько необычный: подчиненное по логике поставленной задачи условие (val) манипулирует основным условием (state). Получается прямо по поговорке "хвост виляет собакой".

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

medossa
Offline
Зарегистрирован: 10.07.2012

итак, всё арбайтен)

задача усложнилась. два датчика, два реле.

опять мозг взорвался)

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

как теперь вторую включать?

maksim
Offline
Зарегистрирован: 12.02.2012

Ну так код покажите...

medossa
Offline
Зарегистрирован: 10.07.2012

Подключено два датчика - дхт11 и дс18б20

#include <dht11.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define WIRE_BUS 9

dht11 DHT11;
OneWire DS(WIRE_BUS);
DallasTemperature sensors(&DS);

byte RELAY1 = 6;
byte RELAY2 = 8;
byte LDR = 7;
int LDR_MAP, VAL;
float DHT_HUM, DHT_TEMP, DS_TEMP;
bool STATE = 0, F = 0;

void setup()
	{
         pinMode(RELAY1, OUTPUT);
         pinMode(RELAY2, OUTPUT);
	 Serial.begin(9600);       
         sensors.begin();          
	}

void loop()
  {
     float CHK_DHT = DHT11.read(WIRE_BUS);
     sensors.requestTemperatures();
     DHT_HUM = DHT11.humidity;
     DHT_TEMP = DHT11.temperature;
     DS_TEMP = sensors.getTempCByIndex(0);
     Serial.print("HUM: ");
     Serial.println(DHT_HUM);
     Serial.print("TEMP: ");
     Serial.println(DHT_TEMP);
     Serial.print("DS: ");
     Serial.println(DS_TEMP);
       if(Serial.available()) STATE = Serial.read() - '0';
        {
         if(DHT_TEMP > 26.00 && !F)
           {
             STATE = HIGH;
             F = 1;
           }
           if(DS_TEMP < 26.00 && F)
             {
               STATE = LOW;
               F = 0;           
             }
          digitalWrite(RELAY1, STATE);
        }
     /////
     VAL = analogRead(LDR);
     int LDR_MAP = map(VAL, 1023, 0, 0, 255);
     if(LDR_MAP < 150)
/// Вот в этом блоке надо также послать что-то в порт для вкл/откл реле2
        digitalWrite(RELAY2, HIGH);
          else digitalWrite(RELAY2, LOW);
     delay(300);
       }

 

maksim
Offline
Зарегистрирован: 12.02.2012

В общем покажу на предыдущем примере

#define relay1 9
#define relay2 9
#define porog1 400
#define porog2 400

bool state1 = 0, f1 = 0, state2 = 0, f2 = 0;


void setup()
{
  Serial.begin(9600);
  pinMode(relay1, OUTPUT);
   pinMode(relay2, OUTPUT);
}

void loop()
{
  if(Serial.available()) 
  {
    char c = Serial.read();
    if(c == '1') state1 = Serial.read() - '0'; 
    if(c == '2') state2 = Serial.read() - '0'; 
    while(Serial.available()) Serial.read();
  }
  
  int val1 = analogRead(A2);
  if (val1 < porog1 && !f1) 
  {
    state1 = HIGH;
    f1 = 1;
  }
  if (val1 >= porog1 && f1)
  {
    state1 = LOW;
    f1 = 0;
  }
  digitalWrite(relay1, state1);
  
  int val2 = analogRead(A1);
  if (val2 < porog2 && !f2) 
  {
    state2 = HIGH;
    f2 = 1;
  }
  if (val2 >= porog2 && f2)
  {
    state2 = LOW;
    f2 = 0;
  }
  digitalWrite(relay2, state2);
}

В монитор пишите 10, 11, 20, 21

medossa
Offline
Зарегистрирован: 10.07.2012

23 строчка не понятна, что она делает?

 while(Serial.available()) Serial.read();

 

sp34
Offline
Зарегистрирован: 05.03.2013

Интересует вот такой вопрос в условиях : как правильно из двух вариантов описать цифровые переменные , что бы условие не пропустило значение 300(первая часть условия) и значение 30.00(вторая часть условия)

Вариант 1.

 if(hot>0&&hot<300&&tempS1>26.00&&tempS1<30.00) 

xxxxxxxxxxxxxxxxxxxx  

if(hot>301&&hot<500&&tempS1>30.01&&tempS1<40.00)

xxxxxxxxxxxxxxxxxxx

Вариант 2.

if(hot>=0&&hot<=300&&tempS1>=26.00&&tempS1<=30.00)

xxxxxxxxxxxxxxxxxxxxxxx

if(hot>300&&hot<500&&tempS1>30.00&&tempS1<40.00)

xxxxxxxxxxxxxxxxxxxxxxxxx

 

Я больше склоняюсь ко второму варианту , но боюсь ошибиться.

medossa
Offline
Зарегистрирован: 10.07.2012

Друзья, что б тему не создавать новую, подскажите. Опять этот сериал)

Как отделить друг от друга получение данных разных типов на ардуине, например, тут надо принимать char:

if(Serial.available() < 2) {
     char sr = Serial.read() - '0';
     if(sr то-то то-то)
}

if(Serial.available() > 2) {
    int sr = Serial.read() - '0';
    if(sr то-то то-то)
}

и в этом же скетче принимать и int. Причём думал сделать if(Serial.available() > 2) для int, т.к. там трёхзначное число, но что-то не катит.

В первом случае принимается символ 'H', 'T', 'C', а где int там 234, 450 и т.д.

 

medossa
Offline
Зарегистрирован: 10.07.2012

и еще, почему при посылке в порт числа 340 к примеру или 739  выводится каждая цифра в столбик...

void setup() {
 Serial.begin(115200);
}

void loop() {
 if(Serial.available()) {
  int val = Serial.read() - '0'; 
  Serial.println(val);
 }
}
  
  

число 340 выглядет так:

//шлём в порт 340 вывод такой
3
4
0

//шлём в порт 3496 вывод такой
3
4
9
6

 

medossa
Offline
Зарегистрирован: 10.07.2012

с int'ом разобрался, оказывается есть Serial.parseInt()

первый вопрос в силе

UPD.  parseInt() работает туго, обработка числа около секунды происходит...

step962
Offline
Зарегистрирован: 23.05.2011

medossa пишет:

первый вопрос в силе

А вы их пронумеровали? С какого из ваших сообщений необходимо начинать отсчет? С самого первого или с шестнадцатого?

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

medossa
Offline
Зарегистрирован: 10.07.2012

to step962

вопрос снят. победил вроде)

типы данных таки)

 

akniet_909@mail.ru
Offline
Зарегистрирован: 19.03.2013

 

www.algofinder.com

Great website for those, who are interested in mathematics and informatics.

 

The website contains efficient algorithms, in the field of combinatorics, route optimization and prime numbers. To run these programs you will need only the C compiler. The build-up of these programs is simple, quick and elegant.