Сигнал определенной длины на выходе, при входящем сигнале HIGH/
- Войдите на сайт для отправки комментариев
Втр, 17/07/2018 - 18:43
Здравствуйте!!! Не судите строго, ибо новичок... Нужно получить сигнал длиной 300 мкс на выходе, при входящем сигнале.
Есть двигатель, к нему подключены цифровые датчики Холла (3 шт) - это будут входные сигналы. При вращении двигателя, в каждую единицу времени на входной пин (2,, 3, 4) поступает сигнал HIGH, нужно при входном HIGH сформировать сигнал длиной 300 мкс и затем отключиться до следующего сигнала HIGH. В моем искетче я пытаюсь сделать это для одного из входных сигналов, потом повторить его и для других 2. Я Пытался сделать их с помощью delayMicroseconds, но тщетно. Посидев в форумах я пришел к тому что его надо делать через таймер. но реализовать его так и не получается.
#define button 2 #define button2 3 #define led 5 #define led2 6 #define delayTime 300 int prevValue = 0; int prevValue2 = 0; long previousMicros = 0; void setup() { pinMode(led, OUTPUT); pinMode(led2, OUTPUT); pinMode(button, INPUT); pinMode(button2, INPUT); } void loop() { if (prevValue == LOW && digitalRead(button) == HIGH) { unsigned long currentMicros = micros(); if (currentMicros - previousMicros < 300) { previousMicros = currentMicros; digitalWrite(led, HIGH); //digitalWrite(led, HIGH); //delayMicroseconds(1000); //digitalWrite(led, LOW); //delayMicroseconds(2); //digitalWrite(led2, LOW); prevValue = LOW; } } } //if ((prevValue2 == LOW) && (digitalRead(button2) == HIGH)) //{ //digitalWrite(led2, HIGH); //delayMicroseconds(100); //digitalWrite(led2, LOW); //delayMicroseconds(2); //delayMicroseconds(2000); //prevValue2= LOW; //} //}
А что не так с delayMicroseconds или с micros? В чём проблема-то?
Двигатель крутится примерно 5000 об/мин, при 3 даттчиках холла которые установлены относительно друг от друга в 120 градусах, идет быстрый опрос. Думаю из-за задержек delayMicroseconds() или неправильного подбора
42
digitalWrite(led2, LOW);
43
delayMicroseconds(2000);
получается "наскок" , т.е. когда программе нужно опрашивать пин 3 для второго датчика, она еще в задерже delayMicroseconds(2000); Это мое объяснение всему этому.
Вот и я пытаюсь задать через таймер, чтобы в таймере задать время выходного сигнала, а потом сразу выключать его, чтобы не было задержек
Вот и я пытаюсь задать через таймер, чтобы в таймере задать время выходного сигнала, а потом сразу выключать его, чтобы не было задержек
Ничего не понял. Где пытаетесь? Почему нет кода с таймером?
в этом случае он постоянно горит в HIGH.
и правильно делает !
в какой строке вы его в LOW уводите ?
внимательно на 28 строку взгляните
может таймер нужно вынести перед
if (prevValue == LOW && digitalRead(button) == HIGH)?
какой таймер ? я вижу вы и представления не имеете что такое таймер и как с ним работать.
про 28 строку я имел ввиду переменную previousMicros.
да если бы я все знал, вряд ли писал в форумах. Наверное форумы для этого и созданы, чтобы помогать друг другу, а не упрекать человека что он чего-то не знает. ))
вы думаете, наобум вставляя переменные и фукции, заработает ? нет !
я вам намекал что условие в 28 строке у вас не сработает ни разу !
потому что previousMicros не проинациализирована должным образом.
и это только первый "косяк".
Фо́рум (лат. forum — арх. преддверие гробницы; площадка в давильне для подлежащего обработке винограда; рыночная площадь, городской рынок; торжище, центральная площадь):
Форум (площадь) — типология общественного пространства в древнеримском градостроительстве; центральная городская площадь, где проходила городская жизнь, заключались сделки, велись переговоры.
Из вики. Определение. Где тут слова о ПОМОЩИ? И что понимать под помощью? Написать за вас программу? Или хватит подсказок? Например у вас 3 фазы и казалось бы должны быть три переменные которым присваивается значение времени при появлении сигнала на соответствующем пине и поднимается выход. Проверять три раза время и если где-то оно истекло выход снимать. Но если входной сигнал будет длиннее 300 мс что произойдёт? А если полный цикл будем меньше 900 мс что будет? Как избежать таких ситуаций?
Наверное форумы для этого и созданы, чтобы помогать
Это Вы так думаете. На самом же деле жизнь устроена по-другому. Вот недавно такому как Вы давали вот эту ссылку. Там в третьем абзаце чётко и понятно написано, что на самом деле (а не в Вашем воображении) происходит, когда человек заходит на форум и требует написать ему код.
А что касается упрёков, так Вам сначала сказали "посмотрите на 28-ю" строку. Вы, вместо того, чтобы посмотреть и решить проблему (или хотя бы спросить "что с ней не так?") начали постить какие-то другие коды и возмущаться. что Вам не помогли. А решение Вам дали - Вы его проигнорировали.
Регулятор BLDC мотора на датчиках Холла - ТАК не делается. В сети полно готовых прошивок для мег, но они все "на ассемблере" .. догадаетесь "почему"? :)
В целом, не майтесь. купите готовый контроллер мотора - это дешевле и проще.
я Вас понял....
посмотрите пожалуйста этот код. Выходной сигнал появился, но он никак не реагирует на мою переменную delayTime(длительность выходного сигнала), просто выходной сигнал в точности повторяет входной.
Может так
посмотрите пожалуйста этот код. Выходной сигнал появился, но он никак не реагирует на мою переменную delayTime(длительность выходного сигнала), просто выходной сигнал в точности повторяет входной.
реагирует, просто вы не видите погасание диода на единицы микросекунд.
оооо получилось. Спасибо огромное всем!!!
я на осциллографе смотрю. видно))
Чуть подправил
Давайте сначала малость ускорим:
Строка 22 if (prevValue == LOW && (PIND&B00000100==B00000100))
Строка 24 PORTD!=B00100000
Строка 30 ....
Строка 32 ....
Строка 34 .... не нужна нулите в 32
Если время между входными сигналами заведомо больше 300мс, то можно уменьшить количество проверок и действовать по следующему алгоритму:
1. При поступлении сигнала включаем выход и считываем значение времени
2. При прохождении 300мс выключаем выход.
По хорошему - это будет работать и при интервалах входных сигналов менее 300мс. Просто выход не будет выключаться.
Где-то так
Если время между входными сигналами заведомо больше 300мс, то можно уменьшить количество проверок и действовать по следующему алгоритму:
1. При поступлении сигнала включаем выход и считываем значение времени
2. При прохождении 300мс выключаем выход.
По хорошему - это будет работать и при интервалах входных сигналов менее 300мс. Просто выход не будет выключаться.
Где-то так
выход здесь включается при нажатии на кнопку и и отключается через delayTime после отпускания ея.
Судя по программе delayTime будет осчитываться от момента когда button упадёт в LOW? А если он милисекунд 200 продержится, то на выходе импульс будет 300+200 = 500 мс?
Судя по программе delayTime будет осчитываться от момента когда button упадёт в LOW? А если он милисекунд 200 продержится, то на выходе импульс будет 300+200 = 500 мс?
Уел :)
Правда атор поста не указывал, по какому фронту начинать отсчет и я принял время прохождения датчика несущественным. Но можно ковырнуть и так:
Согласен - будет срабатывать как попало, но тогда вся эта шняга смысла не имеет.
Кстати можно еще ускорить для более точного определения интервала, убрав операцию чтения во время подсчета времени:
Никого я не ел. Это ж элементарная логика из стартового сообщения: нужно при входном HIGH сформировать сигнал длиной 300 мкс...
А теперь ещё два таких же блока для ещё двух входов и что будет, если длительность loop будет больше входного импульса?
Скетч в #26 (http://arduino.ru/forum/programmirovanie/signal-opredelennoi-dliny-na-vy...) посту будет работать коректно при импульсе любой длины, но mykaida прав, при работе с микрос желательно переходить на управление портом на прямую!