Данная статья будет посвящена рассмотрению метода георадиолокации, его принципам работы и возможностям применения в геологии и инженерных изысканиях, разберем, из чего состоит георадар, как он функционирует, а также какие задачи позволяет решать георадиолокационные исследования при изучении подповерхностных слоев.
Метод георадиолокации (GPR‑ Ground Penetrating Radar) — это геофизический метод, основанный на зондировании грунта с помощью электромагнитных волн, ультравысоких частот (обычно от десятков МГц до нескольких ГГц), он применяется для исследования структуры подповерхностных слоев без их разрушения.
На видео представлен пример работы георадара
на глубине от 1 до 1.5 метра просматривается газовая труба
Методом георадиолокации обладает георадар - это высокотехнологичный прибор, разработанный для подповерхностного зондирования, его конструкция сочетает несколько ключевых узлов, которые обеспечивают работу системы:
Передатчик - генерирует элекромагнитные импульсы и посылает их в грунт;
Приемник - улавливает отраженные сигналы и преобразует их для последующей обработки;
Модуль управления - отвечает за синхронизацию излучения и приема сигналов, а также передачу данных в систему обработки;
Поглотитель - представляют собой материалы с диэлектрическими потерями, предназначенные для подавления нежелательных отражений радиосигналов в корпусе прибора и между компонентами антенной системы, что повышает качество получаемой информации. Их состав включает диэлектрические материалы с включениями ферритов, углеродных волокон или других проводящих частиц, которые поглощают электромагнитную энергию.
Основное свойство таких поглотителей – эффективное рассеивание и поглощение электромагнитных волн в заданном диапазоне частот, обеспечивая тем самым улучшение сигнала и разрешение в георадарных данных.
В геологии георадары применяются для решения следующих задач:
Картирование геологических структур - восстановление геометрии относительно протяжных границ, поверхности коренных пород под рыхлыми осадками, уровня грунтовых вод, границ между слоями с различной степенью водонасыщения, поиск месторождений, строительных материалов;
Определение свойств различных отложений по скорости распространения электромагнитных волн, опираясь на связь этих свойств с диэлектрической проницаемостью пород;
Определение толщины ледяного покрова;
Определение мощности водоносного слоя и картирование поддонных отложений;
Определение мощности зоны сезонного промерзания или оттаивания, картирование границ мерзлых и талых пород.
При проведении георадарных исследований основное внимание уделяется двум параметрам:
время пробега электромагнитной волны — сколько времени требуется сигналу, чтобы пройти от передатчика до отражающей границы и вернуться обратно к приёмнику;
амплитуда отражения — насколько сильным оказался отражённый сигнал.
Отражение возникает на границах раздела разных сред: между сухими и влажными грунтами (уровень грунтовых вод), мерзлыми и талыми породами, коренными и рыхлыми слоями, разными по составу породами, а также на стыке природных и искусственных материалов (например, грунт — бетон, новый и старый асфальт).
Сила отражённого сигнала зависит от коэффициента отражения, который определяется разницей диэлектрических проницаемостей двух соседних слоёв. Чем больше эта разница, тем контрастнее будет отражение.
Амплитуда отраженного сигнала от границы между слоями пропорциональна величине Котр. (коэффициент отражения):
Скорость распространения электромагнитной волны также связана с диэлектрической проницаемостью среды:
где c — скорость света в вакууме, ε — диэлектрическая проницаемость материала. В георадиолокации скорость обычно измеряется в сантиметрах на наносекунду (см/нс). Для удобства формула часто записывается так:
Здесь особенно важно, что воздух имеет диэлектрическую проницаемость 1, а вода — 81. Поэтому именно соотношение воды и воздуха в породе в первую очередь определяет её свойства.
Сухие, плотные и монолитные породы обладают низкой диэлектрической проницаемостью и высокой скоростью распространения сигнала.
Влагонасыщенные, пористые и трещиноватые — наоборот, имеют высокую диэлектрическую проницаемость и замедляют прохождение электромагнитной волны.
Таким образом, измеряя времена пробега сигнала и анализируя его амплитуду, можно определить строение подповерхностных слоёв и физические свойства пород.
Электромагнитный импульс в георадиолокации — это короткий сигнал, состоящий из 1,0–2,0 периодов квазигармонической волны, который излучается в исследуемую среду с помощью антенны. Благодаря своей малой длительности такой импульс имеет широкий спектр частот, что позволяет фиксировать отражения от различных границ между средами — сухими и влажными грунтами, мерзлыми и талыми породами, разными по составу слоями или инженерными конструкциями. Отражённые импульсы улавливаются приёмной антенной, усиливаются и обрабатываются, а время их прохождения используется для восстановления строения подповерхностных слоёв.
Малая временная длительность излучаемого импульса приводит к возникновению достаточно широкого частотного спектра излучения
Квазигармоническая волна — это электромагнитный сигнал, близкий по форме к гармоническому (синусоидальному), но ограниченный во времени и содержащий лишь 1–2 периода колебаний. В отличие от идеальной бесконечной гармонической волны, квазигармоническая имеет широкий спектр частот, что делает её удобной для зондирования: она позволяет выявлять отражения от разных по свойствам границ в грунте и инженерных сооружениях.
Первое отражение на радарограмме называют прямой волной (сигналом прямого прохождения). Прямая волна в большинстве случаев одинаковая для всех трасс профиля. Она определяется конструкцией антенны и поверхностью профиля. Прочие волны на радарограмме являются отраженными от каких либо слоев или локальных объектов в грунте (или другой среде исследования).
Дифрагированная волна возникает из-за явления дифракции — это ситуация, когда электромагнитная волна «огибает» препятствие или рассеивается на нём. Такое происходит в том случае, если размер объекта сравним с длиной волны или меньше её.
В георадиолокации дифракция чаще всего возникает, когда сигнал встречает вытянутые объекты: трубы, кабели, элементы арматуры и другие инженерные конструкции.
На радарограмме дифракция имеет характерный «подпись» — отражение отображается не как прямая линия, а в виде гиперболы. Точка вершины этой гиперболы указывает на реальное местоположение объекта в грунте.
Проще говоря, если на записи появляется гипербола, значит под поверхностью находится небольшой протяжённый предмет, например труба или кабель.
Пример поиска водоносного слоя
Отчетливо можно рассмотреть что глубина водоносного слоя пролегает от 5 до 6 метров
Водоносный слой — это природный горизонт горных пород, способный накапливать и проводить подземные воды благодаря своей пористости и проницаемости. Чаще всего такими породами являются пески, гравий или трещиноватые известняки. Эти слои играют ключевую роль в формировании и движении грунтовых вод, выступают естественными резервуарами и источниками питьевой или технической воды.
Для геодезии и инженерной геологии водоносный слой имеет особое значение: он влияет на выбор места строительства, устойчивость фундаментов, проектирование подземных сооружений и коммуникаций. По сути, это скрытая под землёй «водная артерия», от свойств и глубины залегания которой во многом зависит как природная среда, так и деятельность человека.
Амплитуда отражённого сигнала в георадиолокации напрямую связана с контрастом диэлектрических свойств соседних слоёв.
У водоносного слоя ключевая особенность — высокая диэлектрическая проницаемость, так как вода имеет ε ≈ 81 (для сравнения: воздух — 1, сухой песок — 3–5, сухой известняк — 6–8). Когда электромагнитный импульс встречает границу «сухой грунт → водонасыщенный слой», возникает резкий скачок в значении ε.
Это приводит к:
сильному увеличению амплитуды отражённого сигнала — чем больше разница между слоями, тем ярче отражение на записи;
появлению чёткой границы на радиолокационном разрезе (обычно в виде яркой горизонтальной линии).
Таким образом, водоносный слой определяется по мощному отражению, возникающему на контакте сухих и влагонасыщенных грунтов.
Таблица значений диэлектрической проницаемости (ε) различных сред
В заключение можно сказать, что метод георадиолокации является эффективным и универсальным инструментом для изучения подповерхностных структур. Он позволяет получать ценную информацию о строении грунтов, глубине залегания водоносных слоёв, границах промерзания и подземных объектах без разрушения исследуемой среды.
Благодаря своей информативности, оперативности и не нарушающему характеру исследований, георадиолокация занимает важное место в геологии, инженерных изысканиях и строительной практике.
Если статья показалась Вам интересной, буду рад выпустить для Вас еще множество статей исследований по всевозможным видам устройств, так что, если не хотите их пропустить – буду благодарен за подписку на мой ТГ-канал: https://t.me/ChipCraft.
Автономные системы становятся все более востребованными - от портативных приборов до сложных промышленных комплексов - надежное управление напряжением питания превращается в ключевой фактор их долговечности и эффективности. Сердце любой такой системы - аккумулятор, а его безопасность и срок службы, напрямую зависит от контроля напряжения.
В данной статье будет представлен пример контроля напряжения, над блоком питания - внутри которого (никель-металлгидридная аккумуляторная сборка NiMH 14.4В/12 банок по 1.2В(1.4В- при полной зарядке)).
В блоке питания уже есть палата управления над аккумулятором, которая выполняет задачи:
Работа с кнопкой;
Работа со светодиодом;
Работа с пъезоэлектрическим излучателем(звуковая индикация);
Контроль заряда/разряда аккумулятора(дает звуковой сигнал при напряжении менее 9 вольт и более 14).
В процессе анализа и статистики использования оборудования стало очевидно, что многие пользователи часто забывают своевременно отключать блоки питания. В результате аккумуляторные сборки продолжают разряжаться даже при отсутствии необходимости, напряжение падает до критических значений, и аккумулятор быстро теряет свою емкость, становясь непригодным для дальнейшей эксплуатации.
Помимо этого, подключенная система оказывается в неопределенном состоянии, на плату управления и различные датчики по-прежнему подается питание, что приводит к избыточной нагрузке. В качестве этого сокращается ресурс электронных компонентов и снижается надежность всего устройства.
Для решения данной проблемы я продемонстрирую пример системы контроля напряжения блока питания, в качестве микроконтроллера выбран STM32F103С8T6, который выполняет следующие задачи:
Непрерывный мониторинг напряжения аккумуляторной сборки, измерение производится через АЦП с использованием DMA;
Оповещение пользователя о низком заряде, при падении напряжения ниже установленного порога (в данном примере - 9.0В) система активизирует звуковой сигнал, время работы оповещения ограничено - звуковая индикация будет длится 5 минут;
Переход в энергосберегающий режим, если напряжение остается ниже порога и пользователь не предпринял действий в течении заданного времени, микроконтроллер переводит систему в режим сна, это сопровождается отключением тактирования и всей периферии, что минимизирует и предотвращает глубокий разряд аккумулятора.
Схема подключения NiMH АКБ, делителя напряжения к АЦП МК, кнопки вкл/выкл и пъезо-излучателя
Перечень компонентов
Объяснение схемы
Узел[1]
Входной силовой ключ, исток подключен к +12V, сток идет к блоку питания(+12_АКК) через предохранители, а затвор подтянут к земле, применение (защищенная подача напряжения питания с аккумуляторного блока);
Узел[2]
Вторичный силовой ключ, обеспечивает управляемое включение/отключение напряжения питания основной нагрузки системы, управление происходит через МК, сигнал PWR_ON, после включения данного узла, на стоке напряжение питания +12ВК активизируется и передает напряжение другим частям схемы, в моем примере это (узел[4]-Звуковая индикация и узел[5]-lделитель напряжения), но также можно использовать данный узел и на включение преобразователей напряжения;
Узел[3]
Данный узел обеспечивает логику взаимодействия с кнопкой включения/выключения, кнопка sa2, при нажатии формирует управляющий сигнал, диод АD4 и конденсатор С1 обеспечивают фильтрацию и антидребезг;
Узел[4]
Данный узел обеспечивает звуковую индикацию, сигнал BEEP подключается к МК;
Узел[5]
Данный узел является делителем напряжения, делит напряжение до уровня, подходящего для измерения АЦП МК (обычно до 3.3V), подстроечный резистор R8, выставлен на 1.7кОм.
Настройка микроконтроллера STM32F103 в CubeIDE
Конфигурация TIM1(PA11)
Таймер TIM1 выполняет роль генератора для звуковой индикации.
Настройка таймера:
Предделитель (Prescaler) и период (Auto-Reload) выбраны так, чтобы на выходе формировался сигнал с частотой в диапазоне, воспринимаемом слухом (обычно 1–5 кГц);
Режим работы – PWM (широтно-импульсная модуляция);
Коэффициент заполнения (Pulse) определяет громкость и характер звучания.
Принцип работы: Таймер генерирует ШИМ-сигнал, который подаётся на транзисторный ключ. Транзистор управляет пьезоизлучателем или динамиком. В результате получается слышимый звук.
Преимущества такого решения:
Микроконтроллеру не нужно вручную формировать частоту – этим занимается таймер;
Легко изменять тональность: достаточно переписать значения ARR/PSC;
Можно реализовать разные звуковые эффекты (короткие сигналы, мелодии) простым управлением таймером из программы.
Конфигурация ADC(PA1)
В проекте используется многоканальный режим работы АЦП с двумя каналами в последовательности (Regular conversion sequence).
Rank 1 – внешний канал (ADC Channel 1). Этот вход подключён к делителю напряжения и используется для измерения напряжения аккумулятора. Благодаря этому микроконтроллер может в реальном времени контролировать состояние питания устройства.
Rank 2 – внутренний канал (Vrefint). Это встроенный источник опорного напряжения микроконтроллера. Он служит для автоматической калибровки и компенсации возможных изменений питающего напряжения. С его помощью можно более точно измерять значение внешних сигналов, в том числе напряжение аккумулятора.
Для повышения эффективности задействован DMA: результаты обоих измерений (Rank 1 и Rank 2) автоматически передаются в память, а процессор получает только готовые данные.
Для правильной настройки ADC я воспользовался данной информацией, там подробно расписано как работать с ADC МК-STM32.
Конфигурация пина для работы с кнопкой
Для работы с кнопкой выбран вывод PB11, сконфигурированный в режиме:
GPIO_EXTI – внешний прерывающий вход. Это значит, что нажатие кнопки обрабатывается не опросом в цикле, а через аппаратное прерывание;
Mode - External interrupt, Falling edge trigger – прерывание срабатывает по спаду сигнала (при замыкании кнопки на землю);
Pull-up – включен внутренний подтягивающий резистор, который удерживает вход в состоянии логической «1», пока кнопка не нажата.
Кнопка подключена так, что в обычном состоянии на входе PB11 присутствует логическая «1» благодаря встроенному подтягивающему резистору (Pull-up). При нажатии контакт замыкается на землю, формируется логический «0» и происходит спад сигнала. Этот спад фиксируется модулем EXTI, который вызывает прерывание.
Конфигурация пина для работы с сигналом PWR_ON
Сигнал PWR_ON играет роль электронного «выключателя питания».
В исходном состоянии (Low) нагрузка обесточена.
При активации (перевод вывода в High) силовой MOSFET открывается, и напряжение +12ВК подаётся на остальные узлы системы.
В примере данная линия питает:
узел [4] – звуковую индикацию,
узел [5] – делитель напряжения для мониторинга питания.
Аналогично этот узел можно использовать и для включения DC/DC-преобразователей или других модулей, требующих управляемого питания.
Конфигурация Clock
Реализация программного кода
Ссылка на скачивание исходного кода [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_исходный_код - Adc_VoltageControl_STM32F103C8T6]
Заголовочный файл keys.h (работа с кнопками)
В данном файле определены:
Функции работы с кнопками;
Битовые маски состояний;
константы для различных сценариев нажатий.
keys.h
Реализация модуля keys.c (работа с кнопками)
Данный модуль включает в себя задачи:
Устранение дребезга контактов;
Различие между коротким и долгим нажатием;
Отслеживание событий нажатия, удержания и отпускания.
keysDrv_Handler()
Вызывается постоянно в основном цикле или из системного таймера.
При заполнении половины буфера → срабатывает прерывание, ставится флаг;
ADC_Calc_Handler считывает данные, фильтрует и усредняет;
Вызывается adc_calcVoltage, которая переводит вольты;
Значение доступно через adc_GetVoltage();
Если напряжение меньше 9 В (по critical_stress) → отрабатывает аварийное выключение.
ADC_Calk.c
Пояснение к функции adc_calcVoltage()
Расчет VDDA, где:
VREFINT_TYP - калибровочное значение 1.20, взято из datasheet, у других МК на заводе производитель прошивает калибровочное значение в ПЗУ при изготовлении, пример получения значения с МК STM32F030CCTx [0x1FFFF7BA];
4095 - когда измеряется источник встроенным АЦП, результат выражается в единицах квантования, максимум которых равен 4095, поэтому в формуле используется множитель 4095 - это нормализация значения, чтобы связать измеренный АЦП с напряжением VDDA.
ADC_vref - значение встроенного источника опорного напряжения
Перевод значения канала в напряжение
ADC_in - напряжение измеренное с делителя напряжения (узел[5])
Коррекция через делитель напряжения
Вход подключен через делитель R1=221кОм и R2 = 27кОм, переводим в Ом,
добавил смещение (-0.5) для подстройки измерений.
Таблица замеров напряжения от 14.5 вольт до 7 вольт.
Прикладываю видео-тестирования прохода по спаду напряжения, а также видео-тестирования, сброс напряжения и уход в сон микроконтроллера при низком напряжении ссылка [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_тестирование_ Adc_VoltageControl]
Реализация модуля proj_main.c (Главный метод)
Данный модуль объединяет несколько подсистем:
Кнопка управления (одиночное и двойное нажатие);
Контроль напряжения питания через АЦП;
Звуковая индикация состояния;
Автоматический переход в сон при низком напряжении.
proj_main.c
Вывод
Данная система контроля над блоком питания реализует:
Обработку кнопок с фильтрацией дребезга, с поддержкой короткого/долгого/двойного нажатия и отпускания;
Мониторинг напряжения через АЦП с защитой от просадок и автоматическим отключением при критическом низком уровне;
Звуковая индикация (короткие, двойные сигналы) для информирования пользователя о событиях;
Энергосбережение переход в режим STOP и пробуждение по прерыванию.
Систему можно использовать как основу для портативных приборов, автономных устройств и встраиваемых систем, где важно одновременно удобное управление и защита электроники.
Если статья показалась Вам интересной, буду рад выпустить для Вас еще множество статей исследований по всевозможным видам устройств, так что, если не хотите их пропустить – буду благодарен за подписку на мой ТГ-канал: https://t.me/ChipCraft.
Современные компьютерные мыши, тачпады, сенсорные панели и мобильная робототехника, обязаны своей точностью и отзывчивостью миниатюрным системам движения. Одним из таких является PAT9125 - это высокоточный двухосевой оптический датчик, способный с невероятной точностью отслеживать перемещение по различным поверхностям.
PAT9125 представляет собой интеллектуальный датчик, в основе которого - микроскопическая камера и инфракрасная подсветка. Он реализует текстуру поверхности под собой, фиксируя мельчайшие смещения и на основе полученных данных изображений рассчитывает вектор движения. Благодаря высокой кадровой частоте, датчик способен точно отслеживать даже быстрое перемещение, сохраняя стабильность и минимальную задержку.
Основные характеристики:
Количество осей: 2 (X и Y);
Разрешение: до 1200 CPI (Counts Per Inch);
Интерфейсы связи: I2C и SPI;
Скорость кадров: до 2300 FPS (кадров в секунду);
Рабочее расстояние: около 1.2мм ± 0.2мм от поверхности.
Применение и обработка данных
Считывание данных с датчика по I2C и SPI - интерфейсам, дает доступ к приращениям по осям X и Y. Эти значения можно использовать для расчета абсолютного перемещения, а при необходимости - перевести в сантиметры или метры, учитывая установленное разрешение (CPI), Таким образом, PAT9125 может эффективно выполнять роль оптического энкодера, позволяя измерять расстояние, путь и даже направление движения.
Пример схемы электрической принципиальной, подключение к микроконтроллеру STM32F103 по интерфейсу I2C.
Реализация программного кода (Настройка, прием данных, конвертация) PAT9125 и микроконтроллера STM32F103.
Настройка в CubeIDE
Выберем I2C и выставим параметры:
I2C Speed Mode: Standard Mode;
I2C Speed Frequency(KHz): 100.
Метод PAT9125_Init
В данном методе производится инициализация датчика:
Считывание ID и проверка доступности устройства;
Установление разрешения CPI, через метод PAT9125_SetCpi().
Метод PAT9125_SetCPI
Данный метод, устанавливает заданный CPI в регистры X[0x0D] и Y[0x0E], считывает один байт из регистра датчика PAT9125 по I2C, (выставлено 1000 CPI, что эквивалентно 0.0254 мм/отсчет).
Метод PAT9125_ReadReg
Считывает один байт из регистра датчика PAT9125 по I2C (используется для чтения текущих значений (идентификатора устройства, данных движения и т.д.)).
Метод PAT9125_WriteReg
Данный метод, записывает значение value в регистр reg датчика PAT9125, используется для настройки параметров датчика, например (Установка CPI-разрешения).
Метод PAT9125_ReadMotion
Данный метод, считывает информацию о перемещении по осям X и Y из датчика (режим Burst Read), так же обновляет общее смещение total_x, total_y, и вызывает функцию обновления общего пройденного пути, простыми словами (используется каждый раз, когда нужно получить новые данные движения с датчика).
Поддерживает форматы:
8-битный формат и 12-битный (определяется макросом USE_12BIT_FORMAT), для работы в 8-битном формате, просто закоментируйте макрос(#define USE_12BIT_FORMAT),
в режиме 12-бит, данные собираются из старших и младших байтов и расширяются до знакового значения.
Метод ProcessMotionData
Данный метод является основным обработчиком движения, вызывает метод PAT9125_ReadMotion, обрабатывает данные и формирует строки для вывода по UART.
Метод UpdateTotalDistance
Данный метод вычисляет прирост пройденного пути на основе новых данных смещения и обновляет общий путь total_distance_cm
Метод convert_to_cm
Преобразует значение смещения из отсчетов в сантиметры, используя установленное разрешение CPI
Метод calculateBetaRadians
Данный метод вычисляет угол направления движения по данным X и Y
Ссылка на скачивание исходного кода [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_исходный_код -оптический_датчик_PAT9125]
Вывод
Это полноценный драйвер + обработчик данных с датчика PAT9125, включающий:
Считывание и обработку данных о движении;
Перевод в физические единицы (см, мм, радианы);
Калибровка чувствительности.
В целом, PAT9125 - это пример того, как миниатюрные технологии могут обеспечить высочайшую точность в системах, где важна каждая микронная деталь, благодаря своей компактности, энергоэффективности и простоте интеграции, он становится идеальным выбором для современных устройств ввода и мобильных систем позиционирования.
Если статья показалась Вам интересной, буду рад выпустить для Вас еще множество статей исследований по всевозможным видам устройств, так что, если не хотите их пропустить – буду благодарен за подписку на мой ТГ-канал: https://t.me/ChipCraft.
GPS-приемники сегодня используются в самых разных устройствах - от автомобильных трекеров до беспилотных летательных аппаратов, независимо от применения, большинство таких модулей передают информацию о положении в формате NMEA 0183, в этой статье я разберу, как принять эти данные от GPS-модуля на микроконтроллер STM32 и преобразовывать их в удобный для программы вид.
А также в статье будут рассмотрены два варианта подключения GPS-приемников к микроконтроллеру STM32:
Модуль GPS c UART-интерфейсом (TTL-уровни), подключаемый на прямую к микроконтроллеру;
Модуль GPS с интерфейсом RS-232, данные от такого типа gps, необходимо принимать через преобразователь уровней TTL.
В данном проекте используются GPS-приемники: LS23030 (UART) и LS23036(RS-232).
Схема подключения GPS-UART
Подключение модуля-GPS(UART) к микроконтроллеру STM32F103
Сигнал GPS, подключается к выводу PA10-31_контакт - RX(МК-STM32F103)
Для более стабильного напряжения питания можно использовать следующую схему, в которой работает понижающий преобразователь MP231, но необходим источник +12В, в моем случае используется аккумуляторная сборка (NiMH/Pb +12В).
Понижающий преобразователь напряжения MP2315 [ +12V до +5V ]
Вид осциллограммы передаваемых данных модуля-gps(uart) (линия TX)
Осциллограмма амплитуды данных от модуля-gps(uart)
Показатель амплитуды данных от модуля gps(uart) = delta [ 3.4V ], можно подключать к микроконтроллеру STM32.
Схема подключения GPS(RS-232)
Подключение модуля-GPS(RS-232) через ADM3202 к МК-STM32F103
Сигнал модуля-gps(rs-232), сначала приходит на 13 контакт преобразователя ADM3202, далее преобразованный сигнал (TTL) уходит на PA10-31_контакт - RX(МК-STM32F103)
Схема подключения ADM3202 к МКSTM32 - макет
Макет ADM3202 и подключение к STM32F103
Также для более стабильного напряжения питания по +5В, можно использовать схему преобразователя напряжения MP2315.
Для более стабильного напряжения питания по +3В, можно использовать следующую схему, в которой работает линейный стабилизатор напряжения LP2985.
Линейный стабилизатор напряжения LP2985 (+5В +3В)
Краткая информация о преобразователе ADM3202
Микроконтроллеры STM32, работают с логическими уровнями TTL/CMOS - обычно это 3.3В или 5В, интерфейс RS-232, напротив, использует более высокие и отрицательные напряжения ( от ±3В до ±12В), что делает их напрямую несовместимыми.
Если подключить напрямую модуль-GPS (RS-232) к выводам МК-STM32, это может не только привести к искажению данных, но и физически повредить выводы. ADM3202 решает эту задачу, переводя сигналы из одного уровня в другой, в обоих направлениях.
ADM3202 - это двухканальный приемопередатчик уровней RS-232 - TTL, выполняет сразу две задачи:
Преобразование входящих RS-232 сигналов в безопасные TTL-уровни(RX-канал);
Преобразование исходящих TTL-сигналов микроконтроллера в RS-232(TX-канал).
Для формирования требуемых амплитуд RS-232, внутри микросхемы используется помповый преобразователь напряжения(chage pump) с четырьмя внешними конденсаторами, это позволяет работать от одного источника питания (от 3В до 5.5В).
Вид осциллограммы передаваемых данных модуля-gps(rs-232) до преобразования ADM3202
Осциллограмма амплитуды данных от модуля-gps(rs-232) до преобразования ADM3202
Показатель амплитуды данных от модуля gps(rs-232) до преобразования = delta [ 10.6V ], нельзя подключать к микроконтроллеру STM32.
Вид осциллограммы передаваемых данных модуля-gps(rs-232) после преобразования ADM3202
Осциллограмма амплитуды данных от модуля-gps(rs-232) после преобразования ADM3202
Показатель амплитуды данных от модуля gps(rs-232) после преобразования = delta [ 3.6V ], можно подключать к микроконтроллеру STM32.
Настройка микроконтроллера STM32F103 в CubeIDE
Конфигурация Parametr Settings
В параметрах USART (Parametr Settings) я выбираю:
Mode: Asynchronous (асинхронный режим);
Baud Rate: 9600 бит/с (в моем примере два модуля-gps (rs-232 и uart) работают на скорости 9600).
все остальные параметры без изменений.
Настройка "Parameter settings"
Конфигурация NVIC Settings
Захожу в параметр (NVIC Settings) и включаю глобальное прерывание
Для отслеживания состояния интерфейса USART и обработки важных событий (например, завершения приема или ошибки), в разделе NVIC Settings было включено глобальное прерывание USART, это обеспечивает возможность немедленного реагирования со стороны микроконтроллера на изменения состояния периферии без постоянного опроса регистров.
Настройка "NVIC Settings"
При работе с GPS-модулями, которые передают NMEA-сообщения раз в секунду (1Hz), важно правильно организовать прием данных, чтобы не пропустить ни одного пакета. Необходимо настроить DMA в режиме Circular данный режим минимизирует нагрузку на процессор и гарантирует надежный прием.
Конфигурация DMA Settings
Захожу в параметр DMA Settings и выполняю следующие настройки:
Data Width: Byte (8 бит, соответствует формату NMEA).
Настройка "DMA Settings"
Реализация программного кода(настройка и прием данных)
Коротко о NMEA 0183
Это текстовый протокол, используемый для передачи данных между морским и авиационным навигационным оборудованием, включая GPS-приемники. Большинство современных GPS-модулей выводят информацию именно в этом формате.
Основные особенности:
Текстовый формат – данные передаются в виде ASCII-строк;
Структура сообщений – каждая строка начинается с $, содержит идентификатор типа данных и заканчивается контрольной суммой;
Скорость передачи – обычно 9600 бод (но может быть и выше для высокочастотных модулей);
Частота обновления – чаще всего 1 раз в секунду (1Hz), но бывают 5Hz, 10Hz и более.
Пример строки (GGA – Global Positioning System Fix Data):
После обработки GGA:
Время: 11:25:30
Широта: 60.20576° N
Долгота: 30.261315° E
Качество фикса: 1
Спутников: 10
Высота: 45.3 м
Пример строки (RMC – Recommended Minimum Navigation Information):
Определение структур данных в заголовочном файле [ NMEA.h ]
Для удобства работы с навигационной информацией из gps-приемника, здесь я заранее описываю набор структур, каждая из которых отвечает за свой логический блок данных.
Реализация модуля парсинга протокола NMEA.c
Функция decodeGGA()
Парсит строку $GPGGA и заполняет структуру GGASTRUCT данными: время, координаты, высота, количество спутников, качество фиксации.
Шаги работы функции:
Подготовка к поиску нужных данных
Переменная inx - это текущий индекс в строке GGAbuffer;
Сначала иду пропуск ненужных полей (счетчик двигается до следующей ,)
Проверка валидации качества позиционирования
В NMEA поле качества фиксации (Fix Quality) может быть:
0 - нет фикса, 1 - GPS Fix, 2-DGPS Fix, 4/5/6 другие корректные варианты;
Если поле содержит из разрешенных цифр, то в gga->isfixValid устанавливается в 1, иначе функция возвращает ошибку.
Чтение времени
Извлекается время в формате HHMMSS (UTC);
Преобразуются числа;
Корректируется по смещению GMT, при необходимости меняется день (daychange++ или daycahnge--).
Чтение широты (Latitude)
Формат в NMEA: DDMM.MMM;
Первые цифры - градусы, остальное - минуты;
Код выделяет минуты, делит их на 60 и добавляет к градусам;
Если NS == 'S', широта делается отрицательной.
Чтение долготы (Longitude)
Формат в NMEA: DDMM.MMM;
Аналогично широте, но первые 3 цифры - градусы;
Если EW == 'W', долгота делается отрицательной.
Чтение типа вычисления координат
Из поля после долготы извлекается число (gga->calc.calculation), указывающее метод позиционирования.
Чтение количества спутников
Следующее поле - количество видимых спутников (gga->numofsat).
Пропуск HDOP
HDOP (Horizontal Dilution of Precision) не используется, просто пропускается.
Чтение высоты
Поле с высотой (gga->alt.altitude) и единицами (gga->alt.unit, обычно 'M' - метры).
Завершение
Возвращается 0 при успешном разборе.
Функция decodeRMC()
Парсит строку $GPRMC и заполняет структуру RMCSTRUCT и извлекает: валидность данных, скорость, курс и дату.
Пропуск времени
Сначала идет поле времени, но в этой функции оно не сохраняется.
Проверка валидности
Если после времени идет А(Active) - данные актуальны;
Если V(Void) нет актуальных данных, функция возвращает ошибку.
Пропуск координат
Пропускаются поля широты, долготы и направления (NS/EW).
Чтение скорости
В NMEA скорость указывается в узлах;
Код переводит строку в число с плавающей точкой и записывает в rmc->speed.
Чтение курса
Следующее поле - курс (угол направления движения в градусах относительно севера).
Чтение даты
Формат: DDMMYY;
Код выделяет день, месяц, год, корректирует день с учетом daychange (из GGA), и записывает в rmc->date.
Реализация модуля обработчика потока от UART-GPS uartProc_GNSS.c
Функция uart_Handler_GNSS - это основной обработчик UART-потока, вызывается постоянно из главного цикла.
Логика работы:
Проверяет, сработали ли прерывания DMA (половина буфера или полный буфер);
Если пришли новые данные - устанавливает флаг активности GPS (gParams.isGPS = 1);
Поиск GGA или RMC
В режиме shabloneMode = 0 ищет последовательность GGA или RMC;
Когда шаблон найден, переключаемся в режим shabloneMode = 1;
В режиме 1 копирует байты до символа конца строки (13 или 10);
Действие когда собрана строка
Записывает строку в буфер buf_GGA или buf_RMC в зависимости от типа;
Обновляет время последнего получения GPS (gps_time_receive).
Декодирование
Вызывает decodeGGA() и decodeRMC() для извлечения данных в структуру gpsData.
Формирование выходного пакета:
Если хотя бы одно из сообщений валидно, формирует строку с координатами, временем, количеством спутников, режим фикса, высотой и курсом.
Записывает в результат в uart_rezult_buf_out_AB[] с преамбулой 0x5A 0xA5 и длиной пакета.
Если в течение (DELAY_GPS_STATUS_CONNECT)1000 миллисекунд новых данных нет - GPS считается отключенным (gParams.isGPS= 0).
uint8_t* dpi_getGPS_buffer (Возвращает указатель на готовый пакет данных для передачи ведущему устройству, а так же его размер).
void uart_startRecieving_GNSS (Запускает прием данных от GPS-приемника в режиме DMA).
Ссылка на скачивание исходного кода [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_исходный_код -Исходный код для Module_GPS_NMEA0183]
Графический GPS-трекер я разработал для тестирования на С#, если Вам будет интересно, пишите в комментариях и я с радостью напишу статью.
Если статья показалась Вам интересной, буду рад выпустить для Вас еще множество статей исследований по всевозможным видам устройств, так что, если не хотите их пропустить – буду благодарен за подписку на мой ТГ-канал: https://t.me/ChipCraft.
GPS-приемники сегодня используются в самых разных устройствах - от автомобильных трекеров до беспилотных летательных аппаратов, независимо от применения, большинство таких модулей передают информацию о положении в формате NMEA 0183, в этой статье я разберу, как принять эти данные от GPS-модуля на микроконтроллер STM32 и преобразовывать их в удобный для программы вид.
А также в статье будут рассмотрены два варианта подключения GPS-приемников к микроконтроллеру STM32:
Модуль GPS c UART-интерфейсом (TTL-уровни), подключаемый на прямую к микроконтроллеру;
Модуль GPS с интерфейсом RS-232, данные от такого типа gps, необходимо принимать через преобразователь уровней TTL.
В данном проекте используются GPS-приемники: LS23030 (UART) и LS23036(RS-232).
Схема подключения GPS-UART
Подключение модуля-GPS(UART) к микроконтроллеру STM32F103
Сигнал GPS, подключается к выводу PA10-31_контакт - RX(МК-STM32F103)
Для более стабильного напряжения питания можно использовать следующую схему, в которой работает понижающий преобразователь MP231, но необходим источник +12В, в моем случае используется аккумуляторная сборка (NiMH/Pb +12В).
Понижающий преобразователь напряжения MP2315 [ +12V до +5V ]
Вид осциллограммы передаваемых данных модуля-gps(uart) (линия TX)
Осциллограмма амплитуды данных от модуля-gps(uart)
Показатель амплитуды данных от модуля gps(uart) = delta [ 3.4V ], можно подключать к микроконтроллеру STM32.
Схема подключения GPS(RS-232)
Подключение модуля-GPS(RS-232) через ADM3202 к МК-STM32F103
Сигнал модуля-gps(rs-232), сначала приходит на 13 контакт преобразователя ADM3202, далее преобразованный сигнал (TTL) уходит на PA10-31_контакт - RX(МК-STM32F103)
Схема подключения ADM3202 к МКSTM32 - макет
Макет ADM3202 и подключение к STM32F103
Также для более стабильного напряжения питания по +5В, можно использовать схему преобразователя напряжения MP2315.
Для более стабильного напряжения питания по +3В, можно использовать следующую схему, в которой работает линейный стабилизатор напряжения LP2985.
Линейный стабилизатор напряжения LP2985 (+5В +3В)
Краткая информация о преобразователе ADM3202
Микроконтроллеры STM32, работают с логическими уровнями TTL/CMOS - обычно это 3.3В или 5В, интерфейс RS-232, напротив, использует более высокие и отрицательные напряжения ( от ±3В до ±12В), что делает их напрямую несовместимыми.
Если подключить напрямую модуль-GPS (RS-232) к выводам МК-STM32, это может не только привести к искажению данных, но и физически повредить выводы. ADM3202 решает эту задачу, переводя сигналы из одного уровня в другой, в обоих направлениях.
ADM3202 - это двухканальный приемопередатчик уровней RS-232 - TTL, выполняет сразу две задачи:
Преобразование входящих RS-232 сигналов в безопасные TTL-уровни(RX-канал);
Преобразование исходящих TTL-сигналов микроконтроллера в RS-232(TX-канал).
Для формирования требуемых амплитуд RS-232, внутри микросхемы используется помповый преобразователь напряжения(chage pump) с четырьмя внешними конденсаторами, это позволяет работать от одного источника питания (от 3В до 5.5В).
Вид осциллограммы передаваемых данных модуля-gps(rs-232) до преобразования ADM3202
Осциллограмма амплитуды данных от модуля-gps(rs-232) до преобразования ADM3202
Показатель амплитуды данных от модуля gps(rs-232) до преобразования = delta [ 10.6V ], нельзя подключать к микроконтроллеру STM32.
Вид осциллограммы передаваемых данных модуля-gps(rs-232) после преобразования ADM3202
Осциллограмма амплитуды данных от модуля-gps(rs-232) после преобразования ADM3202
Показатель амплитуды данных от модуля gps(rs-232) после преобразования = delta [ 3.6V ], можно подключать к микроконтроллеру STM32.
Настройка микроконтроллера STM32F103 в CubeIDE
Конфигурация Parametr Settings
В параметрах USART (Parametr Settings) я выбираю:
Mode: Asynchronous (асинхронный режим);
Baud Rate: 9600 бит/с (в моем примере два модуля-gps (rs-232 и uart) работают на скорости 9600).
все остальные параметры без изменений.
Настройка "Parameter settings"
Конфигурация NVIC Settings
Захожу в параметр (NVIC Settings) и включаю глобальное прерывание
Для отслеживания состояния интерфейса USART и обработки важных событий (например, завершения приема или ошибки), в разделе NVIC Settings было включено глобальное прерывание USART, это обеспечивает возможность немедленного реагирования со стороны микроконтроллера на изменения состояния периферии без постоянного опроса регистров.
Настройка "NVIC Settings"
При работе с GPS-модулями, которые передают NMEA-сообщения раз в секунду (1Hz), важно правильно организовать прием данных, чтобы не пропустить ни одного пакета. Необходимо настроить DMA в режиме Circular данный режим минимизирует нагрузку на процессор и гарантирует надежный прием.
Конфигурация DMA Settings
Захожу в параметр DMA Settings и выполняю следующие настройки:
Data Width: Byte (8 бит, соответствует формату NMEA).
Настройка "DMA Settings"
Реализация программного кода(настройка и прием данных)
Коротко о NMEA 0183
Это текстовый протокол, используемый для передачи данных между морским и авиационным навигационным оборудованием, включая GPS-приемники. Большинство современных GPS-модулей выводят информацию именно в этом формате.
Основные особенности:
Текстовый формат – данные передаются в виде ASCII-строк;
Структура сообщений – каждая строка начинается с $, содержит идентификатор типа данных и заканчивается контрольной суммой;
Скорость передачи – обычно 9600 бод (но может быть и выше для высокочастотных модулей);
Частота обновления – чаще всего 1 раз в секунду (1Hz), но бывают 5Hz, 10Hz и более.
Пример строки (GGA – Global Positioning System Fix Data):
После обработки GGA:
Время: 11:25:30
Широта: 60.20576° N
Долгота: 30.261315° E
Качество фикса: 1
Спутников: 10
Высота: 45.3 м
Пример строки (RMC – Recommended Minimum Navigation Information):
Определение структур данных в заголовочном файле [ NMEA.h ]
Для удобства работы с навигационной информацией из gps-приемника, здесь я заранее описываю набор структур, каждая из которых отвечает за свой логический блок данных.
Реализация модуля парсинга протокола NMEA.c
Функция decodeGGA()
Парсит строку $GPGGA и заполняет структуру GGASTRUCT данными: время, координаты, высота, количество спутников, качество фиксации.
Шаги работы функции:
Подготовка к поиску нужных данных
Переменная inx - это текущий индекс в строке GGAbuffer;
Сначала иду пропуск ненужных полей (счетчик двигается до следующей ,)
Проверка валидации качества позиционирования
В NMEA поле качества фиксации (Fix Quality) может быть:
0 - нет фикса, 1 - GPS Fix, 2-DGPS Fix, 4/5/6 другие корректные варианты;
Если поле содержит из разрешенных цифр, то в gga->isfixValid устанавливается в 1, иначе функция возвращает ошибку.
Чтение времени
Извлекается время в формате HHMMSS (UTC);
Преобразуются числа;
Корректируется по смещению GMT, при необходимости меняется день (daychange++ или daycahnge--).
Чтение широты (Latitude)
Формат в NMEA: DDMM.MMM;
Первые цифры - градусы, остальное - минуты;
Код выделяет минуты, делит их на 60 и добавляет к градусам;
Если NS == 'S', широта делается отрицательной.
Чтение долготы (Longitude)
Формат в NMEA: DDMM.MMM;
Аналогично широте, но первые 3 цифры - градусы;
Если EW == 'W', долгота делается отрицательной.
Чтение типа вычисления координат
Из поля после долготы извлекается число (gga->calc.calculation), указывающее метод позиционирования.
Чтение количества спутников
Следующее поле - количество видимых спутников (gga->numofsat).
Пропуск HDOP
HDOP (Horizontal Dilution of Precision) не используется, просто пропускается.
Чтение высоты
Поле с высотой (gga->alt.altitude) и единицами (gga->alt.unit, обычно 'M' - метры).
Завершение
Возвращается 0 при успешном разборе.
Функция decodeRMC()
Парсит строку $GPRMC и заполняет структуру RMCSTRUCT и извлекает: валидность данных, скорость, курс и дату.
Пропуск времени
Сначала идет поле времени, но в этой функции оно не сохраняется.
Проверка валидности
Если после времени идет А(Active) - данные актуальны;
Если V(Void) нет актуальных данных, функция возвращает ошибку.
Пропуск координат
Пропускаются поля широты, долготы и направления (NS/EW).
Чтение скорости
В NMEA скорость указывается в узлах;
Код переводит строку в число с плавающей точкой и записывает в rmc->speed.
Чтение курса
Следующее поле - курс (угол направления движения в градусах относительно севера).
Чтение даты
Формат: DDMMYY;
Код выделяет день, месяц, год, корректирует день с учетом daychange (из GGA), и записывает в rmc->date.
Реализация модуля обработчика потока от UART-GPS uartProc_GNSS.c
Функция uart_Handler_GNSS - это основной обработчик UART-потока, вызывается постоянно из главного цикла.
Логика работы:
Проверяет, сработали ли прерывания DMA (половина буфера или полный буфер);
Если пришли новые данные - устанавливает флаг активности GPS (gParams.isGPS = 1);
Поиск GGA или RMC
В режиме shabloneMode = 0 ищет последовательность GGA или RMC;
Когда шаблон найден, переключаемся в режим shabloneMode = 1;
В режиме 1 копирует байты до символа конца строки (13 или 10);
Действие когда собрана строка
Записывает строку в буфер buf_GGA или buf_RMC в зависимости от типа;
Обновляет время последнего получения GPS (gps_time_receive).
Декодирование
Вызывает decodeGGA() и decodeRMC() для извлечения данных в структуру gpsData.
Формирование выходного пакета:
Если хотя бы одно из сообщений валидно, формирует строку с координатами, временем, количеством спутников, режим фикса, высотой и курсом.
Записывает в результат в uart_rezult_buf_out_AB[] с преамбулой 0x5A 0xA5 и длиной пакета.
Если в течение (DELAY_GPS_STATUS_CONNECT)1000 миллисекунд новых данных нет - GPS считается отключенным (gParams.isGPS= 0).
uint8_t* dpi_getGPS_buffer (Возвращает указатель на готовый пакет данных для передачи ведущему устройству, а так же его размер).
void uart_startRecieving_GNSS (Запускает прием данных от GPS-приемника в режиме DMA).
Ссылка на скачивание исходного кода [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_исходный_код -Исходный код для Module_GPS_NMEA0183]
Графический GPS-трекер я разработал для тестирования на С#, если Вам будет интересно, пишите в комментариях и я с радостью напишу статью.
Если статья показалась Вам интересной, буду рад выпустить для Вас еще множество статей исследований по всевозможным видам устройств, так что, если не хотите их пропустить – буду благодарен за подписку на мой ТГ-канал: https://t.me/ChipCraft.
Современные робототехнические системы, дроны и автоматизированные устройства требуют точного определения перемещения в пространстве. Один из ключевых компонентов для этой задачи — Оптический модуль визуальной инерциальной навигации, такой как MTF02.Этот компактный и энергоэффективный сенсор позволяет устройствам "чувствовать" движение даже без GPS или внешних ориентиров.
Оптический датчик MTF-02
В конструкции датчика MTF-02 интегрированы две ключевые подсистемы:
ToF motion sensor (Time-of-Flight) для получения точечного расстояния;
Сенсор оптического потока (Optical flow) для отслеживания движения поверхности.
Основные характеристики
Напряжение питания:4 - 5.5В, потребление ~200мВт;
Размеры/вес: ~25x10x4,5мм 1,5г;
Оптический поток: 42° - при освещенности 60 ≥ Lux;
Минимальная высота: ≥ 8см;
Максимальная скорость: до 7м/c на высоте 1 метр;
FoV-камера: до 2,5 м @ 90% отражения и 600 Lux, мертвая зона FoV-камеры после 2см;
Длина волны ToF: 940нм.
Процесс работы MTF-02:
ToF motion sensor — технология измерения расстояния до объекта с помощью времени задержки отраженного сигнала (лазерного или ИК-импульса). Точечные датчики измеряют дистанцию до одной точки.
Optical flow - датчик захватывает изображение поверхности вниз и вычисляет относительное движение при частоте ~50 Гц, работает начиная с высоты 8см и далее для алгоритмов стабилизации движения при полете или перемещении в помещении.
Это похоже на то, как компьютерная мышь определяет свое перемещение, но с более высокой точностью.
Задача стоит следующая: мне необходимо разработать такую систему, которая способна сканировать в пространстве над поверхностью т.е. по "воздуху".
Для решения поставленной задачи, был выбран датчик MTF-02, обладающий необходимыми характеристиками для одновременного определения пройденного пути, координат перемещения в плоскости (X, Y) и оценки высоты объекта.
Благодаря встроенномуToF motion sensor, обеспечивающей точное измерение расстояния, а также модулю оптического потока, MTF-02 способен адаптироваться к условиям, когда отсутствует прямая опора или контрольный фон, это делает его особенно эффективным в задачах, где важно отслеживать перемещение объекта в подвешенном состоянии или при движении над неровной/неоднородной поверхностью.
Схема подключения датчика MTF-02
Сигнал TX датчика MTF-02 подключается к STM32F103(PA10-31 контакт - RX), а так же +5В и GND
Для более стабильного напряжения питания можно использовать следующую схему, в которой работает понижающий преобразователь MP231, но необходим источник +12В, в моем случае используется аккумуляторная сборка (NiMH/Pb +12В).
Вид осциллограммы передаваемых данных модуля MTF-02 по интерфейсу USART (линия TX)
Настройка микроконтроллера STM32F103 в CubeIDE
Настройка интерфейса USART в микроконтроллере STM32F103
В пункте [ 1 ] настраиваю скорость (Baud Rate [115200]), остальные параметры без изменений;
В пункте [ 2 ] заходим в параметр "DMA Settings" и включаем его на примем данных;
В рамках реализации приема данных по интерфейсу(USART) была задействована технология прямого доступа к данным (DMA), что позволило существенно снизить нагрузку на центральный процессор.
Для этого приемный сигнал USART(USART_RX) был сконфигурирован на работу в режиме DMA, при котором поступающие данные автоматически записываются в выделенный участок оперативной памяти без участия ядра.
В пункте [ 3 ] заходим в параметр "NVIC Settings" и включаем глобальное прерывание.
Для отслеживания состояния интерфейса USART и обработки важных событий (например, завершения приема или ошибки), в разделе NVIC Settings было включено глобальное прерывание USART, это обеспечивает возможность немедленного реагирования со стороны микроконтроллера на изменения состояния периферии без постоянного опроса регистров.
Реализация программного кода(настройка и прием данных)
//буфер для сборки строки #define SIZEBUF_result 96 char uart_rezult_buf1[SIZEBUF_result]={0,}; char uart_rezult_buf2[SIZEBUF_result]={0,}; char* uart_rezult_buf=uart_rezult_buf1; short uart_rezult_buf_i=0;//индекс char* uart_bufRow=uart_rezult_buf1;//буфер с целой строкой //E N D буфер для сборки строки //E N D для составления строк
//Данные полученные от структуры float distance_m=0.0f; int16_t flow_vel_x_cop=0; float flow_vel_x_cop_ab=0.0f; int16_t flow_vel_y_cop=0; float flow_vel_y_cop_ab=0.0f; uint32_t time_ms_s = 0; float distance_global =0.0f; //E N D данные полученные от структуры
//Данные после преобраз.сглаживания float smoothed_x = 0.0f; // Сглаженная скорость по X (см/с) float smoothed_y = 0.0f; // Сглаженная скорость по Y (см/с) float smoothed_distance = 0.0f; // Сглаженная дистанция (м) float total_velocity = 0.0f; // Общая скорость из сглаж. линейных скор. и дистанции (см/с) //E N D Данные после преобраз.сглаживания
staticfloat total_path_m = 0.0f; // Пройденный путь (метры) float total_path_m_cop = 0.0f; long total_path_m_cop_long =0; //тест staticfloat position_x_m = 0.0f; // Положение по X (в метрах) float position_x_m_cop = 0.0f; long position_x_m_cop_long= 0; staticfloat position_y_m = 0.0f; // Положение по Y (в метрах) float position_y_m_cop = 0.0f; long position_y_m_cop_long= 0; float beta_rad = 0.0f;
// Буферы для сглаживания данных #define BUFFER_SIZE 5 // Размер буфера для сглаживания, если необходимо еще медленее, уменьшать размер float flow_vel_x_buffer[BUFFER_SIZE] = {0}; // Буфер для flow_vel_x float flow_vel_y_buffer[BUFFER_SIZE] = {0}; // Буфер для flow_vel_y float distance_buffer[BUFFER_SIZE] = {0}; // Буфер для дистанции uint8_t buffer_index = 0; // Индекс текущего положения в буфере // E N D Буферы для сглаживания данных
Данный метод отвечает за получение, предварительную обработку и подготовку к использованию данных, поступающих от датчика MTF-02.
Основные задачи метода • Приём данных с датчика Метод реагирует на прерывания DMA — по заполнению первой или второй половины приёмного буфера. Это позволяет работать с потоком данных непрерывно, без потерь.
• Буферизация и переключение кадров Используются два чередующихся буфера (uart_rezult_buf1 и uart_rezult_buf2), чтобы приём новых данных и обработка предыдущих шли параллельно.
• Декодирование пакета Полученные байты передаются в функцию micolink_decode, которая разбирает пакет и выделяет физические величины:
flow_vel_x_cop — линейная скорость по оси X
flow_vel_y_cop — линейная скорость по оси Y
distance_m — дистанция до поверхности
• Сглаживание данных Для уменьшения шумов значения проходят через циклический буфер и усредняются функцией calculate_average. Это даёт стабильные показания скорости и расстояния.
• Интегрирование скорости в путь На основе сглаженных скоростей выполняется интегрирование (update_position) для получения пройденного пути по осям X и Y. Параллельно рассчитывается общая длина пути и угол движения (calculateBetaRadians).
• Подготовка данных для передачи Формируются готовые строки (sprintf) с данными в удобном текстовом формате для отладки, логирования или передачи в другие системы.
void uart_Handler_MTF(void) { HAL_Delay(1);//чтобы HAL_GetTick() не выдавал ноль uint32_t ms = HAL_GetTick(); // uint32_t time_sec = ms / 1000; char isData=0; char* pData=(char*)uart_rx_buffer_MTF;
if(uartRxFullIRDone){ uartRxFullIRDone = 0; // Указатель на вторую половину основного буфера DMA pData=(char*)&uart_rx_buffer_MTF[UART_RX_BUFFER_SIZE/2]; isData=1; } if(uartRxHalfIRDone){ uartRxHalfIRDone = 0; // Указатель на первую половину основного буфера DMA pData = (char*)uart_rx_buffer_MTF; isData=1; } if(isData) { isData=0;
smoothed_x = calculate_average(flow_vel_x_buffer); smoothed_y = calculate_average(flow_vel_y_buffer); smoothed_distance = calculate_average(distance_buffer); //E N D Сглаженные значения float time_sec = ms/1000.0f;//перевод в секунды
update_position(smoothed_x,smoothed_y,ms);//интегрирование линейной скорости для расчёта пройденного пути, с учётом фильтрации малых шумов.
update_motion(smoothed_x,smoothed_y,smoothed_distance, ms);//расчёт общей скорости и пройденного пути
//делаю копию потому что position_x_m,y и total_path_m static (если одтать в буфер staic, то работать система не будет) position_x_m_cop = position_x_m; position_y_m_cop = position_y_m; total_path_m_cop = total_path_m*1000.0f; total_path_m_cop_long = (long)roundf(total_path_m_cop);
flow_vel_x_cop_ab=position_x_m_cop * 1000.0f;//перевод в мм flow_vel_y_cop_ab=position_y_m_cop * 1000.0f; position_x_m_cop_long = (long)roundf(flow_vel_x_cop_ab); position_y_m_cop_long = (long)roundf(flow_vel_y_cop_ab); //E N D
beta_rad = calculateBetaRadians(flow_vel_x_cop_ab, flow_vel_y_cop_ab);//получение угла в радианах
Данный метод отвечает за расчёт общей скорости и пройденного пути, он выполняет ключевую навигационную задачу — на основе данных от MTF-02 вычисляет, с какой скоростью движется объект и какое расстояние он прошёл с момента старта измерений.
Принцип работы • Измерение времени между кадрами Функция хранит момент предыдущего вызова (last_time_ms) и определяет, сколько секунд прошло между текущим и прошлым измерением (delta_time_s). Это позволяет интегрировать движение по времени.
• Вычисление мгновенной скорости
Используются проекции скорости по осям X и Y (flow_vel_x, flow_vel_y).
Их векторная сумма (sqrtf(...)) даёт модуль скорости в плоскости.
Результат умножается на измеренное датчиком расстояние до поверхности (distance_m), что учитывает масштаб оптического потока.
Деление на 100 применяется, если исходные скорости приходят в сантиметрах в секунду (приведение к м/с).
• Интегрирование для получения пути Общая скорость умножается на интервал времени — это даёт приращение пути за данный шаг. Приращение накапливается в переменной total_path_m, которая отражает суммарное пройденное расстояние с начала работы системы.
• Обновление времени В конце функция сохраняет текущее время вызова, чтобы при следующем измерении корректно вычислить delta_time_s.
Простыми словами Метод update_motion — это шагомер с точностью до миллиметров, но не по количеству шагов, а по точным данным от оптического датчика. Он измеряет скорость движения, умножает её на прошедшее время и складывает результат в копилку пройденного пути
// Функция расчёта общей скорости и пройденного пути void update_motion(float flow_vel_x, float flow_vel_y, float distance_m,uint32_t time_ms) {
staticuint32_t last_time_ms = 0; // Время предыдущего измерения
float delta_time_s = (time_ms - last_time_ms) / 1000.0f; // Время в секундах
if (delta_time_s > 0) { // Рассчитываем общую скорость (м/с) float total_velocity_m_per_s =distance_m * sqrtf(flow_vel_x * flow_vel_x + flow_vel_y * flow_vel_y)/100.0f;// деление на 100 если скорости передаются в см/c если в м/то не надо делить // Интегрируем скорость для расчёта пути total_path_m += total_velocity_m_per_s * delta_time_s; } last_time_ms = time_ms; // Обновляем время последнего измерения }
Метод update_position
Данный метод отвечает за то, чтобы перевести показания датчика MTF-02 из скоростей в координаты — то есть понять, где сейчас находится объект относительно точки старта.
Как это работает Определение времени между измерениями Метод вычисляет, сколько секунд прошло с момента предыдущего вызова (delta_time_s). Это нужно, чтобы правильно учесть, на какое расстояние мог сдвинуться объект.
• Отсев шумов Если скорость по X или Y слишком мала (меньше 0,01 см/с), она считается шумом и приравнивается к нулю. Это предотвращает накопление ошибок из-за микроколебаний или дрожания датчика.
• Перевод в метры в секунду Показания датчика приходят в сантиметрах в секунду, поэтому они делятся на 100, чтобы работать в метрической системе (м/с).
Интегрирование — путь из скорости
Скорость умножается на время, прошедшее с предыдущего измерения.
Полученное приращение добавляется к текущим координатам position_x_m и position_y_m.
Таким образом, шаг за шагом накапливается точка текущего положения в метрах.
• Обновление времени Сохраняется момент последнего измерения, чтобы при следующем вызове правильно рассчитать delta_time_s.
Простыми словами update_position — это математический «следопыт»: он берёт скорости, отбрасывает шум, переводит их в пройденное расстояние и складывает с предыдущими координатами. В результате получается текущая позиция объекта в двухмерном пространстве.
//интегрирование линейной скорости для расчёта пройденного пути, с учётом фильтрации малых шумов. void update_position(float flow_vel_x, float flow_vel_y,uint32_t time_ms){
staticuint32_t last_time_ms = 0;// Время последнего измерения (мс)
// Вычисляем разницу во времени между измерениями в секундах float delta_time_s = (time_ms - last_time_ms) / 1000.0f; if (delta_time_s > 0.0f) {
// Проверка на малые скорости и шумы if (fabsf(flow_vel_x) < 0.01f) flow_vel_x = 0.0f; // Игнорируем шум по X if (fabsf(flow_vel_y) < 0.01f) flow_vel_y = 0.0f; // Игнорируем шум по Y
// Переводим скорости из см/с в м/с float velocity_x_mps = flow_vel_x / 100.0f; // Линейная скорость по X (м/с) float velocity_y_mps = flow_vel_y / 100.0f; // Линейная скорость по Y (м/с)
// Интегрируем скорости для обновления положенияx` position_x_m += velocity_x_mps * delta_time_s; // Путь = Скорость * Время position_y_m += velocity_y_mps * delta_time_s; } // Обновляем время последнего измерения last_time_ms = time_ms; }
Метод calculate_average вычисление среднего значения из буфера, необходи для сглаживания данных поступающих от датчика MTF-02
float calculate_average(float*buffer) { float sum = 0.0; for (int i = 0; i < BUFFER_SIZE; i++) { sum += buffer[i]; } return sum / BUFFER_SIZE; } //E N D функция вычисления среднего значения из буфера
В работе с датчиком MTF-02 информация передаётся в виде бинарных сообщений по протоколу MicoLink. Этот набор функций выполняет полный цикл приёма — от поимки первого байта до получения готовых чисел скорости и высоты.
1. Метод micolink_parse_char, осуществляет приём и разбор данных, обрабатывает поток входящих байтов, поступающих от датчика.
Каждый байт проходит через «машину состояний»:
Заголовок — признак начала пакета.
ID устройства и системы — кому адресовано сообщение.
ID сообщения — тип передаваемых данных (например, показания дальномера).
Длина полезной нагрузки — сколько байт занимает полезная информация.
Полезная нагрузка — сами измеренные значения (скорости, дистанция).
Контрольная сумма — защита от ошибок в передаче.
Если всё прошло успешно и контрольная сумма совпала — пакет считается принятым.
2. Метод micolink_check_sum, осуществляет проверку целостности Каждое сообщение содержит контрольную сумму — специальное число, рассчитанное по всем байтам пакета.
Если расчёт на приёмной стороне совпадает с переданным значением, значит, данные достоверны.
Этот шаг защищает от искажений, которые могут возникнуть в линии связи.
3. Метод micolink_decode, осуществляет декодирование,после успешного приёма пакет разбирается по смыслу.
В случае с MICO_LINK_MSG_ID_RANGE_SENSOR из него извлекаются:
time_ms — отметка времени измерения;
distance_m — высота над поверхностью, в метрах;
flow_vel_x и flow_vel_y — линейные скорости по осям X и Y (см/с).
Эти значения затем используются для расчёта скорости, перемещения и построения траектории движения.
// Функция обработки данных uint8_t* data, size_t size void micolink_decode(uint8_t* data, size_t size) { //static MICOLINK_MSG_t msg;
if (micolink_parse_char(&msg,data,size) == false) { return; }
После вызова данного метода MTF-02 начинает передавать пакеты данных по UART, а контроллер непрерывно принимает их в выделенный буфер, не тратя ресурсы на побайтовую обработку. Когда буфер наполняется наполовину или полностью, срабатывают соответствующие обработчики (uartRxHalfIRDone и uartRxFullIRDone), и начинается разбор протокола MicoLink.
Ссылка на скачивание исходного кода [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_исходный_код -Исходный код для датчика MTF-02]
Вывод
Датчик MTF-02 — это отличное решение для проектов, требующих точного измерения перемещения без сложных навигационных систем. Его простота, низкая цена и энергоэффективность делают его популярным в робототехнике, дронах и умных устройствах.
Ссылка на скачивание исходного кода [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_исходный_код -Исходный код для датчика MTF-02]
Вывод
Датчик MTF-02 — это отличное решение для проектов, требующих точного измерения перемещения без сложных навигационных систем. Его простота, низкая цена и энергоэффективность делают его популярным в робототехнике, дронах и умных устройствах.
Заключение
Если статья показалась Вам интересной, буду рад выпустить для Вас еще множество статей исследований по всевозможным видам устройств, так что, если не хотите их пропустить – буду благодарен за подписку на мой ТГ-канал: https://t.me/ChipCraft.
Современные компьютерные мыши, тачпады, сенсорные панели и мобильная робототехника, обязаны своей точностью и отзывчивостью миниатюрным системам движения. Одним из таких является PAT9125 - это высокоточный двухосевой оптический датчик, способный с невероятной точностью отслеживать перемещение по различным поверхностям.
PAT9125 представляет собой интеллектуальный датчик, в основе которого - микроскопическая камера и инфракрасная подсветка. Он реализует текстуру поверхности под собой, фиксируя мельчайшие смещения и на основе полученных данных изображений рассчитывает вектор движения. Благодаря высокой кадровой частоте, датчик способен точно отслеживать даже быстрое перемещение, сохраняя стабильность и минимальную задержку.
Основные характеристики:
Количество осей: 2 (X и Y);
Разрешение: до 1200 CPI (Counts Per Inch);
Интерфейсы связи: I2C и SPI;
Скорость кадров: до 2300 FPS (кадров в секунду);
Рабочее расстояние: около 1.2мм ± 0.2мм от поверхности.
Применение и обработка данных
Считывание данных с датчика по I2C и SPI - интерфейсам, дает доступ к приращениям по осям X и Y. Эти значения можно использовать для расчета абсолютного перемещения, а при необходимости - перевести в сантиметры или метры, учитывая установленное разрешение (CPI), Таким образом, PAT9125 может эффективно выполнять роль оптического энкодера, позволяя измерять расстояние, путь и даже направление движения.
Пример схемы электрической принципиальной, подключение к микроконтроллеру STM32F103 по интерфейсу I2C.
Реализация программного кода (Настройка, прием данных, конвертация) PAT9125 и микроконтроллера STM32F103.
Настройка в CubeIDE
Выберем I2C и выставим параметры:
I2C Speed Mode: Standard Mode;
I2C Speed Frequency(KHz): 100.
Метод PAT9125_Init
В данном методе производится инициализация датчика:
Считывание ID и проверка доступности устройства;
Установление разрешения CPI, через метод PAT9125_SetCpi().
Метод PAT9125_SetCPI
Данный метод, устанавливает заданный CPI в регистры X[0x0D] и Y[0x0E], считывает один байт из регистра датчика PAT9125 по I2C, (выставлено 1000 CPI, что эквивалентно 0.0254 мм/отсчет).
Метод PAT9125_ReadReg
Считывает один байт из регистра датчика PAT9125 по I2C (используется для чтения текущих значений (идентификатора устройства, данных движения и т.д.)).
Метод PAT9125_WriteReg
Данный метод, записывает значение value в регистр reg датчика PAT9125, используется для настройки параметров датчика, например (Установка CPI-разрешения).
Метод PAT9125_ReadMotion
Данный метод, считывает информацию о перемещении по осям X и Y из датчика (режим Burst Read), так же обновляет общее смещение total_x, total_y, и вызывает функцию обновления общего пройденного пути, простыми словами (используется каждый раз, когда нужно получить новые данные движения с датчика).
Поддерживает форматы:
8-битный формат и 12-битный (определяется макросом USE_12BIT_FORMAT), для работы в 8-битном формате, просто закоментируйте макрос(#define USE_12BIT_FORMAT),
в режиме 12-бит, данные собираются из старших и младших байтов и расширяются до знакового значения.
Метод ProcessMotionData
Данный метод является основным обработчиком движения, вызывает метод PAT9125_ReadMotion, обрабатывает данные и формирует строки для вывода по UART.
Метод UpdateTotalDistance
Данный метод вычисляет прирост пройденного пути на основе новых данных смещения и обновляет общий путь total_distance_cm
Метод convert_to_cm
Преобразует значение смещения из отсчетов в сантиметры, используя установленное разрешение CPI
Метод calculateBetaRadians
Данный метод вычисляет угол направления движения по данным X и Y
Ссылка на скачивание исходного кода [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_исходный_код -оптический_датчик_PAT9125]
Вывод
Это полноценный драйвер + обработчик данных с датчика PAT9125, включающий:
Считывание и обработку данных о движении;
Перевод в физические единицы (см, мм, радианы);
Калибровка чувствительности.
В целом, PAT9125 - это пример того, как миниатюрные технологии могут обеспечить высочайшую точность в системах, где важна каждая микронная деталь, благодаря своей компактности, энергоэффективности и простоте интеграции, он становится идеальным выбором для современных устройств ввода и мобильных систем позиционирования.
Если статья показалась Вам интересной, буду рад выпустить для Вас еще множество статей исследований по всевозможным видам устройств, так что, если не хотите их пропустить – буду благодарен за подписку на мой ТГ-канал: https://t.me/ChipCraft.