Помогите Уважаемые гуру. HELP.
- Войдите на сайт для отправки комментариев
Вс, 23/12/2012 - 23:23
Доброго времени суток гуру. Пытаюсь разобраться в программирование arduino да и вообще контроллеров awr. Но пока как-то туго получается... :(( . Значит есть простой алгоритм - есть 2 входных аналоговых напряжения batt и vpower которые мы должны контролировать и один цифровой входной сигнал acc. Также 2 выхода - MOSFET1,MOSFET2.
- Проверяем напряжение batt - если оно меньше чем 2.5в более чем 30сек., то на включение кнопки acc не реагируем и проверяем наличие напряжения vpower. Если vpower меньше 2.5в длительное время ,то ничего не делаем (подразумеваем что MOSFET2- выключен,если нет ,то выключаем).Если vpower больше чем 2.5в (тоесть как минимум включен MOSFET2),то включаем MOSFET1 на 1сек. и контролируем напряжение vpower. Eсли через 120 сек напряжение не пропало ,то выключаем MOSFET2. Если пропало то MOSFET2 выключаем через 10сек после того как пропало напряжение vpower.
- Проверяем напряжение batt – если оно больше чем 2.5в,то готовы реагировать на включение/выключение кнопки acc . При наличии логической единицы на кнопки acc , при том что batt больше 2.5в и отсутствие напряжения vpower ,при том что MOSFET2 включен ,если выключен то включаем MOSFET2 , ждем 3 сек.если MOSFET2 включен ,то не ждем 3 сек. асразу включаем MOSFET1 На 1сек ,через 5сек проверяем включение напряжения vpower. Vpower должен появится.
- При выключении acc ждем 5минут и если acc не появилось ,то включаем MOSFET1 на 1 сек и контролируем снятие напряжения vpower если снялось то ok,если не снялось через 120 сек то выключаем MOSFET2.
//----------------------------------------- //- (пины) ардуино - //----------------------------------------- int batt=A0; //аналоговый вход(пин) контроля напряжения борт сети int vpower=A1; // аналоговый вход(пин) контроля напряжения материнки int acc=0; // аналоговый вход(пин2) прерывание 0 int MOSFET1=6; // цыфровой выход(пин) ключа1 int MOSFET2=13; // цыфровой выход(пин) ключа2 void setup() { pinMode(MOSFET1,OUTPUT); pinMode(MOSFET2,OUTPUT); attachInterrupt(acc, DChi, RISING); // прерывание attachInterrupt(acc, DClow, FALLING); // прерывание } void DChi() { } void DClow() { } void loop() { int battValue=analogRead(batt); // считываем и присваеваем значения напряжения if (battValue<800 ) //Если напряжение питания ниже примерно 2.5v то- battValue = LOW; // =0 else if (battValue>810) //Если напряжение питания больше примерно 2.5v то- battValue = HIGH; // =1 int vpowerValue=analogRead(vpower); // считываем и присваеваем значения напряжения if (vpowerValue<800) //Если напряжение питания ниже примерно 2.5v то- vpowerValue = LOW; // =0 else if (vpowerValue>810) //Если напряжение питания больше примерно 2.5v то- vpowerValue = HIGH; // =1 }
Чет не могу вкурить как организовать на С. Я работаю на PLC контроллерах на языке РКС,там все просто... А здесь.... Наверное старею. GGG. Если кто может направте на путь истинный с подробными каментариями,как можно код написать данного алгоритма и какие есть варианты. Сильно не пинайте - всего 3 дня вожусь с ардуиной... Спасибо.
Аналоговые входы 10 бит, т.е. значения от 0 до 1023, т.е. 0 в до 5 в. 800 - это не 2.5 в.
Гистерезис - прекрасно. Я про сравнение 800 - 810.
Чтобы определить длительность превышения напряжения фиксируйте моменты измерения времени с помощью millis(), потом сравнивайте текущее время с сохраненным.
Прерывания на кнопку.. можно, но посмотрите примеры, что бы бороться с дребезгом.
Использование пина 13 позволяет видеть его состояние, поскольку на этот пин подключен светодиод на плате. Можно это увидеть, если запустить пример Blink.
800 эт просто пример... с дребезгом не проблема (rc ) цепочка или триггер шмитта,большого быстродействия не надо.. светодиодом моргал пару дней назад :)). Немного не догоняю с прерываниями и как использовть millis если надо разные задержски в разном месте?
А что с прерываниями? В них нужно просто изменить состояние переменной, которая хранит состояние кнопки. Плюс обработка должна быть как можно короче.
По поводу millis, нам нужно знать, как долго есть превышение напряжения, значит нужно завести переменную (хотя я бы сделал структуру) на каждый вход, в ней запоминать время начала превышения напряжения. Аналогично по снижению. Аналогично для каждого входа.
После того, как это сделано, проверяем наступление событий.
Еще, переменные, используемые в прерываниях, нужно объявить volatile. Почитайте про это.
Не всегда. Это в случае елси дуина сама питается точно 5v-вольтами, а если там просело до 4.3 то и 1023 будет означать 4.3. Вообщем 1023 означает "100% питания камня".
В даташитах можно найти фокус с включением внутренего опорного напряжения, где-то на форуме мелькала тема, как контролировать качество питания самой дуины.
В частных случаях - конечно так. Согласен, надо было написать 100% питания. Тем более вчера мерял, у меня 4,96В или около того.
Что значит зделал бы структуру ? Можно на примере как работать с millis и с прерыванием ?
А зачем вам тут прерывания? Тем более, с аналоговым пином оно вам не сильно поможет.
attachInterrupt работает со вторым и третим цифровыми пинами.
Почитайте про attachInterrupt в документации.
Вообщем "прерывания" - в сторону.
Что вы, в стартовом скетче, фактически и сделали.
Просто крутимся в loop(), читаем аналоговые пины, если у них какие-то нужные нам значения - что-нибудь делаем
Меняем переменную-флаг, запоминаем время "когда это произошло" (функция millis() - возвращается текущие время в миллисекундах), вызваем какие-то "функции обработчи".
А зачем вам тут прерывания? Тем более, с аналоговым пином оно вам не сильно поможет.
attachInterrupt работает со вторым и третим цифровыми пинами.
Почитайте про attachInterrupt в документации.
Вообщем "прерывания" - в сторону.
Что вы, в стартовом скетче, фактически и сделали.
Просто крутимся в loop(), читаем аналоговые пины, если у них какие-то нужные нам значения - что-нибудь делаем
Меняем переменную-флаг, запоминаем время "когда это произошло" (функция millis() - возвращается текущие время в миллисекундах), вызваем какие-то "функции обработчи".
С millis немного догнал... Спасибо . Там опечатка - это 2й цифровой пин. Просто по условию задачи мне надо однократно реагиравать на появление либо снятия сигнала acc . Вот и думал что на прерывании по фронту и по спаду... Можно как то по другому организовать?
С millis немного догнал... Спасибо . Там опечатка - это 2й цифровой пин. Просто по условию задачи мне надо однократно реагиравать на появление либо снятия сигнала acc . Вот и думал что на прерывании по фронту и по спаду... Можно как то по другому организовать?
Можно, что мешает?
Заведите себе переменную "прошлое состояние" пина.
В каждом проходе loop смотрите на пин. Если прошлое 0, а текущие 1 - значит это "фронт", если прошлой 1 а текущие 0 - значит спад.
Если прошлое и текущие равны - значит ничего не изменилось.
Ну и в конце loop, запомнить "текущие состояние" в переменную "прошлое" (для будущего прохода).
Примерно так:
Спасибо . Сейчас буду мозговать . :)
Спасибо . Сейчас буду мозговать . :)
Это самое трудное (без сарказма). Причем, боюсь, ваш опыт будет скорее мешать чем помогать. Так как тут нужно именно "перестроить мышление".
Если не ошибаюсь, то на PLC у вас все было аналогово-паралельно, а тут все "в один поток, пошагово-дискретно". Соотсвественно и задача в голове "декомпозируется" немного по другим паттернам.
Здесь попал в точку - мозг сопротивляется до последнего...
Я больше по железу причем профессионально. На логике разработать такую схему - несколько минут, написать программу под PLC –тоже быстро, но С+ ….Пока мой мозг очень туго воспринемает..
http://any-book.org/download/48176.files/image100.jpg
http://www.indusoft.ru/files/articles/Pikad_durus6.jpg
Это ,так из простых примеров..
Вот и рошу помощи ,немножко разживать... Вообще это управление carpc блока питания ,включение-выключение мамки и т.д.
А вообще, если я правильно понял PLC & PKC, то это автоматы. Почему бы здесь не сделать точно так же?
Спроектировать машину состояний/переходов (МСП) и т.п. Потом это запрограммировать.
МСП ты спроектируешь, с программированием - помогу, если нужно.
Я попробовал, набросал кусочек проги по простому, но без МСП достаточно муторно/мутно и всё плохо получается :) потому дальше не стал маяться.
Или я не правильно понял про PLC & PKC?
PLC - Программируемый логический контроллер. К примеру http://simatek.by/assets/images/slides/4.jpg http://www.pjboner.com/wp-content/uploads/wpsc/product_images/rx3i.jpg У них может быть 200входов + 200 выходов ,аналоговые ,цифровые,шим,поддержка куча разных протоколов связи между собой и т.д.
Для управления разного промышленного и не только оборудования http://www.neoteo.com/images/Cache/C1B3x590y590.jpg ( в принцепе ограничения применения нету...)
LAD- он же РКС (язык технологического программирования), оперирующий типовыми элементами Релейно-Контактной Схемы (логики) и автоуправления. Имеет эффективные средства для программирования математических функций.
FBD-он же ФДБ – язык функционально-блоковых диаграмм. Обеспечивает создание исходного текста при помощи графического редактора с использованием графических образов функциональных блоков. Установка взаимосвязей между блоками осуществляется простым указанием их входов/выходов.
Алгоритм выключения при разряженном аккумуляторе написал,но как написать тоже самое на millis ?
Я свой исходник приложу, но он сырой и вообще не знаю как работает, только для примера и он не законченный.
Диаграмма состояний - это классно. От этого и нужно плясать.
Главное в следующем, loop - это можно рассматривать как бесконечный цикл (условно, разумеется, потому что при выходе из loop еще кое что происходит). Поэтому нужно в каждом цикле проверять состояния сенсоров/датчиков, считать время состояния сенсоров (это уже есть) и управлять исполнительными устройствами. В настоящем варианте нет именно обработки задержек включения мосфетов и т.п. Остальное вроде должно работать. Все пины в начале программы описаны, задержки в середине исходника, возможно где то не совсем такие, какие надо. Но сегодня уже спать нужно :) Итак из-за Ардуины недосып, который у меня уже хронический, перерос даже не знаю во что, сон каждый день по 5,5 часов. Какой гад придумал Ардуино! :)
Возможно для тебя этот код будет сложноватым, чтобы с этим разбираться, потому сильно не заморачивайся, хотя посмотреть - посмотри. Если что объясню. А может и народ подтянется, кому интересно. Да, комментарии в коде есть, так что может быть будет проще разбираться.
Хотя лично я бы сделал здесь автомат Мура или около того, тогда было бы совсем хорошо. А он здесь напрашивается. Кстати говоря, он напрашивается и во множестве других задач.
UPD: Да, никаких delay в коде не нужно делать, здесь всё основано на том, что прошло какое то время с моемнта срабатывания сенсора, аналогично нужно сделать, при включении мосфета1, зафискировать время и также как для сенсоров, считать, как долго он включен, потом переключить второй мосфет или что там по алгоритму. Кстати, совсем немного прогу не доделал, но теперь уже только в выходные.
Без delay() нужно почитать вот этот пример:
http://arduino.ru/tutorials/BlinkWithoutDelay
Или вот еще примерчик накорябал. Включаем диод по нажатию кнопки (или какому-то другому вашему условию) на 5 sec без delay()