Что есть: 1. Arduino Uno 2. Модель железной дороги 3. На ней железнодорожный переезд (шлагбаум), управляемый серво 4. Локомотив с магнитом 5. Два датчика Холла (http://amperka.ru/product/troyka-hall-sensor) 6. Два геркона Что надо: Организовать закрытие шлагбаума при подъезде к нему локомотива и открытие после того, как локомотив проедет переезд. При этом шлагбаум должен срабатывать при проезде локомотива как в одну, так и в другую сторону. Желательно использовать герконы, так как имеющиеся датчики Холла крупноваты для их размещения под рельсами. Помогите написать скетч! Заранее благодарю!
Ну вот немного упоротого кода набросал, как я понял. Правда вместо датчиков у меня пара кнопок. Но их нажатие описано в функциях, возвращающих активировался/не активировался, которые можно будет переписать под конкретный датчик. Вот так примерно: Код (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); } } Только было бы неплохо переполнение таймера еще рассмотреть)
Почитайте http://wiki.amperka.ru/конспект-arduino:кнопка ПРАВИЛЬНО ВСЕГДА подключать серву к отдельному источнику питания с общей землёй с ардуиной .
Ну у меня кнопки еще были притянуты к земле стягивающим резистором, для уменьшения наводок. Кнопки по умолчанию выдают сигнал 0 а, по нажатии +5 В. http://wiki.amperka.ru/конспект-arduino:кнопка +у сервы конденсаторы парралельно стоят для сглаживания пульсаций. Примерно такое вышло По подключению герконов - уже сами определяете при каких значениях на А0 и А1 у них срабатывание и соответственно возможно внесение корректировок в функции.
х - читаются значения с датчиков(ваших герконов) если значение х больше или равно 500 - это значит сработал
А вот еще вопрос. Можно ли на одну Ардуину прописать еще две аналогичных программы. Ну типа еще один переезд, и для открытия ворот депо при подъезде к нему локомотива. Я так понимаю, что наличие свободных входов на плате это позволяет. Сервы буду запитывать от отдельного источника питания.
Программа будет в любом случае одна. Просто нужно будет предусмотреть реакцию на все датчики и избавиться от циклов внутри 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; } //свитч по первому объекту (переезду) // свитчи по состояниям других объектов ..... } Код не проверял. Но принцип вроде должен быть понятен