В обычных мышках прячется высокочувствительный оптический датчик. Там скрывается своя маленькая «камера» и процессор обработки, который отслеживает передвижения малейших точек на поверхности. В топовых мышках разрешающая способность составляет всего 3 мкм!
С какими подмышиными камнями мы столкнулись, плюс техническая часть, расскажем дальше!
Следующее ТЗ дал заказчик: сделать как можно скорее, с любой мышкой (возможно беспроводной), выводить на 7 сегментный индикатор, обнулять по кнопке, компьютер не подходит, нужна разрешающая способность 0.01 мм, максимальное расстояние 1000 мм.
Для начала как все это делалось:
План:
Считывание координат xy с мышки: Реализовать считывание данных можно несколькими способами: а) Непосредственно с микросхемы оптического сенсора + Можно обойтись простым контроллером - Про универсальность можно забыть совсем б) Подключить мышку по USB к простым контроллерам (например к ардуино) + Простота и дешивизна - Надо паять - Под рукой была только arduino, а к ней можно подключить мышки совместимые с PS/2, а они обычно очень неточные. Можно было на stm32, но отладочные платы сильно подорожали, самому паять не было времени. (но если интересно, то несколько лет назад был такой похожий проект именно на stm32f4discovery) в) Взять какой нибудь простой одно платный компьютер. Под рукой был как раз Raspberri pi. + Подходит для любых USB мышек + Хорошая производительность - Дорого, но может избыточная мощность потребуется потом
В итоге, под нож хирурга легла Малина пи 3. Четыре 64 битных ядра A-53 по 1GHz, 512 МБ оперативки и много других космических для этой задачи циферок.
Задачка: Индикация должна быть на выданных 7-сегментных индикаторах. Получается нам необходимо по 6 цифр на одну координату, итого 12 индикаторов. Каждый индикатор имеет 7 ножек на цифры+ ножка на светодиод точки (dp), общий провод не считаем. Итого после простых расчетов получаем, что мы должны управлять 96 проводниками плюс нужна кнопка. 96 резисторов не очень хотелось тратить.
Послушайте!
Ведь, если светодиод зажигают — значит — это нужно один резистор?
Управлять сразу таким массивом ножек нету возможности. Выход есть! И даже несколько!
1) Использовать дополнительные микросхемы по типу max7219, или сдвиговые регистры, мультплексоры, и т.д.
+ Можно почти бесконечно наращивать количество индикаторов
— Max7219 оказалась с рабочим напряжением 5 В
— Не было под рукой ничего подходящего.
2) Можно сделать динамическую индикацию. В один момент времени зажигать только один светодиодный индикатор. Если индикаторы переключать очень быстро, то человеческий глаз не заметит подставы.
+ Нужно только 8 проводов и резисторов на один индикатор и 12 на переключение индикаторов. Плюс не забываем кнопку. Итого: всего 21 ножка против 96. Берем!
— Так как мы пытаемся управлять целым индикатором через один пин распберри, то максимальный ток у нас ограничен 50 мА. Всегда берем запас, и берем 35 мА на все 8 светодиодов (что не шибко). Еще к этому добавим быстрое переключение индикаторов. В итоге у нас каждый светит в 12 раз меньше положенного. Доработать можно 12 транзисторами, но оставил я это на потом, т.к. яркости в конечном счете хватило.
Теперь начинается софт:
На распберри пи надо поставить linux. Я поставил минимальный дистрибутив
RASPBIAN JESSIE LITE.
Далее через программу putty подключился к IP малинки, и дальше все через командную строку.
Чтобы было проще работать с GPIO(портами ввода и вывода) есть замечательная библиотека WiringPi.
Как устанавливать её и управлять портами, вы сможете найти много информации в сети, поэтому не буду подробно останавливать на этом.
Дальше надо создать папочку нашего проекта:
cd /home/pi
sudo mkdir mouse
cd /home/pi/mouse
Дальше открываем редактор и вставляем код с гита. ВАЖНО! Код писал на очень скорую руку!
sudo nano
для выхода из редактора надо нажать Alt+x и сохранить файл с названием blinker.c. Дальше надо обязательно скомпилировать с указанием wiring pi:
gcc -o mouse mouse.c -l wiringPi
Все! Теперь подключаем мышку, вставляем провода и запускаем!
// pin number declarations. We're using the Broadcom chip pin numbers.
const int p21pin = 2;
const int p22pin = 3;
const int p23pin = 4;
const int p24pin = 17;
const int p25pin = 27;
const int p26pin = 22;
const int p11pin = 10;
const int p12pin = 9;
const int p13pin = 11;
const int p14pin = 5;
const int p15pin = 6;
const int p16pin = 13;
const int papin = 8;
const int pbpin = 23;
const int pcpin = 12;
const int pdpin = 20;
const int pepin = 21;
const int pfpin = 24;
const int pgpin = 18;
const int pdppin = 16;
const int butpin = 26;
sudo ./mouse
Автозапуск при загрузке:
sudo nano /etc/rc.local
и перед exit 0 дописать две строчки
cd /home/pi/mouse
sudo ./mouse &
Работать с этой прогой очень просто. по нажатию кнопки мыши или просто кнопки на плате идет обнуление. При долгом нажатии кнопки переходим в режим регулировки DPI. Это важный параметр который задается мышкой и показывает сколько отсчетов мы получим при движении на один дюйм. Соответственно копка на плате и на мышке прибавляет и убавляет DPI. Долго нажимаем, наше значение записалось в файл и надежно хранится до следующей загрузки системы. Для чистоты эксперимента в программе, индикация, получение информации с мышки и кнопка обрабатываются а параллельных процессах.
Дальше самое интересное! Тестирование и результаты!
Какие есть нюансы работы с мышкой:
1. Оси X и Y на моей мышке были не параллельны боковым граням, приходилось для высчитывания реального расстояния пользоваться «пифагоровыми штанами».
2. Разрешающая способность не равно погрешность!
Простым языком — разрешающая способность действительно показывает минимальное перемещение, которое увидит мышка, (отсчеты в компьютере должны быть дискретны минимальной разрешающей способности). А вот что мышка ничего не пропустит, ничем не гарантируется. Можно уменьшить эту величину используя хорошие поверхности (чтобы оптический сенсор мог отслеживать перемещения), использовать небольшие скорости. Но пропуски будут всегда! Для пользователя это означает постоянный уход нуля и непрогнозируемую погрешность измерения.
3. USB HID по которому работает мышь не гарантирует доставку информации в компьютер! То есть неизвестно пропустил ли компьютер какую нибудь информацию с мышки или нет. Вероятность пропажи информации малая, но все же есть.
4. Настройки чувствительности(разрешающей способности) иногда хранятся не в мышке, а в программе для мышки.
5. Тут я сильно зол! Дело в том, что мышку я брал самую крутую из ассортимента Logitech, это самая продвинутая была на тот день модель logitech performance mx. Но какого было мое удивление, когда мышь давала разные погрешности при движении вперед и назад. ЭТО КАК? Поясню для пользователя. Если постоянно двигать мышку назад и вперед, то курсор ощутимо так все снижается и снижается. Это на любых платформах. Приходится периодически поднимать мышку и ставить на новое место. После того, как я заметил это, моя жизнь превратилась в кошмар! #Logitech logitech объясните существенную разницу в погрешностях измерения вперед и назад!
Видеодемонстрации работы:
В итоге: недостатки перевесили все плюсы мышки как измерительного прибора. Поэтому проект закрыл и выкладываю для дорогих моих читателей на GeekTimes.
Комментарии (42)
lingvo
18.07.2017 15:55+2Мда. Совсем неправильный метод решения задачи вы выбрали. Ну ничего — многому научились зато. Ну и, надеюсь, мышь и Распберри не пропали даром?
barbanel
18.07.2017 15:57+1По поводу пункта 5, чисто мои домыслы в порядке возрастания бредовости:
— Обычно когда двигаешь мышку, ее координаты меняются с учетом ускорения движения, т.е. резкий рывок мышью даст большее значение чем медленный но на то же самое расстояние. Возможно незаметно для себя вы движете мышь вперед со скоростью, отличной от движения мыши назад.
— Это фичереквест менеджеров, чтобы в будущем выпустить мышьс еще более тонкой батареейс увеличенной точностью всего за 99.99$
— Некий инженер со склонностью петь и танцевать в любой непонятной ситуации, написал в коде:
if ( device_move_direction.to_string = g_move_backward.to_string )
{
// it's about time to sing and dance now
g_error_rate = g_error_rate * random();
}nmi77
18.07.2017 18:38+4Первый вариант скорее всего верный — для измерительных целей в драйвере нужно выключить аксселерацию.
edge790
19.07.2017 15:16Возможно, я не прав, но акселерация — это фича аппаратного уровня.
+ Интересует вопрос: а стелко увеличительное с сенсора сняли?(Если оно было)
На данный момент все производители мышей гонятся за DPI, из-за чего прибегают к «грязным трюкам» типа увеличительных стекол.
Идея простая — жертвуем максимальным ускорением мыши (G) но увеличиваем DPI (т.е. передвижение курсора на X точек за Y дюймов)
Soul_in_Gun
20.07.2017 06:58Данная мышка использует лазеро-оптический тип сенсора, а не «просто оптический», которые грешат положительной акселерацией. В среде геймеров данные параметры (как негативно влияющие на производительность игрока) подробно отслеживаются, созданы списки сенсоров-вендоров где данные погрешности указаны.
Соответственно просто скорость движения вверх и вниз неравномерны отчего и создаётся данная проблема.
Решение — использовать мышь с сенсором не имеющим акселерацию, помимо конечно отключения софтварной акселерации
golf2109
18.07.2017 16:06объясните существенную разницу в погрешностях измерения вперед и назад
разные фронты сигналовbasilbasilbasil
18.07.2017 16:08датчик оптический, какие фронты?
golf2109
18.07.2017 19:48при чем тут «датчик оптический»?
Вы оптический сигнал напрямую в процессор заводите?
На выходе датчика сигнал все-таки электрический.
Фронты электрические передние и задние могут отличатьсяRed_Lion
19.07.2017 07:52Оптический датчик в мышке это буквально небольшая камера, а определение ее перемещения идет за счет сравнения нескольких кадров.
Andy_Big
19.07.2017 08:07+1Там датчик — это миникамера, обрабатывается изображение, а не поток импульсов энкодера.
Mulin
18.07.2017 16:43А если использовать тот же принцип что и в оптических мышах, но в качестве «датчика» заюзать вебку и считать перемещение софтом?
PS Столкнулся с той же проблемой, когда делал датчик перемещения для 3D принтера. Но я там оптическую головку крепил прямо на экструдер, а объектив смотрел на потолок корпуса, таким образом я одним датчиком читал и X и Y.
Gryphon88
18.07.2017 16:58+10Задача уже решалась на ГТ (там, кстати неплохие комментарии). Я тоже, как додавлю разрешение, напишу. В конце сообщения под спойлером ссылки, во всех есть код и схема, но сначала несколько ремарок:
1. Лучше брать проводную мышь постарше, года так 2010-2015, у них пристойное разрешение и они отдают картинку, и подпаяться просто. Я работал на чипе ADNS-2051 (даташит)
2. С чипом мыши можно общаться двумя способами: через серийный порт (просто, но медленно, не больше 30 fps) или читать квадратурные выходы (до 1500 fps, там вроде по сдвигу генерится прерывание и дергается нога)
3. Чипы среднехреновые, в том числе по шуму и расстоянию между пикселами… По шуму можно откалиброваться, но геморно.
4. Разрешение указывают маркетологи, более точной оценкой является расстояние между центрами пикселов делить на 2,5. Можно улучшить разрешение постпроцессингом, в первую очередь через обработку subpixel shift.
5. Оптическая система важна. Или ставьте на прототип вместе с пластиковой родной линзой, или пересчитывайте фокусное расстояние и увеличение
6. Чтобы уменьшить «плытие» и улучшить результаты постпроцессинга используйте подложку с фактурой. Идеал — диффракционная решетка с шагом в 1/2 пиксела сенсора, но и плотная (ок 80 г/м) матовая немелованная бумага подойдёт, волокна работают каак chaotic test target
Ссылки1. Сурово: только мышиный сенсор и LPT-порт. Картинки к статье
2. Ардуино и мышь, одна из первых попыток
3. Ардуино и мышь-2, более подробно
4. Ардуино, мышь и JS Хипстота, зато сразу в браузер
5. Арудиновская библиотека для работы с мышиными сенсорами
6. ATMega8 и сенсор
7. AVRовская библиотека AVRCam, чтение мышиного сенсора, постобработка, трекинг. Можно скачать бесплатно, там просто ссылка незаметнаяrstepanov
18.07.2017 17:26При использовании энкодера ошибка будет всегда накапливаться, достаточно подергать взад-вперед раз сто — и точность будет уже не доли миллиметра, а скорее десятки сантиметров :) Для таких задач лучше применять что-то типа этого:
https://sensing.honeywell.com/honeywell-sensing-longfellow2-linear-position-transducer-productsheet.pdfrstepanov
18.07.2017 17:28Или китайчатина подешевле: https://ru.aliexpress.com/store/product/Free-shipping-Rational-WTB5-0-001mm-600mm-dro-linear-scale-Lathe-accessories-absolute-position-encoder-for/1021179_32386818977.html
dlinyj
18.07.2017 18:46+1Очень много мыслей, но нет толкового описания работы с мышью.
SergeySavkin
19.07.2017 12:37Мышь подключается по USB. Дальше идет работа со стандартными драйверами.
VBKesha
18.07.2017 18:48— max7219 оказалась с рабочим напряжением 5 В
Я проверял два модуля на этих чипах, никаких проблем они не испытывали пари работе от 3,3В и питание и сигналы, и спокойно работали при 5В питании, и 3.3 логике управления.
VBKesha
18.07.2017 18:54+1По поводу результатов, А что если поставить несколько сенсоров, разнонаправленых, и потом сводить с них результат воедино?
Gryphon88
18.07.2017 21:52+2В смысле — разнонаправленных? В мыши квадратная матрица, от 15*15 до 128*128
rPman
20.07.2017 23:09Нужно совместить два разных метода, один точный — на основе сенсора мыши, другой грубый — на основе подсчета рисок на линейке. Грубый используется для калибровки.
iG0Lka
18.07.2017 19:26+1Из решения аналогичных задач в свое время родился проект w-mouse.
Его автор — Walkie, как раз использует мышиные сенсоры, на производстве, для определения перемещения.
Если нужен реальный результат советую Вам с ним связатся.
Кстати w-mouse имеет счетчик посланных отсчетов по X и Y, зная текущее дпи легко подсчитывать смещение.
скрин экрана настройки
longtolik
18.07.2017 19:33+1Здравствуйте, можете попробовать ещё датчик от электронного штангенциркуля, (digital caliper). Он работает по IIC, в основном.
На датчике мыши я делал энкодеры, и они меня не разочаровали. Посмотреть можно здесь:
http://www.rlocman.ru/shem/schematics.html?di=162625 там же и ссылки на некоторые чипы.andersong
19.07.2017 08:57У простых электронных штангетов данные относительные, те требуется установка нуля при каждом включении, но читал про штангеты (марку забыл), где данные абсолютные, те штангет после включения сразу выдает показания, в каком бы месте каретка ни находилась. Как это реализовано? На шкалу нанесены кодирующиие метки?
longtolik
19.07.2017 09:34Насколько я понимаю, питание на чип подаётся постоянно, кнопка отключает ЖКИ. Поэтому батарейка и «садится», независимо от того, работает ли он в режиме измерения или просто лежит в футляре. Те, с которыми я работал, все «помнили» показания, но если вытащить батарейку, то «сбрасывались». У всех был разъем для подключения, но вот протокол может быть нескольких типов.
Если это критично, то можно сделать так: микроконтроллер считывает показания в ОЗУ (регистр), цепь питания двухступенчатая, то есть, присутствует ещё что-то вроде конденсатора или ионистора. Напряжение от блока или элементов питания подаётся на один из входов микроконтроллера, и когда оно падает ниже критического уровня, наступает прерывание, в ходе обработки которого показания быстро переписываются в энергонезависимую память. После включения, если они не пусты, то считываются в ОЗУ.
P.S. Раньше микро-ЭВМ успевали всю свою память записывать на диск, когда напряжение 220 Вольт пропадало, но постоянное напряжение ещё держалось на конденсаторах блока питания.
nafikovr
19.07.2017 13:46вариант с мышкой тоже относительный. промышленный линейные датчики тоже относительные, но имеют реперные метки.
x893
18.07.2017 19:40А если поставить два сенсора с противоположной ориентацией?
И корректировать вперед-назад с двух? И то же самое сделать по второй координате?
И не нашел подключение мыши в картинке названия контактов на RPi.
lonelymyp
18.07.2017 21:58+4Неужели не захотелось погуглить прежде чем пробовать?
Все многочисленные проекты использующие мышиный сенсор испытывают примерно одинаковые проблемы, мышиный сенсор пропускает движение.
За последние лет 10-15 ничего особо в этом плане не изменилось.
avf1906
19.07.2017 15:18насчет индикаторов — на али искать по слову tm1637 — два провода = 6 цифр + 16 кнопок (на кнопки ограничение, не поддерживаются одновременные нажатия). хотя наиболее массовые с 4 цифрами, может на будущее пригодится
basilbasilbasil
SergeySavkin
1.В итоге другую мышь и взяли, но она просто на расстоянии 100мм дает погрешность 1 мм, а нам нужна 0.01мм
2. Микронасчеки можно, но за нас это сделала природа, например дерево или бумага.
basilbasilbasil
да, но насечки природного происхождения неупорядоченные.
SergeySavkin
Тут правильно ответил Gryphon88 «волокна работают как chaotic test target»