Помогите со скетчом

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем ivan221, 12 окт 2015.

  1. ivan221

    ivan221 Нуб

    Подскажите, как сделать чтобы коды кнопок были записаны изначально, а не устанавливались при включении,и как сделать чтобы можно было не удерживать кнопку а, и оно работало и при повторном нажатии выключалась, скетч прилагается,брал отсюда:http://wiki.amperka.ru/projects:irjalousie
    Заранее спасибо



    Код (C++):
    // Мы будем использовать библиотеки для работы с ИК и с сервоприводами
    #include <IRremote.h>
    #include <Servo.h>
    // Определим номера используемых пинов
    #define RECV_PIN   2
    #define SERV_PIN   3
    #define BUZZER_PIN 4
    // Определим тип «действие»
    enum Command
    {
      CMD_NONE = 0,
      CMD_OPEN = 1,
      CMD_CLOSE = 2
    };
    // Создадим объект для пользования ИК-библиотекой
    IRrecv irrecv(RECV_PIN);
    decode_results results;
    // Создадим переменные, которые будут хранить коды кнопок пульта
    unsigned long codeOpen = 0;
    unsigned long codeClose = 0;
    // Определим переменные для хранения полученной команды и времени её получения
    unsigned long cmdStartTime;
    unsigned char cmd;
    // Создадим объект для управления сервоприводом постоянного вращения
    Servo srv;
    // Из-за особенностей реализации нельзя использовать библиотеку IRremote
    // вместе с функцией beep (они используют одно и тоже прерывание). Чтобы
    // справиться с этой бедой мы, не используя прерываний, реализовали свою версию
    // функции beep.
    void beeep(int pin, int freq, unsigned long duration)
    {
      unsigned long start;
      // Переводит пин в выход
      pinMode(pin, OUTPUT);
      // Запоминаем момент начала выполнения
      start = millis();
      // В течение duration миллисекунд пищим
      while (millis() - start < duration) {
        // Частота писка определяется паузами между изменениями состояния пина
        digitalWrite(pin, HIGH);
        delay(1000/freq/2);
        digitalWrite(pin, LOW);
        delay(1000/freq/2);
      }
      // На всякий случай переводит пин обратно в режим чтения
      pinMode(pin, INPUT_PULLUP);
    }
    // Функция "обучения" устройства (запоминания кодов кнопок открытия/закрытия)
    void learn(void)
    {
      // Ждём получения корректной команды
      // (условие окончания цикла находится в его теле)
      while (true) {
        if (irrecv.decode(&results)) {
          // Получили какой-то код. Сообщим библиотеке, что мы обработали событие.
          irrecv.resume();
          // Пропускаем коды короче 16 бит (наши пульты давали коды 16 или 32 бита,
          // остальные считаем ошибочными)
          if (results.bits >= 16) {
            // Сохраняем пришедший код как код на открытие
            codeOpen = results.value;
            // В знак подтверждения пикаем
            beeep(BUZZER_PIN, 500, 100);
            break;
          }
          // Ждём 100 мс, чтобы пропустить случайный приём пачки одинаковых кодов
          delay(100);
        }
      }
      // На всякий случай ждём 200 мс (пользователь явно быстрее не будет на кнопки
      // нажимать)
      delay(200);
      // Таким же методом принимаем второй код (на закрытие)
      while (true) {
        if (irrecv.decode(&results)) {
          irrecv.resume();
          if (results.bits >= 16 && results.value != codeOpen) {
            codeClose = results.value;
            beeep(BUZZER_PIN, 500, 100);
            break;
          }
          delay(100);
        }
      }
    }
    // Функция инициализации устройства
    void setup(void)
    {
      // Запускаем библиотеку IRRemote
      irrecv.enableIRIn();
      // Инициализируем команду (не было команды)
      cmd = CMD_NONE;
      // Сообщаем пользователю, что мы запустились тройным пиком
      beeep(BUZZER_PIN, 500, 100); delay(100);
      beeep(BUZZER_PIN, 500, 100); delay(100);
      beeep(BUZZER_PIN, 500, 100); delay(100);
      // Запускаем процедуру "обучения"
      learn();
      // Пищим в знак окончания процедуры обучения
      beeep(BUZZER_PIN, 2000, 1000);
    }
    // Пуск сервопривода постоянного вращения
    void start(void)
    {
      srv.attach(SERV_PIN);
      srv.write(cmd == CMD_OPEN ? 0 : 120);
    }
    // Остановка мотора
    void stop(void)
    {
      // Самый простой способ остановить серву постоянного вращения — отсоединиться
      // от неё
      srv.detach();
    }
    // Рабочий цикл программы
    void loop(void)
    {
      unsigned long codeValue;
      int codeLen;
      // Запускаем сканирование команды по ИК
      if (irrecv.decode(&results)) {
        // Сообщаем библиотеке, что приняли её информацию
        irrecv.resume();
        // Получаем код и длину кода
        codeValue = results.value;
        codeLen = results.bits;
        // Отсеиваем неправильные коды
        if (codeLen >= 16) {
          // Если пришёл код на открытие и на данный момент привод не крутится в
          // противоположную сторону, включаем открытие.
          if (codeValue == codeOpen && cmd != CMD_CLOSE) {
            cmd = CMD_OPEN;
            cmdStartTime = millis();
            start();
          } else if (codeValue == codeClose && cmd != CMD_OPEN) {
            // Если пришёл код на закрытие и на данный момент привод не крутится в
            // противоположную сторону, включаем открытие.
            cmd = CMD_CLOSE;
            cmdStartTime = millis();
            start();
          }
          // Если приходит команда на резкую смену направления вращения — спасаем
          // серву от смерти, игнорируя такую плохую команду.
        } else if (codeLen == 0 && (cmd == CMD_OPEN || cmd == CMD_CLOSE)) {
          // Некоторые пульты при удержании кнопки в нажатом состоянии посылают код
          // нулевой длины. Будем считать это повтором команды.
          cmdStartTime = millis();
        }
        delay(100);
      }
      // Здесь мы выключаем привод через 500 мс после последней полученной команды
      if (cmd == CMD_OPEN || cmd == CMD_CLOSE) {
        if (millis() - cmdStartTime > 500) {
          cmd = CMD_NONE;
          stop();
          // Дождёмся полной остановки привода
          delay(1000);
        }
      }
    }


    Извините если этот вопрос показался вам глупым, я только недавно узнал о этой плате и еще плохо разобрался
     
    Последнее редактирование: 12 окт 2015
  2. Mestniy

    Mestniy Гуру

    Что-бы поставить первоначальное значение, нужно перед setup, присвоить значение кнопки 0 или 1 (off или on).
    А вот как сделать еденичное нажатие кнопки:

     
  3. Mestniy

    Mestniy Гуру

    Разобрались?
     
  4. Megakoteyka

    Megakoteyka Оракул Модератор

    Из функции обучения сделайте отдельный скетч - пускай он просто выводит в монитор коды принятых команд.
    В основном скетче выбросьте функцию обучения, а кодами команд проинициализируйте переменные:
    Код (C++):
    const long codeOpen = код_команды_1;
    const long codeClose = код_команды_2;
     
  5. Megakoteyka

    Megakoteyka Оракул Модератор

    Сперва исходник прочитайте, потом советы давайте.
     
    Mestniy нравится это.
  6. ivan221

    ivan221 Нуб

    Спасибо,разобрался