Управление разспашными воротами Arduino

Подключение исполнительных устройств, датчиков, контроллеров.

Модератор: immortal

Ответить
tammat
Сообщения: 165
Зарегистрирован: Пт янв 20, 2012 3:05 pm
Благодарил (а): 9 раз
Поблагодарили: 1 раз

Управление разспашными воротами Arduino

Сообщение tammat » Вт янв 21, 2014 3:56 pm

Добрый день, энтузиасты!
Прикупил тут arduino Pro mini +Ardumoto+RF433+ пару актуаторов для солнечных батарей.
На сайтах про arduino(arduino.cc и arduino.ru) нашел пару скетчей и попытался объединить для управления воротами с брелка от GSM сигнализации.
пока на светодиодах все работает
может-кому нибудь потребуется.
За комментарии и советы буду благодарен.
Хотелось бы еще добавить
1) управление через Uart для управления с MDM или другой arduino
2) пару соников для обнаружения перпятствий,
3) управление двумя электромеханическими замками(калитка и замок на воротах).
И у кого есть опыт как организовать питание и от сети (БП на 12V и аккумулятора на 12В, в случае отсутствия сети).
Спасибо.
Ну сам скетч.
Сознательно не использовал при управлении через RF mode 1,3

Код: Выделить всё

/*Simple Gate Controller*/
/*
Author: tammat
 Email: tamatvey@gmail.com
 Date: 21 Jan 2014
 Description: This is just a simple PWM driven Electric gate System. A replacement
 board for the existing fried board due to lightning strikes. It works the same and
 performs better than the original system.
 
 Next phase for this code will be using some electronics current sensor for
 detecting the load of the motors so it will know when to cut off the power of the
 gate instead of using the delay as the timing to open or close the gate. 
 */
#include <RemoteReceiver.h>
#define REMOTE_BUTTON_1 8
#define REMOTE_BUTTON_2 9
#define GATE_A_DIRECTION 12
#define GATE_B_DIRECTION 13
#define PWM_A 3
#define PWM_B 11

#define RUN 1
#define STOP 0

//Define RC Key on Remote Control
#define GATE_1  000000      // Unlock
#define GATE_2  000000      // Lock
#define GATE_3  000000       // S
#define GATE_4  000000      // Alarm

// Variables
int remote_button_1_state = LOW;			// Getting the reading from the remote controller
int remote_button_2_state = LOW;			// Getting the reading from the remote controller
int gate_1_direction_state = LOW;			// LOW = close, HIGH = open
int gate_2_direction_state = HIGH;			// LOW = close, HIGH = open
int gate_function = 0;					// 0 = do nothing (idle)
// 1 = button one pressed
// 2 = button two pressed
// 3 = button one and two pressed
boolean Code=false;
unsigned long lastTick = 0;
unsigned long lastDebounce = 0;
unsigned long code;

void detect_remote_command() {
  unsigned long lastTick = 0;

  // Delay for 2 seconds before starting the detection process
  delay(500);

  lastTick = millis();
  Serial.println("Detecting remote command while executing motor process.");
  while(millis() - lastTick < 17000) {//17 seconds - time of work 
    // If detected some commands from the remote....emergency stop
    // Getting data from the remote controller
    remote_button_1_state = digitalRead(REMOTE_BUTTON_1);
    remote_button_2_state = digitalRead(REMOTE_BUTTON_2);
    if (code!=00000)
    {
      code=00000;
      motor(0, 0, STOP);
      motor(1, 0, STOP);
      Serial.println("EMERGENCY STOPPED the MOTORS as remote key signal received.");
      delay(500);
      return;
    }
    if(remote_button_1_state == LOW || remote_button_2_state == LOW) {
      // Stop all the motors...
      motor(0, 0, STOP);
      motor(1, 0, STOP);

      Serial.println("EMERGENCY STOPPED the MOTORS as remote key signal received.");
      delay(500);
      return;
    }
  }

  // Stops all motor now
  motor(0, 0, STOP);
  motor(1, 0, STOP);

  Serial.println("Normal stopping on Motors");
}

