Конфликт прерываний?

Тема в разделе "Микроконтроллеры AVR", создана пользователем DrProg, 8 дек 2015.

  1. DrProg

    DrProg Вечный нерд

    Как я уже писал ранее, была создана система плавным управлением двигателей через прерывания. Работало замечательно, пока не захотелось попробовать ручное управление через блютуз.

    Создал простенький механизм на RemoveXY состоящий из двух ползунков, каждый из которых должен управлять своим двигателем (почти как на тракторе). Запустил и увидел странное. При подключении блютуза переменные ответственные за состояние оборотов двигателя начали как то хаотично меняться. Вот на видео хорошо заметно дрожание светодиода имитирующего двигатель:



    Вроде бы реагируют правильно, но откуда то появляются плавающие значения там где их быть не должно.
    Впечатление такое, что в момент обработки прерывания происходит обработка другого прерывания (предположительно от SerialSoftware на чем висит bluetooth), которое каким то образом вредит переменной. Такое возможно?

    Принятые меры, не увенчавшиеся успехом:
    Переменные созданы с префиксом volatile.
    Перепробовал все 5 16битных таймера как A так и B, от этого меняется только вид помехи и номер пина с помехой - то первый то второй.
    Увеличивал время между прерываниями в несколько раз.
    Ума не приложу что еще может быть не так.
     
    Последнее редактирование: 8 дек 2015
    ИгорьК нравится это.
  2. Mestniy

    Mestniy Гуру

    В подтяжке не может быть дело?
    Но если дело в ложном прерывании, то ложное можно как-то отсеять от верного програмным путем?
    А еще могут быть помехи, либо по причине неисправного блютуз, либо помехи связаны с электромагнитными полями.
    Конечно это только предположения.
     
    Последнее редактирование: 8 дек 2015
  3. Mestniy

    Mestniy Гуру

    Еще у меня была похожая проблема с мотором. Оказалось что некоторые пины на макетной плате со временем разболтались и просто VCC терялось.
    Может в контакте дело!
     
  4. AlexU

    AlexU Гуру

    Информации маловато: что за прерывания? как используются? как управляются светодиоды (пины, каким сигналом)? и т.п. и т.д.?
     
  5. DrProg

    DrProg Вечный нерд

    Контакты не при чем. Меняется сама переменная. То есть если запустить Serial.print() то видно что значение меняется на несколько единиц само по себе.
     
    ИгорьК нравится это.
  6. Mestniy

    Mestniy Гуру

    Блютуз может шалит? Менять не пробовали?
     
  7. Unixon

    Unixon Оракул Модератор

    У микроконтроллеров AVR не бывает вложенных прерываний.
     
    DrProg нравится это.
  8. DrProg

    DrProg Вечный нерд

    Как теоретически может меняться переменная извне? Программно она меняется только в одном месте в прерывании как простая функция от другой переменной, которая не меняется в данный момент.
     
    ИгорьК нравится это.
  9. Mestniy

    Mestniy Гуру

    Блин, ну хоть убейте мне кажеться проблема в резисторе! У вас он стоит? Если да, то на сколько? И вообще, можно схему? Мне в одной из схем пришлось 5kOm ставить, потомучто, при меньшем сопротивлении аппарат глючил!
     
  10. DrProg

    DrProg Вечный нерд

    Не в приходящем сигнале дело, еще раз говорю! Самопроизвольно меняется содержимое переменной без видимой на то причины.
     
    ИгорьК нравится это.
  11. Alex19

    Alex19 Гуру

    Было такое пару раз.

    Причин может много, в основном работа памятью, самые типичные работа с указателем, выход за пределы и т.д.. Но и с прерываниями, работа с переменными как в прерывании и в коде - атомарные операции и т.д..

    Сложно понять, что там происходит, не видя кода. Если нет отладчика найти такую ошибку трудно, порой просто комментирую код, пока программа не начнет стабильно работать, а дальше добавление кода и проверки.
     
    DrProg нравится это.
  12. DrProg

    DrProg Вечный нерд

    Я вот тоже грешу на проблемы с памятью. Но вроде бы неоткуда, во всяком случае в моем участке кода. Может в подключаемых библиотеках косяк?
     
    ИгорьК нравится это.
  13. Alex19

    Alex19 Гуру

    Все может быть, но если речь о SerialSoftware, то сильно сомневаюсь, что там есть проблемы с памятью, ей уже давно не первый год. Сам пользуюсь данной библиотекой ни когда проблем не замечал. Больше всего прерываний с SerialSoftware было в такой конфигурации - она + прерывания UART + прерывания Timer1 и Timer2, работает как часы.

    Когда вызывается прерывание, все прерывания отключаются пока выполняется обработчик прерывания. Если в это время произойдет 1 прерывание, оно будет выполнено после, если несколько, то только 1 будет выполнено после, остальные потеряются. Именно поэтому прерывания должны быть минимальными по времени исполнения.

    Если Вы потеряли прерывание, то это не изменит переменную произвольно.

    Кроме того, что уже сказал, если используются глобальные переменные добавьте static перед volatile - http://www.c-cpp.ru/books/staticheskie-globalnye-peremennye.

    Больше на ум с ходу ни чего не приходит.
     
    Последнее редактирование: 8 дек 2015
    DrProg нравится это.
  14. DrProg

    DrProg Вечный нерд

    На библиотеку RemoteXY думаю, а у нее свой SerialSoftware зачем то. Пока прерывания не используются, все замечательно. Может какой то массив выпирает за свои пределы? Собрал переменные в структуру, так вообще одна из них вообще начала плавать от 0 до -254 случайным образом как будь то от непритянутого аналогового входа. Как такое возможно?
     
    ИгорьК нравится это.
  15. ИгорьК

    ИгорьК Гуру

    Сам иногда задаюсь подобными вопросами. Вот график analogRead простейшего датчика освещенности. Не вел бы записей - не удивлялся:
    12343251.jpg
     
  16. Alex19

    Alex19 Гуру

    Там нет своей реализации, там своя обертка для стандартного SerialSoftware, но сама отправка происходит стандартной библиотекой. Если Вы думаете, что проблема в нем, воспользуйтесь HardwareSerial, у Вас же Mega.

    Возможно, когда ошибка в вызове аналогичной функции, стоила мне дня жизни.
    Код (C++):
    static void __attribute__ ((noinline)) s_struct_w(uint8_t *cb,uint8_t siz) {
      while(siz--) *cb++ = read8();
    }
    Сложно, что-то сказать не видя кода, мне сложно понять зачем прерывания. К примеру 1-но на ADC, ШИМ для моторов. Для ШИМ если не ошибаюсь, есть режим формирования без прерываний.

    Посмотрите так же используются ли одни и те же регистры, как в прерывании, так и в коде программы.

    Отмечу, что еще не желательно делать в прерываниях.
    1. Вызывать функции, тем более которые вызываются в вне прерывания.
    2. Разрешать прерывания sei.

    И что требуется.
    1.
    Очень хорошо и просто написано, поэтому процитировал.

    Очень полезная статья - http://easyelectronics.ru/avr-uchebnyj-kurs-podprogrammy-i-preryvaniya.html, читайте с заголовка Бег по граблям.

    Если у Вас есть осциллограф, а лучше логический анализатор можно попробовать разобраться когда происходит сбой. Выставлять значение на портах во время прерывания, так можно оценить загрузку, а так же сравнивать значение переменной с эталонным.

    К примеру 1 прерывание 2 пин вверх, если там переменной отхождение от эталона 13 порт вверх, конец прерывания 2 порт вниз. и т.д. Так же в программе проверять переменную, так Вы поймете после чего произошел сбой, так же подсказал когда-то Megakoteyka.
     
  17. DrProg

    DrProg Вечный нерд

    Прерывание обрабатывается меньше двух миллисекунд. Ничего лишнего там нет. Попинал немного библиотеку, перезаписал оформление типов, вроде бы успокоилось. В чем причина была так до конца и не понял. При использовании чужих наработок всегда есть риск что что-нибудь пойдет не так. Но объять необъятное тоже нелегко.

     
    Последнее редактирование: 9 дек 2015
    ИгорьК нравится это.