Оглавление:

Arduino UNO Logic Sniffer: 8 шагов (с изображениями)
Arduino UNO Logic Sniffer: 8 шагов (с изображениями)

Видео: Arduino UNO Logic Sniffer: 8 шагов (с изображениями)

Видео: Arduino UNO Logic Sniffer: 8 шагов (с изображениями)
Видео: Using an Arduino Uno as Logical Analyzer 2024, Июль
Anonim
Анализатор логики Arduino UNO
Анализатор логики Arduino UNO

Этот проект начался как простой эксперимент. Во время исследования таблицы данных ATMEGA328P для другого проекта я обнаружил кое-что довольно интересное. Блок захвата входа Timer1. Это позволяет микроконтроллеру Arduino UNO обнаруживать фронт сигнала, сохранять временную метку и запускать прерывание, причем аппаратно.

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

Я не единственный, кому пришла в голову эта идея, и вы найдете их множество, просто загуглив «Arduino Logic Analyzer». В начале проекта, поскольку он только начинался как эксперимент, я даже не знал, что люди уже сделали это, и был впечатлен хорошими результатами, которых они достигли с этим маленьким элементом оборудования. Однако мне не удалось найти другой проект, использующий блок ввода ввода, поэтому, если вы уже видели это, дайте мне знать!

Подводя итог, мой логический анализатор:

  • Есть один канал,
  • Иметь графический интерфейс,
  • Связь с интерфейсом через USB,
  • Запускается на плате Arduino UNO.

Наконец, он будет иметь глубину памяти 800 отсчетов и сможет успешно захватывать сообщение UART 115200 бод (я действительно не тестировал его на более высоких скоростях).

Это руководство содержит части этого проекта «как это работает» и «как это использовать», так что для тех, кого не интересует техническая сторона, вы можете сразу перейти к шагу 4.

Запасы

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

Тебе понадобится:

  • Плата Arduino UNO (или эквивалент, если он основан на микроконтроллере ATMEGA328P),
  • Компьютер,
  • Что-то для отладки (другая плата Arduino UNO отлично подойдет для некоторых тестов).

Здесь можно найти код для Arduino UNO и веб-интерфейса. Вам также потребуются программы p5.serialcontrol и PulseView.

Шаг 1: принцип работы

Принцип работы
Принцип работы

Идея проста. Вы выбираете настройки захвата и нажимаете «получить». Веб-интерфейс отправит их в программное обеспечение p5.serialcontrol, которое позволяет нам использовать последовательный интерфейс из браузера, поскольку у него нет прямого доступа к нему. Затем программа p5.serialcontrol передает информацию на плату Arduino UNO, которая собирает данные и отправляет их обратно в интерфейс по тому же пути.

Легкий! Что ж … Поскольку я не очень хорошо разбираюсь в программировании человеко-машинного интерфейса или в веб-технологиях, мой язык определенно немного уродлив и содержит ошибки. Но он позволяет мне начать захват и получить обратно мои данные, для чего он был разработан, так что я думаю, что это нормально. Для более серьезной аналитической работы я импортирую свои записи в PulseView, который прост в использовании и предлагает хороший набор функций и декодеров протоколов, как мы увидим позже.

Блок ввода входного сигнала Arduino UNO может быть сконфигурирован для использования различных делений тактовой частоты, тем самым уменьшая разрешение, но увеличивая задержку перед переполнением. Он также может срабатывать при нарастании, падении или обоих фронтах, чтобы начать сбор данных.

Шаг 2: эскиз Arduino UNO

Эскиз Arduino UNO
Эскиз Arduino UNO

Я написал и скомпилировал скетч с помощью Arduino IDE. Сначала я начал с установки Timer1 в «Нормальный» режим работы, записав в его регистры TCCR1A и TCCR1B в setup (). Затем я создал несколько функций, чтобы немного упростить его использование в будущем, например, функцию для установки деления часов с именем "setTim1PSC ()". Я также написал функции для активации и деактивации модуля захвата ввода Timer1 и прерывания переполнения.

Я добавил массив "samples", в котором будут храниться полученные данные. Это глобальный массив, для которого я установил значение «volatile», чтобы компилятор не произвел оптимизацию и не поместил его во флэш-память, как это было во время моих первых компиляций. Я определил его как массив «uint16_t», так как Timer1 также 16-битный, с длиной 810. Мы прекращаем сбор при 800 значениях, но поскольку тест выполняется вне прерываний по очевидным причинам скорости, я решил оставить 10 больше значений для предотвращения переполнения. С несколькими дополнительными переменными для остальной части кода скетч использует 1313 байт (88%) памяти, оставляя нам 235 байт свободной ОЗУ. У нас уже много памяти, и я не хотел увеличивать емкость сэмплов, так как это могло вызвать странное поведение из-за слишком малого объема памяти.