void motor(int id, int direction, int mode) {
  if(id == 0) {
    if(mode == RUN) {
      if(direction == 0) {
        digitalWrite(GATE_A_DIRECTION, LOW);
      } 
      else {
        digitalWrite(GATE_A_DIRECTION, HIGH);
      }
      digitalWrite(PWM_A, HIGH);
    } 
    else {
      digitalWrite(GATE_A_DIRECTION, direction);
      digitalWrite(PWM_A, LOW);
    }
  }

  if(id == 1) {
    if(mode == RUN) {
      if(direction == 0) {
        digitalWrite(GATE_B_DIRECTION, LOW);
      } 
      else {
        digitalWrite(GATE_B_DIRECTION, HIGH);
      }
      digitalWrite(PWM_B, HIGH);
    } 
    else {
      digitalWrite(GATE_B_DIRECTION, direction);
      digitalWrite(PWM_B, LOW);
    }
  }
}

void gate_command(int mode) {
  switch(mode) {
  case 1:
    // Open/Close gate A
    gate_1_direction_state = !gate_1_direction_state;
    Serial.print("GATE A DIRECTION (BUTTON 1): ");
    Serial.println(gate_1_direction_state);

    // Initiate open gate process
    motor(0, gate_1_direction_state, RUN);

    // Detect button press for emergency stop opening or closing gate
    detect_remote_command();

    break;

  case 2:
    // Open/Close gate A & B
    gate_1_direction_state = !gate_1_direction_state;
    gate_2_direction_state = !gate_2_direction_state;
    //    Serial.println("GATE DIRECTION (BUTTON 2)");
    if (gate_1_direction_state==1 &&gate_2_direction_state==0)
    {
      Serial.println("Opening...");
      motor(0, gate_1_direction_state, RUN);
      delay(1000);//Задержка одной створки при открытии
      motor(1, gate_2_direction_state, RUN);
    }
    if (gate_1_direction_state==0 && gate_2_direction_state==1)
    {
      Serial.println("Closing...");
      motor(1, gate_2_direction_state, RUN);
      delay(1000);//Задержка одной створки при открытии
      motor(0, gate_1_direction_state, RUN);

    }

    /*   Serial.print("GATE A DIRECTION: ");
     Serial.println(gate_1_direction_state);
     Serial.print("GATE B DIRECTION: ");
     Serial.println(gate_2_direction_state);
     
     // Initiate open gate process
     motor(0, gate_1_direction_state, RUN);
     motor(1, gate_2_direction_state, RUN);
     */
    // Detect button press for emergency stop opening or closing gate
    detect_remote_command();
    code =000000;
    break;

  case 3:
    // Open/Close gate B
    gate_2_direction_state = !gate_2_direction_state;
    Serial.print("GATE B DIRECTION (BUTTON 1 and BUTTON 2): ");
    Serial.println(gate_2_direction_state);

    // Initiate open gate process
    motor(1, gate_2_direction_state, RUN);

    // Detect button press for emergency stop opening or closing gate
    detect_remote_command();

  }
}

void setup() {
  Serial.begin(9600);
  Serial.println("Starting GateDuino Controller Version 1.0 alpha");
  Serial.println("Initializing Parameters");

  pinMode(REMOTE_BUTTON_1, INPUT);	// set the pin as input
  digitalWrite(REMOTE_BUTTON_1, HIGH);	// turn on the internal pullup resistor 20k

  pinMode(REMOTE_BUTTON_2, INPUT);	// set the pin as input
  digitalWrite(REMOTE_BUTTON_2, HIGH);	// turn on the internal pullup resistor 20k

  pinMode(GATE_A_DIRECTION, OUTPUT);	// set the pin as output
  pinMode(GATE_B_DIRECTION, OUTPUT);	// set the pin as output
  pinMode(PWM_A, OUTPUT);			// set the pin as output
  pinMode(PWM_B, OUTPUT);			// set the pin as output
  RemoteReceiver::init(0, 1, showCode);
}

