При видеокаротаже мы опускаем в скважину камеру и видим на экране обсадную трубу, фильтры, отложения и повреждения, застрявшие насосы и тд. Но есть проблема: на видео нет глубины. Ты видишь картинку, но не знаешь, на какой глубине находится камера. Можно конечно сделать метки на кабеле, условно, каждые 1 -2 метра, но это жутко не удобно и их нужно стоять и считать, вообще тот еще костыль. Раньше использовали вторую видео камеру, которая снимала механический счетчик с отображением метров, но тоже костыль. Нужно потом накладывать друг на друга картинку, что не самый удобный вариант.
А можно наложить глубину прямо на видеопоток в реальном времени. Это экономит часы расшифровки и исключает ошибки, а главное это отображение глубины и видео прямо тут и сейчас.
Вот как я это сделал. Начнем с железа :
Микроконтроллер: Arduino Nano
Почему? Простота и размер. Он маленький, дешёвый, легко программируется. Вставляется в разъём на плате OSD-модуля. В сети куча примеров по данной теме, решил использовать то, что уже было сделано другими.
Чип OSD: MAX7456
Этот чип умеет в реальном времени накладывать символы на аналоговый видеосигнал. Выпускается в готовых модулях — например, MinimOSD. Такие модули изначально делали для квадрокоптеров (F3/F4 flight controllers), но они отлично подходят для каротажа.
Почему не готовый видеорегистратор со встроенным OSD?
Дорого.
Нельзя программировать под свои задачи.
Обычно нет возможности принимать данные по Serial извне.
Библиотека: стандартный SPI + самописные функции. Готовые библиотеки из интернета не
всегда корректно работали с PAL, поэтому часть кода писал сам.
Я использовал готовый модуль MinimOSD, который уже включает MAX7456 и всю схему обвязки. Подключение — по UART (TX → RX, RX → TX, земля). Arduino отправляет на модуль символы для отображения. Самому паять SPI-подключение не нужно. Можно конечно купить чип сделать плату ( также есть схема в сети, кстати достаточно подробная ) но я человек-лень.
Видеосигнал от камеры идёт на видеовход модуля, с выхода — на монитор или видеорегистратор. Модуль смешивает исходное видео с наложенными символами.
В итоге берем модуль, очищаем его память, подаем питание:
После подачи питания нужно сбросить MAX7456 и настроить видеорежим:
digitalWrite(MAX7456SELECT, LOW); spi_transfer(VM0_reg); spi_transfer(MAX7456_reset); // сброс digitalWrite(MAX7456SELECT, HIGH); delay(500);
// Настройка яркости строк (белый уровень 90%) for (x = 0; x < MAX_screen_rows; x++) { spi_transfer(x + 0x10); spi_transfer(WHITE_level_90); }
// Включаем OSD, синхронизация по VSYNC, режим PAL (у нас Россия) spi_transfer(VM0_reg); spi_transfer(VERTICAL_SYNC_NEXT_VSYNC | OSD_ENABLE | VIDEO_MODE_PAL);
Основной регистратор на STM32 Black Pill отправляет данные по Serial на Arduino. Формат очень простой: текстовая строка, заканчивающаяся \n.
Если строка начинается с
C— это глубина в метрах (например,"C123.45\n").Если с
G— это локация муфт (например,"G87.2\n").
Arduino читает в буфер:
while (Serial.available() > 0) { Serial.readBytesUntil(0x0a, mass, 64); } потом отображает :
if (mass[0] == 0x43) { // ‘C’ // извлекаем число и выводим printDisplayCircle(result); } if (mass[0] == 0x47) { // ‘G’ printDisplayLocate(result); }
Функция OSD_write_to_screen — самая важная. Она помещает строку в заданные координаты (x,y). Координаты подбирались экспериментально, чтобы цифры не наезжали на важные элементы изображения.
cpp
void OSD_write_to_screen(const char s[], byte x, byte y, byte blink, byte invert) { // x - горизонталь (символы, до 30) // y - вертикаль (строки, до 16) // blink - мигание (0 - нет, 1 - да) // invert - инверсия фона (0 - нормально, 1/3 - инверсия) ... }
Последний параметр invert особенно полезен: инвертированные символы отлично видны на светлом фоне (например, на яркой воде или белой трубе).
Вот как выглядит обмен в реальном времени:
Оператор на регистраторе (STM32 Black Pill, дисплей DWIN) включает режим видео.
Энкодер глубины выдаёт импульсы. STM32 пересчитывает их в метры.
По Serial (UART) на Arduino уходит строка:
"C125.30\n"(125 метров 30 см).Arduino принимает её, разбирает и вызывает
printDisplayCircle("125.30").На экране монитора, рядом с глубиной, отображается цифра.
Для локации муфт — аналогично: "G45.1\n" и вывод в левом верхнем углу надпись "Loc: 45.1".
Скорость обмена: 9600 бод. Этого достаточно, потому что глубина меняется не быстрее 1-2 раз в секунду (скорость спуска 5-10 м/мин).



Когда сделал плату, поставил камеру, пришла пора сделать корпус.

Самое сложное- выточить стекло, нужно точить строго в размер, попадет вода-помрет все. Для связи с кабелем сделал наконечник прибора, да не просто, а герметичный:

Уплотнения- резина, зазоры все по заводу), максимальное давление выдержало около 50 атм, это 500 метров под водой.