В своем стремлении всегда увеличивать скорость выполнения я использовал указатели на функции вместо операторов if внутри прерываний, чтобы сократить время их выполнения до минимума. Выводом захвата всегда будет Arduino UNO номер 8, так как он единственный, подключенный к входному блоку захвата Timer1.

Процесс захвата показан на изображении выше. Он запускается, когда Arduino UNO получает действительный фрейм данных UART, содержащий желаемые настройки захвата. Затем мы обрабатываем эти настройки, настраивая правильные регистры для захвата на выбранном фронте и используя правильное деление тактовой частоты. Затем мы разрешаем прерывание PCINT0 (изменение вывода) для обнаружения фронта первого сигнала. Когда мы его получаем, мы сбрасываем значение Timer1, отключаем прерывание PCINT0 и включаем прерывание ICU (Input Capture Unit). С этого момента любой спадающий / нарастающий фронт сигнала (в зависимости от выбранной конфигурации) запускает блок захвата входа, таким образом сохраняя метку времени этого события в регистре ICR1 и выполняя прерывание. В этом прерывании мы помещаем значение регистра ICR1 в наш массив «выборок» и увеличиваем индекс для следующего захвата. Когда Timer1 или массив переполняются, мы отключаем прерывание захвата и отправляем данные обратно в веб-интерфейс через UART.

Я решил использовать прерывание смены вывода для запуска захвата, поскольку входной блок захвата позволяет захватывать только один или другой край, но не оба. Это также вызывает проблемы, когда вы хотите захватить оба края. Мое решение заключалось в том, чтобы инвертировать бит, который управляет выбором края в регистре управления захватом ввода при каждой полученной выборке. Таким образом, мы теряем скорость выполнения, но по-прежнему можем использовать функции блока ввода данных.

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

Шаг 3. Веб-интерфейс и P5.js

Веб-интерфейс и P5.js
Веб-интерфейс и P5.js

Как видно из названия, веб-интерфейс был создан с помощью p5.js. Для тех, кто еще этого не знает, я настоятельно рекомендую вам пойти и проверить веб-сайт, так как это действительно хорошая библиотека. Он основан на обработке, прост в использовании, позволяет очень быстро получать хорошие результаты и хорошо документирован. По всем этим причинам я выбрал эту библиотеку. Я также использовал библиотеку quicksettings.js для меню, grafica.js для построения моих данных и библиотеку p5.serialport для связи с Arduino UNO.

Я не буду тратить слишком много времени на интерфейс, так как я просто разработал его для предварительного просмотра данных и управления настройками, а также потому, что он вообще не был предметом моего эксперимента. Однако в следующих частях я объясню различные шаги по использованию всей системы, объясняя, таким образом, различные доступные элементы управления.

Шаг 4: Настройка системы

Первым делом загрузите сюда Arduino UNO и код интерфейса, если это еще не сделано. Затем вы можете перепрограммировать вашу плату Arduino UNO с помощью скетча «UNO_LS.ino» через Arduino IDE.

Вы должны были загрузить программное обеспечение p5.serialcontrol из его репозитория на github. Вы должны получить zip-файл, соответствующий вашей операционной системе (я тестировал его только в Windows). Распакуйте zip-архив в папку, запустите найденный в нем исполняемый файл и оставьте его в таком виде. Не пытайтесь подключиться к какому-либо последовательному порту, просто оставьте его работать в фоновом режиме, он будет использоваться в качестве реле.

Откройте папку «Интерфейс». Вы должны найти файл с именем "index.html". Откройте его в браузере, это веб-интерфейс.

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

Шаг 5: подключение, настройка и получение

Подключение, настройка и приобретение
Подключение, настройка и приобретение

Чтобы подключить интерфейс к плате Arduino UNO, просто выберите соответствующий порт в списке и нажмите кнопку «Открыть». Если операция прошла успешно, в сообщении «состояние» должно отображаться что-то вроде «COMX открыт».

Теперь вы можете выбрать параметры захвата. Во-первых, это выбор края. Я рекомендую вам всегда использовать "Оба", так как это даст вам лучшее представление реального сигнала. Если при установке «Оба» сигнал не улавливается (например, если частота сигнала слишком высока), вы можете попробовать выбрать настройку фронта «Растущий» или «Спадающий», в зависимости от сигнала, который вы пытаетесь увидеть.

