Я думаю Вам стоит записать несколько видео уроков по нормальному программированию ардуины. Начать с чего то попроще и выйти на регистры порты прерывания таймеры и заложить основы программирования циклы условия побитовые операции организация памяти стек, куча. Количество подписчиков вырастит в разы!!! У вас очень хорошо получается рассказывать!!! Кто за лайк !!!
Это классно. Только, мне кажется, чтобы воспроизводимые сигналы реально можно было как-то использовать, и чтоб они при этом не сильно поплыли, неплохо бы их хоть как-то усилить, хотя бы просто транзистором, но можно и покруче выход намутить, на ОУ и транзисторах (npn+pnp). А вообще, есть такая мысль интересная (навеяло этими размышлениями о ЦАПах и АЦПшках), если сделать и ЦАП и АЦП, и программку, то можно же тогда записывать и воспроизводить вообще любые сигналы, подобно тому, как мы это делаем со звуком, только максимально допустимая частота больше, чем у звуковухи, а минимальная вообще 0, тогда с любой самодельной схемы можно сигнал записать, поразглядывать, и воспроизвести, и подать куда хошь, на другую схему например. А если ещё для симуляторов схем плагин какой-нибудь намутить, чтоб сигнал выводили в файл, то вообще можно для экспериментов деталюхи не брать, а реальный сигнал получать из ЦАПа. Не знаю, делал ли такое кто-нибудь, но мысль вроде интересная. На трёх ЦАПах тогда можно хоть различные версии инверторов моделировать, и пробовать их на моторчике от жёсткого, подключив к ЦАПам. Думаю, 3-4 канала хватит на любые проекты вообще. А если ещё забахать всё это на симметричном питании, а с компом данными обмениваться через оптроны например, то и с настоящей переменкой можно "играться". Ну, с маленькой, но с настоящей)))
Отличное изложение. В целях отладки вместе с целевой функцией выводят ещё и некий синхроимпульс - чтобы картинка на осциллографе не прыгала. Но если мне потребуется генерить стандартные функции, то я предпочту поставить копеечный внешний DDS. А если произвольной формы, то не копеечный, тысяч за пять рублей с превосходными параметрами временной и амплитудной точности, модуляцией и прочей радио-лабудой ;).
Да, конечно даже мелкая AD9833 справится с синусом гораздо лучше и легко подключается к МК. Такой вариант только где-то на очень низких частотах (1-10Гц, иногда нужен и такой сигнал) может приблизиться к младшим аппаратным DDS (если увеличить таблицу и разрядность аккумулятора), тем не менее принцип работы у них одинаков и переход от простого к сложному это предпочтительный путь :)
Крайне обидно, мне бы это видео пару лет назад...прошу Вас записать серию роликов по программированию avr, спасибо за контент, всегда приятно смотреть)
256 - Много точек. При 36 точках гармонические искажения всего 0,3% на 25кГц. Можно выводить точки с частотой примерно 500 000гц. А АЦП не пробовал на встроенном компараторе сделать. У меня получилось 16 разрядов 33кГц. Программно поразрядным взвешиванием.
Насколько я помню у самых маленьких аппаратных DDS типа AD9833 в таблице памяти 1024 значения. Много это или мало, это все должно определяться под задачу так же как и требуемая частота семплов. Для многоразрядных АЦП есть доступные Σ-Δ.
@@TDMLab Есть конечно, но чисто из спортивного интереса сделать Металлодетектор только на Ардуино за 5 копеек, в то время как фирменные стоят от 50000 до миллиона рублей. Теория фильтрации там интересная :)) Хотя есть уже реализация с отрытым кодом на AD1115, но интересно разобраться самому.
Вместо word удобнее использовать типы типа uint16_t чтобы не думать какой размер текущий компилятор с текущими настройками на текущей платформе даст общим типам.
Да, но более точно так: чем больше настраивающее слово тем быстрее накапливается аккумулятор, и соответственно быстрее адрес "бежит" по таблице и отсюда выше частота.
Здравствуйте! Спасибо большое за видео. Извините, что так поздно пишу - только натолкнулся на него. У меня вопрос. А то, что весь PORTD устанавливается на выход не приведёт к тому, что МК нельзя будет по UART'у прошить в дальнейшем?
Пробовал разные варианты 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 параллельных ячеек памяти, инфа из которых отдается уже на резики по перепаду от генератора (которым тактируем это микруху и МК). Получим своевременную выдачу битов на резисторы с практически идеальными параметрами по амплитуде и равномерности внутренних сопротивлений выводов. А МК тоже будет работать в тепличных условиях - от него в этом случае всего лишь требуется не ошибиться на километр (не записать откровенную дезу в микруху). Короче внешняя микра и внешний ген затащат я думаю.
@@TDMLab справедливо, но можно же было процедурно генерировать эту таблицу при загрузке, экономя флеш (Простите, что придираюсь, я так, теоретические соображения, не из злых намерений, просто работаю на тиньках 13 и у меня из-за них бзик на оптимизацию))
@@lava_frai Да можно было, но способ создания таблицы прямого отношения к самому алгоритму DDS не имеет, так что я не раскрывал это отдельно. Да все в порядке, нормальный вопрос.
Как ни где не используются? В программе целых два вектора прерываний. Строчка #include может быть убрана потому, что Arduino IDE добавляет ее по умолчанию.
Контакт поменял и заработало. Спасибо за видео. Ещё бы хотелось узнать, куда можно приписать Serial.println(analogRead(0)), чтобы увидеть графики без осциллографа
@@xqwyx-11 посмотрите переменную, которую я в порт вывожу и её и ставьте в serial print Но не факт, что будет работать, данные сыпяться очень быстро и там ещё прерывание есть, оно будет мешать.
почему бы не воспользоватся указателем в который записывать адрес таблицы и сэкономить такт на сравнение? и почему бы не бежать по таблице в основном цикле, а делать перестройку по прерыванию (нажатию)? хотя я честно говоря не понял как вы сделали внешние прерывание не на D2/D3 которые уже заняты, где-то я читал что ардуинка умеет только на этих ногах.
Да, можно. Бежать по таблице в основном цикле это значит зависеть от длительности исполнения этого основного цикла. Прерывание позволяет создать жесткий и контролируемый реал-тайм. Существуют так же прерывания не по отдельным пинам, а по всему порту одновременно. Собственно прерывание PCINT0 будет исполнено если произошло изменение хотя бы на одном выводе порта C. Дальше в самом векторе уже можно разобраться что конкретно произошло.
Очень странный метод регулятора частоты ,получается что просто кромсаешь таблицу.Но зачем ,ведь скорости достаточно что бы всегда пробегать весь массив ! Просто менять OCR0A = 39; у вас а надо сделать OCR0A= ADCH; и получим тот же регулятор частоты ,только он всегда будет гладкий!
Это DDS, стандартный и общеупотребимый алгоритм. Если менять OCR0A, то можно получить для 8-ми битного регистра ровно 255 возможных значений частоты, а DDS, может сформировать несравнимо более мелкий шаг перестройки и его параметры гибко настраиваются разрядностью фазового аккумулятора и длиной таблицы.
@@TDMLab Для "пилы" таблица вообще не нужна, тем более если Вы используете switch. Другой вариант - менять указатели на таблицы, тогда не нужен switch. Нет необходимости считать синус "на ходу", можно посчитать один раз, заполнить таблицу, и потом использовать рассчитанные значения как в Вашем случае. Посчитать один раз можно как минимум двумя способами: в setup, либо объявить в loop статический указатель на таблицу, проинициализировав который возвращаемым значением из функции, которая и рассчитает значения. В обработчике кнопки, учитывая, что у Вас всего два значения, вместо инкремента mode и проверки на >1 можно заменить одной строчкой mode = !mode.
@@motofritz да, для пилы таблица не нужна, я вроде это говорю в видео. Да, можно сгенерировать таблицу например в сетапе. Да, и про кнопку тоже верно. В целом это лишь пример работы DDS, и код может быть оптимизирован разными способами в зависимости от того что нужно сэкономить. Как мне показалось, выше человек спрашивал именно про расчет на ходу, что собственно я и не рекомендую.
Я думаю Вам стоит записать несколько видео уроков по нормальному программированию ардуины. Начать с чего то попроще и выйти на регистры порты прерывания таймеры и заложить основы программирования циклы условия побитовые операции организация памяти стек, куча. Количество подписчиков вырастит в разы!!! У вас очень хорошо получается рассказывать!!! Кто за лайк !!!
Это классно. Только, мне кажется, чтобы воспроизводимые сигналы реально можно было как-то использовать, и чтоб они при этом не сильно поплыли, неплохо бы их хоть как-то усилить, хотя бы просто транзистором, но можно и покруче выход намутить, на ОУ и транзисторах (npn+pnp). А вообще, есть такая мысль интересная (навеяло этими размышлениями о ЦАПах и АЦПшках), если сделать и ЦАП и АЦП, и программку, то можно же тогда записывать и воспроизводить вообще любые сигналы, подобно тому, как мы это делаем со звуком, только максимально допустимая частота больше, чем у звуковухи, а минимальная вообще 0, тогда с любой самодельной схемы можно сигнал записать, поразглядывать, и воспроизвести, и подать куда хошь, на другую схему например. А если ещё для симуляторов схем плагин какой-нибудь намутить, чтоб сигнал выводили в файл, то вообще можно для экспериментов деталюхи не брать, а реальный сигнал получать из ЦАПа. Не знаю, делал ли такое кто-нибудь, но мысль вроде интересная. На трёх ЦАПах тогда можно хоть различные версии инверторов моделировать, и пробовать их на моторчике от жёсткого, подключив к ЦАПам. Думаю, 3-4 канала хватит на любые проекты вообще. А если ещё забахать всё это на симметричном питании, а с компом данными обмениваться через оптроны например, то и с настоящей переменкой можно "играться". Ну, с маленькой, но с настоящей)))
Отличное изложение. В целях отладки вместе с целевой функцией выводят ещё и некий синхроимпульс - чтобы картинка на осциллографе не прыгала.
Но если мне потребуется генерить стандартные функции, то я предпочту поставить копеечный внешний DDS. А если произвольной формы, то не копеечный, тысяч за пять рублей с превосходными параметрами временной и амплитудной точности, модуляцией и прочей радио-лабудой ;).
Да, конечно даже мелкая AD9833 справится с синусом гораздо лучше и легко подключается к МК. Такой вариант только где-то на очень низких частотах (1-10Гц, иногда нужен и такой сигнал) может приблизиться к младшим аппаратным DDS (если увеличить таблицу и разрядность аккумулятора), тем не менее принцип работы у них одинаков и переход от простого к сложному это предпочтительный путь :)
@@TDMLab спасибо. Работа с регистрами стала для меня откритием
Крайне обидно, мне бы это видео пару лет назад...прошу Вас записать серию роликов по программированию avr, спасибо за контент, всегда приятно смотреть)
Спасибо
256 - Много точек. При 36 точках гармонические искажения всего 0,3% на 25кГц. Можно выводить точки с частотой примерно 500 000гц.
А АЦП не пробовал на встроенном компараторе сделать. У меня получилось 16 разрядов 33кГц. Программно поразрядным взвешиванием.
Насколько я помню у самых маленьких аппаратных DDS типа AD9833 в таблице памяти 1024 значения. Много это или мало, это все должно определяться под задачу так же как и требуемая частота семплов. Для многоразрядных АЦП есть доступные Σ-Δ.
@@TDMLab Есть конечно, но чисто из спортивного интереса сделать Металлодетектор только на Ардуино за 5 копеек, в то время как фирменные стоят от 50000 до миллиона рублей. Теория фильтрации там интересная :))
Хотя есть уже реализация с отрытым кодом на AD1115, но интересно разобраться самому.
Вместо word удобнее использовать типы типа uint16_t чтобы не думать какой размер текущий компилятор с текущими настройками на текущей платформе даст общим типам.
Да, так и есть.
Хорошо для тех, у кого есть осцилограф, ну или хотя-бы частотометр. А как бы эту схемку приартачить к LCD и приращивать значение тактовыми кнопками?
th-cam.com/video/RaKAYiVj1qk/w-d-xo.html
Спасибо, познавательно!
То есть от величины настраевающего слова зависит количество адресов точек, чем больше АЦП тем меньше точек и больше частота верно?
Да, но более точно так: чем больше настраивающее слово тем быстрее накапливается аккумулятор, и соответственно быстрее адрес "бежит" по таблице и отсюда выше частота.
Здравствуйте! Спасибо большое за видео. Извините, что так поздно пишу - только натолкнулся на него.
У меня вопрос. А то, что весь PORTD устанавливается на выход не приведёт к тому, что МК нельзя будет по UART'у прошить в дальнейшем?
Если не сносить загрузчик, то все будет нормально.
Добрый день! Этот же метод записи синусов вы применили в Частотнике, только там ocr шимом управляет?
Да, так и есть. Этот метод называется 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 параллельных ячеек памяти, инфа из которых отдается уже на резики по перепаду от генератора (которым тактируем это микруху и МК). Получим своевременную выдачу битов на резисторы с практически идеальными параметрами по амплитуде и равномерности внутренних сопротивлений выводов.
А МК тоже будет работать в тепличных условиях - от него в этом случае всего лишь требуется не ошибиться на километр (не записать откровенную дезу в микруху).
Короче внешняя микра и внешний ген затащат я думаю.
Ачем использовать таблицы,если сигранды можно генерировать налету синусоиду - функцией синуса, а пилу - переполняющейся переменной типа byte?
Время исполнения функции sin большое, а для пилы да, не обязательно, я говорю, вроде, это в видео.
@@TDMLab справедливо, но можно же было процедурно генерировать эту таблицу при загрузке, экономя флеш
(Простите, что придираюсь, я так, теоретические соображения, не из злых намерений, просто работаю на тиньках 13 и у меня из-за них бзик на оптимизацию))
@@lava_frai Да можно было, но способ создания таблицы прямого отношения к самому алгоритму DDS не имеет, так что я не раскрывал это отдельно.
Да все в порядке, нормальный вопрос.
Нужна помощь в создании мк для зимней электронной удочки САМОТРЯС .Если вы нет то может есть человек на примете кто поможет .Поляна за мной.
А зачем добавлять прерывания #include
если они ни где не используются?
Как ни где не используются? В программе целых два вектора прерываний.
Строчка #include может быть убрана потому, что Arduino IDE добавляет ее по умолчанию.
Спасибо
Собрал такую же установку и загрузил такой же код, но на выходе только постоянное напряжение на 1,5 В
Положение потенциометра или что то не так в схеме. Чем смотрите?
Контакт поменял и заработало. Спасибо за видео.
Ещё бы хотелось узнать, куда можно приписать Serial.println(analogRead(0)), чтобы увидеть графики без осциллографа
@@xqwyx-11 посмотрите переменную, которую я в порт вывожу и её и ставьте в serial print
Но не факт, что будет работать, данные сыпяться очень быстро и там ещё прерывание есть, оно будет мешать.
почему бы не воспользоватся указателем в который записывать адрес таблицы и сэкономить такт на сравнение? и почему бы не бежать по таблице в основном цикле, а делать перестройку по прерыванию (нажатию)? хотя я честно говоря не понял как вы сделали внешние прерывание не на D2/D3 которые уже заняты, где-то я читал что ардуинка умеет только на этих ногах.
Да, можно. Бежать по таблице в основном цикле это значит зависеть от длительности исполнения этого основного цикла. Прерывание позволяет создать жесткий и контролируемый реал-тайм. Существуют так же прерывания не по отдельным пинам, а по всему порту одновременно. Собственно прерывание PCINT0 будет исполнено если произошло изменение хотя бы на одном выводе порта C. Дальше в самом векторе уже можно разобраться что конкретно произошло.
виду любитель 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, и код может быть оптимизирован разными способами в зависимости от того что нужно сэкономить.
Как мне показалось, выше человек спрашивал именно про расчет на ходу, что собственно я и не рекомендую.