Помогите написать скетч!

Тема в разделе "Закажу проект", создана пользователем Immolatus, 2 янв 2015.

  1. Immolatus

    Immolatus Нуб

    Что есть:
    1. Arduino Uno
    2. Модель железной дороги
    3. На ней железнодорожный переезд (шлагбаум), управляемый серво
    4. Локомотив с магнитом
    5. Два датчика Холла (http://amperka.ru/product/troyka-hall-sensor)
    6. Два геркона

    Что надо:
    Организовать закрытие шлагбаума при подъезде к нему локомотива и открытие после того, как локомотив проедет переезд. При этом шлагбаум должен срабатывать при проезде локомотива как в одну, так и в другую сторону. Желательно использовать герконы, так как имеющиеся датчики Холла крупноваты для их размещения под рельсами.
    Помогите написать скетч!
    Заранее благодарю!
     
  2. Sanchogus

    Sanchogus Нерд

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

    Вот так примерно:

    Код (Text):
    #include <Servo.h>

    #define SENS1 A0    //датчики типо тут
    #define SENS2 A1    //но у меня тупо кнопки...

    #define SERVA 3    //пин сервы

    #define CLOSE 0    //угол в котором переезд "закрыт" 0 или 180
    #define FORCED_ON 20000 //при случайном включении или отказе второго датчика откроет переезд через ххххх milliseconds

    Servo servo1;  //объявили серву

    void setup()
    {
      pinMode(SENS1, INPUT);
      pinMode(SENS2, INPUT);
      servo1.attach(SERVA); //привязали серву к пину
      servo1.write(90);  //поднят изначально
    }


    boolean firstsens(void)  //обрабатываем сигналы с "датчиков"
    {                        //если датчик активирован возвращаем true, иначе false
      int x = analogRead(SENS1);
      if (x >= 500)
      {
        return true;
      }
      else
      {
        return false;
      }
    }

    boolean secondsens(void)  //обрабатываем сигналы с "датчиков"
    {                        //если датчик активирован возвращаем true, иначе false
      int x = analogRead(SENS2);
      if (x >= 500)
      {
        return true;
      }
      else
      {
        return false;
      }
    }

    void loop()
    {
    /*
      firstsens();    - проверить 1й датчик
      secondsens();  - проверить 2й датчик
    */

    unsigned long int time1; //время от начала срабатывания датчика для принудительного открытия в случае ошибок

    //наиболее вероятные случаи:

    /////////////////

    //сработал 1

    if (firstsens())
      {
        time1 = millis();  //фиксируем время
        while ((millis() - time1) <= FORCED_ON)  //пока не настало время принудительного открытия
        {
          servo1.write(CLOSE);    //переезд закрыт
          if (secondsens())      // если активирован другой датчик
          {
            servo1.write(90);    //открыть переезд
            break;                //завершить цикл досрочно
          }
        }
        servo1.write(90);    //открыть переезд принудительно
        delay(500);            //ждем, дабы не было ложной сработки второго датчика
      }

    ////////////

    //сработал 2

    if (secondsens())          //аналогично случаю 1
      {
        time1 = millis();
        while ((millis() - time1) <= FORCED_ON)
        {
          servo1.write(CLOSE);
          if (firstsens())
          {
            servo1.write(90);
            break;
          }
        }
        servo1.write(90);    //открыть переезд принудительно
        delay(500);
      }

    }
    Только было бы неплохо переполнение таймера еще рассмотреть)
     
    Последнее редактирование: 3 янв 2015
  3. Immolatus

    Immolatus Нуб

    Спасибо большое!
    Завтра попробую, обязательно отпишусь.
     
  4. Immolatus

    Immolatus Нуб

    Если не ошибаюсь, схема подключения должна быть такая:?
    Вместо тактовых кнопок - герконы 2015-01-03 21-09-11 Скриншот экрана.png
     
  5. vvr

    vvr Инженерище

  6. Sanchogus

    Sanchogus Нерд

    Ну у меня кнопки еще были притянуты к земле стягивающим резистором, для уменьшения наводок. Кнопки по умолчанию выдают сигнал 0 а, по нажатии +5 В.
    http://wiki.amperka.ru/конспект-arduino:кнопка


    +у сервы конденсаторы парралельно стоят для сглаживания пульсаций.

    Примерно такое вышло

    [​IMG]

    По подключению герконов - уже сами определяете при каких значениях на А0 и А1 у них срабатывание и соответственно возможно внесение корректировок в функции.
     
    Последнее редактирование: 4 янв 2015
  7. vvr

    vvr Инженерище

    Наверно только сгоревшая дуня заставляет некоторых читать как серву подключать:D
     
  8. Sanchogus

    Sanchogus Нерд

    Под рукой нет лишних источников :(
    Конденсаторов побольше понатыкать и норм. :D
     
  9. Immolatus

    Immolatus Нуб

    Братцы, спасибо!
    Все работает!

    Вот только не понял, что эта строка делает: if (x >= 500)
     
  10. vvr

    vvr Инженерище

    х - читаются значения с датчиков(ваших герконов)
    если значение х больше или равно 500 - это значит сработал
     
  11. Immolatus

    Immolatus Нуб

  12. Immolatus

    Immolatus Нуб

    А вот еще вопрос.
    Можно ли на одну Ардуину прописать еще две аналогичных программы. Ну типа еще один переезд, и для открытия ворот депо при подъезде к нему локомотива. Я так понимаю, что наличие свободных входов на плате это позволяет. Сервы буду запитывать от отдельного источника питания.
     
  13. geher

    geher Гуру

    Программа будет в любом случае одна. Просто нужно будет предусмотреть реакцию на все датчики и избавиться от циклов внутри loop, чтобы обеспечить одновременную реакцию на разные датчики.
    Впрочем, если поезд по дороге шатается только один, а объекты разнесены по дороге, то можно обойтись и без избавления от циклов, поскольку поезд не сможет оказаться возле какого-то объекта, пока находится возле другого.
    Если же поездов более одного, или объекты рядом, то придется делать что-то вроде такого:

    Код (Text):

    //  открыто
    # define OS_OPEN 0
    // закрыто, поезд подъезжает со стороны первого датчика
    # define OS_CLOSE1 1
    // закрыто поезд подъезжает со стороны второго датчика
    # define OS_CLOSE2 2
    // Состояние первого объекта (переезда)
    int object_1_state=OS_OPEN;
    ; //время от начала срабатывания датчика для принудительного открытия в случае ошибок
    unsigned long int object_1_time
    void loop()
    {
    /*
      firstsens();    - проверить 1й датчик
      secondsens();  - проверить 2й датчик
    */


    //наиболее вероятные случаи:

    /////////////////

    switch(object_1_state){
       case OS_OPEN: //было открыто
           if (firstsens()) // сработал первый
           {
                object_1_time=millis(); //фиксируем время срабатывания
                object_1_state=OS_CLOSE1; //Переходим в состояние "закрыто по датчику 1"
                servo1.write(CLOSE);    //переезд закрыт
           }
          else
           if (secondsens()) // сработал второй
           {
                object_1_time=millis(); //фиксируем время срабатывания
                object_1_state=OS_CLOSE2; //Переходим в состояние "закрыто по датчику 2"
                servo1.write(CLOSE);    //переезд закрыт
           }  
          break;
       case OS_CLOSE1:
          if (((millis() - object_1_time) <= FORCED_ON)||secondsens()) //время прошло или поезд прошел и второй датчик
          {
               servo1.write(90);    //открыть переезд
               object_1_state=OS_OPEN; // состояние - открыто
          }
          else
          {
                servo1.write(CLOSE);    //переезд закрыт состояние не меняется
          }
          break;
       case OS_CLOSE2:
          if (((millis() - object_1_time) <= FORCED_ON)||firstsens()) //время прошло или поезд прошел и первый датчик
          {
               servo1.write(90);    //открыть переезд
               object_1_state=OS_OPEN; // состояние - открыто
          }
          else
          {
                servo1.write(CLOSE);    //переезд закрыт состояние не меняется
          }
          break;
     } //свитч по первому объекту (переезду)
      // свитчи по состояниям других объектов
      .....
    }
     
    Код не проверял. Но принцип вроде должен быть понятен
     
  14. Immolatus

    Immolatus Нуб

    Спасибо большое, разберусь.
    Поездов пока три :)