Вторая настройка - это деление часов. Это даст вам разрешение, при котором вы сможете захватить сигнал. Вы можете установить коэффициент деления на «8», «64», «256» или «1024». Плата Arduino UNO использует кварц 16 МГц для синхронизации микроконтроллера, поэтому частота дискретизации будет «16 МГц / коэффициент деления». Будьте осторожны с этой настройкой, так как она также определяет, как долго вы сможете захватывать сигнал. Поскольку Timer1 является 16-битным таймером, допустимое время захвата до переполнения будет «(2 ^ 16) * (коэффициент деления) / 16MHz». В зависимости от выбранной вами настройки он будет находиться в диапазоне от ~ 33 мс до 4,2 с. Держите свой выбор в уме, он вам понадобится позже.

Последняя настройка - шумоподавитель. Я не проводил много тестов на нем, и в 99% случаев он вам не понадобится, поэтому просто оставьте его не отмеченным. Для тех, кому это все еще интересно, вы можете поискать шумоподавитель в разделе Timer / Counter1 таблицы ATMEGA328P.

Не забудьте подключить контакт 8 платы Arduino UNO к вашему сигналу и соединить заземления вместе, чтобы иметь одинаковое опорное напряжение как для схемы тестирования, так и для логического анализатора. Если вам нужна изоляция заземления или вам нужно измерить сигналы с уровнями, отличными от 5 В, вам, вероятно, потребуется добавить в свою схему оптоизолятор.

После того, как все настроено правильно, вы можете нажать кнопку «Получить».

Шаг 6. Сохранение результатов и экспорт данных в CSV

Получение результатов и экспорт данных в CSV
Получение результатов и экспорт данных в CSV

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

Сюжет дает вам только предварительный просмотр и не имеет инструментов для анализа данных. Таким образом, чтобы провести дальнейший анализ ваших данных, вам нужно будет импортировать их в PulseView.

Первый шаг - экспортировать CSV-файл, содержащий все ваши данные. Для этого вам просто нужно нажать кнопку «Экспорт» в веб-интерфейсе. При появлении запроса сохраните файл в известном месте.

Теперь откройте PulseView. В верхней строке меню нажмите «Открыть» (значок папки) и выберите «Импортировать значения, разделенные запятыми…». Выберите ранее созданный CSV-файл, содержащий ваши данные.

Появится небольшое окошко. Оставьте все как есть, вам просто нужно изменить настройку «Samplerate» в соответствии с коэффициентом деления часов, выбранным для захвата. Ваша частота дискретизации будет «16 МГц / (коэффициент деления)». Затем нажмите «ОК», ваш сигнал должен появиться на экране.

Шаг 7: Анализ сигнала PulseView

Анализ сигналов PulseView
Анализ сигналов PulseView

PulseView имеет множество декодеров протоколов. Чтобы получить к ним доступ, нажмите «Добавить декодер протокола» в верхней строке меню (самый правый инструмент). Для своего эксперимента я просто отправил простое сообщение UART на 9600 бод, поэтому я поискал "UART".

Он добавит канал с тегом слева (точно так же, как и для ваших данных). Щелкнув по тегу, вы можете изменить настройки декодера. Выбрав правильные, я смог получить то же сообщение, что и отправленное моим тестовым устройством. Это показывает, что вся система работает должным образом.

Шаг 8: Заключение

Заключение
Заключение

Даже если вначале проект был экспериментом, я доволен полученными результатами. Я смог без проблем отобрать сигналы UART на скорости до 115200 бод в режиме «Оба» фронта, и мне даже удалось подняться до 230400 бод в режиме «падающего» фронта. Вы можете увидеть мою тестовую установку на картинке выше.

Моя реализация имеет несколько недостатков, начиная с того факта, что она может захватывать только один сигнал за раз, так как только вывод 8 Arduino UNO "способен захватывать вход". Если вы ищете логический анализатор Arduino с большим количеством каналов, посмотрите на него Катоблепаса.

Вы не можете ожидать, что Arduino UNO сможет захватывать сигналы с высокими частотами (несколько МГц), поскольку он работает только на частоте 16 МГц (если бы кто-нибудь это сделал, мне было бы интересно увидеть его метод). Тем не менее, я все еще впечатлен результатами, которые мы можем получить с помощью этого микроконтроллера ATMEGA328P.

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

Это была моя первая обучающая программа, и я думаю, она длинная. Я надеюсь, что это чтение было для вас интересным.

Сообщите мне, если вы обнаружите ошибки или у вас возникнут вопросы!

Рекомендуемые: