Объясните метаморфозу с обработкой прерывания
- Войдите на сайт для отправки комментариев
Есть подпрограмма обработки прерывания
//***********************************************************
ISR(TIMER1_COMPA_vect)
//***********************************************************
{
moveONESteps() ; // делаем один шаг перемещения
StopStep_X = true; // разрешаем работу мотора "X"
StopStep_Y = true; // разрешаем работу мотора "Y"
count_ ++ ; // увеличиваем счетчик всех шагов перемещения
count_a ++ ; // увеличиваем счетчик шагов перемещения в сегменте
Delta_Move -- ; // уменьшаем указатель остатка шагов перемещения
if ( count_ <= max_count_Acceleration ){ // если разгоняемся, то
stepCount = count_ ; } //
if ( stepCount >= Delta_Move ){ // если тормозим, то
stepCount = Delta_Move ; } //
TCNT1 = 0; // обнуляем таймер
OCR1A = delay_H[stepCount] ; // определяем длительность работы таймера для следующего шага
if ( Delta_Move_Segment == count_a ){ //
movementDone = true; // выcтавляем флаг окончания движения
TIMER1_INTERRUPTS_OFF // запрещаем прерывания таймера
// delayMicroseconds(200) ; // *************
}
}
//************************************************************
void moveONESteps() //
//************************************************************
{
if ( StopStep_X == true ) { X_STEP_HIGH } // формируем импульс "STEP_X"
if ( StopStep_Y == true ) { Y_STEP_HIGH } // формируем импульс "STEP_Y"
delayMicroseconds(12) ; // держим сигналы "STEP_"
X_STEP_LOW // сбрасываем сигнал "STEP_X"
Y_STEP_LOW // сбрасываем сигнал "STEP_Y"
}
Эта подпрограмма выполняет пошаговое вращение двух шаговых двигателей. с учетом фаз разгона и торможения.
Она используется на плате ардуино MEGA 2560 и через плату RAMPS 1.4 управляет движками X и Y.
При работе прототипа, столкнулся со следующей проблемой - Если производится перемещение на любое расстояние из точкки А в точку B, заданное одним значением (например в G-коде - "G1 X50.00") то перемещение происходит плавно и тихо.
А если перемещение задается отрезками
"G1 X10.00"
"G1 X20.00"
"G1 X30.00"
"G1 X40.00"
"G1 X50.00"
то перемещение происходит с рывками и шумом! При этом разгон и торможение, как и положено, происходят на первом и последнем сегменте (то есть на первом разгоняемся, на последнем тормозимся, а все промежуточные сегменты идут с одинаковой скоростью).
Если в 25 строке кода, разрешить действие задержки (delayMicroseconds(200);), то есть увеличить время выполнения подпрограммы обработки прерывания на 200 микросекунд, то ничего криминального не происходит, и в обоих случаях перемещение происходит плавно и тихо!!!
Когда на логическом анализаторе смотришь на сигналы "STEP_X" и "STEP_Y", то на "шумной" диаграмме видны 4 четких прерываниий сигналов, протяженностью 6.05 - 6.06 милисекунды.
Объясните пожалуйста
1 - Откуда у этой метаморфозы ноги растут?
2 - Почему увеличение времени работы подпрограммы обработки прерывания убирает обрывы во временной диаграмме?
Боюсь, что по этому фрагменту ничего не определеить.
Совершенно непонятно, как строка "G1 X50.00" превращается в указания драйверу, нет описания переменных, ну и т.д.
Нужен полный код )
попробуй выделить отдельный компилируемы и загружаемый код, иллюстрирующий проблемму.
Например я загружу, посмотрю на осцилографе и подумаю, где ошибка.
Пока кажется, что ошибке в непредставленной части кода.
Вангую: где-то в прерываниях беснуются переменные, объявленные без volatile.
Боюсь, что по этому фрагменту ничего не определеить.
Совершенно непонятно, как строка "G1 X50.00" превращается в указания драйверу, нет описания переменных, ну и т.д.
Нужен полный код )
Cтрока "G1 X50.00" превращается в указания драйверу подпрограммой
прерывание задается операторами
попробуй выделить отдельный компилируемы и загружаемый код, иллюстрирующий проблемму.
Это как?
Вангую: где-то в прерываниях беснуются переменные, объявленные без volatile.
Волатильными у меня объявлены
попробуй выделить отдельный компилируемы и загружаемый код, иллюстрирующий проблемму.
Это как?
Это написать маленькую программу, на основе большой, которую можно тут опубликовать (по размеру) и в которой происходит тоже самое.
ALEGYR, в идеале все операции с 16-битными регистрами таймеров нужно выполнять при выключенном таймере. Попробуйте для эксперимента перед 19 строчкой остановить а после 20-й запустить таймер.
Это написать маленькую программу, на основе большой, которую можно тут опубликовать (по размеру) и в которой происходит тоже самое.
Мужики, вы меня ставите в тупик!
Одному нужен полный код, а другому "маленькую программу, на основе большой".
У меня в обоих вариантах заданых перемещений меняется только ОДНА 26 строка в подпрограмме обработки прерывания
ISR(TIMER1_COMPA_vect)
и больше я нигде и ничего во всей программе не изменияю!ALEGYR, в идеале все операции с 16-битными регистрами таймеров нужно выполнять при выключенном таймере. Попробуйте для эксперимента перед 19 строчкой остановить а после 20-й запустить таймер.
Я не знаю как (чем) его остановить! :(
Мужики, вы меня ставите в тупик!
Одному нужен полный код, а другому "маленькую программу, на основе большой".
Смотри: я прошу что-то ВМЕСТО полного кода. Повтори ошибку выкинув неважное, экран, кнопки и прочее.
Просто законченная программа, которую можно запустить на Меге. Вместо драйвера ШД, можно будет просто посмотреть осликом или логаналайзером на ногу СТЕП.
Часто новичек сам находит ошибку, готовя тестовый пример, но если ошибка сохранится - посмотрим.
Скорее всего трабл в том, что ты не останавливаешь тайме, а только запрещаешь прерывания... но нужно тестить.
Я не знаю как (чем) его остановить! :(
Ну блии-ин! Это не серьезно! Даташит читай... как ты иначе хочешь разговора?
Смотри: я прошу что-то ВМЕСТО полного кода. Повтори ошибку выкинув неважное, экран, кнопки и прочее.
А у меня в полном коде и нет ни кнопок, ни экрана, используется только СОМ порт.
Просто законченная программа, которую можно запустить на Меге. Вместо драйвера ШД, можно будет просто посмотреть осликом или логаналайзером на ногу СТЕП.
Я могу скинуть экран с логаналайзера Saleae Logic 1.1.15. Там у меня и СТЕПЫ и ДИРЫ и RX и ТX
Вангую: где-то в прерываниях беснуются переменные, объявленные без volatile.
Волатильными у меня объявлены
Тут не все переменные, которые используются в прерывании. С остальными, что?
Я могу скинуть экран с логаналайзера Saleae Logic 1.1.15. Там у меня и СТЕПЫ и ДИРЫ и RX и ТX
Дорогой! Будь, плз, внимательным. Я верю тому, что ты написал, мне твоих логов не нужно.
Мне нужно увидеть такую же ошибку на своей плате, у себя в мастерской. Твой полный код для этого не годится, потому, что он связан с твоим железом. Нужно сделать независимый от железа код, для голой Меги 2560, но с тем же поведением. Это возможно, потому, что непонятное поведение в серии прерываний таймера, а не в железоспецифичной части кода.
У себя мне это нужно, потому, что я сделаю кучу отладочных принтов, посмотрю то, о чем сейчас не думаю.
Тебе нужна помощь - я пишу как ее получить, а ты начинаешь торговаться...
прерывание задается операторами
ведь останавливал же и запускал, но судя по отсутствию комментариев код скопипастен и не осознан.
Вангую: где-то в прерываниях беснуются переменные, объявленные без volatile.
Волатильными у меня объявлены
Тут не все переменные, которые используются в прерывании. С остальными, что?
Остальные выглядят так -
Вам кажется прикольным использовать эти переменные в обработчике? Фигли тогда жалуетесь?
Мне нужно увидеть такую же ошибку на своей плате, у себя в мастерской. Твой полный код для этого не годится, потому, что он связан с твоим железом. Нужно сделать независимый от железа код, для голой Меги 2560, но с тем же поведением. Это возможно, потому, что непонятное поведение в серии прерываний таймера, а не в железоспецифичной части кода.
У себя мне это нужно, потому, что я сделаю кучу отладочных принтов, посмотрю то, о чем сейчас не думаю.
Тебе нужна помощь - я пишу как ее получить, а ты начинаешь торговаться...
Для меня не проблема выставить тут всю программу! Для меня проблема отредактивровать ее под ТВОЕ железо!
Вам кажется прикольным использовать эти переменные в обработчике? Фигли тогда жалуетесь?
А разве я жалуюсь?! Я просто задал два вопроса
1- Откуда у этой метаморфозы ноги растут?
2 - Почему увеличение времени работы подпрограммы обработки прерывания убирает обрывы во временной диаграмме?
и попросил их мне объяснить.
А что касается прикольного использования переменных, то я еще нахожусь в начальной школе, и всех правил правописания не освоил.
Остальные выглядят так -
Если переменные используются внутри обработчика прерываний - где volatile?
Первое правило правописания должно быть таково, что все переменные, которые используются в обработчике, должны быть volatile.
прерывание задается операторами
ведь останавливал же и запускал, но судя по отсутствию комментариев код скопипастен и не осознан.
исходником была программа
Если переменные используются внутри обработчика прерываний - где volatile?
Так они точно также используются и с delayMicroseconds(200) ; (26 строкой в первом сообщении темы) и без нее. Я же их никак не меняю, а вот результаты получаю разные!!! ПОЧЕМУ?
Я же их никак не меняю, а вот результаты получаю разные!!! ПОЧЕМУ?
Это называется оптимизация. "Некогда объяснять, но..." ;)
--------------
Под какое "мое железо"? Я тебе написал: сделай пример просто под 2650, под голую. Я запущу у себя в мастерской и точно скажу - волатиль тут или неправильная работа с таймером.
--------------
волатиль просто проверь - поставь и пересобери.
Первое правило правописания должно быть таково, что все переменные, которые используются в обработчике, должны быть volatile.
Не проблема! Сейчас поставлю все volatile и проверю.
Не проблема! Сейчас поставлю все volatile и проверю.
Результат ОТРИЦАТЕЛЬНЫЙ!!!
Анализа на сифилис?
Помнится, я как-то словил странный стук на шаговике... Оказалось, что сам дурак - написал алгоритм так, что при иногда один шаг отличался от другого на 1 мс. Шаговик кряхтел при некоторых обстоятельствах, как предпенсионер.
Анализа на сифилис?
Анализа на правильное правописание переменных в подпрограмме обработки прерыванний.
Поставил на все оставшиеся переменные указатель volatile, но тарахтение не прошло. Вставляю задержку delayMicroseconds(200) ; и все идет тихо и гладко!
Помнится, я как-то словил странный стук на шаговике... Оказалось, что сам дурак - написал алгоритм так, что при определенных обстоятельствах один шаг отличался от другого на 1 мс. Шаговик кряхтел при некоторых обстоятельствах, как предпенсионер.
У меня шаги при разгоне и торможении меняются в 5 раз от стартовых 1-3 милисекунд и до выхода на скорость 20-60 микросекунд, и никаких посторонних звуков не происходит. Тарахтение происходит только если прямое перемещение разбито на отрезки и в подпрограмме обработки прерывания отсутствует задержка при выходе из режима прерывания.
Ребята, я не в курсе, на меге delayMicroseconds(200) в прерывании работает?
delayMicroseconds() работает, delay() не работает. millis() и micros() стоят, как у Мавзолея.
У меня шаги при разгоне и торможении меняются в 5 раз от стартовых 1-3 милисекунд и до выхода на скорость 20-60 микросекунд, и никаких посторонних звуков не происходит. Тарахтение происходит только если прямое перемещение разбито на отрезки и в подпрограмме обработки прерывания отсутствует задержка при выходе из
Если последовательно увеличивается, то мож и ничего, а у меня на прямом ходе флапало и тарахтело. Тоже сначала ничего не понимал, потом вывел миллисы в сериал...
Задержка в прерывании -- это почище гвоздя в сапоге. Никаких задержек в обработчике быть не должно в принципе.
Так, если все еще чего-то хочешь - готовь программу... в крайнем случае, хер с тобой, выложи как есть. Еще проведи эксперимент - 200 мкс лечат, а 100? а 50?... короче, понял, да?
На все про все, повторюсь, если это тебе надо, у тебя - день. Завтра шабат и я заниматься херней не буду.
Всем Шабат шалом, в этом чате! ;) ;) ;)
Если последовательно увеличивается, то мож и ничего, а у меня на прямом ходе флапало и тарахтело. Тоже сначала ничего не понимал, потом вывел миллисы в сериал...
Что такое "флапало" и "вывел миллисы в сериал" ?
Если последовательно увеличивается, то мож и ничего, а у меня на прямом ходе флапало и тарахтело. Тоже сначала ничего не понимал, потом вывел миллисы в сериал...
Что такое "флапало" и "вывел миллисы в сериал" ?
1) от англ. flap — махать, хлопать. Т.е. междушаговый интервал был то N, то N+1 мс.
2) Serial.println(millis()-stepStartTime); В обработчике прерывания наврядли такой способ поможет. Я просто поделился опытом - рокот и стук был из-за неравномерности шага. Может вы своим delayMicroseconds() его выравниваете и таинственный стук пропадает.
Задержка в прерывании -- это почище гвоздя в сапоге. Никаких задержек в обработчике быть не должно в принципе.
Так ее там вроде как и нет! Задержка используется только ОДИН раз за все перемещение по сегменту, и только после запрета прерывания по таймеру!!!
Ее в изначальном варианте не было. Я ее ввел только тогда, когда стал разбираться с тарахтением.
Так, если все еще чего-то хочешь - готовь программу...
То что мне надо я написал в своем первом сообщении!
Объясните пожалуйста
1 - Откуда у этой метаморфозы ноги растут?
2 - Почему увеличение времени работы подпрограммы обработки прерывания убирает обрывы во временной диаграмме?
А что касается
в крайнем случае, хер с тобой, выложи как есть. Еще проведи эксперимент - 200 мкс лечат, а 100? а 50?... короче, понял, да?
то на 50 тарахтит, а на 100, 200, 300 уже не тарахтит!
1) от англ. flap — махать, хлопать. Т.е. междушаговый интервал был то N, то N+1 мс.
2) Serial.println(millis()-stepStartTime); В обработчике прерывания наврядли такой способ поможет. Я просто поделился опытом - рокот и стук был из-за неравномерности шага. Может вы своим delayMicroseconds() его выравниваете и таинственный стук пропадает.
Это на каком движке надо было шагать с междушаговым интервалом от N, то N+1 мс ?
Мои nema 17 на междушаговом интервале в 1-2 мс просто стартуют и останавливаются
На неме и рокотало.
Вы хотите, чтобы я назвал вам точные цифры? Уверены, что наши немы эквивалентны, драйверы и блоки питания одинаковы на 100% и эффект повторится? Я указал на возможную причину. Можете проверять ее или просто игнорировать - дело ваше.
На неме и рокотало.
Вы хотите, чтобы я назвал вам точные цифры?
Нет не хочу! Я хочу сказать, что с 1-2 милисекунд движок стартует из полного покоя, и успевает остановится если он вращался. Все что будет дольше, вынуждает вращаться шаговый движок как-бы в режиме СТАРТ-СТОП, и это сопровождается характерным рокотом или тарахтением. А если при этом, на каждом шаге, еще и переключался сигнал ENABLE, то звук будет еще заметнее, за счет постоянного включения и выключения выходного каскада драйвера.
У шагового двигателя нет старта или стопа. Вал просто перескакивает между обмотками (или зависает между ними при микрошаге) в случае подачи импульса на вход STEP драйвера. Чтобы изучить (изучить) истинные причины рокота необходимы целенаправленные и практически лабораторные исследования. Таковых я не проводил. Наблюдением поделился. Используйте его, если пожелаете.
Зачем Enable дергать на каждом шаге - не представляю на данный момент.
У шагового двигателя нет старта или стопа.
...
Зачем Enable дергать на каждом шаге - не представляю на данный момент.
я писал
как-бы в режиме СТАРТ-СТОП,
а что касается сигнала "Enable", то в некоторых скетчах, его используют не на все время движения, а на каждый сегмент движения. Зачем это делают я не понимаю, но люди это используют.
Так, если все еще чего-то хочешь - готовь программу... в крайнем случае, хер с тобой, выложи как есть.
Выкладываю то что получилось. Это все проверено на моем железе
ОК. Завтра посмотрю.
Я еще не компилировал, сорри.
У меня пес приболел - к вету поеду.
НО! Я посмотрел - все проблеммы в том (ИМХО), что ты не останавливаешь таймер.
Вместо TIMER1_INTERRUPTS on и off - напиши одновременные пуск и останов в этот макрос.
вот так ON
#define TIMER1_INTERRUPTS_ON {
TCCR1B |= ((1 << CS11) | (1 << CS10));
TIMSK1 |= (1 << OCIE1A);
}вот так OFF
#define TIMER1_INTERRUPTS_OFF {
TCCR1B &= ~((1 << CS11) | (1 << CS10));
TIMSK1 &= ~(1 << OCIE1A);
}Сорри, проверять не было времени. Возможно еще что-то добавить нужно.
И укажи, плз, тестовый пример, на котором неравномерность проявляется. Чтобы я не угадывал, как и куда этот пример подать.
Вместо TIMER1_INTERRUPTS on и off - напиши одновременные пуск и останов в этот макрос.
вот так ON
#define TIMER1_INTERRUPTS_ON {
TCCR1B |= ((1 << CS11) | (1 << CS10));
TIMSK1 |= (1 << OCIE1A);
}вот так OFF
#define TIMER1_INTERRUPTS_OFF {
TCCR1B &= ~((1 << CS11) | (1 << CS10));
TIMSK1 &= ~(1 << OCIE1A);
}изменил в программе строки #define TIMER1_INTERRUPTS_ON и #define TIMER1_INTERRUPTS_OFF
проблема осталась!
И укажи, плз, тестовый пример, на котором неравномерность проявляется. Чтобы я не угадывал, как и куда этот пример подать.
примером использую текстовый файл
Времени катастрофически мало. Работа по дому срочная... Сорри.
Но: в программе такое количество ляпов и ошибок, что прости, но я устал пытаться понять, как она разбирает команды.
То есть ясно, что в моменте стыковки команд возникает неравномерность шага... но в каком месте - это тайна. ;) в коде, представленном мне, даже шаги разгона-торможения вычисляются неверно., тип команды всегда один и пр. и пр. Посмотри на массив delay_H! ;)
Посмотри на то, как и где он вообще используется!! Распечатай его.
-------------------
Давай я тебя попрошу о следующем:
Напиши на русском языке, что код должен делать, в каком виде принимать команды, какой у команд синтаксис? Пока ограничимся только командами движения.
Зачем ты хочешь отслеживать цепочки? Почему эту работу не отдать отпимизатору G-кода, а не станку? Команда перемещения - это разгон+движение+торможение. Если два перемещения состыкованы, то какие случаи станок должен (по твоему мнению) должен отслеживать?
------------------
Может попробовать сперва на одной оси -X? для отладки? Напиши словами - какую идею ты хочешь отладить?