Я думаю Вам стоит записать несколько видео уроков по нормальному программированию ардуины. Начать с чего то попроще и выйти на регистры порты прерывания таймеры и заложить основы программирования циклы условия побитовые операции организация памяти стек, куча. Количество подписчиков вырастит в разы!!! У вас очень хорошо получается рассказывать!!! Кто за лайк !!!
Отличное изложение. В целях отладки вместе с целевой функцией выводят ещё и некий синхроимпульс - чтобы картинка на осциллографе не прыгала. Но если мне потребуется генерить стандартные функции, то я предпочту поставить копеечный внешний DDS. А если произвольной формы, то не копеечный, тысяч за пять рублей с превосходными параметрами временной и амплитудной точности, модуляцией и прочей радио-лабудой ;).
Да, конечно даже мелкая AD9833 справится с синусом гораздо лучше и легко подключается к МК. Такой вариант только где-то на очень низких частотах (1-10Гц, иногда нужен и такой сигнал) может приблизиться к младшим аппаратным DDS (если увеличить таблицу и разрядность аккумулятора), тем не менее принцип работы у них одинаков и переход от простого к сложному это предпочтительный путь :)
Это классно. Только, мне кажется, чтобы воспроизводимые сигналы реально можно было как-то использовать, и чтоб они при этом не сильно поплыли, неплохо бы их хоть как-то усилить, хотя бы просто транзистором, но можно и покруче выход намутить, на ОУ и транзисторах (npn+pnp). А вообще, есть такая мысль интересная (навеяло этими размышлениями о ЦАПах и АЦПшках), если сделать и ЦАП и АЦП, и программку, то можно же тогда записывать и воспроизводить вообще любые сигналы, подобно тому, как мы это делаем со звуком, только максимально допустимая частота больше, чем у звуковухи, а минимальная вообще 0, тогда с любой самодельной схемы можно сигнал записать, поразглядывать, и воспроизвести, и подать куда хошь, на другую схему например. А если ещё для симуляторов схем плагин какой-нибудь намутить, чтоб сигнал выводили в файл, то вообще можно для экспериментов деталюхи не брать, а реальный сигнал получать из ЦАПа. Не знаю, делал ли такое кто-нибудь, но мысль вроде интересная. На трёх ЦАПах тогда можно хоть различные версии инверторов моделировать, и пробовать их на моторчике от жёсткого, подключив к ЦАПам. Думаю, 3-4 канала хватит на любые проекты вообще. А если ещё забахать всё это на симметричном питании, а с компом данными обмениваться через оптроны например, то и с настоящей переменкой можно "играться". Ну, с маленькой, но с настоящей)))
Крайне обидно, мне бы это видео пару лет назад...прошу Вас записать серию роликов по программированию avr, спасибо за контент, всегда приятно смотреть)
Вместо word удобнее использовать типы типа uint16_t чтобы не думать какой размер текущий компилятор с текущими настройками на текущей платформе даст общим типам.
256 - Много точек. При 36 точках гармонические искажения всего 0,3% на 25кГц. Можно выводить точки с частотой примерно 500 000гц. А АЦП не пробовал на встроенном компараторе сделать. У меня получилось 16 разрядов 33кГц. Программно поразрядным взвешиванием.
Насколько я помню у самых маленьких аппаратных DDS типа AD9833 в таблице памяти 1024 значения. Много это или мало, это все должно определяться под задачу так же как и требуемая частота семплов. Для многоразрядных АЦП есть доступные Σ-Δ.
@@TDMLab Есть конечно, но чисто из спортивного интереса сделать Металлодетектор только на Ардуино за 5 копеек, в то время как фирменные стоят от 50000 до миллиона рублей. Теория фильтрации там интересная :)) Хотя есть уже реализация с отрытым кодом на AD1115, но интересно разобраться самому.
Да, но более точно так: чем больше настраивающее слово тем быстрее накапливается аккумулятор, и соответственно быстрее адрес "бежит" по таблице и отсюда выше частота.
Здравствуйте! Спасибо большое за видео. Извините, что так поздно пишу - только натолкнулся на него. У меня вопрос. А то, что весь PORTD устанавливается на выход не приведёт к тому, что МК нельзя будет по UART'у прошить в дальнейшем?
@@TDMLab справедливо, но можно же было процедурно генерировать эту таблицу при загрузке, экономя флеш (Простите, что придираюсь, я так, теоретические соображения, не из злых намерений, просто работаю на тиньках 13 и у меня из-за них бзик на оптимизацию))
@@lava_frai Да можно было, но способ создания таблицы прямого отношения к самому алгоритму DDS не имеет, так что я не раскрывал это отдельно. Да все в порядке, нормальный вопрос.
Пробовал разные варианты R-2R DAC, но лучше разрешения, чем 7 бит получить не удалось. Так что не рекомендую. Источником погрешности, по-видимому, является разброс внутренних сопротивлений выходных пинов микроконтроллера (порядка +/-100 Ом), так что использование даже 0.1% резисторов не помогает. Другой источник ошибки - нестабильность питания микроконтроллера, проявляющаяся на выходных пинах. И совсем дело плохо на высоких частотах >1 мГц, где проявляются осцилляции от бит-флипс (...01111...1000), отфильтровать которые не удается
Да, я согласен, что R2R на резисторах это ЦАП-ы для "бедных", тем не менее применяются в дешевых DDS синтезаторах i2.wp.com/elschemo.ru/wp-content/uploads/2018/03/IMG_20171222_210949.jpg i.imgur.com/3jp9fmQ.jpg Для резисторов, на сколько я помню, расчет такой: их точность должна быть не хуже чем 100%/2^n где n - разрядность ЦАП-а, то есть для 10 бит почти влезают 0,1% резисторы. 1% резисторы - 6-7 бит. Вообще где-то видел и 14 битные R2R, но там уже по идеи даже 0,01% - не катят и это был скорее коммерческий ход. По идеи не должно быть у МК +/-100 Ом, там КМОП ключи, что-то многовато 100Ом, как он 20мА на выходе даст при 100 Омах, падение будет 2 Вольта. Это конечно проблема, но не на столько, ПЛИС-ы более стабильные в теории, еще можно буферезировать и вместе с этим отвязать от цифрового питания.
@@TDMLab Я, собственно, и пытался сделать скоростной R-2R DAC для DDS, с разрешением около 20 ns/step, с использованием PSoC5 от Cypress Semiconductors: (линк удалён, search youtube for "PSoC5 DDS with slew and amplitude control"). Остановился на 4-х битах, дальше улучшения формы сигнала не заметно. DDS сделан полностью на "железе", используя PLD логику микроконтроллера. На низких частотах добиться разрешения DAC даже 8-бит не удалось, получилось с натяжкой 7-бит (резисторы 20к 0.1%), что хуже даже встроенного 8-бит DAC. Пробовал также resistor array, с тем же результатом. Поэтому подозреваю что пины микроконтроллера неодинаковые.
@@odissey2 Странно, возможно это действительно особенности выходов МК, иногда бывают разные режимы работы выходных транзисторов. Честно говоря всегда считал что уж 8 бит можно получить на R2R, тем более этот вид ЦАП-ов раньше был распространен и в интегральном исполнении. Сам планирую поковырять Spartan-7 от Xilinx и сделать на ней DDS и думал как раз на r2r 0,1% 1k и 2k + буферизация.
Просто нужно использовать цифровые технологии - не грузить выходы МК на резики, а грузить на высокоомные входы микросхемы 74ABT574, которая 8 параллельных ячеек памяти, инфа из которых отдается уже на резики по перепаду от генератора (которым тактируем это микруху и МК). Получим своевременную выдачу битов на резисторы с практически идеальными параметрами по амплитуде и равномерности внутренних сопротивлений выводов. А МК тоже будет работать в тепличных условиях - от него в этом случае всего лишь требуется не ошибиться на километр (не записать откровенную дезу в микруху). Короче внешняя микра и внешний ген затащат я думаю.
Контакт поменял и заработало. Спасибо за видео. Ещё бы хотелось узнать, куда можно приписать Serial.println(analogRead(0)), чтобы увидеть графики без осциллографа
@@xqwyx-11 посмотрите переменную, которую я в порт вывожу и её и ставьте в serial print Но не факт, что будет работать, данные сыпяться очень быстро и там ещё прерывание есть, оно будет мешать.
почему бы не воспользоватся указателем в который записывать адрес таблицы и сэкономить такт на сравнение? и почему бы не бежать по таблице в основном цикле, а делать перестройку по прерыванию (нажатию)? хотя я честно говоря не понял как вы сделали внешние прерывание не на D2/D3 которые уже заняты, где-то я читал что ардуинка умеет только на этих ногах.
Да, можно. Бежать по таблице в основном цикле это значит зависеть от длительности исполнения этого основного цикла. Прерывание позволяет создать жесткий и контролируемый реал-тайм. Существуют так же прерывания не по отдельным пинам, а по всему порту одновременно. Собственно прерывание PCINT0 будет исполнено если произошло изменение хотя бы на одном выводе порта C. Дальше в самом векторе уже можно разобраться что конкретно произошло.
Как ни где не используются? В программе целых два вектора прерываний. Строчка #include может быть убрана потому, что Arduino IDE добавляет ее по умолчанию.
Очень странный метод регулятора частоты ,получается что просто кромсаешь таблицу.Но зачем ,ведь скорости достаточно что бы всегда пробегать весь массив ! Просто менять OCR0A = 39; у вас а надо сделать OCR0A= ADCH; и получим тот же регулятор частоты ,только он всегда будет гладкий!
Это DDS, стандартный и общеупотребимый алгоритм. Если менять OCR0A, то можно получить для 8-ми битного регистра ровно 255 возможных значений частоты, а DDS, может сформировать несравнимо более мелкий шаг перестройки и его параметры гибко настраиваются разрядностью фазового аккумулятора и длиной таблицы.
@@TDMLab Для "пилы" таблица вообще не нужна, тем более если Вы используете switch. Другой вариант - менять указатели на таблицы, тогда не нужен switch. Нет необходимости считать синус "на ходу", можно посчитать один раз, заполнить таблицу, и потом использовать рассчитанные значения как в Вашем случае. Посчитать один раз можно как минимум двумя способами: в setup, либо объявить в loop статический указатель на таблицу, проинициализировав который возвращаемым значением из функции, которая и рассчитает значения. В обработчике кнопки, учитывая, что у Вас всего два значения, вместо инкремента mode и проверки на >1 можно заменить одной строчкой mode = !mode.
@@motofritz да, для пилы таблица не нужна, я вроде это говорю в видео. Да, можно сгенерировать таблицу например в сетапе. Да, и про кнопку тоже верно. В целом это лишь пример работы DDS, и код может быть оптимизирован разными способами в зависимости от того что нужно сэкономить. Как мне показалось, выше человек спрашивал именно про расчет на ходу, что собственно я и не рекомендую.
Я думаю Вам стоит записать несколько видео уроков по нормальному программированию ардуины. Начать с чего то попроще и выйти на регистры порты прерывания таймеры и заложить основы программирования циклы условия побитовые операции организация памяти стек, куча. Количество подписчиков вырастит в разы!!! У вас очень хорошо получается рассказывать!!! Кто за лайк !!!
Спасибо
Отличное изложение. В целях отладки вместе с целевой функцией выводят ещё и некий синхроимпульс - чтобы картинка на осциллографе не прыгала.
Но если мне потребуется генерить стандартные функции, то я предпочту поставить копеечный внешний DDS. А если произвольной формы, то не копеечный, тысяч за пять рублей с превосходными параметрами временной и амплитудной точности, модуляцией и прочей радио-лабудой ;).
Да, конечно даже мелкая AD9833 справится с синусом гораздо лучше и легко подключается к МК. Такой вариант только где-то на очень низких частотах (1-10Гц, иногда нужен и такой сигнал) может приблизиться к младшим аппаратным DDS (если увеличить таблицу и разрядность аккумулятора), тем не менее принцип работы у них одинаков и переход от простого к сложному это предпочтительный путь :)
@@TDMLab спасибо. Работа с регистрами стала для меня откритием
Это классно. Только, мне кажется, чтобы воспроизводимые сигналы реально можно было как-то использовать, и чтоб они при этом не сильно поплыли, неплохо бы их хоть как-то усилить, хотя бы просто транзистором, но можно и покруче выход намутить, на ОУ и транзисторах (npn+pnp). А вообще, есть такая мысль интересная (навеяло этими размышлениями о ЦАПах и АЦПшках), если сделать и ЦАП и АЦП, и программку, то можно же тогда записывать и воспроизводить вообще любые сигналы, подобно тому, как мы это делаем со звуком, только максимально допустимая частота больше, чем у звуковухи, а минимальная вообще 0, тогда с любой самодельной схемы можно сигнал записать, поразглядывать, и воспроизвести, и подать куда хошь, на другую схему например. А если ещё для симуляторов схем плагин какой-нибудь намутить, чтоб сигнал выводили в файл, то вообще можно для экспериментов деталюхи не брать, а реальный сигнал получать из ЦАПа. Не знаю, делал ли такое кто-нибудь, но мысль вроде интересная. На трёх ЦАПах тогда можно хоть различные версии инверторов моделировать, и пробовать их на моторчике от жёсткого, подключив к ЦАПам. Думаю, 3-4 канала хватит на любые проекты вообще. А если ещё забахать всё это на симметричном питании, а с компом данными обмениваться через оптроны например, то и с настоящей переменкой можно "играться". Ну, с маленькой, но с настоящей)))
Крайне обидно, мне бы это видео пару лет назад...прошу Вас записать серию роликов по программированию avr, спасибо за контент, всегда приятно смотреть)
Спасибо, познавательно!
Хорошо для тех, у кого есть осцилограф, ну или хотя-бы частотометр. А как бы эту схемку приартачить к LCD и приращивать значение тактовыми кнопками?
th-cam.com/video/RaKAYiVj1qk/w-d-xo.html
Вместо word удобнее использовать типы типа uint16_t чтобы не думать какой размер текущий компилятор с текущими настройками на текущей платформе даст общим типам.
Да, так и есть.
256 - Много точек. При 36 точках гармонические искажения всего 0,3% на 25кГц. Можно выводить точки с частотой примерно 500 000гц.
А АЦП не пробовал на встроенном компараторе сделать. У меня получилось 16 разрядов 33кГц. Программно поразрядным взвешиванием.
Насколько я помню у самых маленьких аппаратных DDS типа AD9833 в таблице памяти 1024 значения. Много это или мало, это все должно определяться под задачу так же как и требуемая частота семплов. Для многоразрядных АЦП есть доступные Σ-Δ.
@@TDMLab Есть конечно, но чисто из спортивного интереса сделать Металлодетектор только на Ардуино за 5 копеек, в то время как фирменные стоят от 50000 до миллиона рублей. Теория фильтрации там интересная :))
Хотя есть уже реализация с отрытым кодом на AD1115, но интересно разобраться самому.
То есть от величины настраевающего слова зависит количество адресов точек, чем больше АЦП тем меньше точек и больше частота верно?
Да, но более точно так: чем больше настраивающее слово тем быстрее накапливается аккумулятор, и соответственно быстрее адрес "бежит" по таблице и отсюда выше частота.
Здравствуйте! Спасибо большое за видео. Извините, что так поздно пишу - только натолкнулся на него.
У меня вопрос. А то, что весь PORTD устанавливается на выход не приведёт к тому, что МК нельзя будет по UART'у прошить в дальнейшем?
Если не сносить загрузчик, то все будет нормально.
Добрый день! Этот же метод записи синусов вы применили в Частотнике, только там ocr шимом управляет?
Да, так и есть. Этот метод называется DDS, прямой цифровой синтез, применяется в генераторах, частотниках и т. д.
Ачем использовать таблицы,если сигранды можно генерировать налету синусоиду - функцией синуса, а пилу - переполняющейся переменной типа byte?
Время исполнения функции sin большое, а для пилы да, не обязательно, я говорю, вроде, это в видео.
@@TDMLab справедливо, но можно же было процедурно генерировать эту таблицу при загрузке, экономя флеш
(Простите, что придираюсь, я так, теоретические соображения, не из злых намерений, просто работаю на тиньках 13 и у меня из-за них бзик на оптимизацию))
@@lava_frai Да можно было, но способ создания таблицы прямого отношения к самому алгоритму DDS не имеет, так что я не раскрывал это отдельно.
Да все в порядке, нормальный вопрос.
Пробовал разные варианты R-2R DAC, но лучше разрешения, чем 7 бит получить не удалось. Так что не рекомендую. Источником погрешности, по-видимому, является разброс внутренних сопротивлений выходных пинов микроконтроллера (порядка +/-100 Ом), так что использование даже 0.1% резисторов не помогает. Другой источник ошибки - нестабильность питания микроконтроллера, проявляющаяся на выходных пинах. И совсем дело плохо на высоких частотах >1 мГц, где проявляются осцилляции от бит-флипс (...01111...1000), отфильтровать которые не удается
Да, я согласен, что R2R на резисторах это ЦАП-ы для "бедных", тем не менее применяются в дешевых DDS синтезаторах
i2.wp.com/elschemo.ru/wp-content/uploads/2018/03/IMG_20171222_210949.jpg
i.imgur.com/3jp9fmQ.jpg
Для резисторов, на сколько я помню, расчет такой: их точность должна быть не хуже чем 100%/2^n где n - разрядность ЦАП-а,
то есть для 10 бит почти влезают 0,1% резисторы. 1% резисторы - 6-7 бит.
Вообще где-то видел и 14 битные R2R, но там уже по идеи даже 0,01% - не катят и это был скорее коммерческий ход.
По идеи не должно быть у МК +/-100 Ом, там КМОП ключи, что-то многовато 100Ом, как он 20мА на выходе даст при 100 Омах, падение будет 2 Вольта.
Это конечно проблема, но не на столько, ПЛИС-ы более стабильные в теории, еще можно буферезировать и вместе с этим отвязать от цифрового питания.
@@TDMLab Я, собственно, и пытался сделать скоростной R-2R DAC для DDS, с разрешением около 20 ns/step, с использованием PSoC5 от Cypress Semiconductors:
(линк удалён, search youtube for "PSoC5 DDS with slew and amplitude control").
Остановился на 4-х битах, дальше улучшения формы сигнала не заметно. DDS сделан полностью на "железе", используя PLD логику микроконтроллера.
На низких частотах добиться разрешения DAC даже 8-бит не удалось, получилось с натяжкой 7-бит (резисторы 20к 0.1%), что хуже даже встроенного 8-бит DAC. Пробовал также resistor array, с тем же результатом. Поэтому подозреваю что пины микроконтроллера неодинаковые.
@@odissey2 Странно, возможно это действительно особенности выходов МК, иногда бывают разные режимы работы выходных транзисторов. Честно говоря всегда считал что уж 8 бит можно получить на R2R, тем более этот вид ЦАП-ов раньше был распространен и в интегральном исполнении.
Сам планирую поковырять Spartan-7 от Xilinx и сделать на ней DDS и думал как раз на r2r 0,1% 1k и 2k + буферизация.
@@TDMLab Интересно. Будем ждать видео про R-2R DAC.
Просто нужно использовать цифровые технологии - не грузить выходы МК на резики, а грузить на высокоомные входы микросхемы 74ABT574, которая 8 параллельных ячеек памяти, инфа из которых отдается уже на резики по перепаду от генератора (которым тактируем это микруху и МК). Получим своевременную выдачу битов на резисторы с практически идеальными параметрами по амплитуде и равномерности внутренних сопротивлений выводов.
А МК тоже будет работать в тепличных условиях - от него в этом случае всего лишь требуется не ошибиться на километр (не записать откровенную дезу в микруху).
Короче внешняя микра и внешний ген затащат я думаю.
Собрал такую же установку и загрузил такой же код, но на выходе только постоянное напряжение на 1,5 В
Положение потенциометра или что то не так в схеме. Чем смотрите?
Контакт поменял и заработало. Спасибо за видео.
Ещё бы хотелось узнать, куда можно приписать Serial.println(analogRead(0)), чтобы увидеть графики без осциллографа
@@xqwyx-11 посмотрите переменную, которую я в порт вывожу и её и ставьте в serial print
Но не факт, что будет работать, данные сыпяться очень быстро и там ещё прерывание есть, оно будет мешать.
почему бы не воспользоватся указателем в который записывать адрес таблицы и сэкономить такт на сравнение? и почему бы не бежать по таблице в основном цикле, а делать перестройку по прерыванию (нажатию)? хотя я честно говоря не понял как вы сделали внешние прерывание не на D2/D3 которые уже заняты, где-то я читал что ардуинка умеет только на этих ногах.
Да, можно. Бежать по таблице в основном цикле это значит зависеть от длительности исполнения этого основного цикла. Прерывание позволяет создать жесткий и контролируемый реал-тайм. Существуют так же прерывания не по отдельным пинам, а по всему порту одновременно. Собственно прерывание PCINT0 будет исполнено если произошло изменение хотя бы на одном выводе порта C. Дальше в самом векторе уже можно разобраться что конкретно произошло.
А зачем добавлять прерывания #include
если они ни где не используются?
Как ни где не используются? В программе целых два вектора прерываний.
Строчка #include может быть убрана потому, что Arduino IDE добавляет ее по умолчанию.
Спасибо
Нужна помощь в создании мк для зимней электронной удочки САМОТРЯС .Если вы нет то может есть человек на примете кто поможет .Поляна за мной.
виду любитель lua)))
В конце автор сказал АЦП . А название ЦАП
Контент у вас конечно выше всяких похвал.
Есть чему поучиться.
Но зачем вы пишете в IDE ардуино?
Почему не мп лаб или атмел студио?
Нет принципиальной разницы, а аудитория у ардуино много больше)
Посмотрел, но не понял зачем значение потенциометра постоянно суммируется? что это дает.
Эта сумма служит адресом в таблице, чем быстрее она увеличивается тем быстрее программа пробегает по таблице и тем выше частота.
Очень странный метод регулятора частоты ,получается что просто кромсаешь таблицу.Но зачем ,ведь скорости достаточно что бы всегда пробегать весь массив ! Просто менять OCR0A = 39; у вас а надо сделать OCR0A= ADCH; и получим тот же регулятор частоты ,только он всегда будет гладкий!
Это DDS, стандартный и общеупотребимый алгоритм. Если менять OCR0A, то можно получить для 8-ми битного регистра ровно 255 возможных значений частоты, а DDS, может сформировать несравнимо более мелкий шаг перестройки и его параметры гибко настраиваются разрядностью фазового аккумулятора и длиной таблицы.
Такие вещи лучше на гите выкладывать.
а почему нельзя было синусоиду по формуле посчитать? PORTD=sin(x);
Расчет синуса "на ходу" занимает много машинного времени.
@@TDMLab Для "пилы" таблица вообще не нужна, тем более если Вы используете switch. Другой вариант - менять указатели на таблицы, тогда не нужен switch. Нет необходимости считать синус "на ходу", можно посчитать один раз, заполнить таблицу, и потом использовать рассчитанные значения как в Вашем случае. Посчитать один раз можно как минимум двумя способами: в setup, либо объявить в loop статический указатель на таблицу, проинициализировав который возвращаемым значением из функции, которая и рассчитает значения. В обработчике кнопки, учитывая, что у Вас всего два значения, вместо инкремента mode и проверки на >1 можно заменить одной строчкой mode = !mode.
@@motofritz да, для пилы таблица не нужна, я вроде это говорю в видео.
Да, можно сгенерировать таблицу например в сетапе.
Да, и про кнопку тоже верно.
В целом это лишь пример работы DDS, и код может быть оптимизирован разными способами в зависимости от того что нужно сэкономить.
Как мне показалось, выше человек спрашивал именно про расчет на ходу, что собственно я и не рекомендую.