как поменять частоту шим на iskra neo чтоб избавиться от писка на вентиляторе?

Тема в разделе "Arduino & Shields", создана пользователем Толик Иванов, 20 дек 2015.

  1. Толик Иванов

    Толик Иванов Administrator Администратор

    дело вот в чем, нашел видос по изменению частоты ШИМ для uno, но на iskra neo другой процессор, и пример из видео не работает...

     
  2. Radius

    Radius Гик

    Процессор практически такой же. Подключайте нагрузку в выводам имеющим значок ~. Если не работает, проверьте схему подключения, может быть перепутали ноги транзистора.
     
  3. Толик Иванов

    Толик Иванов Administrator Администратор

    я не перепутал, вентилятор крутится и изменяет скорость. вопрос как от писка избавится, в виде повышают частоту шим и писк пропадает. но делают это на 328 процессоре как в уно. а у меня процессор как в ардуино леонардо
     
  4. Radius

    Radius Гик

    Попробуйте поставить параллельно вентилятору электролитический конденсатор, он сгладит пульсации ШИМ и на выходе будет просто постоянное напряжение.
     
  5. Толик Иванов

    Толик Иванов Administrator Администратор

    так и сделал но все равно есть присутствие звука
    еле уловимое, но спать при таком ультразвуке не будет комфортно.
    все же интересно узнать советы по поднятию частоты
     
  6. Radius

    Radius Гик

    Либо конденсатор маловат (желательно не менее 1000 мкФ) либо это особенность вентилятора.
     
  7. Karabas

    Karabas Гик

    У ардуино две частоты ШИМ-а, вывода 5 и 6 около киллогерца, остальные 490 Гц. Может имеет смысл понизить частоту (если вы используете выхда 5 или 6), вентилятор вещь ниерцеонная, ему все равно.
    Второе, можно создать програмный ШИМ с большй или меньшей частотой. Полезная функция micros() для этого.
     
  8. Толик Иванов

    Толик Иванов Administrator Администратор

    ребята, ктонибудь из вас посмотрел видео? Обратили внимание на таблицу из которой была скопирована строка позволившая аппаратно повысить шим? Так вот она не для чипа леонардо. Вопрос: как повысить частоту аналогичным способом на леонардо?
     
  9. Alex19

    Alex19 Гуру

    Не буду грузить Вас регистрами, сделаем все по простому, как на видео частота 62,5KHz, попробуйте данное решение
    Код (C++):
    TCCR4B = TCCR4B & B11111000 | B00000001;
    Частота выхода 6 и 13 будет 31,37KHz

    Против стандартных для Leonardo
    Код (C++):
    Pin 3 - 976,6Hz
    5 - 490Hz
    6 - 490Hz
    9 - 490Hz
    10 - 490Hz
    11 - 976,6Hz
    13 - 490Hz
    Теперь у Вас
    Код (C++):
    Pin 3 - 976,6Hz
    5 - 490Hz
    6 - 31,37KHz
    9 - 490Hz
    10 - 490Hz
    11 - 976,6Hz
    13 - 31,37KHz
    Я ошибся в соседнем топике - http://forum.amperka.ru/threads/Увеличение-частоты-ШИМ.6834/, 10 pin на другом таймере (в pin mapping-е написано 10 pin (PCINT6/OC1B/OC4B/ADC13) PB6, получается 1 таймер).

    Все тесты проводились на оригинальной Leonardo, частота проверялась на лог. анализаторе, может быть не точно +/- пару процентов. Если нужно именно 62,5KHz, пишите.
     
    Толик Иванов нравится это.
  10. Толик Иванов

    Толик Иванов Administrator Администратор

    круто!!! блин! большое Вам спасибо!!!! как долго я ждал этого ответа:)
     
  11. ИгорьК

    ИгорьК Гуру

    Alex19, если мне не изменяет память, попытка выполнить функцию analogWrite () восстанавливает частоту в исходное. Поэтому здесь не хватает малости - указания регистра куда писать цифры для изменения скважности ШИМ.
     
  12. Alex19

    Alex19 Гуру

    Если бы знал, что Вам нужно просто поднять частоту или посмотреть видео раньше и ответ был бы раньше.

    Просто голова забита своим, думал, что Вам нужен полный контроль от формирования сигнала, до частоты, как мне. Сам сейчас активно перехожу на Leonardo.
     
    Толик Иванов нравится это.
  13. Alex19

    Alex19 Гуру

    Нет, просто попробуйте, я проверял, а не просто дал код.

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

    ИгорьК Гуру

    Людей Вы не загрузили, а я - призадумался.
    Не часто встречается такой способ установки регистра.
     
  15. Alex19

    Alex19 Гуру

    Все, что тут делается, это просто меняется коэффициент предделителя для ШИМ.

    Происходит все примерно так, в main, перед setup происходит настройка всего, в том числе и таймеров (Они настраиваются 1 раз и дальше не требуют изменения).

    В частности для 4 таймера значение регистра управления TCCR4B при загрузке равно B00000111, последние 4 бита отвечают за коэффициент предделителя работы таймера. В коде выше, мы просто поменяли коэффициент предделителя с 1/64 (B00000111) на 1/1 (B00000001) именно из-за этого частота поднялась до 31,37KHz.

    А дальше analogWrite() устанавливает регистр сравнения OCR4D (для 6 пина) или OCR4A (для 13 пина), благодаря ему мы регулируем скважность сигнала. И если мы будем указывать значение в него, придется отказаться от самой функции analogWrite, иначе она будет просто переписывать значения.

    Вообще такой поход частенько используется людьми работающими с Ардуино. К примеру с тем же ADC (АЦП), далеко ходить не придется - http://geektimes.ru/post/255744/. Там по сути, такая же идея, поменять коэффициент предделителя. Многие (как и сам я) думают/думали, что это магия:). А с опытом приходит понимание, что это такой костыль, когда нет надобности/возможности/времени/желания/и т.д. понять и разобраться в микроконтроллере на основе которой сделана та Ардуина с которой работаешь. Справедливости ради, нужно сказать, что для многих проектов это просто не нужно.
     
    Толик Иванов и ИгорьК нравится это.
  16. ИгорьК

    ИгорьК Гуру

    ... но я всего то имел в виду последвательность операций & и | при установке регистра. Понял, что не помню что делается сначала а что потом. И зачем именно такая конструкция.
     
  17. Alex19

    Alex19 Гуру

    Увы сам не помню наизусть приоритет операций, поэтому когда пишу код, пользуюсь справочниками, сайтами. Сам приоритет операций можно глянуть тут - http://www.viva64.com/ru/t/0064/.

    Теперь o & это побитовое И.
    [​IMG]
    В рамках данной конструкции делает следующие, с 7 по 3 бит, если там нули то там и останутся нули, если единицы, то там и останутся единицы. А последние с 2 по 0 бит, если там будут 1, то станут нулями, если 0 то останутся нулями.
    Код (C++):
    TCCR4B & B11111000
    Кстати, Вы помогли мне найти ошибку, спасибо
    Там 4 бита предделителя и если бы в 3 бите было бы 1, то в итоге получили бы предделитель равный 1/256.
    Должно быть так
    Код (C++):
    TCCR4B & B11110000
    Мы просто обнулили последние 4 бита, если коротко.

    Теперь o | это побитовое ИЛИ
    [​IMG]
    Код (C++):
    | B00000001
    Тут все биты с 7 по 1, как были так и останутся, а вот 0 бит будет взведен в 1, ведь до этого мы обнулили биты с 0 по 3.

    Более подробно прочесть об битовых операциях, можно посмотреть - http://chipenable.ru/index.php/prog...s-kak-rabotat-s-bitami-makroopredeleniya.html, превосходная статья.
     
    Последнее редактирование: 24 дек 2015
  18. Толик Иванов

    Толик Иванов Administrator Администратор

    Спасибо большое, если я правильно все понял, я в сетап просто должен вписать эти установки делителей, и дальше так же как и раньше изменять значения от 0 до 255. И еще я так понимаю если в конце loop у меня delay указан 300мс, то нужно его увеличить , так как оно тоже будет считаться быстрее чем до установки делителей?
     
  19. Alex19

    Alex19 Гуру

    Все что нужно сделать это в setup, добавить эту строку
    Код (C++):
    TCCR4B = TCCR4B & B11110000 | B00000001;
    А дальше работать как работали, не нужно увеличивать delay в конце loop.

    Другое дело, что сам delay в loop, это хоть и рабочее решение для кода в данном видео. Но не верное с точки зрения подхода к программированию микроконтроллеров, увы сейчас нет времени, завтра постараюсь пояснить.
     
  20. Толик Иванов

    Толик Иванов Administrator Администратор

    я знаю что есть milis() но пользоваться ей еще не научился, для моего проекта впринципе delay() не проблема, поэтому не стал плка углубдяться. Со временем разберусь, а если поможете разобраться- буду благодарен☺