детектор движения конвейера
- Войдите на сайт для отправки комментариев
Сб, 03/11/2018 - 22:32
Здравствуйте всем!Прошу новичка сильно не бить,а дать совет.Фабула такова:захотел сделать детектор движения конвейера на датчике Холла,чтобы при остановке или пробуксовке ленты он отключался.Сделал детектор,используя прерывание-работает хорошо.Решил я не использовать прерывание и сделать детектор на 4 канала.Работает,но великовато время реакции,где-то 8-11 с.Повторюсь,я новичок и прошу помощи:может в коде что-то поправить или принципиально иной подход нужен.Заранее благодарен за понимание и помощь.
const int RLY1=12;
const int RLY2=11;
const int RLY3=10;
const int RLY4=9;
const int SENS1=8;
const int SENS2=7;
const int SENS3=6;
const int SENS4=5;
unsigned long durationSENS1;
unsigned long durationSENS2;
unsigned long durationSENS3;
unsigned long durationSENS4;
void setup()
{
pinMode(RLY1,OUTPUT);
pinMode(RLY2,OUTPUT);
pinMode(RLY3,OUTPUT);
pinMode(RLY4,OUTPUT);
pinMode(SENS1,INPUT);
pinMode(SENS2,INPUT);
pinMode(SENS3,INPUT);
pinMode(SENS4,INPUT);
digitalWrite(RLY1,HIGH);
digitalWrite(RLY2,HIGH);
digitalWrite(RLY3,HIGH);
digitalWrite(RLY4,HIGH);
}
void loop()
{
durationSENS1=pulseIn(SENS1,HIGH);
durationSENS1=pulseIn(SENS1,LOW);
if(durationSENS1>>1)
digitalWrite(RLY1,LOW);
else
digitalWrite(RLY1,HIGH);
durationSENS2=pulseIn(SENS2,HIGH);
durationSENS2=pulseIn(SENS2,LOW);
if(durationSENS2>>1)
digitalWrite(RLY2,LOW);
else
digitalWrite(RLY2,HIGH);
durationSENS3=pulseIn(SENS3,HIGH);
durationSENS3=pulseIn(SENS3,LOW);
if(durationSENS3>>1)
digitalWrite(RLY3,LOW);
else
digitalWrite(RLY3,HIGH);
durationSENS4=pulseIn(SENS4,HIGH);
durationSENS4=pulseIn(SENS4,LOW);
if(durationSENS4>>1)
digitalWrite(RLY4,LOW);
else
digitalWrite(RLY4,HIGH);
}
Начните с указания в pulseIn таймаута, потом избавьтесь от этого способа вовсе, почесав голову над "blink без delay". От прерываний отказались, потому что не хватило ног на externalInterrupt? Почитайте про PCINT и сможете навесить их (теоретически) на любые четыре входа)
Если честно, то вы пытаетесь применить код не предназначенный для этого. pulseIn подходит когда нужно обрабатывать всего 1 вход.
Неужели так трудно сделать опрос состояния 4 логических уровней в цикле и при изменении записывать периоды(время прошедшее с последнего изменения), а уже по том сравнивать и проводить другие операции?
Благодарю за разъяснения!Если честно,я понимаю логику процесса опроса датчиков,но не понимаю пока как это реализовать на языке,понятном Ардуине.Если честно,я читаю те 10 книг по теме,которые скачал,и пытаюсь адаптировать хрестоматийные примеры под прикладные задачи.Что-то дописываю,что-то убираю.А прерывание,насколько я понял может обрабатываться только одно?Если есть кураж побыть в роли учителей,буду весьма рад.СПАСИБО!
Если есть кураж побыть в роли учителей,буду весьма рад.
И разумеется с различными вариантами советов.
Начните с указания в pulseIn таймаута, потом избавьтесь от этого способа вовсе, почесав голову над "blink без delay". От прерываний отказались, потому что не хватило ног на externalInterrupt? Почитайте про PCINT и сможете навесить их (теоретически) на любые четыре входа)
Чесание головы над блином без делея ни разу не поможет улучшить работу пульсаин. Это поперечное поведение и применение.
Если у ТС-а все работает хорошо на прерываниях, но задача поставлена обойтись без них, то видимо препод настаивает на освоении режима "захват таймера" (он тут как раз у них недавно стал популярен).
Соответственно, ваши датчики надо вешать на вход ICP таймера (их же недаром 4шт у Мега2560) и разбираться с этим режимом таймера. Он - прост, ежели вчё, и позволяет заменить pulseIn() нормальной неблокирующей работой. И уже ПОТОМ переходить в основном коде на неблокирующее исполнение чере КАК и "блин без делей".
Попобруйте повесить дптчики вместо pulseIn на вход ICP и получить длительности импульсов.
Начните с указания в pulseIn таймаута, потом избавьтесь от этого способа вовсе, почесав голову над "blink без delay". От прерываний отказались, потому что не хватило ног на externalInterrupt? Почитайте про PCINT и сможете навесить их (теоретически) на любые четыре входа)
Чесание головы над блином без делея ни разу не поможет улучшить работу пульсаин.
Я где-то написал, что неблокирующее чтение входов при помощи блинком без делэй следует применить совместно с pulseIn?
"Начните с указания в pulseIn таймаута, потом избавьтесь от этого способа вовсе, почесав голову над "blink без delay"."
Эту мысль можно понять иначе? Поясните подробней в таком разе..
Избавиться от способа замера с pulseIn в пользу блинка без дилэй. А потом уже PCINT и т.д.
Последовательное улучшение с пониманием корня проблемы.
А разве можно избавиться от пульсеин используя "блин без делея"? Он жеж будет ждать конца импульса "до упора" или таймаута в любом разе! Можно СНАЧАЛА уйти от pulseIn() заменив его на измерение по прерываниям, хоть PCINT (но ТС заявил что по прерываниям у него всё работает, хотя в этом коде - не видно "на сколько хорошо"), а уже ПОТОМ переходить на вариации основного кода на "блин без делай". Разве нет?
Но, поскольку у ТС-а "всё работает" по прерываниям, то остается единственный вариант - переход на прерывания от таймеров "по захвату таймера" .. pulseIn() больше заменить нечем. ИМХО конечно, может кто-то знает ещё способы, кроме "прерываний", "захвата таймером" и "в лоб" (pulseIn)..
И ещё замечу: измерение импульса что по прерываниям, что по захвату .. практически одинаковы как по сложности, так и по точности в широком диапазоне (только особо точные измерения лучше по захвату), но ТС-а (или "заказчика") работа "по прерываниям не устроила .. остается только вариант "препода", настаивающего на "захвате таймера". Иного смысла менять "шило на мыло" я не вижу.
P.S. Ну да (дошло) можно конечно "развенуть" сам pulseIn() в неблокирующий цикл "без делея", но .. что это даст ТС-у, если у него уже (как заявлено) есть код "на прерываниях"?
Я полагаю, что у него банально не хватило externalInterrupt-ов в Wiring. В том случае, если не получиться вникнуть в работу МК на уровне регистров, то обретенное понимание причины задержек и простые операции с millis()/micros() позволят решить вопрос в более пристойном виде. Вот и вся моя идея.
А вот такое - вполне возможно. Неплохо было бы, чтобы ТС выложил код "хорошо работающий на прерываниях". Как-то даже забыл, что в Wiring есть "свои" прерывания.. :)
Восхищаюсь я местным населением.
1. никто не спросил у ТС параметры входных импульсов и требования к быстродействию системы, всем всё и так ясно.
2. логичное и простое предложение из #2 игнорируется, вместо него обсуждаются всякие извращения.
Так мы вроде как не штаны ему продаем, чтобы обхватом в талии интересоваться.
Он сообщил все, что хотел, ему ответили какие есть варианты. Все честно на мой взгляд.
Здравствуйте!Благодарю всех неравнодушных за помощь!Немного уточню фабулу.Есть 4 конвейера(это не задача от препода),которые нужно контролировать на предмет "едет-не едет",чтобы при остановке ленты конвейер этот и предыдущие остановились,воизбежание засыпания.Изначально сделал детектор,использовав прерывание.Еще и светодиодную шкалу индикатора скорости туда воткнул(листинг ниже).Но,как я понял из книг,одна плата может обрабатывать одновременно только одно прерывание.То есть,на 4 ленты мне нужно 4 платы.Я замыслил сделать на одной.Сигнал с датчика Холла дискретный,примерно 2 Гц.Всё,что вы пишете читаю как первоклассник,ибо то,что вам очевидно,для меня пока -тёмный лес.Если можно какой-нибудь пример или ссылку на книжку,либо статью,чтобы я понял основное(как,например"блинк без делэй",я не совсем понимаю).Еще раз благодарю всех за помощь и прошу прощения за свою тупость.
const int pinsled[8]={3,4,5,6,7,8,9,10}; int countleds=0; const int RLY=12; volatile int rpmcount=0; int rpm=1; unsigned long lastmillis=0; void setup() { for (int i=0;i<8;i++) { pinMode(pinsled[i],OUTPUT); digitalWrite(pinsled[i],LOW); } attachInterrupt(0,rpm_con,CHANGE); pinMode(RLY,OUTPUT); digitalWrite(RLY,HIGH); } void loop() { if(millis()-lastmillis==1000) { detachInterrupt(0); rpm=rpmcount*2; rpmcount=0; lastmillis=millis(); attachInterrupt(0,rpm_con,CHANGE); if(rpm>>3) { digitalWrite(RLY,LOW); countleds=rpm/6; for(int i=0;i<8;i++) { if(i<countleds) digitalWrite(pinsled[i],HIGH); else digitalWrite(pinsled[i],LOW); } } if(rpm<=1) { digitalWrite(RLY,HIGH); countleds=rpm; for(int i=0;i<8;i++) { digitalWrite(pinsled[i],LOW); } } } } void rpm_con() { rpmcount++; }Здравствуйте!Благодарю всех неравнодушных за помощь!Немного уточню фабулу.Есть 4 конвейера(это не задача от препода),которые нужно контролировать на предмет "едет-не едет",чтобы при остановке ленты конвейер этот и предыдущие остановились,воизбежание засыпания.Изначально сделал детектор,использовав прерывание.Еще и светодиодную шкалу индикатора скорости туда воткнул(листинг ниже).Но,как я понял из книг,одна плата может обрабатывать одновременно только одно прерывание.То есть,на 4 ленты мне нужно 4 платы.Я замыслил сделать на одной.Сигнал с датчика Холла дискретный,примерно 2 Гц.Всё,что вы пишете читаю как первоклассник,ибо то,что вам очевидно,для меня пока -тёмный лес.Если можно какой-нибудь пример или ссылку на книжку,либо статью,чтобы я понял основное(как,например"блинк без делэй",я не совсем понимаю).Еще раз благодарю всех за помощь и прошу прощения за свою тупость.
Что убивает совершенную программу- в нее невозможно что то добавить. Она начинает рассыпаться и глючить. Что у Вас и происходит. Так что теперешний уровень программирования вы исчерпали. Переходите на новый и развивайтесь . Ну или попросите что бы кто-то Вам программу нарисовал за деньги.
ПС Есть 4 конвейера- то это значит у вас должно одновременно работать 4 конечных автомата как минимум с двумя состояниями - движимся или нет.
https://www.arduino.cc/reference/en/language/functions/external-interrup...
Самая простая Ардуина (328-й МК) имеет 2 внешних прерывания через Wiring, но позволяет зацепить для этого все "цифровые" (но обработка сложнее) через PCINT. Если не желаете лезть в дебри - берете мегу и имеете 6 простых прерываний или 5 на Микро Про.
Чтобы не детачить прерывания при чтении volatile - используйте макрос ATOMIC_BLOCK. Но не надо засовывать туда еще и вычисления - просто перекидывайте с volatile переменной во временную и сразу закрывайте блок. Потом уже калькуляции проводите. Так меньше шансов растерять тики от холлов.
СПАСИБО!!!Путь указали,буду пробовать конечный автомат изучать.О результатах буду сообщать.УДАЧИ ВСЕМ!!!
Буду штудировать матчасть.Дождусь "железки" из Китая и буду пробовать.Хочу спросить,а кто такой ТС?Очень надеюсь,что это не какая-то уничижительная аббревиатура.
ТопикСтартер.
http://avrproject.ru/publ/poleznaja_informacija/obrabotka_bolshogo_kolic...
А иногда эта птица даже не страус, а пингвин. Пинать надо долго до воды.
Ой напросишься.))))
ТС-топик стартер или автор темы или "футбольный мяч" который пинают "футболисты"= форумчане что бы забить гол=получить результат. И все потому что человек птица гордая без пинков не взлетает. А иногда эта птица даже не страус, а пингвин. Пинать надо долго до воды.
Пух, ты такие вещества сам покупаешь, или тебе гасударство выдаёт?