- Первое включение и установка wi-fi соединения
- Пользовательский интерфейс управления
- Настройка устройства и конфигурационные файлы
- Информация для разработчиков
По дефолту устройство при загрузке пытается подключиться к следующей wi-fi сети:
SSID: Issaya
PASS: <мобильный заказчика>
Чтобы настроить свою сеть и подключить устройство к другой сети wi-fi, необходимо временно поднять точку доступа с вышеуказанными параметрами,
дождаться пока плата подключится к ней и узнать IP-адрес. Например, посмотреть его на web-странице роутера или с помощью nmap
на Linux системах.
Помните, что на плате RPI есть единственный и дефолтный пользователь в системе:
User: pi
Password: \\
Далее нужно залогиниться по SSH на плату.
ssh pi@<ip-addr>
И выполнить следующие команды для установки нового wi-fi соединения
nmcli device wifi connect YOUR-SSID password "YOUR-PASSWORD"
nmcli device set wlan0 autoconnect yes
sudo reboot
После этого устройство всегда будет подключаться к вашей сети автоматически.
После успешного подключения устройства к сети необходимо узнать его ip-адрес, если он ещё вам неизвестен.
Например, это будет 192.168.1.55.
Веб-интерфейс управления доступен на порту 5000.
То есть, чтобы открыть UI, нужно в браузере зайти на страницу: http://192.168.1.55:5000/
.
UI с устройств Mac/Windows/Linux с использованием Google Chrome (Firefox аналогично)
UI с устройства Android с использованием Google Chrome (Firefox аналогично)
Как только плата стала "онлайн", на ней автоматически запускается два systemd-сервиса:
-
Сервис, реализующий логику преобразования протокола Modbus TCP в Modbus RTU, для взаимодействия с микроконтроллером, подключенным в к плате RPI. Сервис называется
modbus_converter
. -
Сервис, реализующий HTTP-сервер и непосредственный стриминг видео, для взаимодейтсвия с устройстром через браузер. Сервис называется
microscope_server
.
Оба этих сервиса можно настраивать с помощью конфигурационных файлов. Все нужные конфиги и все исполняемые
файлы находятся по пути - /home/pi/.microscope
. (обратите внимание, что в названии есть точка).
Конфигурационный файл сервиса modbus_converter
- это /home/pi/.microscope/modbus_converter.conf
.
Формат файла - JSON. Этот конфиг считается низкоуровневым и служит для настройки пинов и скорости UART на плате RPI, к которому подключён нижестоящий микроконтроллер. Дефолтный конфиг выглядит так:
{
"uart_device": "/dev/ttyAMA5",
"uart_baud": "9600",
"uart_parity": "N",
"uart_data_bit": "8",
"uart_stop_bit": "1",
"modbus_port": "1502",
"modbus_number_of_tcp_connections": "1",
"modbus_connected_microcontroller_slave_addr": "1",
"modbus_camera_slave_addr": "2",
"modbus_loss_connection_timeout_ms": "1000"
}
modbus_port
- порт, на котором сервис modbus_converter
откроет TCP соединение.
modbus_number_of_tcp_connections
- количество возможных TCP соединений. Это для будущего использования. На данный момент поддерживается только одно соединение. Если изменить этот параметр, то сервис выдаст в лог информацию о том, что это пока не поддерживается и всё равно будет создавать только одно соединение.
modbus_connected_microcontroller_slave_addr
- slave-адресс нижестоящего микроконтроллера. Можно установить какой угодно, так как любые присланные данные будут переданы устройству uart_device
,
но важно, чтобы это значение не совпадало c slave-адресом камеры.
modbus_camera_slave_addr
- slave-адрес, на который будет реагировать камера. Это используется,
если хотите получать и управлять видеостримом БЕЗ web-сервера.
Например, это может быть полезно для написания собственного UI, в котором будет управление потоком.
modbus_loss_connection_timeout_ms
- время ожидания ответа (в милисекундах) от нижестоящего микроконтроллера. Если в течении этого промежутка времени нет ответа от устройства uart_device
, то сервис просто начинает заново ожидать указаний по TCP.
!!! Важно !!!
Если какой-либо из параметров был изменён, то НЕОБХОДИМО ПЕРЕЗАПУСТИТЬ сервис, чтобы настройки вступили в силу:
sudo systemctl stop modbus_converter
sudo systemctl start modbus_converter
Или просто перезагрузить устройство:
sudo reboot
Конфигурационный файл сервиса microscope_server
- это /home/pi/.microscope/microscope_server.conf
.
Формат файла - JSON. Этот конфиг считается высокоуровневым и используется для
задания количества шагов двигателей при работе с устройством. Дефолтный конфиг выглядит так:
{
"home_steps_cnt_focus_stepper": "-32766",
"home_steps_cnt_updown_stepper": "-32766",
"home_steps_cnt_leftright_stepper": "-32766",
"swap_updown_and_leftright_logic": "yes",
"work_steps_cnt_focus_stepper": "-300",
"work_steps_cnt_updown_stepper": "-111",
"work_steps_cnt_leftright_stepper": "-112",
"retention_step_size_focus_stepper": "1",
"retention_step_size_updown_stepper": "1",
"retention_step_size_leftright_stepper": "1",
"modbus_repeat_cmd_period_ms": "100",
"modbus_soc_polling_period_ms": "60000",
"modbus_led_max_pwm_percentage": "20",
"modbus_debug_mode": "Off"
}
home_steps_*
- это количество шагов, которые будут посылаться сервисом в нижестоящий
микроконтроллер, когда пользователь нажимает кнопку HOME в интерфейсе управления.
Соответственно при дефолтной конфигурации сервер пошлёт в микроконтроллер следующие данные:
- -32766 шагов на мотор, отвечающий за фокусировки камеры
- -32766 шагов на мотор, отвечающий за движение ввер-вниз
- -32766 шагов на мотор, отвечающий за движение вправо-влево
В этот параметр можно устанавливать как положительные числа(то есть без явного указания знака), так и отрательные (то есть явно пишут знак "-", как в дефолтном конфиге). Либо можно установить значение "0". Это будет означать, что сервер не будет посылать ничего на тот мотор, где указано это значение.
swap_updown_and_leftright_logic
- если указано "yes", то моторы up-down и "left-right" инвертированы.
То есть вы нажимаете ехать, например, кнопки влево/вправо, а по факту команда пошлётся для
моторов вверх/вниз.
work_steps_*
- это количество шагов, которые будут посылаться сервисом в нижестоящий
микроконтроллер, когда пользователь нажимает кнопку WORK в интерфейсе управления.
Тут также можно устанавливать либо положительные числа, либо отрицательные, либо ноль.
retention_step_size_*
- это количество шагов, которые будут посылаться сервисом в нижестоящий микроконтроллер,
когда пользователь удерживает кнопки +/- или up/down/left/right. То есть при однократном нажатии
пошлётся точно 1 шаг. А при удержании будет переодически посылаться кол-во шагов, указанное тут.
modbus_repeat_cmd_period_ms
- период в милисекундах, с которым браузер будет повторять команды при удержании кнопок.
modbus_soc_polling_period_ms
- период в милисекундах, с которым браузер будет опрашивать заряд уст-ва.
modbus_led_max_pwm_percentage
- максимальное значение яркости светодиодов в процентах от максимума ШИМ.
!!!Важно!!! При обновлении какого либо параметра в этом конфиге достаточно просто ОБНОВИТЬ страницу в браузере, чтобы сервер считал новые данные
Запуском стрима можно управлять напримую по Modbus TCP без участия сервера. НО для этого нужно зайти на RPI и остановить работу сервера:
sudo systemctl stop microscope_server
Камера будет реагировать на тот адрес slave-устройства, что указали в конфиг-файле.
Команды для всех остальных адресов будут пересылаться нижестоящему микроконтроллеру.
На данный момент камера поддерживает только одну команду (один Modbus function code) - MODBUS_FC_WRITE_SINGLE_REGISTER=0x06
Это команда на запись аналогового вывода.
Была выбрана именно эта команда, так как в будущем можно сделать, чтобы 16-битные регистры Modbus отвечали за настройки камеры.
Например, настройка зума, баланса белого и тд.
На данный момент поддерживается только один регистр у этой команды - CAMERA_API_LAUNCH_VIDEO_REG_ADDR=0x01
Этот регистр отвечает за состояние видеопотока.
Значения этого регистра могут быть следующие:
typedef enum {
CAMERA_API_LAUNCH_VIDEO_4K_VALUE = 0x00,
CAMERA_API_LAUNCH_VIDEO_1080P_VALUE = 0x01,
CAMERA_API_LAUNCH_VIDEO_STOP_VALUE = 0x02,
} camera_api_supported_cmd_values_t;
Примеры Modbus-команд для камеры:
0x02 0x06 0x00 0x01 0x00 0x00 <crc16> - запустить 4к видео стрим на ip адресс хоста.
0x02 0x06 0x00 0x01 0x00 0x01 <crc16> - запустить 1080p видео стрим на ip адресс хоста.
0x02 0x06 0x00 0x01 0x00 0x02 <crc16> - остановить вообще видеопоток. (Использовалось для отладки).
Если камера получила неподдерживаемые значения fucntion code, регистра или значений регистров, то сервис modbus_converter вернёт соответствующие коды ошибок вышестоящей программе, приславшей неверную команду. В данном случае - программе Modbus Poll.
Как только к сервису modbus_converter
присоединился по TCP какой-то клиент, то сервис самостоятельно определяет IP адрес этого хоста и записывает его в соответствующий конфиг-файл. Далее, как только конвертер получил команду для камеры, то он запускает соответствующий скрипт на RPI. Если запросили 4к, то запускает 4к. Если 1080p, то 1080p.
Предварительно будет считан конфиг-файл с адресом хоста. И именно на этот адрес будет посылать видеострим с помощью gstreamer.
Как установить gstreamer на любую платформу? На плате RPI он уже установлен:
Если вы хотите запустить стрим в каком-либо разрешении, то нужно просто послать соответствующую Modbus-команду на запуск стрима. Предварительно посылать команду "стоп" не нужно. Конвертер сам остановит старый стрим и запустит новый, если это необходимо.
Но на хосте нужно запускать соответствующие скрипты для отображения стрима руками.
Скрипты для хоста лежат в этом репозистории в директории scripts/
. Файлы с префиксом host_
в названии - это скрипты для запуска на хосте для отображения видеопотока.
Все остальные скрипты в этой директории не обязательны для пользователя. Они либо уже есть в образе, либо используются системой сборки для компиляции/установки.
Для стрима 1080p
На хосте запустить ./host_show_mjpg_1080p_stream_with_fps
Для стрима 4к
На хосте запустить ./host_show_h264_stream_with_fps
То есть сценарий запуска такой:
- Сначала посылается соответствующая команда для камеры по Modbus TCP
- Затем на хост-машине запускается соответствующий скрипт. При этом, если ранее на хосте уже был запущен какой-либо из скриптов, то его нужно остановить и только потом запускать новый.
Это нужно делать руками только лишь потому, что стримы посылаются в разных кодировках. Для 4к используется H264. Для 1080p - MJPG. Поэтому на хосте требуется запускать разные декодеры.
# Просмотр логов сервиса modbus_converter в режиме tail -f, показав последние 50 строк лога
sudo journalctl -a -f -n 50 -u modbus_converter
# Просмотр логов сервиса modbus_converter с момента последней загрузки системы
sudo journalctl -b -u modbus_converter
По дефолту сервис скомпилирован с параметром MODBUS_CONVERTER_DEBUG=0
(см. Makefile), поэтому логов будет не очень много.
Логироваться будут только ошибки и немного теоретически полезной информации о состоянии программы.
Если нужен подробный лог происходящего, то нужно пересобрать и перезапустить сервис с
установленным этим дефайном в значение 1
.
# Просмотр логов сервиса microscope_server в режиме tail -f, показав последние 50 строк лога
sudo journalctl -a -f -n 50 -u microscope_server
# Просмотр логов сервиса microscope_server с момента последней загрузки системы
sudo journalctl -b -u microscope_server
В образе включены 3 разных uart, которые можно использовать для подключения к ним uart от нижестоящего микроконтроллера. Здесь пины - это номер пина на 40-ко пиновой гребёнке.
# /dev/ttyAMA3 - UART3.
PIN7 - TX
PIN29 - RX
# /dev/ttyAMA4 - UART4.
PIN24 - TX
PIN21 - RX
# /dev/ttyAMA5 - UART5. <--- дефолт
PIN32 - TX
PIN33 - RX
Если в код были внесены изменения, то все они будут закомичены тут, в этот репозиторий. Чтобы применить изменения на стороне заказчика необходимо сделать следующее:
Залогиниться по ssh на RPI и далее:
1. cd Microscope-controller
2. ./update.sh
После этого можно вновь пользоваться устройством как ранее.
Сам образ представляет из себя дефолтный образ для RPI4 без графического интерфейса.
- Далее были включены девайсы последовательных портов. Для этого в device tree были добавлены overlays. Они включены с помощью записи следующих строк в файл
/boot/config.txt
enable_uart=1
dtoverlay=uart3
dtoverlay=uart4
dtoverlay=uart5
Они загружаются во время boot-time, поэтому команда dtoverlay -l
не покажет их.
Также в образе включен bootlog uart. Можно подсоединить к гребенке на PIN8(tx0) и на PIN10(rx0) uart-usb преобразватель и пользоваться этим uart, как консолью для управления платой RPI без подключения платы к wifi и без SSH.
Посмотреть текущую конфигурацию пинов можно с помощью следующих команд:
$ pinctrl
либо
$ raspi-gpio get
Обе команды выводят информацию о текущих настройках пина. В этом случае в выводе каоманд GPIO-N - это номер gpio на процессоре. То есть НЕ на 40-ко пиновой гребёнке.
- В файл
~/.bashrc
добавлены эти строки:
export LC_ALL="en_US.UTF-8"
export LANG="en_US.UTF-8"
alias ll="ls -l"
alias myip='curl ipinfo.io/ip; echo'
- Пользоваьель pi добавлен в sudouser
sudo adduser pi sudo
- Ограничен размер логов до 100Mb и выключен бродкастинг в journalctl
sudo nano /etc/systemd/journald.conf
SystemMaxUse=100M
ForwardToWall=no
sudo systemctl restart systemd-journald
- Отключено логирование PAM-сессий в journal
sudo nano /etc/sudoers
Defaults !syslog, !pam_session
- Далее были доустановлены в образ следующие программы:
gstreamer
sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio
Программы для компиляции библиотек и конвертера
sudo apt-get install git autoconf libtool
libmodbus
git clone https://github.com/stephane/libmodbus.git
cd ~/Microscope-controller/modbus_tcp_rtu_converter/patches
scp * [email protected]:/home/pi/libmodbus/
cd ~/libmodbus
git apply libmodbus_tid.patch
git apply libmodbus_msglen.patch
sudo ./autogen.sh
sudo ./configure --prefix=/usr/local/
sudo make
sudo make install
libsystemd для Python-обёртки
sudo apt-get install libsystemd-dev
sudo apt-get install python3-dev
lsof
sudo apt-get install lsof
v4l
sudo apt-get install v4l-conf
Flask
# Install Flask itself
cd ~
python3 -m venv .venv
. .venv/bin/activate
cd /home/pi/Microscope-controller/web_server
pip install -r requirements.txt
deactivate
# Run server at <ip>:5000
. .venv/bin/activate
cd /home/pi/Microscope-controller/web_server
flask run --host=0.0.0.0 --debug --app microscope_server.py