Вы когда-нибудь мечтали о 500-герцовой системе датчиков линейного положения? Тогда вам повезло — для этого достаточно печатной платы, простого микроконтроллера и немного математики!
См. также полный исходный код и журнал моих исследований по этому проекту.
▍ Зачем изготавливать штангенциркуль?
Электронный штангенциркуль — потрясающее устройство. Прибор за 30 долларов служил мне верой и правдой в течение нескольких лет, обеспечивая гораздо большую точность, чем требовалось моим навыкам:
В таком штангенциркуле используется ёмкостная связь между платой на электронном дисплее подвижной рамки и пассивной «шкалой» платы неподвижной штанги.
В марте этого года я неторопливо раздумывал над тем, что такой же принцип работы можно использовать для дешёвой системы позиционирования. Например, можно вставить пассивную шкалу в алюминиевый профиль, добавить ёмкостный датчик на низ того шасси, на котором он закреплён, и вуаля — у вас есть система определения позиции с обратной связью и разрешением меньше миллиметра. И всё это по цене печатной платы, нескольких контактов GPIO и прошивки (то есть, по сути, бесплатно).
Я подумал, что кто-то уже должен был сделать подобное, но не смог найти ни одного проекта «опенсорсного штангенциркуля». Самым близким к нему оказалась страница проекта на hackaday.io, созданная буквально за месяц до этого.
Я связался с её автором Mitko и предложил реализовать прошивку, если он отправит мне печатную плату. Моей основной мотивацией было желание изучить цифровую обработку сигналов, потому что я никогда не касался её, если не считать беглого упоминания преобразования Фурье в студенчестве.
Если вам просто нужны готовые способы получения точных измерений и вы не хотите углубляться в дебри, то можно рассмотреть следующие варианты:
- считывание данных измерений непосредственно с дешёвого штангенциркуля при помощи его секретного интерфейса передачи данных,
- поискать комплекты для digital read out (DRO) — это обобщённое название всевозможных ёмкостных, оптических и магнитных прецизионных линейных и угловых схем измерений (обычно для модернизации ручного станочного оборудования цифровым считыванием данных, чтобы вы сами могли быть ЧПУ). Например, можно использовать магнитный энкодер за 200 долларов с линейной лентой по цене 1 доллар за сантиметр.)
▍ Теория штангенциркулей
Вот фотография штангенциркуля, разобранного моим коллегой Mitko (обозначения добавлены мной):
Левая часть — это неподвижная штанга, содержащая пассивную плату с паттерном «отражателей» (они выглядят как заглавная буква T, повёрнутая на 90 градусов по часовой стрелке).
Справа находится электронный дисплей штангенциркуля, двигающийся вверх и вниз по металлической штанге; эта плата имеет длинную площадку приёмника и набор из площадок излучателей, похожих на клавиши пианино.
Если их собрать вместе (сложить, как книгу), основания букв Т отражателей окажутся над излучающими сигнал клавишами пианино, а перекладины — над площадкой приёмника.
(Примечание педанта: на самом деле, не происходит никакого «отражения», пластины имеют ёмкостную связь. Мне просто показалось, что термин «отражатель» передаёт нужный смысл.)
Вот увеличенное изображение из превосходного видео разборки штангенциркуля Big Clive (обозначения добавлены мной):
Верхняя часть — неподвижная штанга, нижняя часть — подвижная рамка.
Обратите внимание на следующие детали геометрии:
- Подвижная рамка излучает 8 сигналов через небольшие «клавиши пианино» (отмечены цифрами), повторяющиеся на протяжении всей длины.
- Основания отражателей имеют длину ровно 4 «клавиши».
По сути, пластина отражателя «складывает» сигналы находящихся под ним клавиш пианино (на этом фото сигналы 0, 1, 2 и 3).
Представьте, что мы сдвинули дисплей штангенциркуля на 0,5 клавиши вправо. Тогда отражатели будут находиться над половиной сигнала 0, целиком над сигналами 1, 2, 3 и над половиной сигнала 4. Если сдвинуться ещё на 0,5 клавиши вправо, то отражатели будут находиться ровно над сигналами 1, 2, 3 и 4.
Отражатели — это просто пассивные куски металла; они умеют лишь суммировать связанные с ними сигналы. Этот суммированный сигнал отражается на общую площадку приёмника подвижной рамки.
Какие же 8 сигналов мы должны излучать?
Если использовать синусоидальные волны одной частоты, но разных фаз, то их отражённая сумма всегда будет синусоидой исходной частоты с некой комбинированной фазой и амплитудой (доказательство).
То есть при перемещении подвижной рамки сдвиг фазы отражённого сигнала меняется.
Так как у нас есть 8 сигналов, мы поровну делим единичную окружность, чтобы n-сигнал был таким:
Тогда мы сможем отслеживать суммарный сдвиг фазы получаемого сигнала (относительно некой исходной позиции) и точно знать, что каждые сдвига в фазовом пространстве соответствуют линейному перемещению шириной в 8 клавиш излучателя.
▍ Реализация в микроконтроллере
Mitko отправил мне по почте версию 1.1 своей печатной платы (схема), изготовленную на основе микроконтроллера STM32F103.
Я написал прошивку при помощи фреймворка Embassy Rust, который работал достаточно хорошо. («Хорошо», насколько это возможно для встроенных устройств — мне пришлось выполнять побочный квест по поиску причин иногда возникавших зависаний, блокировавших отладчик; похоже, это аппаратный баг, проявляющийся только в старых версиях ARM Core.)
Прошивка должна выполнять следующие задачи:
- излучать 8 синусоид,
- измерять отражённую сумму и вычислять смещения фаз.
Давайте разбираться с этим по порядку.
▍ Излучение синусоид
STM32F103 не имеет цифро-аналогового преобразователя, но мы можем излучать синусоиду при помощи импульсно-плотностной модуляции (pulse density modulation, PDM). Эта техника схожа с широтно-импульсной модуляцией (ШИМ, PWM, pulse width modulation) тем, что уровень аналогового сигнала аппроксимируется «включением» цифрового сигнала на нужное время. Однако у PWM время «включённого» сигнала используется за раз, а сигнал PDM распределяет его в пределах окна сэмплирования.
Например, вот как можно представить аналоговый уровень 50% при помощи 8 импульсов:
PWM: X X X X . . . .
PDM: X . X . X . X .
Сигнал PWM остаётся высоким (
x
) в течение первой части периода, а сигнал PDM переключается. Это предпочтительно в нашем случае, потому что помехи переключения будут находиться на повышенной частоте, далеко от нашей низкочастотной синусоиды.Нам нужно, чтобы все волны шли в строгом порядке друг за другом, поэтому мы будем обновлять контакты не один за другим, а единой 32-битной операцией записи в bit set/reset register (BSRR) GPIO.
Более того, поскольку мы заранее знаем, сколько сэмплов PDM нам требуется, мы можем пожалеть наш бедный маленький STM32F103 (у которого даже нет аппаратного модуля для выполнения операций с плавающей запятой) и вычислять все значения BSRR во время компиляции. Формальная система Rust времени компиляции не поддерживает тригонометрию, поэтому мы используем скрипт
build.rs
для генерации строки кода во время компиляции:fn generate_pdm_bsrr(n_samples: usize) -> String {
let mut output = String::new();
output.push_str("pub const PDM_SIGNAL: [u32; ");
output.push_str(&n_samples.to_string());
output.push_str("] = [\n");
let n_waves = 8;
let mut errors = vec![0.0; n_waves];
for sample in 0..n_samples {
let mut bsrr = 0u32;
for wave in 0..n_waves {
let phase_offset = 2.0 * PI * (wave as f64) / (n_waves as f64);
let angle = 2.0 * PI * (sample as f64 / n_samples as f64) + phase_offset;
let cosine = angle.cos() as f32;
let normalized_signal = (cosine + 1.0) / 2.0;
if normalized_signal > errors[wave] {
bsrr |= 1 << wave; // устанавливаем бит
errors[wave] += 1.0 - normalized_signal;
} else {
bsrr |= 1 << (wave + 16); // сбрасываем бит
errors[wave] -= normalized_signal;
}
}
output.push_str(&format!(" {:#034b},\n", bsrr));
}
output.push_str("];\n");
output
}
Затем эта сгенерированная строка записывается в файл, для которого мы обычным образом выполняем
import
из пространства имён нашего основного кода. Затем константный срез PDM_SIGNAL
«запекается» в прошивку, а во время исполнения аппаратный таймер и задача DMA используются для копирования через фиксированные промежутки каждого значения напрямую в BSRR. Это позволяет избежать колебаний излучаемого сигнала, поскольку после начала передачи CPU больше в ней не участвует.▍ Измерение фазового сдвига
Отражённая составная волна измеряется аналого-цифровым преобразователем (ADC) STM32F103. Задача DMA запускается одновременно с излучаемыми сигналами PDM и считывает из буфера фиксированное количество сэмплов.
Как же нам получить фазовый сдвиг?
Если вы похожи на меня, то первым делом бы захотели почитать учебники, чтобы понять, что же это такое. Я рекомендую Understanding Digital Signal Processing Ричарда Лайонса, потому что эта книга написана обыденным языком; также очевидно, что её написал опытный инженер: последняя глава — это просто 150 страниц «трюков с цифровой обработкой сигналов»!
Как мы уже знаем, наш отражённый сигнал — это сумма излучаемых нами синусоидальных сигналов, поэтому он тоже должен быть синусоидой с каким-то фазовым сдвигом; давайте назовём его (где — это некая константа, описывающая изменение амплитуды, вызванное ёмкостной связью, усилением и так далее, по сравнению с исходным излучаемым сигналом).
Как вы, наверно, помните из школьной формулы тригонометрического сложения, это можно переписать так:
Если выполнить корреляцию нашего сигнала с , то у нас остаётся , и аналогично для синуса.
Таким образом:
Сам оператор корреляции прост: это сумма произведений двух сигналов в соответствующих точках времени.
Нам достаточно лишь понять конкретное время сэмплов , которое можно вывести из частоты сэмплирования ADC.
Все члены, за исключением измеренных сэмплов сигналов , известны во время компиляции, поэтому мы снова можем сгенерировать таблицу поиска, которую будет использовать микроконтроллер:
fn generate_sine_cosine_table(
signal_frequency: f64,
sampling_frequency: f64,
num_samples: usize,
) -> String {
let mut output = String::new();
output.push_str("pub const SINE_COSINE_TABLE: [(f32, f32); ");
output.push_str(&num_samples.to_string());
output.push_str("] = [\n");
for i in 0..num_samples {
let angle = 2.0 * PI * signal_frequency * (i as f64 * (1.0 / sampling_frequency));
let sine = angle.sin() as f32;
let cosine = angle.cos() as f32;
output.push_str(&format!(" ({:?}, {:?}),\n", sine, cosine));
}
output.push_str("];\n");
output
}
Тогда скрипт build.rs будет иметь следующий вид:
fn main() {
// программирование во время компиляции в буквальном смысле записью кода в файл, который мы импортируем
let out_dir = std::env::var("OUT_DIR").unwrap();
let dest_path = std::path::Path::new(&out_dir).join("constants.rs");
let mut f = File::create(&dest_path).unwrap();
let pdm_frequency: u32 = 100_000; // 100 кГц
f.write_all(format!("pub const PDM_FREQUENCY: u32 = {:?};\n", pdm_frequency).as_bytes())
.unwrap();
let pdm_length = 128;
let num_samples = 512;
let signal_frequency = pdm_frequency as f64 / pdm_length as f64;
let adc_frequency = 12_000_000.;
let adc_sample_cycles = 71.5;
let adc_sample_overhead_cycles = 12.5; // см. раздел 11.6 справочного руководства
let sampling_frequency = adc_frequency / (adc_sample_cycles + adc_sample_overhead_cycles);
f.write_all(
generate_sine_cosine_table(signal_frequency, sampling_frequency, num_samples).as_bytes(),
)
.unwrap();
f.write_all(generate_pdm_bsrr(pdm_length).as_bytes())
.unwrap();
/// ...
}
Наконец, во время исполнения у нас остаётся такой цикл:
loop {
// запускаем излучение PDM через DMA
// запускаем ADC через DMA
// ждём, пока ADC считает NUM_SAMPLES
// затем...
let mut sum_sine: f32 = 0.0;
let mut sum_cosine: f32 = 0.0;
let adc_buf = unsafe { &ADC_BUF[..] };
for i in 0..NUM_SAMPLES {
let (sine, cosine) = SINE_COSINE_TABLE[i];
sum_sine += adc_buf[i] as f32 * sine;
sum_cosine += adc_buf[i] as f32 * cosine;
}
let phase = sum_sine.atan2(sum_cosine);
// прибавляем последние показания фазы к оценке позиции.
// этот объект также обрабатывает циклический возврат и гистерезис.
position_estimator.update(phase);
info!("Phase: {} Position: {}", phase, position_estimator.position);
if user_button.is_low() {
info!("Button pressed, zeroing");
position_estimator.position = 0.;
}
}
▍ Точность
Для реализации измерений в прошивке необходимо выбрать различные параметры:
- Частоту излучения импульсов PDM.
- Количество импульсов PDM, на которое мы делим один период синусоиды.
- Время сэмплирования ADC.
- Количество сэмплов ADC, считываемых при каждом вычислении фазы.
Вместо того, чтобы пытаться вычислить идеальные параметры из физических принципов (которые, вероятно, зависели бы от всевозможных тонкостей, например, от толщины паяльной маски платы и сопротивлений дорожек), давайте просто попробуем их все и выберем наиболее подходящие. Сформулируем запрос конкретнее: при какой из конфигураций параметров стандартное отклонение для множества измерений, сделанных при одном физическом положении подвижной рамки, будем наименьшим?
Вместо того, чтобы записывать прошивку заново для каждого набора параметров, мы можем написать специальную прошивку-рекордер, которой можно будет управлять через ноутбук. Так мы сможем передавать на ноутбук поток сырых показаний ADC, что позволит там протестировать гораздо более широкий диапазон параметров.
Все грязные подробности можно посмотреть в ноутбуке parameter sweep, а график выглядит так:
Тут много информации, так что давайте разберём её:
- Ось Y соответствует стандартному отклонению записанных фаз (чем меньше, тем лучше — рамка неподвижна, то есть в идеале все измерения должны возвращать одно и то же значение).
- Ось X соответствует частоте, для которой мы отправляем импульсы излучаемого синусоидного сигнала. Все данные здесь представлены для 128 сегментов PDM, а шаг по оси X равен 2 кГц.
- Каждый график соответствует отдельному «размеру окна», то есть количеству сэмплов ADC, с которым мы выполняем корреляцию для получения одного измерения фазы.
- Каждая цветная линия обозначает отдельную частоту сэмплирования ADC (ADC микроконтроллера STM32F103 может выполнять сэмплирование для 8 разных периодов, и мы пробуем их все).
Что показалось мне важным в самих данных:
- Чем выше частота ADC, тем выше должна быть частота PDM, чтобы мы могли начать получать сигнал (то есть для снижения стандартного отклонения). Это кажется мне логичным, ведь если частота ADC гораздо выше частоты сигнала, то наше окно сэмплирования вообще не увидит особых изменений в сигнале, поэтому там будет доминировать шум, и мы не будем иметь понятия, какая фаза.
- Увеличение размера окна обычно повышает точность — логично, потому что мы просматриваем большее количество сэмплов и (предположительно) снижаем влияние шума.
- Наименьшая частота сэмплирования ADC (то есть наибольший период сэмплирования ADC) обеспечивает наилучшие результаты.
- На 250 кГц присутствует странная «кошка»; вероятно, это точка, в которой наша частота сэмплирования ADC недостаточно быстра для самого сигнала. При 250 кГц/128 сегментах PDM наша излучаемая синусоида должна иметь частоту примерно 1950 Гц.
Хотя в этом статическом тесте лучше всего выглядел вариант с увеличением размера окна и периода сэмплирования ADC, это означает снижение частоты возможного вычисления фазы, что ограничивает скорость перемещения подвижной рамки — при её превышении рамка перестанет отслеживать абсолютную позицию.
Поэтому на основании этого теста я решил задать параметры локального вычисления внутри прошивки (показанного в демонстрационном видео) в точке, указанной красной стрелкой:
- размер окна = 128,
- частота PDM = 222 кГц,
- частота сэмплирования ADC = 222,2 кГц.
На самом деле, логично, что отклонение фаз здесь минимально: при этой частоте сэмплирования ADC и размере окна 128 мы практически соответствуем периоду излучаемого 128-сегментного сигнала PDM.
Метки времени в демонстрационном видео показывают, что между считываниями проходит примерно 1,5 мс (0,6 кГц), что почти в три раза больше идеального предела (222,2 кГц / 128 сэмплов => 1,7 кГц), вероятно, из-за времени, необходимого на выполнение вычислений корреляции, вывода на компьютер и работы асинхронного механизма Embassy. Я уверен, что более оптимизированная реализация могла бы достичь предела, например, при помощи вычисления корреляций во время сбора сэмплов, а не после.
Что касается точности, то, взяв из выведенных логов измерения фаз за 200 мс (n = 124), мы получим, что при неподвижной рамке стандартное отклонение фазы составляет 0,039 радиан; это даёт нам ошибку позиционирования (для моей PCB с 8 излучающими «клавишами» = 9,4 мм) примерно в .
Честно говоря, это гораздо лучше, чем я ожидал, особенно учитывая, что STM32F103 выпустили в 2007 году, управляющий сигнал создаётся простым «стучанием» в GPIO, а единственный способ согласования получаемого сигнала — это усилитель с постоянным коэффициентом усиления (мы даже не фильтруем 50-герцовый шум в линии).
▍ Мысли и полученные уроки
- Мне очень понравился процесс потоковой передачи сырых данных на компьютер через USB и выполнения анализа в ноутбуках Python. Он помог и в работе над проектом, когда я путешествовал и находился вдали от оборудования.
- Я не совсем хорошо ориентируюсь в экосистеме Python, поэтому задавал LLM Claude вопросы типа «Можешь сгенерировать график FFT этих данных?», «Пропусти эти данные через фильтр низких частот с отсечкой на 1000 Гц», «Можешь написать сумматор фаз, корректно обрабатывающий циклический возврат?» и так далее. Особенное удовольствие я получил от возможности использования моего легковесного приложения для голосового набора текста, при помощи которого можно просто сообщать свои мысли/идеи LLM.
- Но даже когда мне помогала LLM, создание графиков оказалось сложнее, чем я ожидал:
- Интерактивные графики на основе JS (Plotly и другие) ломались, когда я пытался визуализировать сырые данные всего с примерно сотней тысяч сэмплов.
- Библиотеки для создания статических графиков на основе matplotlib не позволяли простым способом интерактивно считывать точные координаты из точки на графике.
- Агрегация данных при помощи Polars выполнялась вполне неплохо, но для меня было неочевидно, как выполнять агрегацию + создавать график, например, и данных, и их стандартных отклонений между размерностями.
- Вероятно, мне просто нужно выбрать библиотеку на Python для создания графиков и потратить часов двадцать на её изучение.
- Распространение сигнатур комплексных типов в экосистеме Rust Embedded по-прежнему не радует — я застрял в локальном оптимуме «записывать буквально всё в
fn main()
с циклом в конце», чтобы не приходилось прописывать сигнатуры типов.
▍ Дальнейшие улучшения
Вероятно, я не буду развивать этот проект, пока не найду какой-нибудь контекст его применения в робототехнике. Но если вы придумали, как его использовать, то вот несколько идей:
- Разобраться, как создавать параметрические конструкции излучателей/отражателей штангенциркуля в приложениях для моделирования печатных плат наподобие atopile или в каком-нибудь скрипте генерации KiCAD.
- Спроектировать что-нибудь специально для работы с подвижными системами на основе алюминиевых профилей и проверить, насколько дешёвыми/точными они могут быть.
- Сравнить с более «стандартными» системами позиционирования, например, с магнитной лентой или с трекерами SteamVR.
- Превратить это в настоящий работающий штангенциркуль, спроектировав более подходящий корпус (из моего видео можно понять, что изготовленное 3D-печатью основание просто закреплено у меня на столе).
▍ Благодарности
- Mitko за проектирование печатной платы и оборудования. Подробности см. на странице проекта hackday.io.
- Нейтану Перри и Джеффу Макбрайду за помощь в выявлении причины произвольных зависаний STM32F103: бага в кремнии CPU. (Желаю всем нам постараться не столкнуться с ним снова!).
Telegram-канал со скидками, розыгрышами призов и новостями IT ?
Комментарии (42)
BrazilMaterializator
13.11.2024 13:08Выбор слабого SOC и программная замена аппаратных возможностей - legacy или жёсткое ТЗ?
// Неожиданно понял, что это перевод.
Dynasaur
13.11.2024 13:08Вы когда-нибудь мечтали о 500-герцовой системе датчиков линейного положения?
никогда
YDR
13.11.2024 13:08"Мечтают ли андроиды об электроовцах". Теперь мы знаем, что Динозавры о датчиках положения точно не мечтают :-) извините, не удержался. Я сам в некоторой степени динозавр...
strvv
13.11.2024 13:08Если брать патенты о таких системах позиционирования, то они датируются 60-70-ми. Так что это было даже до нас.
Vcoderlab
13.11.2024 13:08Основания отражателей имеют длину ровно 4 «клавиши».
Неверно. Если присмотреться, видно, что справа граница "отражателей" проходит ровно посередине "клавиши". В результате получаем несколько сигналов (по количеству "отражателей"), у которых фаза (или амплитуда) чуть смещена относительно соседей. Всё это в итоге даёт более высокую точность измерения.
YDR
13.11.2024 13:08Да, мне тоже кажется, что "нониусная", "муаровая" система позволит улучшить разрешающую способность. У того же штангенциркуля не то, что 0.6, а 0.01мм. вряд ли там тупо все размеры в 60 раз меньше.
Ещё мне непонятно, как оно поведет себя в движении, если будет ощутимое смещение за время сэмплинга (а оно гарантированно будет)
strvv
13.11.2024 13:08В движении такая система даст сбой, смазываться будет. необходимо применять более быструю - оптическую. Здесь же, на Хабре - https://habr.com/ru/companies/ruvds/articles/592201/
Да и здесь же рассматривали эти емкостные системы позиционирования.
nehrung
13.11.2024 13:08Собственно, нового тут не слишком много. Я ещё в 70-х годах участвовал в разработке системы позиционирования для станка с ЧПУ. Датчиками были линейные индуктосины, выдающие точность 1 микрон (2000 импульсов на 2-миллиметровый шаг печатных дорожек). Принцип тот же, что и в статье, но вместо ёмкостной связи использовалась индуктивная. Собственно, к индуктосинам пришли не от хорошей жизни, а по той причине, что наладить массовое производство точных оптических датчиков линейного перемещения в СССР так и не получилось.
Военные начали использовать индуктосины ещё раньше. Например, в РЛС для точного позиционирования углов поворота антенн (естественно, у них применялись не линейные, а круговые).
SloN1
13.11.2024 13:08"Собственно, к индуктосинам пришли не от хорошей жизни, а по той причине, что наладить массовое производство точных оптических датчиков линейного перемещения в СССР так и не получилось."
А может быть оценили все плюсы и минусы?
Когда я работал с советскими ЧПУ, то там применялись оптические круговые датчики. Насколько я помню, то ли 100, то ли 360 отсчётов на оборот и крепились на вал двигателя. Но ведь там свою погрешность дают зазоры в редукторе.
Если делать линейный из стекла, то конструкция: во-первых, боится любой пыли, во-вторых, хрупкая.
А в советском варианте: распространённейшая технология травления плат, баночка защитного лака (простая физика) и чуть более сложная математика (но с этим в СССР было весьма не плохо). На выходе: точность согласно ТЗ. Чем плохо-то?
В целом: очень часто конечное решение, не смотря на свою кажущуюся неказистость, оказывается оптимальным.
Пока писал, заяндексил про индуктосины: https://kubomc.com/stati/induktosinyi-kubo-texnicheskoe-opisanie
Там смотрите "Стойкость к внешним воздействующим факторам".
Вот ещё из учебника: https://mash-xxl.info/page/109117065156234145031169231119120069226063084008/
iShrimp
13.11.2024 13:08Интересно, можно ли таким же образом сделать абсолютный энкодер?
Если взять однодорожечный код Грея и N излучателей, то для получения N сигналов с помощью 1 приёмника нужно разносить излучатели либо по времени, либо по частоте (как в DTMF с алгоритмом Гёрцеля?)
GidraVydra
13.11.2024 13:08Можно проще - сделать переменный шаг элементов. Обработка будет подороже, придется полноценное Фурье делать, но я не вижу проблемы купить фпга на три доллара дороже.
Andy_Big
13.11.2024 13:08Я разбирал свой штангенциркуль с абсолютной шкалой, но у него неподвижная часть оказалась из стекла с едва видимым под определенным углом напылением. Так и не удалось толком разобрать рисунок на ней.
Fragster
13.11.2024 13:08Может там и нет "рисунка", а просто шум. Даже не супер дорогие мыши имеют разрешение сенсора 2400dpi, что получается примерно 0.01мм на пиксель.
Andy_Big
13.11.2024 13:08У абсолютной шкалы не может не быть рисунка :) По шуму абсолютное положение не определить.
Fragster
13.11.2024 13:08Зачем абсолютное? У меня на штангене есть "установка нуля". А затем от него пляшем, определяя относительное смещение по принципу мыши. Только датчик проще, ибо одномерный (ну или вытянутый).
Andy_Big
13.11.2024 13:08Обсуждается штангенциркуль именно с абсолютной шкалой.
Fragster
13.11.2024 13:08Что значит "штангенциркуль с абсолютной шкалой"? У меня вот такой:
Скрытый текст
Шкала достаточно абсолютная?
Судя по тому, что если очень быстро его двигать он начинает врать - там именно относительное перемещение измеряется. При этом шкала - абсолютная.
Andy_Big
13.11.2024 13:08Что значит "штангенциркуль с абсолютной шкалой"?
Это означает, что подвижная часть не отслеживает относительные перемещения, а определяет свое абсолютное положение на шкале. Если ее убрать от шкалы и приложить к другому месту, она точно покажет новое положение.
Как бы быстро его ни двигать - он не начинает врать. И о кнопке установки нуля можно забыть, потому что ноль не сбивается.Скрытый текст
strvv
13.11.2024 13:08Почему, вполне можно в аболютном позиционере иметь именно рисунок, кодирующий положение.
Moog_Prodigy
13.11.2024 13:08Нет в мышах такой точности. И разрешения такого нет. Я делал энкодеры из мышей. У распространенных матриц разрешение 18х18 пикселей, вот зато скорость обработки бешеная это да, а линза позволяет поднять увеличение сенсора прилично так. Разрешение энкодера из мыши мне удалось получить порядка 0.05мм, но за один оборот всегда разное количество импульсов было, попросту из-за того, что вся обработка перемещения происходит внутри процессора сенсора мыши, т.е. как ему вздумается. И разрешение - это не "точность". Никакой повторяемости. Для ручного энкодера это очень круто, для энкодера обратной связи сервопривода - ну туда-сюда еще, а вот на станок такое смысла ставить нет.
Была у меня мысль по поводу энкодера из компакт-диска и штатной лазерной системы, но что-то стало лень.
Fragster
13.11.2024 13:08Возможно я неудачно выразился со словом "разрешение" (хотя в онлайн каталогах оно называется именно так). В общем - при сдвиге мыши на 1 дюйм - курсор сдвигается на экране на 2400 пикселей, при этом возможен сдвиг и на один пиксель. То, что это сделано с помощью матрицы 18х18 пикселей - может быть. Может быть больше. Главное, чтобы при сдвиге оно успевало сравнить две картинки и определить направление и величину смещения.
Про какой "оборот" мы говорим? Мышей с шариками (который крутил два ортогональных диска с прорезями) не видел уже лет двадцать.
То, что в мышах такое возможно - значит что и в более специфических устройствах подобным же образом можно реализовать, тем более что направление сдвига картинки одно. Сенсор может быть не квадратным, а прямоугольным (вытянутым вдоль направления сдвига).
Moog_Prodigy
13.11.2024 13:08Я скромничать не буду, найдите в гугле по запросу "диджейская вертушка на атмега32 пикабу" , это мой проект. Мне предлагали там же его на Хабр перенести но я думаю такая поделка не стоит Хабра. А потом я и совсем оттуда ушел.
strvv
13.11.2024 13:08Можно и с одной частотой - я чуть выше описал.
В лоб решение, т.е. один сигнал, но приемников много. в соответствии с STGC.
Всё на статоре, а на роторе вместо одного уровня шляпок (T) - несколько таких позиций.
За счёт одной частоты можно поставить усилитель с частотной обратной связью, и дальше пороговый элемент - выше/ниже порога, и получаем сразу бинарный код положения.
GidraVydra
13.11.2024 13:08Как упражнение это интересно, конечно, но точность 0.6 мм на 150 мм хода достигается, извините, даже таким говном мамонта, как реостатная линейка. А на исходном штангене, который и трансмутировали в эту замечательную схему, точность 10-20 мкм. Вопрос - в какой момент оно свернуло не туда и понизило точность копеечной приблуды в 30-60 раз?
ЗЫ. Пока писал комментарий, заметил, что это перевод. А то даже удивился, неужто в копроблогах приличные статьи писать начали?
Gudd-Head
13.11.2024 13:08Основания отражателей имеют длину ровно 4 «клавиши».
Видимо, оно свернуло не туда вот здесь.
Soulskill
13.11.2024 13:08В универе баловался с магнитной индукцией. Два соленоида с обычным ферритовым стержнем. Гипотетически можно добиться сумасшедшей точности, но диапазон измерений довольно сильно ограничен. Питал от звуковухи и записывал на нее же
Andy_Big
13.11.2024 13:08На этом принципе и работают многие прецизионные датчики положения с ходом в несколько мм :)
marshallab
13.11.2024 13:08Разбирался с китайскими штангенами. Они построены на спец чипе типа asic, они всегда включены, даже когда индикация выключена и отслеживают перемещения. Программно суммируют и отнимают положение. Максимальная длина отсчета линейки около 10.5 метров, но это зависит от протокола. Сам чип под каплей очень даде технологичный и сложный. Отдельно чипы купить нельзя. Вообщем снабега повторить не получилось, это весьма сложное устройство оказалось, защищенное патентами к тому же.
BrazilMaterializator
13.11.2024 13:08@BarsMonsterрегулярно показывает внутренности микросхем. Возможно, поставит в очередь и этот чип?
А сколько сигналов на входе чёрного ящика?
sergerz
13.11.2024 13:08Баловался когда-то с корреляционной системой. Берешь стирающую магнитную головку от кассетного магнитофона с двумя зазорами. Разбираешь, мотаешь две катушки на крайних штырях магнитопровода. Там магнитопровод в виде Ш-образного сердечника. Средний штырь освобождаешь от обмотки. И подпиливаешь контактирующую с измеряемой пластиной часть магнитопровода в плоскость. При перемещении головки по пластине из стали на обмотках появляется сигнал. Его усиливаешь и подаешь на АЦП контроллера. Выходную функцию обсчитываешь на взаимную корреляцию двух сигналов с учетом расстояния между зазорами. На выходе получаются некие метки и достаточно точно попадающие в величину перемещения. Правда микроконтроллер оказался слабоват и эксперимент зачах на корню. При контроллерах типа ESP-32 может нормально получиться.
cyber-jet
13.11.2024 13:08Основания отражателей имеют длину ровно 4 «клавиши». - нет, не ровно 4, это шкала нониусов, у нее шаг меньше на величину точности измерения, например в обычном штангенциркуле шкала нониусов имеет шаг 0,9мм что позволяет измерять десятые доли миллиметра.
strvv
13.11.2024 13:08не пугайте страуса, пол бетонный.
это переводная статья, да и тот кто перевёл - в обсуждении практически не участвует.
Fragster
У меня на блютуз рулетке вот такая разметка на обратной стороне - измеряет вполне точно (при измерении одного и того же показания одинаковые)
Предполагаю, что показания получаются оптическим образом.
iliasam
Здесь пишут, что на катушке есть свой энкодер:
https://www.allaboutcircuits.com/news/teardown-tuesday-digital-tape-measure/
Fragster
Возможно, в моем устройстве подобное тоже есть (для увеличения точности? Определения нуля при включении?), но у меня дополнительно есть "регулярная" разметка, а не только "кодированная". К тому же положение поворачивающейся части внутри может зависеть от натяжения ленты и от того, в каком направлении было предыдущее движение ленты. Это может сильно повлиять на точность, а компенсация этого - сильно усложнить механику.
strvv
Так и в штангенциркуле ты можешь сбросить на 0 и изменяя положение, он просто считывает изменениями фазы куда и соответственно смещает переменную отсчёта текущего положения.
В случае, когда требуется абсолютная позиция - применять коды Грея, многодорожечные или однодорожечные (STGC). То есть на подвижной стороне несколько таких регулярных позиций, с них уходят на свои дорожки, с которых регистрируют сигналы на статоре, а напротив этих регулярных позиций, окруженные землей точки с единой генерацией. Получаемый переменный сигнал фильтровать и усиливать, порог перешёл - 1, нет - 0. И в соответствии с кодом - положение.
inkelyad
А можно чуточку больше ключевых слов? А то я заинтересовался, но поиск либо в шуме разных аббревиатур тонет, либо в каких-то слишком теоретических публикациях по теории кодирования и передаче данных.
strvv
Если ввести stgc, то single track grey code однодорожечный код Грея - получается например https://pubmed.ncbi.nlm.nih.gov/30126258/ - это математика,
значит, если брать код грея в поиске хабра - можно найти и реализации.
просто зачастую, не разобравшись как оно реально работает - сложно адаптировать чушой код, аппаратную реализацию под свои задачи.
Можешь задать вопрос в личке, я как будет время и буду в интернете - подскажу.
inkelyad
Да не, я аппаратную реализацию не надо. Оно мне эээ... по эстетическим причинам хочется посмотреть, не пробиваясь через тонны ссылок на предыдущие работы и через статьи про улучшения качества распознования на 10%.
strvv
Специально вновь проверил - на указанной ссылке есть примеры расположения сенсоров и рисунок дорожек, применительно к данному расположению, ниже аннотации статьи, где указатель картинок.
Коротко - количество вариантов может быть до 2^n-2 (т.е. полностью пустой и полный обычно не используется.)