void loop() {
  // Getting data from the remote controller
  remote_button_1_state = digitalRead(REMOTE_BUTTON_1);
  remote_button_2_state = digitalRead(REMOTE_BUTTON_2);

  if (code==GATE_1){
    code=0000000;  
    gate_command(2);
    Serial.println("Drive from Remote Control"); 
  }
  // Debugging only will be removed
  /*  Serial.print("BUTTON (1:2): ");
   Serial.print(remote_button_1_state);
   Serial.print(":");
   Serial.println(remote_button_2_state);
   */
  // When getting the button 2 then will try to open or close the gate based on the previous gate state.
  if(remote_button_1_state == LOW && remote_button_2_state == LOW) {
    gate_command(3);
  }

  if(remote_button_1_state == HIGH && remote_button_2_state == LOW) {
    gate_command(2);
  }

  if(remote_button_1_state == LOW && remote_button_2_state == HIGH) {
    gate_command(1);
  }

  if(remote_button_1_state == HIGH && remote_button_2_state == HIGH) {
    // Do nothing....
    // gate_command(0);
  }

  delay(500);
}

void showCode(unsigned long receivedCode, unsigned int period) {  
  if (code != receivedCode){
    code = receivedCode;
    Serial.print("Code: ");
    Serial.println(receivedCode);
  }
  /*  Serial.print(", period duration: ");
   Serial.print(period);
   Serial.println("us.");*/
}
Аватара пользователя
shemnik69
Сообщения: 590
Зарегистрирован: Пн дек 24, 2012 3:01 pm
Откуда: Саратов Saratov
Благодарил (а): 67 раз
Поблагодарили: 63 раза

Re: Управление разспашными воротами Arduino

Сообщение shemnik69 » Ср янв 22, 2014 11:09 am

Отличная темка. Сам этой идеей страдаю... у меня алгоритм работы и порядок немного другой!
Ворота (створа) откатные. Привод редуктор + двигатель на 220 в. полный реверс на 2 реле. На створе присутствуют концевики (стандартные от пром автоматики , всепогодные) для фиксации сигналов открыто/закрыто, а также неопределенно т.е полуприкрыто/открыто....
Проем створы, в открытом положении, просматривает камера, а также ИК датчики . Т.е. при пересечении проема на высоте примерно 60 см. срабатывает сигнал. Он при срабатывании во время движения (закрытие) стопорит привод на 7 сек, и если препятствие не исчезло, то стопорит еще на 7 сек. и т. д. Скорость движения не велика, и наехать на человека или автомобиль например не получится (в полу открытые ворота я не пробовал заезжать).
Если при открытом положении сработал датчик на 1-2 сек. (человек прошел, или еще что, то МД, делает фото снимок с камеры. Если пересечение, по времени более 4-6 сек. Автомобиль быстрее никак ..то спустя примерно 10 сек! после снятия сигнала! ..створа начинает закрываться.
Т.е . например утром по сигналу МД (6:50) и вечером (17:30) ворота начинают открываться. Включается прожектор под света створы (по времени, а также на основе сигнала датчика освещенности (так удобнее)) и таймер начинает отсчет 15 мин.
Если за это время, автомобиль не выехал (въехал), то сигнал как напоминание say"Закрыть ворота?" если да то мы можем либо сами закрыть (от любых датчиков ( кнопка,брелок планшеты. и т.д) либо система сама закроет это при условии утро. Вечером сценарий другой система ждет еще 15 мин.
Если в данный промежуток времени автомобиль пересек проем (это 5-6 сек) то система через 10 сек закрывает ворота. Иными словами выехал и поехал.. а также въехал и ... сама закроет.
Реализована на основе автомобильной сигналки (брелки и приемник). кнопочная станция (управление со двора). Кнопки на планшете. (открыть и закрыть). А также плата автоматики, реализующая начальное управление.
Обращаю Ваше внимание! что, алгоритм реализован как на уровне железа, т.е защита. пуск/стоп (конечные положения) так же и на уровне программы, но поскольку это не та область, где глюки приветствуются, то она независима от МД. иными словами, если сервер, что либо потеряет или забудет, или заболеет ..то ворота как работали так и будут. Если необходима схема и печатная плата (ЛУТ) то приложу.
Аватара пользователя
sergejey
Site Admin
Сообщения: 4286
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 76 раз
Поблагодарили: 1559 раз
Контактная информация:

Re: Управление разспашными воротами Arduino

Сообщение sergejey » Ср янв 22, 2014 12:10 pm

Ого, сколько интересного :)
Я у себя делал совсем просто: у меня откатные въездные ворота и гаражные сделаны на автоматике Nice, т.е. управляются одним пультом с двумя кнопками. Не мудрствуя лукаво я оставил всё как есть, только разобрал дополнительный пульт и вывел две кнопки на реле, плюс поставил свои концевики, чтобы знать открыты ворота или закрыты. Всё работает со штатными пультами, а так же управляется МД по сценариям либо с телефона.

Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
Аватара пользователя
shemnik69
Сообщения: 590
Зарегистрирован: Пн дек 24, 2012 3:01 pm
Откуда: Саратов Saratov
Благодарил (а): 67 раз
Поблагодарили: 63 раза

Re: Управление разспашными воротами Arduino

Сообщение shemnik69 » Ср янв 22, 2014 12:53 pm

Это правильно!.
Мой вариант изначально опирался на фурнитуру и комплектующие DOORHAN но под руки подвернулся очень простой удобный привод от энергооборудования (HK-47). а также прочие элементы. Не мудрствуя. я его и установил. Кроме того возникло целое поле для возможных вариантов реализации задуманных функций, часть которых я и успешно осуществил. А основные элементы просто были в наличии, но некоторые для приличия приобретены (брелки. датчики. ловушки и пр.)
Кстати Сергей! про сценарии!. Я долго бился с вопросом как осуществить таймерный запуск по определенному времени.
т.е вроде простая задача на которую я потратил почти 5 дней (вечеров) была решена, но не на МД а на смартфоне через программу Automatelt (аналог Taske - рa). может не совсем как надо но зато можно оперативно влиять на команды, причем удаленно.
Проблема! никак не смог мог привязать свойства ключа DS2408 (они управляют сигналами на открытие/закрытие) к таймеру... и примеров где это подробно расписано тоже не нашел. Вот и поэтому так...
С Уважением!
Аватара пользователя
sergejey
Site Admin
Сообщения: 4286
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 76 раз
Поблагодарили: 1559 раз
Контактная информация:

Re: Управление разспашными воротами Arduino

Сообщение sergejey » Ср янв 22, 2014 2:46 pm

shemnik69 писал(а):Это правильно!.
Мой вариант изначально опирался на фурнитуру и комплектующие DOORHAN но под руки подвернулся очень простой удобный привод от энергооборудования (HK-47). а также прочие элементы. Не мудрствуя. я его и установил. Кроме того возникло целое поле для возможных вариантов реализации задуманных функций, часть которых я и успешно осуществил. А основные элементы просто были в наличии, но некоторые для приличия приобретены (брелки. датчики. ловушки и пр.)
Кстати Сергей! про сценарии!. Я долго бился с вопросом как осуществить таймерный запуск по определенному времени.
т.е вроде простая задача на которую я потратил почти 5 дней (вечеров) была решена, но не на МД а на смартфоне через программу Automatelt (аналог Taske - рa). может не совсем как надо но зато можно оперативно влиять на команды, причем удаленно.
Проблема! никак не смог мог привязать свойства ключа DS2408 (они управляют сигналами на открытие/закрытие) к таймеру... и примеров где это подробно расписано тоже не нашел. Вот и поэтому так...
С Уважением!
Запуск по таймеру любой задачи можно сделать через правку метода объекта таймера OnNewMinute, там просто добавить условие типа

Код: Выделить всё

if (timeNow('09:00') {
 //что-то сделать или запустить сценарий
}

Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
Аватара пользователя
shemnik69
Сообщения: 590
Зарегистрирован: Пн дек 24, 2012 3:01 pm
Откуда: Саратов Saratov
Благодарил (а): 67 раз
Поблагодарили: 63 раза

Re: Управление разспашными воротами Arduino

Сообщение shemnik69 » Ср янв 22, 2014 3:24 pm

Спасибо. Сейчас пробовать буду. (до смешного просто)... :cry:
tammat
Сообщения: 165
Зарегистрирован: Пт янв 20, 2012 3:05 pm
Благодарил (а): 9 раз
Поблагодарили: 1 раз

Re: Управление разспашными воротами Arduino

Сообщение tammat » Ср янв 22, 2014 4:02 pm

@shemnik69
Как ты ИК датчики использовал? Это датчики движения? Я думал ультрасоники использовать.
Выложи, если не жалко,схему и плату. может что-нибудь вместе дополним и сообразим
НА двух кнопках тупо сделал без проблем.
А вот совмещение на одной кнопки остановка с любой, не всегда адекватно срабатывает, после нескольких раз, оба мотора останавливаюся через пару секунд,
что-то уже офонарел не могу найти ошибку в скетче.Глаз замылился
Аватара пользователя
shemnik69
Сообщения: 590
Зарегистрирован: Пн дек 24, 2012 3:01 pm
Откуда: Саратов Saratov
Благодарил (а): 67 раз
Поблагодарили: 63 раза

Re: Управление разспашными воротами Arduino

Сообщение shemnik69 » Ср янв 22, 2014 5:51 pm

Доброе время суток!. ИК датчик это не датчик движения. Это стандартный сенсор открытой створы ворот. Как он коммерчески называется не могу сказать но я его приобрел в фирме которая занимается комплектом фурнитуры и опций для откатных ворот.
Принцип простой, на одной половине створы (столбе) излучатель (ик) на другой приемник, сигнал модулирован и не боится помех типа засветка и т.п.
Оформлен хорошо, самому делать не стоит..цена 800-1000 р. за комплект но того стоит . На выходе контакты реле как на замыкание так и на размыкание. Питание 12-24 вольт полярность безразлична (внутри мост на диодах).
Чувствительность, и точность просто класс..потому как луч сфокусирован. Ставить на место оптимально с использованием юстировки типа лазерного указателя или на худой конец водяного уровня тогда он просто точен как и положено.
По поводу схемы. Если дружите с пайкой то попробуйте мой вариант. Не рекламирую но скажу что отказался от МК в пользу простой логики после лета. Когда грозы выводили из стоя всю электронику несмотря на все мыслимые защиты. Так вот самое смешное что гроза бухнет где то, а из за глюка МК (стояла Тинька) она открывала ворота... Меня такой расклад не устроил поэтому сделал на простой логике. Работает прекрасно А поскольку это начальный уровень автоматики (как уже писал то она должна брать на себя всю черновую работу а мозг т.е. МД уже может на высшем уровне что либо делать. (таймеры. смартфоны и т.д) но сами подумайте вот встанет сервер или еще чего и что руками ...после нескольких таких действий особенно с участием например супруги вы ........дальше сами. :lol:
По поводу скетча... я пользуюсь программой FlowCode AVR и по сути сам код не вижу поскольку строю программу из алгоритма одновременно она же позволяет проиграет (моделировать его работу). Затем использую Proteus 7.10 это вообще целая лаборатория. Сами схемы я моделирую тоже на РС с использованием Multisim (не реклама) поэтому для гарантии всегда "собираю" в этой программе прежде чем паять... :D
Печатку прикладываю. Схема для удобства в формате Proteus (так что можете поиграть с кнопками и т.д).
Вложения
процессор ворот плата.zip
(21.44 КБ) 499 скачиваний
Процессор ворота нов2.zip
(25.71 КБ) 465 скачиваний
vova5049
Сообщения: 64
Зарегистрирован: Пт фев 21, 2014 10:56 am
Откуда: Днепропетровск
Благодарил (а): 1 раз
Поблагодарили: 5 раз

Re: Управление разспашными воротами Arduino

Сообщение vova5049 » Ср июн 18, 2014 11:55 am

Здравствуйте shemnik69 Если Вам не сложно, выложите, пожалуйста, ее в каком нибудь растровом формате (jpeg, png...). Я сейчас вплотную занялся воротами, и не могу сообразить, как мне лучше сделать.

У меня стоит в гараже нормальная автоматика для секционных ворот, с ней почти никаких вопросов нет, там есть на плате контакты "IR" для подключения датчика препятствий, но, кроме этого стоит датчик тока, который реагирует на повышенное потребление тока двигателем, останавливает привод и открывает ворота, еще на плате есть пара контактов, на замыкание которых привод реагирует точно также, как и на кнопку пульта, переключая режимы в порядке стоп-открытие-стоп-закрытие. Так как для секционных ворот датчик препятствия это скорее излишество, т.к. он реагирует на прерывание светового потока при сминании резинового уплотнителя и, если площадь соприкосновения большая (например крыша автомобиля), то, с большой вероятностью, раньше сработает датчик тока (уровень срабатывания настраивается).
Здесь я только до конца не понимаю, как правильно реализовать неполное открывание, чтоб MDM понимала открывались или закрывались ворота, чтобы понимать, что будет происходить при нажатии на кнопку. Для того, чтоб MDM знала текущее состояние ворот, я поставил на каждые ворота по два концевика (крайние положения) и подключил их к МегаД. Ну это все решаемо, нужно только немного подумать.

А вот в случае с въездными воротами все сложнее, в свое время решил сэкономить и вместо нормальной автоматики поставил блок управления для ролет от того же производителя, что и гаражный привод, и привязал его к одной из кнопок гаражного пульта. Никаких входов для концевиков у этого блока управления не было, поэтому скоммутировал концевики, которые встроены в привод так, чтобы они отсекали питание двигателя при срабатывании концевика. Сначала переживал, что могут залипнуть контакты и сгореть двигатель, но за 5 лет так ни разу и не залипло, кроме того напряжение как для открытия, так и для зактытия подается блоком на 70 секунд, поэтому, даже если не сработает концевик, врядли успеет сгореть двигатель, а усилия что-то сломать у привода не хватает.

Все это время работа привода меня устраивала, но когда начал настраивать MDM и настало время из нее управлять воротами, решил ставить на въездные ворота датчики препятствия (решил собрать из лазерных указок) и обнаружил, что роллетном блоке управления нет для них входов, а посылать команду на закрытие ворот не зная есть ли препятствие, как-то стремно.

Кроме того на плате есть контакты для кнопочного управления, но логика их работы отлична от кнопки пульта. На плате контакты Open и Close - это разные кнопки и, при нажатии на них при движении створки (как и в случае с пультом) происходит остановка створки.

Теперь не знаю, может правильным будет собрать новый блок управления, …….или подключить датчики препятствия к МДМ через МегаД, ведь если я закрываю ворота с брелока, то я визуально контролтрую пространство перед створкой.

На данный момент комманды на открытие-закрытие ворот посылаю замыканием кнопок пульта.

В общем, хотелось бы услышать советы, наверняка ведь этот путь уже кто-то прошел и не хотелось бы наступать на уже решенные грабли.
2*MegaD328, Система на Raspberry Pi 2
Аватара пользователя
shemnik69
Сообщения: 590
Зарегистрирован: Пн дек 24, 2012 3:01 pm
Откуда: Саратов Saratov
Благодарил (а): 67 раз
Поблагодарили: 63 раза

Re: Управление разспашными воротами Arduino

Сообщение shemnik69 » Пн июл 07, 2014 11:25 am

Как не пытался в растровом формате ..все равно большой объем, давайте указывайте либо "электронку" либо какой еще либо способ доставки..
И еще не совсем по теме.. но наилучший по варианту надежности и простоты, а также и цены, все таки блок на реле (недавно несколько сделали для организации) там сразу от наличия внутри МК, отказались. На реле и проще и надежнее.
И потом если МЕГа у Вас присутствует как элемент согласования сигналов с УД то вообще все упрощается. Сигнальную часть оставляем как есть (т.е связь с центральным блоком УД) а силовую, собранную на реле подключаем через МегаДевайс (как я понял). Получаем независимую по командам систему. Т.е силовая часть отвечает за нижний уровень (пуск. реверс. стоп. и т.д) а Мега преобразует сигналы в команды для УД. Концевые выключатели (ограничители) а также другие желательные страховочные устройства присоединяем как к системе нижнего уровня так и к Меге. как правило концевые выключатели (от пром автоматики) содержат несколько 2-4 контактных пар поэтому сложности быть не должно.
Сама логика проста, "концевик" сработав, контактами на разрыв, отключает двигатель, а контактами на замыкание, дает знак :!: что створа заняла необходимое положение, кроме того, нет проблем от возможных сбоев.
Вот так. Если есть сомнения :?: :?: спрашивайте, схему нарисуем исходя из Ваших условий.. :D
Ответить