├── LICENSE
├── README.md
├── en_notes_start_hi3536ev100.md
├── gk7205v200
├── 659A7_OpenIPC_FPV.bin
├── 88XXau.ko_8812_8821
├── etc
│ ├── init.d
│ │ ├── S95majestic
│ │ └── S98datalink
│ ├── majestic.yaml
│ ├── sensors
│ │ └── imx307_i2c_2l_720p_50fps.ini
│ └── wfb.conf
├── root
│ ├── 1080.sh
│ ├── 1080b.sh
│ ├── 1080c.sh
│ ├── 3K.sh
│ ├── 4K.sh
│ ├── 720.sh
│ ├── 720b.sh
│ ├── 720c.sh
│ ├── 720d.sh
│ ├── channels.sh
│ ├── channels2.sh
│ ├── ircut.sh
│ └── kill.sh
├── u-boot-gk7205v200-universal.bin
└── usr
│ ├── bin
│ ├── telemetry
│ ├── venc
│ └── wifibroadcast
│ ├── lib
│ └── sensors
│ │ └── libsns_imx307_2l_720p_50fps.so
│ └── sbin
│ └── gkrcparams
├── gk7205v200_u-boot-7502v200-for-telemetry.md
├── gk7502v300
├── etc
│ ├── majestic.yaml
│ ├── telemetry.conf
│ └── wfb.conf
├── root
│ └── ircut.sh
└── usr
│ └── lib
│ └── sensors
│ └── libsns_imx307.so
├── gkrcparams.md
├── gstlaunch_on_windows.md
├── hi3536dv100
├── 88XXau-ko
│ ├── 88XXau.ko_8812au
│ └── 88XXau.ko_8812au_8814au
├── etc
│ ├── init.d
│ │ ├── S96gpio_monitor
│ │ └── S99rcjoystick
│ ├── mavlink.conf
│ └── telemetry.conf
├── hi3536dv100.generic.config
├── hi3536dv100_fpv_defconfig
├── lib
│ └── modules
│ │ └── 4.9.37
│ │ └── extra
│ │ ├── 8188eu.ko
│ │ └── 88XXau.ko
├── original_firmware
│ ├── env.txt
│ └── fullflash_202303012255_W25Q128BV_16MB_HI3536DV100_orig_dev2.bin
├── root
│ ├── gpio_monitor.sh
│ ├── resolution.sh
│ └── vdec
├── rootfs.squashfs.hi3536dv100
├── uImage.hi3536dv100
└── usr
│ └── bin
│ ├── mavlink-routerd
│ └── rcjoystick
├── lte-fpv.md
├── mavfwd
├── mavfwd
├── mavfwd.c
└── readme.md
├── note-nvr-tab-ap.md
├── note-two-cameras-switched.md
├── note_nvr_wdt.md
├── note_telemetry_baud.md
├── notes_cam_control.md
├── notes_files
├── IMG_20230323_081622_212.jpg
├── OpenIPC_telemetry.csv
├── OpenIPC_video.csv
├── Screenshot_1.png
├── Screenshot_2.png
├── ZTNCUI.png
├── baud38400.jpg
├── gk7205v200.png
├── hi3536ev100.png
├── hi3536ev100_pinout.png
├── link_hw.png
├── mp_h265.png
├── photo_2023-03-23_02-12-40.jpg
├── qgc-udp-settings.png
├── telemetry.png
├── usb-ethernet.png
└── video.png
├── notes_imx335_gk7205v300.md
├── notes_link_gk7205v200_hi3536ev100.md
├── notes_start_hi3536ev100.md
├── notes_start_ivg-g2s.md
├── nvr_gpio.md
├── rcjoystick.md
├── rcjoystick
├── Config.in
├── rcjoystick.mk
└── src
│ ├── Makefile
│ ├── checksum.h
│ ├── common
│ ├── common.h
│ ├── mavlink.h
│ ├── mavlink_msg_actuator_control_target.h
│ ├── mavlink_msg_actuator_output_status.h
│ ├── mavlink_msg_adsb_vehicle.h
│ ├── mavlink_msg_ais_vessel.h
│ ├── mavlink_msg_altitude.h
│ ├── mavlink_msg_att_pos_mocap.h
│ ├── mavlink_msg_attitude.h
│ ├── mavlink_msg_attitude_quaternion.h
│ ├── mavlink_msg_attitude_quaternion_cov.h
│ ├── mavlink_msg_attitude_target.h
│ ├── mavlink_msg_auth_key.h
│ ├── mavlink_msg_autopilot_state_for_gimbal_device.h
│ ├── mavlink_msg_autopilot_version.h
│ ├── mavlink_msg_battery_status.h
│ ├── mavlink_msg_button_change.h
│ ├── mavlink_msg_camera_capture_status.h
│ ├── mavlink_msg_camera_fov_status.h
│ ├── mavlink_msg_camera_image_captured.h
│ ├── mavlink_msg_camera_information.h
│ ├── mavlink_msg_camera_settings.h
│ ├── mavlink_msg_camera_tracking_geo_status.h
│ ├── mavlink_msg_camera_tracking_image_status.h
│ ├── mavlink_msg_camera_trigger.h
│ ├── mavlink_msg_can_filter_modify.h
│ ├── mavlink_msg_can_frame.h
│ ├── mavlink_msg_canfd_frame.h
│ ├── mavlink_msg_cellular_config.h
│ ├── mavlink_msg_cellular_status.h
│ ├── mavlink_msg_change_operator_control.h
│ ├── mavlink_msg_change_operator_control_ack.h
│ ├── mavlink_msg_collision.h
│ ├── mavlink_msg_command_ack.h
│ ├── mavlink_msg_command_cancel.h
│ ├── mavlink_msg_command_int.h
│ ├── mavlink_msg_command_long.h
│ ├── mavlink_msg_component_information.h
│ ├── mavlink_msg_component_metadata.h
│ ├── mavlink_msg_control_system_state.h
│ ├── mavlink_msg_current_event_sequence.h
│ ├── mavlink_msg_data_stream.h
│ ├── mavlink_msg_data_transmission_handshake.h
│ ├── mavlink_msg_debug.h
│ ├── mavlink_msg_debug_float_array.h
│ ├── mavlink_msg_debug_vect.h
│ ├── mavlink_msg_distance_sensor.h
│ ├── mavlink_msg_efi_status.h
│ ├── mavlink_msg_encapsulated_data.h
│ ├── mavlink_msg_esc_info.h
│ ├── mavlink_msg_esc_status.h
│ ├── mavlink_msg_estimator_status.h
│ ├── mavlink_msg_event.h
│ ├── mavlink_msg_extended_sys_state.h
│ ├── mavlink_msg_fence_status.h
│ ├── mavlink_msg_file_transfer_protocol.h
│ ├── mavlink_msg_flight_information.h
│ ├── mavlink_msg_follow_target.h
│ ├── mavlink_msg_generator_status.h
│ ├── mavlink_msg_gimbal_device_attitude_status.h
│ ├── mavlink_msg_gimbal_device_information.h
│ ├── mavlink_msg_gimbal_device_set_attitude.h
│ ├── mavlink_msg_gimbal_manager_information.h
│ ├── mavlink_msg_gimbal_manager_set_attitude.h
│ ├── mavlink_msg_gimbal_manager_set_manual_control.h
│ ├── mavlink_msg_gimbal_manager_set_pitchyaw.h
│ ├── mavlink_msg_gimbal_manager_status.h
│ ├── mavlink_msg_global_position_int.h
│ ├── mavlink_msg_global_position_int_cov.h
│ ├── mavlink_msg_global_vision_position_estimate.h
│ ├── mavlink_msg_gps2_raw.h
│ ├── mavlink_msg_gps2_rtk.h
│ ├── mavlink_msg_gps_global_origin.h
│ ├── mavlink_msg_gps_inject_data.h
│ ├── mavlink_msg_gps_input.h
│ ├── mavlink_msg_gps_raw_int.h
│ ├── mavlink_msg_gps_rtcm_data.h
│ ├── mavlink_msg_gps_rtk.h
│ ├── mavlink_msg_gps_status.h
│ ├── mavlink_msg_high_latency.h
│ ├── mavlink_msg_high_latency2.h
│ ├── mavlink_msg_highres_imu.h
│ ├── mavlink_msg_hil_actuator_controls.h
│ ├── mavlink_msg_hil_controls.h
│ ├── mavlink_msg_hil_gps.h
│ ├── mavlink_msg_hil_optical_flow.h
│ ├── mavlink_msg_hil_rc_inputs_raw.h
│ ├── mavlink_msg_hil_sensor.h
│ ├── mavlink_msg_hil_state.h
│ ├── mavlink_msg_hil_state_quaternion.h
│ ├── mavlink_msg_home_position.h
│ ├── mavlink_msg_hygrometer_sensor.h
│ ├── mavlink_msg_isbd_link_status.h
│ ├── mavlink_msg_landing_target.h
│ ├── mavlink_msg_link_node_status.h
│ ├── mavlink_msg_local_position_ned.h
│ ├── mavlink_msg_local_position_ned_cov.h
│ ├── mavlink_msg_local_position_ned_system_global_offset.h
│ ├── mavlink_msg_log_data.h
│ ├── mavlink_msg_log_entry.h
│ ├── mavlink_msg_log_erase.h
│ ├── mavlink_msg_log_request_data.h
│ ├── mavlink_msg_log_request_end.h
│ ├── mavlink_msg_log_request_list.h
│ ├── mavlink_msg_logging_ack.h
│ ├── mavlink_msg_logging_data.h
│ ├── mavlink_msg_logging_data_acked.h
│ ├── mavlink_msg_mag_cal_report.h
│ ├── mavlink_msg_manual_control.h
│ ├── mavlink_msg_manual_setpoint.h
│ ├── mavlink_msg_memory_vect.h
│ ├── mavlink_msg_message_interval.h
│ ├── mavlink_msg_mission_ack.h
│ ├── mavlink_msg_mission_clear_all.h
│ ├── mavlink_msg_mission_count.h
│ ├── mavlink_msg_mission_current.h
│ ├── mavlink_msg_mission_item.h
│ ├── mavlink_msg_mission_item_int.h
│ ├── mavlink_msg_mission_item_reached.h
│ ├── mavlink_msg_mission_request.h
│ ├── mavlink_msg_mission_request_int.h
│ ├── mavlink_msg_mission_request_list.h
│ ├── mavlink_msg_mission_request_partial_list.h
│ ├── mavlink_msg_mission_set_current.h
│ ├── mavlink_msg_mission_write_partial_list.h
│ ├── mavlink_msg_mount_orientation.h
│ ├── mavlink_msg_named_value_float.h
│ ├── mavlink_msg_named_value_int.h
│ ├── mavlink_msg_nav_controller_output.h
│ ├── mavlink_msg_obstacle_distance.h
│ ├── mavlink_msg_odometry.h
│ ├── mavlink_msg_onboard_computer_status.h
│ ├── mavlink_msg_open_drone_id_arm_status.h
│ ├── mavlink_msg_open_drone_id_authentication.h
│ ├── mavlink_msg_open_drone_id_basic_id.h
│ ├── mavlink_msg_open_drone_id_location.h
│ ├── mavlink_msg_open_drone_id_message_pack.h
│ ├── mavlink_msg_open_drone_id_operator_id.h
│ ├── mavlink_msg_open_drone_id_self_id.h
│ ├── mavlink_msg_open_drone_id_system.h
│ ├── mavlink_msg_open_drone_id_system_update.h
│ ├── mavlink_msg_optical_flow.h
│ ├── mavlink_msg_optical_flow_rad.h
│ ├── mavlink_msg_orbit_execution_status.h
│ ├── mavlink_msg_param_ext_ack.h
│ ├── mavlink_msg_param_ext_request_list.h
│ ├── mavlink_msg_param_ext_request_read.h
│ ├── mavlink_msg_param_ext_set.h
│ ├── mavlink_msg_param_ext_value.h
│ ├── mavlink_msg_param_map_rc.h
│ ├── mavlink_msg_param_request_list.h
│ ├── mavlink_msg_param_request_read.h
│ ├── mavlink_msg_param_set.h
│ ├── mavlink_msg_param_value.h
│ ├── mavlink_msg_ping.h
│ ├── mavlink_msg_play_tune.h
│ ├── mavlink_msg_play_tune_v2.h
│ ├── mavlink_msg_position_target_global_int.h
│ ├── mavlink_msg_position_target_local_ned.h
│ ├── mavlink_msg_power_status.h
│ ├── mavlink_msg_radio_status.h
│ ├── mavlink_msg_raw_imu.h
│ ├── mavlink_msg_raw_pressure.h
│ ├── mavlink_msg_raw_rpm.h
│ ├── mavlink_msg_rc_channels.h
│ ├── mavlink_msg_rc_channels_override.h
│ ├── mavlink_msg_rc_channels_raw.h
│ ├── mavlink_msg_rc_channels_scaled.h
│ ├── mavlink_msg_request_data_stream.h
│ ├── mavlink_msg_request_event.h
│ ├── mavlink_msg_resource_request.h
│ ├── mavlink_msg_response_event_error.h
│ ├── mavlink_msg_safety_allowed_area.h
│ ├── mavlink_msg_safety_set_allowed_area.h
│ ├── mavlink_msg_scaled_imu.h
│ ├── mavlink_msg_scaled_imu2.h
│ ├── mavlink_msg_scaled_imu3.h
│ ├── mavlink_msg_scaled_pressure.h
│ ├── mavlink_msg_scaled_pressure2.h
│ ├── mavlink_msg_scaled_pressure3.h
│ ├── mavlink_msg_serial_control.h
│ ├── mavlink_msg_servo_output_raw.h
│ ├── mavlink_msg_set_actuator_control_target.h
│ ├── mavlink_msg_set_attitude_target.h
│ ├── mavlink_msg_set_gps_global_origin.h
│ ├── mavlink_msg_set_home_position.h
│ ├── mavlink_msg_set_mode.h
│ ├── mavlink_msg_set_position_target_global_int.h
│ ├── mavlink_msg_set_position_target_local_ned.h
│ ├── mavlink_msg_setup_signing.h
│ ├── mavlink_msg_sim_state.h
│ ├── mavlink_msg_smart_battery_info.h
│ ├── mavlink_msg_statustext.h
│ ├── mavlink_msg_storage_information.h
│ ├── mavlink_msg_supported_tunes.h
│ ├── mavlink_msg_sys_status.h
│ ├── mavlink_msg_system_time.h
│ ├── mavlink_msg_terrain_check.h
│ ├── mavlink_msg_terrain_data.h
│ ├── mavlink_msg_terrain_report.h
│ ├── mavlink_msg_terrain_request.h
│ ├── mavlink_msg_time_estimate_to_target.h
│ ├── mavlink_msg_timesync.h
│ ├── mavlink_msg_trajectory_representation_bezier.h
│ ├── mavlink_msg_trajectory_representation_waypoints.h
│ ├── mavlink_msg_tunnel.h
│ ├── mavlink_msg_uavcan_node_info.h
│ ├── mavlink_msg_uavcan_node_status.h
│ ├── mavlink_msg_utm_global_position.h
│ ├── mavlink_msg_v2_extension.h
│ ├── mavlink_msg_vfr_hud.h
│ ├── mavlink_msg_vibration.h
│ ├── mavlink_msg_vicon_position_estimate.h
│ ├── mavlink_msg_video_stream_information.h
│ ├── mavlink_msg_video_stream_status.h
│ ├── mavlink_msg_vision_position_estimate.h
│ ├── mavlink_msg_vision_speed_estimate.h
│ ├── mavlink_msg_wheel_distance.h
│ ├── mavlink_msg_wifi_config_ap.h
│ ├── mavlink_msg_winch_status.h
│ ├── mavlink_msg_wind_cov.h
│ ├── testsuite.h
│ └── version.h
│ ├── mavlink_conversions.h
│ ├── mavlink_get_info.h
│ ├── mavlink_helpers.h
│ ├── mavlink_sha256.h
│ ├── mavlink_types.h
│ ├── minimal
│ ├── mavlink.h
│ ├── mavlink_msg_heartbeat.h
│ ├── mavlink_msg_protocol_version.h
│ ├── minimal.h
│ ├── testsuite.h
│ └── version.h
│ ├── protocol.h
│ ├── rcjoystick.c
│ └── standard
│ ├── mavlink.h
│ ├── standard.h
│ ├── testsuite.h
│ └── version.h
├── sbus-to-usb-joystick
├── ArduinoJoystickLibrary
│ ├── CONTRIBUTING.md
│ ├── LICENSE
│ ├── README.md
│ ├── examples
│ │ ├── ArcadeStickExample
│ │ │ └── ArcadeStickExample.ino
│ │ ├── DrivingControllerTest
│ │ │ └── DrivingControllerTest.ino
│ │ ├── FlightControllerTest
│ │ │ └── FlightControllerTest.ino
│ │ ├── FunduinoJoystickShield
│ │ │ └── FunduinoJoystickShield.ino
│ │ ├── GamepadExample
│ │ │ └── GamepadExample.ino
│ │ ├── HatSwitchTest
│ │ │ └── HatSwitchTest.ino
│ │ ├── JoystickButton
│ │ │ └── JoystickButton.ino
│ │ ├── JoystickKeyboard
│ │ │ └── JoystickKeyboard.ino
│ │ ├── JoystickTest
│ │ │ └── JoystickTest.ino
│ │ └── MultipleJoystickTest
│ │ │ └── MultipleJoystickTest.ino
│ ├── library.properties
│ └── src
│ │ ├── DynamicHID
│ │ ├── DynamicHID.cpp
│ │ └── DynamicHID.h
│ │ ├── JoystickMHX.cpp
│ │ └── JoystickMHX.h
├── photo_2023-03-30_04-58-32.jpg
├── readme.md
├── sbus-inverter-diagram-schematics.jpg
├── sbus-to-usb-joystick.ino
├── sbus.cpp
└── sbus.h
├── sigmastar
├── .dot
├── ssc338q-nand.bin
└── ssc338q_initramfs.zip
├── usb-eth-modem.md
├── usb-modeswitch.md
├── usb-modeswitch
├── glibc
│ ├── libusb-1.0.so.0.3.0
│ └── usb_modeswitch
└── musl
│ ├── libusb-1.0.so.0.3.0
│ └── usb_modeswitch
├── usb-tethering.md
├── user_TipoMan
├── .dot
├── gkrcparams
└── mavfwd_mavlink2.tar
├── wfb.zip
└── wfbopenhd.zip
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 OpenIPC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # sandbox-fpv
2 | Sandbox for FPV experiments. Telegram-group: `https://t.me/+BMyMoolVOpkzNWUy` | [link](https://t.me/+BMyMoolVOpkzNWUy)
3 |
4 | ## News
5 | * `26.07.2023` - FPV link setup via 4G modem .
6 |
7 | * `01.07.2023` - A short note about the imx335 gk7205v300 camera . About baud for telemetry .
8 |
9 | * `22.06.2023` - Finally, the problem with the picture being jerky at 30fps was resolved .
10 |
11 | * `06.04.2023` - Added coupler firmware for ivg-g2s with u-boot on board.
12 |
13 | * `05.04.2023` - Added functionality to rcjoystick for displaying packet losses (link quality) in rssi.
14 |
15 | * `04.04.2023` - OpenIPC has added the majestic streamer, now the ivg-g2s camera runs h265 cbr (constant bitrate). This gave a cleaner picture and a significant reduction in noise. At the same time, changes were made to the link launch process. The main service is now S98datalinkwith the config /etc/datalink.conf, and wfb is now launched via /usr/bin/wifibroadcast. The articles have been corrected to accommodate this innovation.
16 |
17 | * `01.04.2023` - Due to certain circumstances, wfb-ng was replaced in my camera and recorder with an alternative from OpenHD . Here is the package for assembly in buildroot OpenIPC. The shell wrappers take into account both options, due to the presence of a parameter link_idthat is not required in the OpenHD implementation. Archive with binaries of both options.
18 |
19 | ## Notes
20 |
21 | * [Notes on setting up the link on the gk7205v200 camera and hi3536ev100 (dv100) recorder](notes_link_gk7205v200_hi3536ev100.md)
22 | * [Notes on camera firmware gk7205v200 on OpenIPC](notes_start_ivg-g2s.md)
23 | * [Notes on firmware for hi3536ev100 recorder on OpenIPC](notes_start_hi3536ev100.md)
24 | * [A note about the imx335 gk7205v300 camera](notes_imx335_gk7205v300.md)
25 | * [Adding smoothness to video on goke/hisilicon cameras](gkrcparams.md)
26 | * [A note about controlling the camera via RC channels from the ground](notes_cam_control.md)
27 | * [Switch between two cameras in the air](note-two-cameras-switched.md)
28 | * [Loader for telemetry for gk7502v200, which does not hang the camera upon reboot](gk7205v200_u-boot-7502v200-for-telemetry.md)
29 | * [Controlling buttons from the front panel on the recorder](nvr_gpio.md)
30 | * [Connecting and setting up a tablet or smartphone for video and OSD via USB](usb-tethering.md)
31 | * [Connecting the tablet to the recorder via wifi via the tablet's AP](note-nvr-tab-ap.md)
32 | * [Connecting the tablet to the recorder via ethernet-usb-device](usb-eth-modem.md)
33 | * [Using the hardware as a joystick to transmit RC channels via mavlink](rcjoystick.md)
34 | * [About the analogue of RSSI](rcjoystick.md#rssi)
35 | * [SBUS-to-USB joystick for using any equipment with an sbus receiver](sbus-to-usb-joystick)
36 | * [FPV link setup via 4G modem](lte-fpv.md)
37 | * [Installing usb_modeswitch on a camera with fpv, lite firmware](usb-modeswitch.md)
38 |
39 | #### Miscellaneous
40 | * [mavfwd for inav (one way msp) for camera](user_TipoMan/mavfwd_mavlink2.tar?raw=true)
41 | * [Displaying video on windows and MP](gstlaunch_on_windows.md)
42 | * [Disabling watchdog on the hi3536dv100 recorder](note_nvr_wdt.md)
43 | * [Different from 115200 baud on camera uart for telemetry](note_telemetry_baud.md)
44 |
45 | ## Road map
46 | * ~~Starting video with transfer from the recorder to the PC.~~
47 | * ~~Launch one- and two-way telemetry.~~
48 | * ~~Starting video transfer via usb tethering to an Android tablet.~~
49 | * ~~Building and testing LTE firmware on e3372h + zerotier~~
50 | * ~~Starting telemetry routing via mavlink-router.~~
51 | * ~~Finding ways to control the camera through mavlink.~~.
52 | * Finding ways to output video and osd via hdmi.
53 | * ~~~Switching between several cameras, where one is the master with wfb-ng, and the rest are slaves.~~~
54 | * Development of expansion board for camera: bec 5v/3.3v; usb hub, uart, wifi/modem power transistor, microSD.
55 | * Development of a zoom lens control board and a method for controlling commercially available boards.
56 | * Development of a stabilizing gimbal controlled from the ground via wfb-ng.
57 |
58 |
59 |
60 | ## Russians:
61 |
62 | ## Новое
63 | * `26.07.2023` - Настройка FPV-линка [через 4G модем](lte-fpv.md).
64 |
65 | * `01.07.2023` - Короткая заметка о камере [imx335 gk7205v300](notes_imx335_gk7205v300.md). О [baud для телеметрии](note_telemetry_baud.md).
66 |
67 | * `22.06.2023` - Наконец [решилась](gkrcparams.md) проблема с дерганностью картинки на 30fps.
68 |
69 | * `06.04.2023` - Добавлена [прошивка coupler](notes_start_ivg-g2s.md#L33) для ivg-g2s с u-boot на борту.
70 |
71 | * `05.04.2023` - В rcjoystick [добавлен](rcjoystick.md#rssi) функционал для целей отображения потерь пакетов (качества линка) в rssi.
72 |
73 | * `04.04.2023` - В OpenIPC "допилили" стример majestic, теперь на камере ivg-g2s работает h265 cbr (постоянный битрейт). Это дало более чистую картинку и значительное уменьшение шума. Вместе с этим были внесены изменения в процесс запуска линка. Основным сервисом теперь является `S98datalink` с конфигом `/etc/datalink.conf`, а запуск wfb теперь производится через `/usr/bin/wifibroadcast`. Статьи были исправлены под это нововведение.
74 |
75 | * `01.04.2023` - В связи с некоторыми обстоятельствами, wfb-ng был заменен в моих камере и регистраторе на альтернативу от [OpenHD](https://github.com/OpenHD/wifibroadcast/). [Тут](wfbopenhd.zip) пакет для сборки в buildroot OpenIPC. В шелл-обертках учтены оба варианта, по наличию параметра `link_id` который не требуется в реализации от OpenHD. [Архив](https://github.com/OpenIPC/sandbox-fpv/blob/master/wfb.zip) с бинарниками обоих вариантов.
76 |
77 | ## Заметки
78 |
79 | * [Заметки о настройке линка на камере gk7205v200 и регистраторе hi3536ev100 (dv100)](notes_link_gk7205v200_hi3536ev100.md)
80 | * [Заметки о прошивке камеры gk7205v200 на OpenIPC](notes_start_ivg-g2s.md)
81 | * [Заметки о прошивке регистратора hi3536ev100 на OpenIPC](notes_start_hi3536ev100.md)
82 | * [Заметка о камере imx335 gk7205v300](notes_imx335_gk7205v300.md)
83 | * [Добавляем плавности видео на goke/hisilicon камерах](gkrcparams.md)
84 | * [Заметка о управлении камерой через RC каналы с наземки](notes_cam_control.md)
85 | * [Переключение между двумя камерами в воздухе](note-two-cameras-switched.md)
86 | * [Загрузчик под телеметрию для gk7502v200, который не вешает камеру при ребуте](gk7205v200_u-boot-7502v200-for-telemetry.md)
87 | * [Управление кнопками с front panel на регистраторе](nvr_gpio.md)
88 | * [Подключение и настройка планшета или смартфона для видео и OSD по USB](usb-tethering.md)
89 | * [Подключение планшета к регистратору по wifi через AP планшета](note-nvr-tab-ap.md)
90 | * [Подключение планшета к регистратору через ethernet-usb-device](usb-eth-modem.md)
91 | * [Использование аппаратуры как джойстика для передачи каналов RC через mavlink](rcjoystick.md)
92 | * [Про аналог RSSI](rcjoystick.md#rssi)
93 | * [SBUS-to-USB joystick для использования любой аппаратуры с sbus приемником](sbus-to-usb-joystick)
94 | * [Настройка FPV-линка через 4G модем](lte-fpv.md)
95 | * [Установка usb_modeswitch на камеру с прошивкой fpv, lite](usb-modeswitch.md)
96 |
97 | #### Разное
98 | * [mavfwd для inav (односторонний msp) для камеры](user_TipoMan/mavfwd_mavlink2.tar?raw=true)
99 | * [Отображение видео на windows и в MP](gstlaunch_on_windows.md)
100 | * [Отключение watchdog на регистраторе hi3536dv100](note_nvr_wdt.md)
101 | * [Отличный от 115200 baud на uartе камеры для телеметрии](note_telemetry_baud.md)
102 |
103 | ## Дорожная карта
104 | * ~~Запуск видео с передачей с регистратора на пк.~~
105 | * ~~Запуск одно-и двусторонней телеметрии.~~
106 | * ~~Запуск передачи видео через usb tethering на android-планшет.~~
107 | * ~~Сборка и тестирование прошивки LTE на e3372h + zerotier~~
108 | * ~~Запуск маршрутизации телеметрии через mavlink-router.~~
109 | * ~~Поиск путей управления камерой сквозь mavlink~~.
110 | * Поиск способов вывода видео и osd через hdmi.
111 | * ~~~Переключение между несколькими камерами, где одна ведущая с wfb-ng, а остальные ведомые.~~~
112 | * Разработка платы расширения для камеры: bec 5v/3.3v; usb hub, uart, транзистор питания wifi/modem, microSD.
113 | * Разработка платы управления зум-объективом и способа управления имеющимися в продаже платами.
114 | * Разработка стабилизирующего подвеса, управляемого с земли сквозь wfb-ng.
115 |
--------------------------------------------------------------------------------
/en_notes_start_hi3536ev100.md:
--------------------------------------------------------------------------------
1 | ### Notes on NVR hi3536ev100 firmware on OpenIPC for FPV purposes
2 | [RU](notes_start_hi3536ev100.md)
3 |
4 |
5 | How memory works
6 | To begin with, you need to figure out how the memory of the recorder (and the camera too) works and what needs to be flashed. Data is stored on spi-flash 16mb in the form of mtd blocks:
7 |
8 | ```
9 | cat /proc/cmdline
10 | mem=150M console=ttyAMA0,115200 panic=20 root=/dev/mtdblock3 rootfstype=squashfs init=/init mtdparts=hi_sfc:256k(boot),64k(env),2048k(kernel),8192k(rootfs),-(rootfs_data)
11 | ls /dev/mtdb*
12 | /dev/mtdblock0 /dev/mtdblock1 /dev/mtdblock2 /dev/mtdblock3 /dev/mtdblock4
13 | ```
14 | As follows from the output, block zero is the u-boot bootloader; Next comes a block for storing environment variables (`printenv`, `setenv` commands are written to RAM, and `saveenv` saves it in this block); next is the uImage core; then rootfs.squashfs (immutable file system image); and finally rootfs_data or also overlay - a changeable part where differences from rootfs are written if you change any files. Thus, by clearing the overlay, we will reset the file system to default:
15 | ```
16 | sf probe 0 #select a device
17 | sf erase 0xA50000 0x500000 #we clean
18 | reset #reboot nvr
19 | ```
20 | It's even easier to reset the firmware to factory defaults using the `firstboot` command.
21 |
22 | An address calculator for commands is available [here](https://openipc.org/tools/firmware-partitions-calculation). In our case, the rootfs partition: 8192kB, which means the start address of the overlay will be 0xA50000. For a camera with a flash of 8mB and a rootfs size of 5120kB, the addresses will be different, including environment variables!
23 |
24 |
25 | The bootloader of this recorder does not have a password, and you can access it via uart/115200 baud by pressing Ctrl+C several times at startup while connected to the debug-uart port of the recorder via a usb-uart 3v3 adapter (ftdi, ch340). Debug uart is located opposite the VGA connector on the opposite edge of the board and is labeled gnd/tx/rx. We don't need to flash the bootloader, we don't need burn. Our ENVs (environment variables) are different from the factory ones, but they are easier to install directly from the bootloader line by line:
26 | ```
27 | setenv ipaddr '192.168.0.222' #here is the ip in your subnet from the free ones
28 | setenv serverip '192.168.0.107' #PC address with tftp server
29 | setenv netmask '255.255.255.0'
30 | setenv bootcmd 'sf probe 0; sf read 0x82000000 0x50000 0x200000; bootm 0x82000000'
31 | setenv uk 'mw.b 0x82000000 ff 1000000;tftp 0x82000000 uImage.${soc}; sf probe 0; sf erase 0x50000 0x200000; sf write 0x82000000 0x50000 ${filesize}'
32 | setenv ur 'mw.b 0x82000000 ff 1000000;tftp 0x82000000 rootfs.squashfs.${soc}; sf probe 0; sf erase 0x250000 0x800000; sf write 0x82000000 0x250000 ${filesize}'
33 | setenv bootargs 'mem=192M console=ttyAMA0,115200 panic=20 root=/dev/mtdblock3 rootfstype=squashfs init=/init mtdparts=hi_sfc:256k(boot),64k(env),2048k(kernel),8192k(rootfs) ,-(rootfs_data)'
34 | setenv osmem '192M'
35 | setenv totalmem '256M'
36 | setenv soc 'hi3536dv100'
37 | #here we clear variables that are no longer needed
38 | setenvda; setenv du; setenv dr; setenv dw; setenv dl; setenv dc; setenv up; setenv tk; setenvdd; setenv de; setenv jpeg_addr; setenv jpeg_size; setenv vobuf; setenv loadlogo; setenv appVideoStandard; setenv appSystemLanguage; setenv appCloudExAbility
39 | saveenv #save the new variable environment
40 | printenv #see if everything is ok
41 | ```
42 | The original env and full dump of the chip (16mb backup of factory firmware in case of recovery) are available [here](https://github.com/OpenIPC/sandbox-fpv/tree/master/hi3536dv100/original_firmware).
43 |
44 | As you may have noticed, the uk and ur variables store macros for the uImage and rootfs downloading them from [tftp server](https://pjo2.github.io/tftpd64/) specified in serverip variable. All addresses correspond to the bootargs variable, the contents of which specify the file system layout for the kernel at boot. The layout is different from the usual for goke/hisilicone cameras, our core is the same as lite/fpv, 2MB in size, but the file system is 8MB in size, like ultimate. The remaining ~5MB are used by the overlay (your changes to the files relative to the original rootfs). For firmware, use official builds from the releases page [openipc/firmware](https://github.com/OpenIPC/firmware/releases/download/latest/openipc.hi3536dv100-nor-fpv.tgz). The archive contains the kernel and file system.
45 |
46 | So, after setting the variables, you can start flashing the remaining part. Start the tftpd server, put uImage.hi3536dv100 and rootfs.squashfs.hi3536dv100 in its root, select the appropriate network interface and run the macro in the bootloader: `run uk`. A series of commands must be executed, the output of which should indicate that the uImage file has been downloaded and flashed into flash. Similarly, run `run ur` to flash rootfs. If the addresses are set correctly, but the download is stuck at "Downloading", change the registrar address to a nearby free one: `setenv ipaddr '192.168.0.223'`.
47 | If everything went without errors, do a `reset` and boot into the operating system, login root, password 12345.
48 |
49 | The configs from the hi3536dv100 catalog are not relevant, but they may be of interest regarding connecting the tablet via usb/wifi/ethernet hotspot; you can transfer them, by analogy, to the configs of the official firmware or use separate bash scripts. Usually the essence of these changes is to determine the address of the connected tablet (which is the gateway for the registrar in cases where the tablet has a dhcp server) and specifying this address in an additional instance of wfb_rx for the video stream and for telemetry streams.
50 |
51 | The firmware is updated via the Internet using the command `sysupgrade -r -k -n`.
52 |
53 |
54 | Update without internet from /tmp
55 | In the future, you can update the recorder's firmware by uploading the kernel and rootfs into the `/tmp` directory via WinSCP and running `sysupgrade --kernel=/tmp/uImage.hi3536dv100 --rootfs=/tmp/rootfs.squashfs.hi3536dv100 -z` . The `-z` parameter is needed if you do not have an Internet connection (does not update the sysupgrade script), `-n` will clear the user fs (overlay).
56 |
57 |
--------------------------------------------------------------------------------
/gk7205v200/659A7_OpenIPC_FPV.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/gk7205v200/659A7_OpenIPC_FPV.bin
--------------------------------------------------------------------------------
/gk7205v200/88XXau.ko_8812_8821:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/gk7205v200/88XXau.ko_8812_8821
--------------------------------------------------------------------------------
/gk7205v200/etc/init.d/S95majestic:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | DAEMON="majestic"
4 | PIDFILE="/var/run/$DAEMON.pid"
5 |
6 | DAEMON_ARGS="-s"
7 |
8 | # shellcheck source=/dev/null
9 | [ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"
10 |
11 | load_majestic() {
12 | printf 'Starting %s: ' "$DAEMON"
13 | [ -f /usr/bin/$DAEMON ] || echo -en "DISABLED, "
14 | # shellcheck disable=SC2086 # we need the word splitting
15 | [ -f /etc/coredump.conf ] && . /etc/coredump.conf
16 | if [ "$coredump_enabled" ]; then
17 | [ "$(cli -g .watchdog.timeout)" -lt "30" ] && cli -s .watchdog.timeout 30
18 | ulimit -c unlimited && echo "|/usr/sbin/sendcoredump.sh" >/proc/sys/kernel/core_pattern
19 | fi
20 |
21 | cli -s .isp.sensorConfig /etc/sensors/imx307_i2c_2l_1080p.ini
22 | cli -s .video0.size 1920x1080
23 | cli -s .video0.fps 30
24 |
25 | start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/usr/bin/$DAEMON" -- $DAEMON_ARGS
26 |
27 | sleep .5
28 |
29 | cli -s .isp.sensorConfig /etc/sensors/imx307_i2c_2l_720p_50fps.ini
30 | cli -s .video0.size 1280x720
31 | cli -s .video0.fps 50
32 |
33 | killall -1 majestic
34 |
35 | sleep 1
36 | gkrcparams --MaxQp 30 --MaxI 2
37 |
38 | status=$?
39 | if [ "$status" -eq 0 ]; then
40 | echo "OK"
41 | else
42 | echo "FAIL"
43 | fi
44 | return "$status"
45 | }
46 |
47 | # The daemon does not create a pidfile, and use "-m" to instruct start-stop-daemon to create one.
48 | start() {
49 | logger -s -p daemon.info -t $(ipcinfo -v) "Loading video system has started..."
50 | export SENSOR=$(fw_printenv -n sensor)
51 | load_majestic
52 | }
53 |
54 | stop() {
55 | printf 'Stopping %s: ' "$DAEMON"
56 | [ -f /usr/bin/$DAEMON ] || echo -en "DISABLED, "
57 | start-stop-daemon -K -q -p "$PIDFILE"
58 | status=$?
59 | if [ "$status" -eq 0 ]; then
60 | rm -f "$PIDFILE"
61 | echo "OK"
62 | else
63 | echo "FAIL"
64 | fi
65 | return "$status"
66 | }
67 |
68 | restart() {
69 | stop
70 | sleep 1
71 | reload
72 | }
73 |
74 | reload() {
75 | load_majestic
76 | }
77 |
78 | case "$1" in
79 | start|stop|restart|reload)
80 | "$1";;
81 | *)
82 | echo "Usage: $0 {start|stop|restart|reload}"
83 | exit 1
84 | esac
85 |
--------------------------------------------------------------------------------
/gk7205v200/etc/init.d/S98datalink:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Start fpv datalink
4 | #
5 |
6 | . /etc/datalink.conf
7 |
8 | chip=$(ipcinfo -c)
9 | fw=$(grep "BUILD_OPTION" "/etc/os-release" | cut -d= -f2)
10 |
11 | start() {
12 | if ! [ -f /etc/system.ok ]; then
13 | killall majestic
14 | tweaksys ${chip}
15 | fi
16 |
17 | echo "Starting FPV datalink..."
18 | if ! [ -f /etc/servicemode ]; then
19 | echo "Start wlan0 in Service Mode (connect to your AP)"
20 | rm -f /etc/servicemode
21 | wpa_passphrase "ssid" "password" >/tmp/wpa_supplicant.conf
22 | sed -i '2i \\tscan_ssid=1' /tmp/wpa_supplicant.conf
23 | sleep 3
24 | wpa_supplicant -B -D nl80211 -i wlan0 -c /tmp/wpa_supplicant.conf
25 | ifconfig wlan0 up
26 | udhcpc -x hostname:openipc-servicemode -T 1 -t 5 -R -b -O search -i wlan0
27 | else
28 | if [ ${fw} = "lte" ]; then
29 | if [ ${usb_modem} = "true" ]; then
30 | echo "Starting lte modem configuration..."
31 | echo "ToDo: Running usb_modeswitch or other shit here..."
32 | fi
33 | # for the future
34 | #cli -s .outgoing.url1 udp://${gs_ipaddr}:${gs_port}
35 | if [ ${use_zt} = "true" ]; then
36 | echo "Starting ZeroTier-One daemon..."
37 | /usr/sbin/zerotier-one -d &
38 | if [ ! -f /var/lib/zerotier-one/networks.d/${zt_netid}.conf ]; then
39 | sleep 8
40 | zerotier-cli join ${zt_netid} &> /dev/null
41 | echo "Don't forget authorize in the my.zerotier.com!"
42 | fi
43 | fi
44 | if [ ${telemetry} = "true" ]; then
45 | /usr/bin/telemetry start
46 | fi
47 | else
48 | echo "Starting wifibroadcast service..."
49 | /usr/bin/wifibroadcast start
50 | fi
51 | fi
52 | }
53 |
54 | stop() {
55 | echo "Stopping all services..."
56 | kill -9 $(pidof wfb_tx)
57 | kill -9 $(pidof telemetry_rx)
58 | kill -9 $(pidof telemetry_tx)
59 | kill -9 $(pidof mavlink-routerd)
60 | kill -9 $(pidof mavfwd)
61 | }
62 |
63 | case "$1" in
64 | start)
65 | start
66 | ;;
67 | stop)
68 | stop
69 | ;;
70 | restart)
71 | stop
72 | start
73 | ;;
74 | *)
75 | echo "Usage: $0 {start|stop|restart}"
76 | exit 1
77 | esac
78 |
--------------------------------------------------------------------------------
/gk7205v200/etc/majestic.yaml:
--------------------------------------------------------------------------------
1 | system:
2 | webAdmin: disabled
3 | buffer: 1024
4 | image:
5 | mirror: false
6 | flip: false
7 | rotate: none
8 | contrast: 50
9 | hue: 50
10 | saturation: 50
11 | luminance: 50
12 | osd:
13 | enabled: false
14 | template: "%a %e %B %Y %H:%M:%S %Z"
15 | nightMode:
16 | enabled: false
17 | records:
18 | enabled: false
19 | path: /mnt/mmc/%Y/%m/%d/%H.mp4
20 | maxUsage: 95
21 | video0:
22 | enabled: true
23 | bitrate: 6144
24 | codec: h265
25 | rcMode: cbr
26 | gopSize: 1.0
27 | size: 1280x720
28 | fps: 50
29 | video1:
30 | enabled: false
31 | jpeg:
32 | enabled: false
33 | mjpeg:
34 | size: 640x360
35 | fps: 5
36 | bitrate: 1024
37 | audio:
38 | enabled: false
39 | volume: auto
40 | srate: 8000
41 | rtsp:
42 | enabled: false
43 | port: 554
44 | hls:
45 | enabled: false
46 | youtube:
47 | enabled: false
48 | motionDetect:
49 | enabled: false
50 | visualize: true
51 | debug: true
52 | ipeye:
53 | enabled: false
54 | watchdog:
55 | enabled: true
56 | timeout: 10
57 | isp:
58 | slowShutter: disabled
59 | drc: 350
60 | lowDelay: true
61 | sensorConfig: /etc/sensors/imx307_i2c_2l_720p_50fps.ini
62 | netip:
63 | enabled: false
64 | outgoing:
65 | - udp://127.0.0.1:5600
66 |
--------------------------------------------------------------------------------
/gk7205v200/etc/sensors/imx307_i2c_2l_720p_50fps.ini:
--------------------------------------------------------------------------------
1 | [sensor]
2 | Sensor_type =stSnsImx307_2l_Obj ;sensor name
3 | Mode =0 ;WDR_MODE_NONE = 0
4 | ;WDR_MODE_BUILT_IN = 1
5 | ;WDR_MODE_QUDRA = 2
6 | ;WDR_MODE_2To1_LINE = 3
7 | ;WDR_MODE_2To1_FRAME = 4
8 | ;WDR_MODE_2To1_FRAME_FULL_RATE = 5
9 | ;WDR_MODE_3To1_LINE = 6
10 | ;WDR_MODE_3To1_FRAME = 7
11 | ;WDR_MODE_3To1_FRAME_FULL_RATE = 8
12 | ;WDR_MODE_4To1_LINE = 9
13 | ;WDR_MODE_4To1_FRAME = 10
14 | ;WDR_MODE_4To1_FRAME_FULL_RATE = 11
15 | DllFile = /usr/lib/sensors/libsns_imx307_2l_720p_50fps.so ;sensor lib path
16 |
17 |
18 | [mode]
19 | input_mode =0 ;INPUT_MODE_MIPI = 0
20 | ;INPUT_MODE_SUBLVDS = 1
21 | ;INPUT_MODE_LVDS = 2 ...etc
22 |
23 | raw_bitness = 10
24 |
25 | [mipi]
26 | ;----------only for mipi_dev---------
27 | data_type = DATA_TYPE_RAW_10BIT
28 | lane_id = 0|2|-1|-1|-1|-1|-1|-1| ;lane_id: -1 - disable
29 |
30 | [isp_image]
31 | Isp_x =0
32 | Isp_y =0
33 | Isp_W =1280
34 | Isp_H =720
35 | Isp_FrameRate=60
36 | Isp_Bayer =0 ;BAYER_RGGB=0, BAYER_GRBG=1, BAYER_GBRG=2, BAYER_BGGR=3
37 |
38 | [vi_dev]
39 | Input_mod = 6
40 | ; VI_MODE_BT656 = 0, /* ITU-R BT.656 YUV4:2:2 */
41 | ; VI_MODE_BT656_PACKED_YUV, /* ITU-R BT.656 packed YUV4:2:2 */
42 | ; VI_MODE_BT601, /* ITU-R BT.601 YUV4:2:2 */
43 | ; VI_MODE_DIGITAL_CAMERA, /* digatal camera mode */
44 | ; VI_MODE_BT1120_STANDARD, /* BT.1120 progressive mode */
45 | ; VI_MODE_BT1120_INTERLEAVED, /* BT.1120 interstage mode */
46 | ; VI_MODE_MIPI, /* MIPI RAW mode */
47 | ; VI_MODE_MIPI_YUV420_NORMAL, /* MIPI YUV420 normal mode */
48 | ; VI_MODE_MIPI_YUV420_LEGACY, /* MIPI YUV420 legacy mode */
49 | ; VI_MODE_MIPI_YUV422, /* MIPI YUV422 mode */
50 | ; VI_MODE_LVDS, /* LVDS mode */
51 | ; VI_MODE_HISPI, /* HiSPi mode */
52 | ; VI_MODE_SLVS, /* SLVS mode */
53 | Work_mod =0 ;VI_WORK_MODE_1Multiplex = 0
54 | ;VI_WORK_MODE_2Multiplex,
55 | ;VI_WORK_MODE_4Multiplex
56 | Combine_mode =0 ;Y/C composite or separation mode
57 | ;VI_COMBINE_COMPOSITE = 0 /*Composite mode */
58 | ;VI_COMBINE_SEPARATE, /*Separate mode */
59 | Comp_mode =0 ;Component mode (single-component or dual-component)
60 | ;VI_COMP_MODE_SINGLE = 0, /*single component mode */
61 | ;VI_COMP_MODE_DOUBLE = 1, /*double component mode */
62 | Clock_edge =1 ;Clock edge mode (sampling on the rising or falling edge)
63 | ;VI_CLK_EDGE_SINGLE_UP=0, /*rising edge */
64 | ;VI_CLK_EDGE_SINGLE_DOWN, /*falling edge */
65 | Mask_num =2 ;Component mask
66 | Mask_0 =0xFFF00000
67 | Mask_1 =0x0
68 | Scan_mode = 1;VI_SCAN_INTERLACED = 0
69 | ;VI_SCAN_PROGRESSIVE,
70 | Data_seq =2 ;data sequence (ONLY for YUV format)
71 | ;----2th component U/V sequence in bt1120
72 | ; VI_INPUT_DATA_VUVU = 0,
73 | ; VI_INPUT_DATA_UVUV,
74 | ;----input sequence for yuv
75 | ; VI_INPUT_DATA_UYVY = 0,
76 | ; VI_INPUT_DATA_VYUY,
77 | ; VI_INPUT_DATA_YUYV,
78 | ; VI_INPUT_DATA_YVYU
79 |
80 | Vsync =1 ; vertical synchronization signal
81 | ;VI_VSYNC_FIELD = 0,
82 | ;VI_VSYNC_PULSE,
83 | VsyncNeg=1 ;Polarity of the vertical synchronization signal
84 | ;VI_VSYNC_NEG_HIGH = 0,
85 | ;VI_VSYNC_NEG_LOW /*if VIU_VSYNC_E
86 | Hsync =0 ;Attribute of the horizontal synchronization signal
87 | ;VI_HSYNC_VALID_SINGNAL = 0,
88 | ;VI_HSYNC_PULSE,
89 | HsyncNeg =0 ;Polarity of the horizontal synchronization signal
90 | ;VI_HSYNC_NEG_HIGH = 0,
91 | ;VI_HSYNC_NEG_LOW
92 | VsyncValid =1 ;Attribute of the valid vertical synchronization signal
93 | ;VI_VSYNC_NORM_PULSE = 0,
94 | ;VI_VSYNC_VALID_SINGAL,
95 | VsyncValidNeg =0;Polarity of the valid vertical synchronization signal
96 | ;VI_VSYNC_VALID_NEG_HIGH = 0,
97 | ;VI_VSYNC_VALID_NEG_LOW
98 | Timingblank_HsyncHfb =0 ;Horizontal front blanking width
99 | Timingblank_HsyncAct =1280 ;Horizontal effetive width
100 | Timingblank_HsyncHbb =0 ;Horizontal back blanking width
101 | Timingblank_VsyncVfb =0 ;Vertical front blanking height
102 | Timingblank_VsyncVact =720 ;Vertical effetive width
103 | Timingblank_VsyncVbb=0 ;Vertical back blanking height
104 | Timingblank_VsyncVbfb =0 ;Even-field vertical front blanking height(interlace, invalid progressive)
105 | Timingblank_VsyncVbact=0 ;Even-field vertical effetive width(interlace, invalid progressive)
106 | Timingblank_VsyncVbbb =0 ;Even-field vertical back blanking height(interlace, invalid progressive)
107 |
108 | ;----- only for bt656 ----------
109 | FixCode =0 ;BT656_FIXCODE_1 = 0,
110 | ;BT656_FIXCODE_0
111 | FieldPolar=0 ;BT656_FIELD_POLAR_STD = 0
112 | ;BT656_FIELD_POLAR_NSTD
113 | DataPath =1 ;ISP enable or bypass
114 | ;VI_PATH_BYPASS = 0,/* ISP bypass */
115 | ;VI_PATH_ISP = 1,/* ISP enable */
116 | ;VI_PATH_RAW = 2,/* Capture raw data, for debug */
117 | InputDataType=1 ;VI_DATA_TYPE_YUV = 0,VI_DATA_TYPE_RGB = 1,
118 | DataRev =FALSE ;Data reverse. FALSE = 0; TRUE = 1
119 | DevRect_x=200 ;
120 | DevRect_y=20 ;
121 | DevRect_w=1280 ;
122 | DevRect_h=720 ;
123 | FullLinesStd=750
124 |
125 | [vi_chn]
126 | CapRect_X =320
127 | CapRect_Y =180
128 | CapRect_Width=1280
129 | CapRect_Height=720
130 | DestSize_Width=1280
131 | DestSize_Height=720
132 |
--------------------------------------------------------------------------------
/gk7205v200/etc/wfb.conf:
--------------------------------------------------------------------------------
1 | wlan=wlan0
2 | region=BO
3 | # By default used channel number, but, you may set freq instead. For ex: 2387M
4 | channel=44
5 | #frequency=5220M
6 | txpower=20
7 | driver_txpower_override=16
8 | bandwidth=20
9 | stbc=1
10 | ldpc=1
11 | mcs_index=1
12 | stream=0
13 | link_id=7669206
14 | udp_port=5600
15 | fec_k=8
16 | fec_n=12
17 | fec_timeout=0
18 | guard_interval=long
19 |
--------------------------------------------------------------------------------
/gk7205v200/root/1080.sh:
--------------------------------------------------------------------------------
1 | #yaml-cli -s .isp.sensorConfig /etc/sensors/imx307_i2c_2l_1080p.ini #use this for imx307
2 | yaml-cli -s .isp.sensorConfig /etc/sensors/imx415.bin
3 | yaml-cli -s .isp.exposure 10
4 | yaml-cli -s .video0.size 1920x1080
5 | yaml-cli -s .video0.fps 30
6 | yaml-cli -s .video0.crop 0x0x1920x1080
7 | sleep .2
8 | /root/kill.sh
9 |
--------------------------------------------------------------------------------
/gk7205v200/root/1080b.sh:
--------------------------------------------------------------------------------
1 | yaml-cli -s .video0.size 1920x1080
2 | yaml-cli -s .video0.crop 0x0x1920x1080
3 | yaml-cli -s .video0.fps 60
4 | yaml-cli -s .isp.sensorConfig /etc/sensors/imx415f.bin
5 | yaml-cli -s .isp.exposure 20
6 | sleep .2
7 | /root/kill.sh
8 |
--------------------------------------------------------------------------------
/gk7205v200/root/1080c.sh:
--------------------------------------------------------------------------------
1 | yaml-cli -s .video0.size 1920x1080
2 | yaml-cli -s .video0.crop 0x0x1920x1080
3 | yaml-cli -s .video0.fps 90
4 | yaml-cli -s .isp.sensorConfig /etc/sensors/imx415f.bin
5 | yaml-cli -s .isp.exposure 30
6 | sleep .2
7 | /root/kill.sh
8 |
--------------------------------------------------------------------------------
/gk7205v200/root/3K.sh:
--------------------------------------------------------------------------------
1 | yaml-cli -s .video0.size 3200x1800
2 | yaml-cli -s .video0.crop 250x150x2560x1440
3 | yaml-cli -s .video0.fps 30
4 | yaml-cli -s .isp.sensorConfig /etc/sensors/imx415.bin
5 | yaml-cli -s .isp.exposure 10
6 | sleep .2
7 | /root/kill.sh
8 |
--------------------------------------------------------------------------------
/gk7205v200/root/4K.sh:
--------------------------------------------------------------------------------
1 | yaml-cli -s .video0.size 3840x2160
2 | yaml-cli -s .video0.crop 575x330x2560x1440
3 | yaml-cli -s .video0.fps 20
4 | yaml-cli -s .isp.sensorConfig /etc/sensors/imx415.bin
5 | yaml-cli -s .isp.exposure 10
6 | sleep .2
7 | /root/kill.sh
8 |
--------------------------------------------------------------------------------
/gk7205v200/root/720.sh:
--------------------------------------------------------------------------------
1 | #yaml-cli -s .isp.sensorConfig /etc/sensors/720p30_imx307_50.ini #use this for imx307
2 | #yaml-cli -s .video0.fps 50 #use thise for imx307
3 | yaml-cli -s .video0.size 1280x720
4 | yaml-cli -s .video0.fps 30
5 | yaml-cli -s .isp.sensorConfig /etc/sensors/imx415.bin
6 | yaml-cli -s .isp.exposure 10
7 | yaml-cli -s .video0.crop 0x0x1280x720
8 | sleep .2
9 | /root/kill.sh
10 |
--------------------------------------------------------------------------------
/gk7205v200/root/720b.sh:
--------------------------------------------------------------------------------
1 | yaml-cli -s .video0.size 1280x720
2 | yaml-cli -s .video0.crop 0x0x1280x720
3 | yaml-cli -s .video0.fps 60
4 | yaml-cli -s .isp.sensorConfig /etc/sensors/imx415f.bin
5 | yaml-cli -s .isp.exposure 20
6 | sleep .2
7 | /root/kill.sh
8 |
--------------------------------------------------------------------------------
/gk7205v200/root/720c.sh:
--------------------------------------------------------------------------------
1 | yaml-cli -s .video0.size 1280x720
2 | yaml-cli -s .video0.crop 0x0x1280x720
3 | yaml-cli -s .video0.fps 90
4 | yaml-cli -s .isp.sensorConfig /etc/sensors/imx415f.bin
5 | yaml-cli -s .isp.exposure 30
6 | sleep .2
7 | /root/kill.sh
8 |
--------------------------------------------------------------------------------
/gk7205v200/root/720d.sh:
--------------------------------------------------------------------------------
1 | yaml-cli -s .video0.size 1280x720
2 | yaml-cli -s .video0.crop 0x0x1280x720
3 | yaml-cli -s .video0.fps 120
4 | yaml-cli -s .isp.sensorConfig /etc/sensors/imx415f.bin
5 | yaml-cli -s .isp.exposure 30
6 | sleep .2
7 | /root/kill.sh
8 |
--------------------------------------------------------------------------------
/gk7205v200/root/channels.sh:
--------------------------------------------------------------------------------
1 | echo $1 $2 >>/tmp/channels.log
2 |
3 | #channel 5
4 | if [ $1 -eq 5 ]; then
5 | if [ $2 -gt 1600 ]; then
6 | CURRENT_SIZE=`yaml-cli -g .video0.size`
7 | if [ $CURRENT_SIZE == '1280x720' ]; then
8 | /root/1080.sh
9 | sleep 3
10 | else
11 | /root/720.sh
12 | sleep 3
13 | fi
14 | fi
15 | fi
16 |
17 | #channel 6
18 | #if [ $1 -eq 6 ]; then
19 | # if [ $2 -lt 1600 ]; then
20 | # /root/ircut.sh off
21 | # else
22 | # /root/ircut.sh on
23 | # fi
24 | #fi
25 |
26 | if [ $1 -eq 6 ]; then
27 | if [ $2 -gt 1600 ]; then
28 | CURRENT_SIZE=`yaml-cli -g .video0.size`
29 | CURRENT_FPS=`yaml-cli -g .video0.fps`
30 | if [ $CURRENT_SIZE == '1280x720' ] && [ $CURRENT_FPS == '30' ] ; then
31 | /root/720b.sh
32 | sleep 3
33 | elif [ $CURRENT_SIZE == '1280x720' ] && [ $CURRENT_FPS == '60' ] ; then
34 | /root/720c.sh
35 | sleep 3
36 | elif [ $CURRENT_SIZE == '1280x720' ] && [ $CURRENT_FPS == '90' ] ; then
37 | /root/720d.sh
38 | sleep 3
39 | elif [ $CURRENT_SIZE == '1280x720' ] && [ $CURRENT_FPS == '120' ] ; then
40 | /root/1080.sh
41 | sleep 3
42 | elif [ $CURRENT_SIZE == '1920x1080' ] && [ $CURRENT_FPS == '30' ] ; then
43 | /root/1080b.sh
44 | sleep 3
45 | elif [ $CURRENT_SIZE == '1920x1080' ] && [ $CURRENT_FPS == '60' ] ; then
46 | /root/1080c.sh
47 | sleep 3
48 | elif [ $CURRENT_SIZE == '1920x1080' ] && [ $CURRENT_FPS == '90' ] ; then
49 | /root/3K.sh
50 | sleep 3
51 | elif [ $CURRENT_SIZE == '3200x1800' ]; then
52 | /root/4K.sh
53 | sleep 3
54 | else
55 | /root/720.sh
56 | sleep 3
57 | fi
58 | fi
59 | fi
60 |
61 | #channel 7
62 | if [ $1 -eq 7 ]; then
63 | if [ $2 -lt 1400 ]; then
64 | yaml-cli -s .image.luminance 50
65 | killall -1 majestic
66 | elif [ $2 -gt 1400 ] && [ $2 -lt 1600 ]; then
67 | yaml-cli -s .image.luminance 90
68 | killall -1 majestic
69 | else
70 | yaml-cli -s .image.luminance 30
71 | killall -1 majestic
72 | fi
73 | fi
74 |
75 | #channel 8
76 | if [ $1 -eq 8 ]; then
77 | if [ $2 -gt 1600 ]; then
78 | CURRENT_BITRATE=`yaml-cli -g .video0.bitrate`
79 | if [ $CURRENT_BITRATE -lt 7168 ]; then
80 | NEW_BITRATE="$(($CURRENT_BITRATE+1024))"
81 | else
82 | NEW_BITRATE="1024"
83 | sleep 2
84 | fi
85 | yaml-cli -s .video0.bitrate $NEW_BITRATE
86 | sleep .2
87 | /root/kill.sh
88 | fi
89 | sleep 3
90 | fi
91 |
92 | exit 1
93 |
--------------------------------------------------------------------------------
/gk7205v200/root/channels2.sh:
--------------------------------------------------------------------------------
1 | if [ $1 -eq 7 ]; then
2 | if [ $2 -gt 1600 ]; then
3 | /root/ircut.sh on
4 | elif [ $2 -gt 1400 ] && [ $2 -lt 1600 ]; then
5 | /root/ircut.sh off
6 | fi
7 | fi
8 |
9 | if [ $1 -eq 8 ]; then
10 | if [ $2 -gt 1600 ]; then
11 | killall venc
12 | venc -p 5600 -f 30 -r 12288 -c 265cbr -v 200_imx307F -d frame --low-delay &
13 | elif [ $2 -gt 1400 ] && [ $2 -lt 1600 ]; then
14 | killall venc
15 | venc -p 5600 -f 50 -r 12288 -c 265cbr -v 200_imx307B -d frame &
16 | fi
17 | fi
18 |
19 | exit 1
20 |
--------------------------------------------------------------------------------
/gk7205v200/root/ircut.sh:
--------------------------------------------------------------------------------
1 | #use: ./ircut.sh on | off
2 |
3 | function gpio_setup {
4 | if [ ! -e /sys/class/gpio/gpio$1 ]; then
5 | echo $1 > /sys/class/gpio/export
6 | fi
7 | echo $2 > /sys/class/gpio/gpio$1/direction
8 | }
9 |
10 | function set_gpio {
11 | echo $2 > /sys/class/gpio/gpio$1/value
12 | }
13 |
14 | function ircut_on {
15 | set_gpio 8 0
16 | set_gpio 9 1
17 | sleep 0.1
18 | set_gpio 8 0
19 | }
20 |
21 | function ircut_off {
22 | set_gpio 8 1
23 | set_gpio 9 0
24 | sleep 0.1
25 | set_gpio 8 0
26 | }
27 |
28 | gpio_setup 8 out
29 | gpio_setup 9 out
30 | ircut_$1
31 |
32 |
33 |
--------------------------------------------------------------------------------
/gk7205v200/root/kill.sh:
--------------------------------------------------------------------------------
1 | killall majestic
2 | sleep 1
3 | majestic
4 | sleep 5
5 | gkrcparams --MaxQp 30 --MaxI 2
6 |
--------------------------------------------------------------------------------
/gk7205v200/u-boot-gk7205v200-universal.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/gk7205v200/u-boot-gk7205v200-universal.bin
--------------------------------------------------------------------------------
/gk7205v200/usr/bin/telemetry:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Start telemetry
4 | #
5 |
6 | . /etc/datalink.conf
7 | . /etc/telemetry.conf
8 |
9 | keydir="/etc"
10 |
11 | fw=$(grep "BUILD_OPTION" "/etc/os-release" | cut -d= -f2)
12 |
13 | start_telemetry() {
14 | if [ ! -f /usr/bin/telemetry_rx -a ! -f /usr/bin/telemetry_tx ]; then
15 | ln -s /usr/bin/wfb_rx /usr/bin/telemetry_rx ; chmod +x /usr/bin/telemetry_rx
16 | ln -s /usr/bin/wfb_tx /usr/bin/telemetry_tx ; chmod +x /usr/bin/telemetry_tx
17 | else
18 | if [ ${one_way} = "false" ]; then
19 | if [ -z "${link_id}" ]; then
20 | telemetry2_rx -r ${stream_rx} -u ${port_rx} -K ${keydir}/drone.key ${wlan} >/dev/null &
21 | else
22 | telemetry_rx -p ${stream_rx} -u ${port_rx} -K ${keydir}/drone.key -i ${link_id} ${wlan} >/dev/null &
23 | fi
24 | fi
25 | if [ -z "${link_id}" ]; then
26 | telemetry2_tx -r ${stream_tx} -u ${port_tx} -K ${keydir}/drone.key -B ${bandwidth} -M ${mcs_index} -S ${stbc} -L ${ldpc} -G ${guard_interval} -k ${fec_k} -p ${fec_p} ${wlan} >/dev/null &
27 | else
28 | telemetry_tx -p ${stream_tx} -u ${port_tx} -K ${keydir}/drone.key -B ${bandwidth} -M ${mcs_index} -S ${stbc} -L ${ldpc} -G ${guard_interval} -k ${fec_k} -n ${fec_n} -T ${fec_timeout} -i ${link_id} ${wlan} >/dev/null &
29 | fi
30 | fi
31 | }
32 |
33 | case "$1" in
34 | start)
35 | echo "Loading MAVLink telemetry service..."
36 |
37 | if [ ${router} -eq 1 ] || [ ${fw} = "lte" ]; then
38 | /usr/bin/mavlink-routerd &
39 | else
40 | mavfwd --master ${serial} --baudrate ${baud} --out 127.0.0.1:${port_tx} --in 127.0.0.1:${port_rx} &
41 | fi
42 | if [ ${fw} = "fpv" ]; then
43 | start_telemetry
44 | fi
45 | echo "Done."
46 | ;;
47 | stop)
48 | echo "Stopping telemetry services..."
49 | kill -9 $(pidof telemetry_rx)
50 | kill -9 $(pidof telemetry_tx)
51 | kill -9 $(pidof mavlink-routerd)
52 | kill -9 $(pidof mavfwd)
53 | ;;
54 | *)
55 | echo "Usage: $0 {start|stop}"
56 | exit 1
57 | esac
58 |
--------------------------------------------------------------------------------
/gk7205v200/usr/bin/venc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/gk7205v200/usr/bin/venc
--------------------------------------------------------------------------------
/gk7205v200/usr/bin/wifibroadcast:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Start wifibroadcast
4 | #
5 |
6 | . /etc/datalink.conf
7 | . /etc/wfb.conf
8 |
9 | keydir="/etc"
10 | chip=$(ipcinfo -c)
11 | vendor=$(ipcinfo -v)
12 |
13 | driver=""
14 |
15 | set_mcs() {
16 | if [ ${vendor} = "ingenic" ]; then
17 | mcs=$(ls -l /lib/firmware | grep "htc_9271" | awk {'print $11'} | cut -d "." -f3)
18 | else
19 | mcs=$(ls -l /lib/firmware/ath9k_htc | grep "htc_9271-1.4.0.fw" | cut -d "." -f6)
20 | fi
21 | if [ -z "${mcs}" ]; then
22 | setmcs ${mcs_index}
23 | fi
24 | if [ ${mcs_index} -eq 1 ] || [ ${mcs_index} -eq 3 ]; then
25 | if [ ! ${mcs_index} -eq ${mcs} ]; then
26 | setmcs ${mcs_index}
27 | sleep 3
28 | fi
29 | fi
30 | }
31 |
32 | # "0bda:8813" -> (8814) -> 8814au
33 | # "0846:9052" -> (8811) -> 8821au
34 |
35 | detect_wifi_card() {
36 | echo "Detecting wifi card vendor..."
37 | devices=$(lsusb | cut -d ' ' -f6 | sort | uniq)
38 | for card in ${devices}
39 | do
40 | case "${card}" in
41 | "0bda:8812" | "0bda:881a" | "0b05:17d2" | "2357:0101")
42 | driver="realtek"
43 | modprobe 88XXau rtw_tx_pwr_idx_override=${driver_txpower_override}
44 | ;;
45 | "0cf3:9271" | "040d:3801")
46 | driver="atheros"
47 | set_mcs
48 | modprobe mac80211
49 | modprobe ath9k_htc
50 | ;;
51 | esac
52 | done
53 |
54 | if [ -z "${driver}" ]; then
55 | echo "No usb wifi card detected. Check wifi stick connection, usb power or possible bad soldering."
56 | exit
57 | else
58 | echo "Detected:" ${driver}
59 | fi
60 |
61 | echo "Awaiting interface ${wlan} in system..."
62 |
63 | local n=0
64 | while ! $(ifconfig -a | grep -q ${wlan})
65 | do
66 | if [ ${n} -ge 5 ]; then
67 | echo "No interface ${wlan}. Check wifi stick connection, usb power or possible bad soldering."
68 | exit
69 | fi
70 | sleep 0.5
71 | n=$(expr ${n} + 1)
72 | done
73 | }
74 |
75 | load_modules() {
76 | modprobe cfg80211
77 | detect_wifi_card
78 | }
79 |
80 | load_interface() {
81 | if [ ${driver} = "realtek" ]; then
82 | ifconfig ${wlan} up
83 | iwconfig ${wlan} mode monitor
84 | elif [ ${driver} = "atheros" ]; then
85 | iwconfig ${wlan} mode monitor
86 | ifconfig ${wlan} up
87 | fi
88 |
89 | iw reg set ${region}
90 |
91 | if [ ! -z "${frequency}" ]; then
92 | iwconfig ${wlan} freq ${frequency}
93 | else
94 | iwconfig ${wlan} channel ${channel}
95 | fi
96 | # dirty fix crash if txpower set. setting txpower disabled because patched driver always set txpower level 58
97 | # iw dev ${wlan} set txpower fixed $((${txpower} * 100))
98 | }
99 |
100 | start_wfb() {
101 | if [ -z "${link_id}" ]; then
102 | wfb2_tx -r ${stream} -u ${udp_port} -K ${keydir}/drone.key -B ${bandwidth} -M ${mcs_index} -S ${stbc} -L ${ldpc} -G ${guard_interval} -k ${fec_k} -p ${fec_p} ${wlan} >/dev/null &
103 | else
104 | wfb_tx -p ${stream} -u ${udp_port} -K ${keydir}/drone.key -B ${bandwidth} -M ${mcs_index} -S ${stbc} -L ${ldpc} -G ${guard_interval} -k ${fec_k} -n ${fec_n} -T ${fec_timeout} -i ${link_id} ${wlan} &
105 | fi
106 | }
107 |
108 | case "$1" in
109 | start)
110 | if [ ${daemon} -eq 1 ]; then
111 |
112 | echo "Loading modules and wifi card driver..."
113 |
114 | load_modules
115 |
116 | echo "Preparing interface wlan..."
117 |
118 | load_interface
119 |
120 | if ! cat ${keydir}/drone.key > /dev/null 2>&1; then
121 | echo "Generating drone & ground station keys..."
122 | cd ${keydir} ; wfb_keygen
123 | else
124 | echo "Drone key exist..."
125 | fi
126 |
127 | echo "Starting Wifibroadcast service..."
128 |
129 | start_wfb
130 |
131 | echo "Done."
132 |
133 | if [ ${telemetry} = "true" ]; then
134 | if [ ${chip} = "gk7205v200" ]; then
135 | # UART2_RX mux
136 | devmem 0x120c0010 32 0x1e04
137 | fi
138 | /usr/bin/telemetry start
139 | fi
140 |
141 | else
142 | echo "Wifibroadcast service disabled in wfb.conf..."
143 | fi
144 | ;;
145 | stop)
146 | echo "Stopping all services..."
147 | kill -9 $(pidof wfb_tx)
148 | kill -9 $(pidof telemetry_rx)
149 | kill -9 $(pidof telemetry_tx)
150 | kill -9 $(pidof mavlink-routerd)
151 | kill -9 $(pidof mavfwd)
152 | ;;
153 | *)
154 | echo "Usage: $0 {start|stop}"
155 | exit 1
156 | esac
157 |
--------------------------------------------------------------------------------
/gk7205v200/usr/lib/sensors/libsns_imx307_2l_720p_50fps.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/gk7205v200/usr/lib/sensors/libsns_imx307_2l_720p_50fps.so
--------------------------------------------------------------------------------
/gk7205v200/usr/sbin/gkrcparams:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/gk7205v200/usr/sbin/gkrcparams
--------------------------------------------------------------------------------
/gk7205v200_u-boot-7502v200-for-telemetry.md:
--------------------------------------------------------------------------------
1 | ## U-Boot для телеметрии
2 | #### только для gk7502v200!
3 |
4 | загрузчик внесён разработчиками в релизы, и если вы прошиваетесь с инструкций на openipc.net, то этого уже делать не надо, только установить bootdelay 0.
5 |
6 | Чтобы поток телеметрии не прерывал загрузку камеры, когда u-boot считает телеметрию "нажатием любой кнопки для входа в консоль загрузчика", нужно залить этот загрузчик
7 | [(ССЫЛКА)](https://github.com/OpenIPC/sandbox-fpv/raw/master/gk7205v200/u-boot-gk7205v200-universal.bin):
8 | ```
9 | # закачайте файл u-boot-gk7205v200-universal.bin в /tmp камеры через winscp ИЛИ выполните команду и УБЕДИТЕСЬ ЧТО ФАЙЛ СКАЧАЛСЯ!!!#curl -o /tmp/u-boot-gk7205v200-universal.bin http://fpv.openipc.net/u-boot-gk7205v200-universal.bin
10 |
11 | flashcp -v /tmp/u-boot-gk7205v200-universal.bin /dev/mtd0
12 | ```
13 | и установите нулевую задержку загрузки командой `fw_setenv bootdelay 0`.
14 |
15 | При первой прошивке просто используйте этот файл вместо указанного на странице инструкций. Только для gk7502v200!
16 |
17 | Данный загрузчик прерывается по комбинации клавиш Ctrl+C, а не любой. Будьте осторожны! Завалите загрузчик - придется паять и шить программатором.
18 |
--------------------------------------------------------------------------------
/gk7502v300/etc/majestic.yaml:
--------------------------------------------------------------------------------
1 | system:
2 | webAdmin: disabled
3 | buffer: 1024
4 | image:
5 | mirror: false
6 | flip: false
7 | rotate: none
8 | contrast: 50
9 | hue: 50
10 | saturation: 50
11 | luminance: 50
12 | osd:
13 | enabled: false
14 | template: "%a %e %B %Y %H:%M:%S %Z"
15 | nightMode:
16 | enabled: false
17 | records:
18 | enabled: false
19 | path: /mnt/mmcblk0p1/%Y-%m-%d-%H.mp4
20 | maxUsage: 95
21 | video0:
22 | enabled: true
23 | bitrate: 5192
24 | codec: h265
25 | rcMode: cbr
26 | gopSize: 0.2
27 | size: 1920x1080
28 | fps: 30
29 | #crop: 320x180x1280x720
30 | video1:
31 | enabled: false
32 | jpeg:
33 | enabled: false
34 | mjpeg:
35 | size: 640x360
36 | fps: 5
37 | bitrate: 1024
38 | audio:
39 | enabled: false
40 | volume: auto
41 | srate: 8000
42 | rtsp:
43 | enabled: false
44 | port: 554
45 | hls:
46 | enabled: false
47 | youtube:
48 | enabled: false
49 | motionDetect:
50 | enabled: false
51 | visualize: true
52 | debug: true
53 | ipeye:
54 | enabled: false
55 | watchdog:
56 | enabled: false
57 | timeout: 10
58 | isp:
59 | sensorConfig: /etc/sensors/smtsec_imx307_i2c_4l_1080p.ini
60 | slowShutter: disabled
61 | drc: 420
62 | lowDelay: true
63 | #rawMode: none
64 | blkCnt: 12
65 | #dis: true
66 | netip:
67 | enabled: false
68 | outgoing:
69 | - udp://127.0.0.1:5600
70 |
--------------------------------------------------------------------------------
/gk7502v300/etc/telemetry.conf:
--------------------------------------------------------------------------------
1 | serial=/dev/ttyAMA0
2 | baud=115200
3 | ### router: use simple mavfwd (0) or classic mavlink-routerd (1)
4 | router=0
5 |
6 | wlan=wlan0
7 | bandwidth=20
8 | stbc=1
9 | ldpc=1
10 | mcs_index=1
11 | stream_rx=144
12 | stream_tx=16
13 | link_id=7669206
14 | port_rx=14551
15 | port_tx=14550
16 | fec_k=1
17 | fec_n=2
18 | fec_timeout=0
19 | guard_interval=long
20 | one_way=false
21 |
--------------------------------------------------------------------------------
/gk7502v300/etc/wfb.conf:
--------------------------------------------------------------------------------
1 | wlan=wlan0
2 | region=BO
3 | # By default used channel number, but, you may set freq instead. For ex: 2387M
4 | channel=44
5 | frequency=
6 | txpower=20
7 | driver_txpower_override=20
8 | bandwidth=20
9 | stbc=1
10 | ldpc=1
11 | mcs_index=1
12 | stream=0
13 | link_id=7669206
14 | udp_port=5600
15 | fec_k=8
16 | fec_n=12
17 | fec_timeout=0
18 | guard_interval=long
19 |
--------------------------------------------------------------------------------
/gk7502v300/root/ircut.sh:
--------------------------------------------------------------------------------
1 | #use: ./ircut.sh on | off
2 |
3 | function gpio_setup {
4 | if [ ! -e /sys/class/gpio/gpio$1 ]; then
5 | echo $1 > /sys/class/gpio/export
6 | fi
7 | echo $2 > /sys/class/gpio/gpio$1/direction
8 | }
9 |
10 | function set_gpio {
11 | echo $2 > /sys/class/gpio/gpio$1/value
12 | }
13 |
14 | function ircut_on {
15 | set_gpio 11 0
16 | set_gpio 10 1
17 | sleep 0.1
18 | set_gpio 11 0
19 | }
20 |
21 | function ircut_off {
22 | set_gpio 11 1
23 | set_gpio 10 0
24 | sleep 0.1
25 | set_gpio 11 0
26 | }
27 |
28 | gpio_setup 11 out
29 | gpio_setup 10 out
30 | ircut_$1
31 |
32 |
33 |
--------------------------------------------------------------------------------
/gk7502v300/usr/lib/sensors/libsns_imx307.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/gk7502v300/usr/lib/sensors/libsns_imx307.so
--------------------------------------------------------------------------------
/gkrcparams.md:
--------------------------------------------------------------------------------
1 | ## Добавляем плавности видео
2 | На режимах 1080p@30fps заметно легкое подергивание видео, а при замедленной съемке таймера видно что картинка замирает на какое то время и далее обновляется. Это происходит из за неравномерности потока, который резко возрастает на ключевых кадрах.
3 | Исправить это можно, перенастроив на камере два параметра энкодера.
4 | Спасибо за проделанную работу TipoMan и widgetii!
5 |
6 | Нам нужно положить файл [gkrcparams](https://github.com/OpenIPC/sandbox-fpv/raw/master/user_TipoMan/gkrcparams) в /usr/sbin, дать права на выполнение `chmod +x /usr/sbin/gkrcparams` и вставить запуск его после старта majestic в /etc/init.d/S95majestic:
7 |
8 | ```
9 | start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/usr/bin/$DAEMON" -- $DAEMON_ARGS
10 | sleep 1 <=== ЭТО ВСТАВИТЬ
11 | gkrcparams --MaxQp 30 --MaxI 2 <=== ЭТО ВСТАВИТЬ
12 | status=$?
13 | ```
14 | После перезапуска картинка должна стать плавной. Прочие настройки в majestic.yaml для режима mcs1:
15 |
16 | ```
17 | video0:
18 | enabled: true
19 | bitrate: 7168
20 | codec: h265
21 | rcMode: cbr
22 | gopSize: 1.0
23 | size: 1920x1080
24 | ```
25 |
26 | Если же картинка все равно иногда подергивается, придется изменить mcs на 3 в `/etc/wfb.conf` потеряв в дальности либо уменьшать битрейт.
27 |
--------------------------------------------------------------------------------
/gstlaunch_on_windows.md:
--------------------------------------------------------------------------------
1 | ## Прием и отображение видео на windows
2 |
3 | В "классическом режиме" (на камере стримит majestic, а NVR пересылает видеопоток на ПК, не забываем указать IP адрес ПК в wfb.conf регистратора) видео можно принимать в QGroundControl, Mission Planner и можно просто вывести в отдельном окне
4 | без привязки к программам. Для этого нужно установить [GStreamer](https://gstreamer.freedesktop.org/download/) и запускать его на прием с некими параметрами, например:
5 | ```
6 | C:\gstreamer\1.0\msvc_x86_64\bin\gst-launch-1.0.exe -v udpsrc port=5600 buffer-size=32768 ! application/x-rtp ! rtph265depay ! queue max-size-buffers=5 ! avdec_h265 ! videoconvert ! videoscale ! video/x-raw,width=1280,height=720,format=BGRA ! autovideosink sync=false
7 | ```
8 |
9 | В данном примере размер видео изменяется до 1280x720. Для запуска видео с разрешением оригинального потока убираем из строки `videoscale ! ` и `width=1280,height=720,`.
10 |
11 |
12 | 
13 |
14 | Для воспроизведения видео в окне Mission Planner нужно кликнуть правой кнопкой мыши по его окну с горизонтом и выбрать `Video > Set GStreamer source`, внести строку параметров: `udpsrc port=5600 buffer-size=32768 ! application/x-rtp ! rtph265depay ! queue max-size-buffers=5 ! avdec_h265 ! videoconvert ! video/x-raw,format=BGRA ! appsink name=outsink`, нажать Ok. Строка сохранится для будущий применений.
15 |
--------------------------------------------------------------------------------
/hi3536dv100/88XXau-ko/88XXau.ko_8812au:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/hi3536dv100/88XXau-ko/88XXau.ko_8812au
--------------------------------------------------------------------------------
/hi3536dv100/88XXau-ko/88XXau.ko_8812au_8814au:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/hi3536dv100/88XXau-ko/88XXau.ko_8812au_8814au
--------------------------------------------------------------------------------
/hi3536dv100/etc/init.d/S96gpio_monitor:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Start gpio monitor
4 | #
5 |
6 | case "$1" in
7 | start)
8 | echo "Starting gpio_monitor daemon..."
9 | /root/gpio_monitor.sh &
10 | ;;
11 | stop)
12 | echo "Stopping gpio_monitor daemon..."
13 | kill -9 $(pidof {exe} ash /root/gpio_monitor.sh)
14 | ;;
15 | *)
16 | echo "Usage: $0 {start|stop}"
17 | exit 1
18 | esac
19 |
--------------------------------------------------------------------------------
/hi3536dv100/etc/init.d/S99rcjoystick:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | start() {
4 | /usr/bin/rcjoystick -t 25 -c 16 -i wlan0 &
5 | }
6 |
7 | stop() {
8 | killall rcjoystick
9 | }
10 |
11 | restart() {
12 | stop
13 | sleep 1
14 | start
15 | }
16 |
17 | case "$1" in
18 | start|stop|restart)
19 | "$1";;
20 | *)
21 | echo "Usage: $0 {start|stop|restart}"
22 | exit 1
23 | esac
24 |
--------------------------------------------------------------------------------
/hi3536dv100/etc/mavlink.conf:
--------------------------------------------------------------------------------
1 | [General]
2 | TcpServerPort = 0
3 | DebugLogLevel = error
4 |
5 | [UdpEndpoint qgroundcontrol]
6 | Mode = Server
7 | Address = 0.0.0.0
8 | Port = 14550
9 |
10 | [UdpEndpoint telemetry_tx]
11 | Group=wfb
12 | Mode = Normal
13 | Address = 127.0.0.1
14 | Port = 14650
15 |
16 | [UdpEndpoint telemetry_rx]
17 | Group=wfb
18 | Mode = Server
19 | Address = 127.0.0.1
20 | Port = 14651
21 |
22 |
--------------------------------------------------------------------------------
/hi3536dv100/etc/telemetry.conf:
--------------------------------------------------------------------------------
1 | serial=/dev/ttyAMA0
2 | baud=115200
3 | ### router: use simple mavfwd (0) or classic mavlink-routerd (1)
4 | router=1
5 |
6 | wlan=wlan0
7 | bandwidth=20
8 | stbc=1
9 | ldpc=1
10 | mcs_index=1
11 | stream_rx=16
12 | stream_tx=144
13 | link_id=7669206
14 | port_rx=14651
15 | port_tx=14650
16 | fec_k=1
17 | fec_n=2
18 | fec_timeout=0
19 | guard_interval=long
20 | one_way=false
21 |
--------------------------------------------------------------------------------
/hi3536dv100/hi3536dv100_fpv_defconfig:
--------------------------------------------------------------------------------
1 | # Architecture
2 | BR2_arm=y
3 | BR2_cortex_a7=y
4 | BR2_ARM_EABI=y
5 | BR2_ARM_FPU_NEON_VFPV4=y
6 | BR2_ARM_INSTRUCTIONS_THUMB2=y
7 | BR2_KERNEL_HEADERS_VERSION=y
8 | BR2_DEFAULT_KERNEL_VERSION="4.9.37"
9 | BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_9=y
10 |
11 | # Toolchain
12 | BR2_PER_PACKAGE_DIRECTORIES=y
13 | BR2_GCC_VERSION_8_X=y
14 | # BR2_TOOLCHAIN_USES_UCLIBC is not set
15 | # BR2_TOOLCHAIN_BUILDROOT_UCLIBC is not set
16 | # BR2_TOOLCHAIN_BUILDROOT_LIBC="uclibc"
17 | # BR2_TOOLCHAIN_USES_MUSL is not set
18 | # BR2_TOOLCHAIN_BUILDROOT_MUSL is not set
19 | # BR2_TOOLCHAIN_BUILDROOT_LIBC="musl"
20 | BR2_TOOLCHAIN_USES_GLIBC=y
21 | BR2_TOOLCHAIN_BUILDROOT_GLIBC=y
22 | BR2_TOOLCHAIN_BUILDROOT_LIBC="glibc"
23 | BR2_PACKAGE_GLIBC_UTILS=y
24 | BR2_TOOLCHAIN_BUILDROOT_CXX=y
25 | # BR2_TOOLCHAIN_BUILDROOT_LOCALE is not set
26 | BR2_TOOLCHAIN_BUILDROOT_USE_SSP=y
27 | BR2_PIC_PIE=y
28 | BR2_GCC_ENABLE_LTO=y
29 | BR2_INSTALL_LIBSTDCPP=y
30 |
31 | # Kernel
32 | BR2_LINUX_KERNEL=y
33 | BR2_LINUX_KERNEL_CUSTOM_VERSION=y
34 | BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="4.9.37"
35 | BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
36 | BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_HISILICON_PATH)/board/hi3536dv100/kernel/hi3536dv100.generic.config"
37 | BR2_LINUX_KERNEL_UIMAGE=y
38 | BR2_LINUX_KERNEL_UIMAGE_LOADADDR="0x80008000"
39 | BR2_LINUX_KERNEL_XZ=y
40 | BR2_LINUX_KERNEL_EXT_HISI_PATCHER=y
41 | BR2_LINUX_KERNEL_EXT_HISI_PATCHER_LIST="$(BR2_EXTERNAL_HISILICON_PATH)/board/hi3536dv100/kernel/patches/ $(BR2_EXTERNAL_HISILICON_PATH)/board/hi3536dv100/kernel/overlay"
42 |
43 | # Filesystem
44 | # BR2_TARGET_TZ_INFO is not set
45 | # BR2_TARGET_ROOTFS_CPIO is not set
46 | BR2_TARGET_ROOTFS_SQUASHFS=y
47 | BR2_TARGET_ROOTFS_SQUASHFS4_XZ=y
48 | BR2_ROOTFS_OVERLAY="$(TOPDIR)/../general/overlay"
49 | BR2_ROOTFS_POST_BUILD_SCRIPT="$(TOPDIR)/../scripts/executing_commands_for_$(BR2_TOOLCHAIN_BUILDROOT_LIBC).sh"
50 |
51 | # OpenIPC configuration
52 | BR2_TOOLCHAIN_BUILDROOT_VENDOR="openipc"
53 | BR2_TARGET_GENERIC_ISSUE="Welcome to OpenIPC"
54 | BR2_TARGET_GENERIC_HOSTNAME="openipc-hi3536dv100"
55 | BR2_GLOBAL_PATCH_DIR="$(TOPDIR)/../general/package/all-patches"
56 |
57 | # OpenIPC packages
58 | BR2_PACKAGE_HISILICON_OSDRV_HI3536DV100=y
59 | BR2_PACKAGE_BUSYBOX_CONFIG="$(TOPDIR)/../general/package/busybox/busybox.config"
60 | BR2_PACKAGE_DROPBEAR_OPENIPC=y
61 | # BR2_PACKAGE_FDK_AAC_OPENIPC is not set
62 | BR2_PACKAGE_FWPRINTENV_OPENIPC=y
63 | # BR2_PACKAGE_HASERL is not set
64 | # BR2_PACKAGE_HISI_GPIO is not set
65 | BR2_PACKAGE_IPCTOOL=y
66 | # BR2_PACKAGE_JSON_C is not set
67 | # BR2_PACKAGE_JSONFILTER is not set
68 | # BR2_PACKAGE_LAME_OPENIPC is not set
69 | BR2_PACKAGE_LIBCURL_OPENIPC=y
70 | BR2_PACKAGE_LIBCURL_OPENIPC_CURL=y
71 | # BR2_PACKAGE_LIBCURL_OPENIPC_VERBOSE is not set
72 | # BR2_PACKAGE_LIBCURL_OPENIPC_PROXY_SUPPORT is not set
73 | # BR2_PACKAGE_LIBCURL_OPENIPC_COOKIES_SUPPORT is not set
74 | # BR2_PACKAGE_LIBCURL_OPENIPC_EXTRA_PROTOCOLS_FEATURES is not set
75 | BR2_PACKAGE_LIBCURL_OPENIPC_MBEDTLS=y
76 | # BR2_PACKAGE_LIBEVENT_OPENIPC is not set
77 | # BR2_PACKAGE_LIBEVENT_OPENIPC_REMOVE_PYSCRIPT is not set
78 | # BR2_PACKAGE_LIBOGG_OPENIPC is not set
79 | # BR2_PACKAGE_LIBWEBSOCKETS_OPENIPC is not set
80 | # BR2_PACKAGE_LIBYAML is not set
81 | # BR2_PACKAGE_MAJESTIC_FONTS is not set
82 | BR2_PACKAGE_MBEDTLS_OPENIPC=y
83 | # BR2_PACKAGE_MBEDTLS_OPENIPC_PROGRAMS is not set
84 | # BR2_PACKAGE_MBEDTLS_OPENIPC_COMPRESSION is not set
85 | # BR2_PACKAGE_MICROBE_WEB is not set
86 | # BR2_PACKAGE_MINI_SNMPD is not set
87 | # BR2_PACKAGE_OPUS_OPENIPC is not set
88 | # BR2_PACKAGE_OPUS_OPENIPC_FIXED_POINT is not set
89 | # BR2_PACKAGE_SSHPASS is not set
90 | # BR2_PACKAGE_UACME_OPENIPC is not set
91 | BR2_PACKAGE_VTUND_OPENIPC=y
92 | # BR2_PACKAGE_YAML_CLI is not set
93 | # BR2_PACKAGE_XMDP is not set
94 |
95 | # WiFi
96 | BR2_PACKAGE_WIRELESS_TOOLS=y
97 | BR2_PACKAGE_WPA_SUPPLICANT=y
98 | # BR2_PACKAGE_WPA_SUPPLICANT_CLI is not set
99 | BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
100 | BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y
101 | BR2_PACKAGE_LINUX_FIRMWARE_OPENIPC=y
102 | # BR2_PACKAGE_LINUX_FIRMWARE_OPENIPC_MT7601U is not set
103 | # BR2_PACKAGE_RTL8188EU is not set
104 | BR2_PACKAGE_LINUX_FIRMWARE_OPENIPC_ATHEROS_9271=y
105 | BR2_PACKAGE_RTL8812AU_OPENIPC=y
106 |
107 | # FPV
108 | BR2_PACKAGE_DATALINK=y
109 | BR2_PACKAGE_WIFIBROADCAST=y
110 | # BR2_PACKAGE_WFBOPENHD is not set
111 | BR2_PACKAGE_MAVLINK_ROUTER=y
112 | # BR2_PACKAGE_MAVFWD is not set
113 |
114 | #FFMPEG
115 | BR2_PACKAGE_FFMPEG_OPENIPC=y
116 |
117 |
118 | # ZEROTIER
119 | BR2_PACKAGE_ZEROTIER_ONE=y
120 |
121 | # IPTABLES
122 | # BR2_PACKAGE_IPTABLES is not set
123 |
124 | # WIREGUARD
125 | # BR2_PACKAGE_WIREGUARD_LINUX_COMPAT is not set
126 | # BR2_PACKAGE_WIREGUARD_TOOLS is not set
127 |
128 | # DEBUG
129 | BR2_PACKAGE_HOST_GDB=y
130 | BR2_PACKAGE_GDB=y
131 |
132 | BR2_PACKAGE_ZLIB=y
133 |
134 | # SDL2
135 | # BR2_PACKAGE_SDL2 is not set
136 | # BR2_PACKAGE_SDL2_IMAGE is not set
137 | # BR2_PACKAGE_SDL2_TTF is not set
138 |
139 |
--------------------------------------------------------------------------------
/hi3536dv100/lib/modules/4.9.37/extra/8188eu.ko:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/hi3536dv100/lib/modules/4.9.37/extra/8188eu.ko
--------------------------------------------------------------------------------
/hi3536dv100/lib/modules/4.9.37/extra/88XXau.ko:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/hi3536dv100/lib/modules/4.9.37/extra/88XXau.ko
--------------------------------------------------------------------------------
/hi3536dv100/original_firmware/env.txt:
--------------------------------------------------------------------------------
1 | === original ENV
2 | hisilicon # printenv
3 | bootcmd=sf probe 0;sf read 0x84000000 0xf60000 0x20000;logoload 0x84000000;decjpg;sf read 0x82000000 0x50000 0x500000;squashfsload 82000000;bootm 0x81000000
4 | bootdelay=0
5 | baudrate=115200
6 | ethaddr=00:0b:3f:00:00:01
7 | ipaddr=192.168.1.10
8 | serverip=192.168.1.1
9 | netmask=255.255.0.0
10 | bootfile="uImage"
11 | da=mw.b 0x82000000 ff 1000000;tftp 0x82000000 u-boot.bin.img;sf probe 0;flwrite
12 | du=mw.b 0x82000000 ff 1000000;tftp 0x82000000 user-x.cramfs.img;sf probe 0;flwrite
13 | dr=mw.b 0x82000000 ff 1000000;tftp 0x82000000 romfs-x.cramfs.img;sf probe 0;flwrite
14 | dw=mw.b 0x82000000 ff 1000000;tftp 0x82000000 web-x.cramfs.img;sf probe 0;flwrite
15 | dl=mw.b 0x82000000 ff 1000000;tftp 0x82000000 logo-x.cramfs.img;sf probe 0;flwrite
16 | dc=mw.b 0x82000000 ff 1000000;tftp 0x82000000 custom-x.cramfs.img;sf probe 0;flwrite
17 | up=mw.b 0x82000000 ff 1000000;tftp 0x82000000 update.img;sf probe 0;flwrite
18 | tk=mw.b 0x82000000 ff 1000000;tftp 0x82000000 zImage.img; bootm 0x82000000
19 | dd=mw.b 0x82000000 ff 1000000;tftp 0x82000000 mtd-x.jffs2.img;sf probe 0;flwrite
20 | de=mw.b 0x82000000 ff 1000000;tftp 0x82000000 u-boot.env.bin.img;sf probe 0;flwrite
21 | jpeg_addr=0x8dc00000
22 | jpeg_size=0xb85f9
23 | vobuf=0x8dd00000
24 | loadlogo=sf probe 0;sf read 0x84000000 0xF60000 0x20000;logoload 0x84000000;decjpg
25 | bootargs=mem=139M console=ttyAMA0,115200 root=/dev/mtdblock1 rootfstype=squashfs mtdparts=hi_sfc:320K(boot),3968K(romfs),7040K(usr),1600K(web),2816K(custom),128K(logo),512K(mtd) coherent_pool=2M
26 | appVideoStandard=PAL
27 | appSystemLanguage=English
28 | appCloudExAbility=E7nsOhUNSfs=
29 | stdin=serial
30 | stdout=serial
31 | stderr=serial
32 | verify=n
33 | ver=U-Boot 2010.06-svn1560 (May 06 2021 - 19:15:51)
34 |
35 | Environment size: 1617/65532 bytes
36 |
--------------------------------------------------------------------------------
/hi3536dv100/original_firmware/fullflash_202303012255_W25Q128BV_16MB_HI3536DV100_orig_dev2.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/hi3536dv100/original_firmware/fullflash_202303012255_W25Q128BV_16MB_HI3536DV100_orig_dev2.bin
--------------------------------------------------------------------------------
/hi3536dv100/root/gpio_monitor.sh:
--------------------------------------------------------------------------------
1 | ##IR
2 | ##Y2 !17
3 | ##Y1 !6
4 | ##X2 !13
5 | ##Y3 !8
6 | ##X1 !7
7 | ##ALARM 10
8 | ##REC 11
9 |
10 | function gpio_setup {
11 | if [ ! -e /sys/class/gpio/gpio$1 ]; then
12 | echo $1 > /sys/class/gpio/export
13 | fi
14 | echo $2 > /sys/class/gpio/gpio$1/direction
15 | }
16 |
17 | function set_gpio {
18 | echo $2 > /sys/class/gpio/gpio$1/value
19 | }
20 |
21 |
22 | function get_gpio {
23 | return `cat /sys/class/gpio/gpio${1}/value`
24 | }
25 |
26 | #buttons
27 | for i in 6 7 8 13 17
28 | do
29 | gpio_setup $i in
30 | done
31 |
32 | #ALARM led
33 | gpio_setup 10 out
34 |
35 | while [ true ]
36 | do
37 | get_gpio 6
38 | if [ "$?" -eq 0 ]; then
39 | set_gpio 10 1
40 | echo 6 >>/tmp/gpio.log
41 | #ifdown usb0
42 | #ifup usb0
43 | /usr/bin/wifibroadcast restart
44 | sleep .1
45 | set_gpio 10 0
46 | fi
47 |
48 | get_gpio 7
49 | if [ "$?" -eq 0 ]; then
50 | set_gpio 10 1
51 | echo 7 >>/tmp/gpio.log
52 | ifconfig eth0:1 192.168.11.1
53 | sleep .5
54 | set_gpio 10 0
55 | fi
56 |
57 | get_gpio 8
58 | if [ "$?" -eq 0 ]; then
59 | set_gpio 10 1
60 | echo 8 >>/tmp/gpio.log
61 | sleep .5
62 | set_gpio 10 0
63 | fi
64 |
65 | get_gpio 13
66 | if [ "$?" -eq 0 ]; then
67 | set_gpio 10 1
68 | echo 13 >>/tmp/gpio.log
69 | sleep .5
70 | set_gpio 10 0
71 | fi
72 |
73 | get_gpio 17
74 | if [ "$?" -eq 0 ]; then
75 | set_gpio 10 1
76 | echo 17 >>/tmp/gpio.log
77 | sleep .5
78 | set_gpio 10 0
79 | fi
80 |
81 | sleep .2
82 | done
--------------------------------------------------------------------------------
/hi3536dv100/root/resolution.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ARG="`cat /etc/vdec.conf`"
4 | value=${ARG#*mode=}
5 | value2=${value%%p60*}
6 | if [ $value2 == '720' ]; then
7 | sed -i -e 's/mode=720p60/mode=1080p60/g' /etc/vdec.conf
8 | elif [ $value2 == '1080' ]; then
9 | sed -i -e 's/mode=1080p60/mode=720p60/g' /etc/vdec.conf
10 | fi
11 | reboot # Please probe this for re-read config: killall -1 vdec
12 |
13 |
--------------------------------------------------------------------------------
/hi3536dv100/root/vdec:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/hi3536dv100/root/vdec
--------------------------------------------------------------------------------
/hi3536dv100/rootfs.squashfs.hi3536dv100:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/hi3536dv100/rootfs.squashfs.hi3536dv100
--------------------------------------------------------------------------------
/hi3536dv100/uImage.hi3536dv100:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/hi3536dv100/uImage.hi3536dv100
--------------------------------------------------------------------------------
/hi3536dv100/usr/bin/mavlink-routerd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/hi3536dv100/usr/bin/mavlink-routerd
--------------------------------------------------------------------------------
/hi3536dv100/usr/bin/rcjoystick:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/hi3536dv100/usr/bin/rcjoystick
--------------------------------------------------------------------------------
/lte-fpv.md:
--------------------------------------------------------------------------------
1 | ## Подключение камеры к планшету или ПК через LTE (4G) модем
2 |
3 | Летать через 4G - крайне интересная тема для самолетов под стабилизацией или автоматическим маршрутом. Разобъем процесс настройки на задачи:
4 |
5 | * настроить интернет через модем на камере
6 | * настроить свой сервер zerotier (можно воспользоваться публичным)
7 | * подключить камеру и ПК к одной сети zerotier и настроить стрим
8 |
9 | Следуя [этим инструкциям](usb-modeswitch.md), настроим usb_modeswitch и сетевой интерфейс eth1 на камере под прошивкой OpenIPC LTE. Если у вас FPV или LITE прошивка, предварительно нужно ее сменить онлайн:
10 | ```
11 | #тут меняем fpv на lte в файле /etc/os-release, можно это сделать вручную
12 | sed -i 's/BUILD_OPTION=fpv/BUILD_OPTION=lte/' /etc/os-release
13 | #а это если у вас lite версия
14 | sed -i 's/BUILD_OPTION=lite/BUILD_OPTION=lte/' /etc/os-release
15 |
16 | sysupgrade --force_ver -k -r -n
17 | ```
18 | Мы получаем камеру с заводскими настройками и lte прошивкой, в которой в отличие от fpv удален wfb а взамен установлен zerotier-one клиент.
19 | На самом деле, правильным решением будет не использовать usb_modeswitch а настроить вторичную композицию модема сразу на cdc_ethernet. Тогда модем перестанет быть универсальным и сразу будет отображаться как сетевая карта, но зато исчезнет вероятность возникновения ряда проблем.
20 |
21 | #### zerotier
22 | Это программное обеспечение для объединения нескольких устройств в одну локальную сеть. Существует публичный сервер для создания своей сети, но лучше поднять свой.
23 | Для этого потребуется vps-сервер под ubuntu.
24 | ```
25 | apt-get install -y apt-transport-https gnupg mc iftop #устанавливаем зависимости
26 | curl -s https://install.zerotier.com | sudo bash #устанавливаем клиентскую часть
27 |
28 | curl -O https://s3-us-west-1.amazonaws.com/key-networks/deb/ztncui/1/x86_64/ztncui_0.7.1_amd64.deb #устанавливаем панель управления
29 | apt-get install ./ztncui_0.7.1_amd64.deb
30 |
31 | echo 'HTTPS_PORT=6443' > /opt/key-networks/ztncui/.env #порт для вебморды управления
32 | echo 'NODE_ENV=production' >> /opt/key-networks/ztncui/.env #режим работы
33 | echo 'HTTPS_HOST=nn.mm.ff.dd' >> /opt/key-networks/ztncui/.env #внешний ip-адрес нашего сервера
34 |
35 | systemctl restart ztncui
36 | ```
37 |
38 | Входим по ссылке https://ip_addr:6443, логин admin, пароль password.
39 | Далее создаем сеть и настраиваем параметры выдачи адресов, какие вам больше нравятся, остальные настройки по умолчанию.
40 | В режиме private после подключения клиента требуется установить галочку Authorized чтобы разрешить ему подключение.
41 |
42 | 
43 |
44 | Существует альтернатива в виде [публичного сервера](https://my.zerotier.com/), но вопрос надежности и быстродействия остается подвешенным. Программы - клиенты для windows, android скачивать [тут](https://www.zerotier.com/download/).
45 |
46 | Подключение к сети производится через указание Network ID, 16-значной символьной строки, которую берем из панели управления. Для камеры ее указываем в /etc/datalink.conf
47 | ```
48 | use_zt=true
49 | zt_netid=a8867b0bxxxxxxxxx
50 | ```
51 | после чего перезагружаем камеру. При наличии интернет-подключения, хоть LTE хоть ethernet, камера должна подключиться к сети zerotier. Это можно проверить через веб-панель управления и на камере командой ifconfig.
52 | ```
53 | ztuplek3wb Link encap:Ethernet HWaddr 92:31:B1:54:8B
54 | inet addr:10.7.0.1 Bcast:10.7.0.255 Mask:255.255.255.0
55 | inet6 addr: fe80::9031:b1ff:fe54/64 Scope:Link
56 | UP BROADCAST RUNNING MULTICAST MTU:2800 Metric:1
57 | RX packets:93 errors:0 dropped:0 overruns:0 frame:0
58 | TX packets:1236835 errors:0 dropped:0 overruns:0 carrier:0
59 | collisions:0 txqueuelen:1000
60 | RX bytes:5677 (5.5 KiB) TX bytes:1493618333 (1.3 GiB)
61 | ```
62 |
63 | Для ПК или андроид-устройства [устанавливаем](https://www.zerotier.com/download/) программу и аналогично добавляем сеть по ее id, авторизуем устройство в веб-панели. Пробуем перекрестный ping, он должен проходить. Если имеется файервол/брендмауер, как например под windows, нужно добавить в нем разрешающее правило с нашей подсетью.
64 |
65 | #### Настройка стрима
66 | Остается в /etc/majestic.yaml указать ip-адрес наземки из сети zerotier и видео можно принимать. Не забудьте согласовать кодеки.
67 | ```
68 | outgoing:
69 | - udp://ip_from_zerotier:5600
70 | ```
71 |
72 | #### Телеметрия
73 | Проверку телеметрии я еще не делал, но работать все должно как то так.
74 | Используется mavlink-routerd с конфигом /etc/mavlink.conf. Нужно указать эндпоинты для локального serial и наземки по ip-адресу zerotier:
75 | ```
76 | [General]
77 | TcpServerPort = 0
78 |
79 | [UartEndpoint drone]
80 | Device = /dev/ttyAMA0
81 | Baud = 115200
82 |
83 | [UdpEndpoint qgroundcontrol]
84 | Mode = Normal
85 | Address = gs_ip_from_zerotier
86 | Port = 14550
87 | ```
88 |
89 | Так как соединение является двунаправленным, автоматически получаем телеметрию в обе стороны.
90 |
--------------------------------------------------------------------------------
/mavfwd/mavfwd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/mavfwd/mavfwd
--------------------------------------------------------------------------------
/mavfwd/readme.md:
--------------------------------------------------------------------------------
1 | ### Зачем нужен mavfwd
2 | `mavfwd` в первую очередь необходим для связи телеметрийного потока wifibroadcast,
3 | разделенного на входящий и исходящий на разных udp-портах, с uart камеры, который
4 | подключен к uart полетного контроллера UAV, настроенного на обмен телеметрией.
5 | Поддерживается mavlink 1 и 2 версий. Подробности о параметрах доступны по `mavfwd --help`.
6 |
7 | Во вторую очередь, mavfwd способен мониторить передаваемые в mavlink-пакете [RC_CHANNELS #65](https://mavlink.io/en/messages/common.html#RC_CHANNELS)
8 | значения каналов с 4-го и выше, указанное в параметре --channels числом. По изменению значений каналов вызывается bash-скрипт /root/channels.sh,
9 | передавая ему параметрами номер канала и его значение. Это нужно, чтобы организовать какое-то управление хост-системой (камерой), например ее перезагрузку
10 | или настройку каких-то параметров стримера. В приложенном примере производятся:
11 | * переключение разрешений 1080p / 720p;
12 | * включение и отключение ircut камеры;
13 | * пороговое изменение яркости, три режима, для подбора нужного под текущие условия освещённости (яркий день, обычный день, ночь).
14 |
--------------------------------------------------------------------------------
/note-nvr-tab-ap.md:
--------------------------------------------------------------------------------
1 | ## Подключение планшета к регистратору по wifi через AP планшета
2 |
3 | Схема проста: в регистратор вставляется [TL-725n](https://www.tp-link.com/ru/home-networking/adapter/tl-wn725n/) или аналогичный адаптер на rtp8188eu, либо адаптер под
4 | который есть драйвер в прошивке OpenIPC; планшет включает точку доступа; регистратор коннектится к этой точке доступа; при перезапуске сервис wfb обнаруживает указанный wlan и
5 | настраивает трансляцию и телеметрию на планшет.
6 |
7 | ### Поднимем сеть
8 | * Закачаем драйвер [8188eu](hi3536dv100/lib/modules/4.9.37/extra/8188eu.ko) в `/lib/modules/4.9.37/extra/`
9 | * Настроим поднятие сети на адаптере в [`/etc/network/interfaces`](hi3536dv100/etc/network/interfaces), указывая свои ssid и password:
10 | ```
11 | auto wlan1
12 | iface wlan1 inet dhcp
13 | pre-up if ! lsmod | grep 8188eu; then insmod /lib/modules/4.9.37/extra/8188eu.ko; fi
14 | pre-up sleep 1
15 | pre-up wpa_passphrase "ssid" "password" >/tmp/wpa_supplicant.conf
16 | pre-up sed -i '2i \\tscan_ssid=1' /tmp/wpa_supplicant.conf
17 | pre-up sleep 3
18 | pre-up wpa_supplicant -B -D nl80211 -i wlan1 -c/tmp/wpa_supplicant.conf
19 | post-down killall wpa_supplicant
20 | ```
21 | ### Поправим конфиги сервисы
22 | * Закачаем обновленные [`/usr/bin/wifibroadcast`](hi3536dv100/usr/bin/wifibroadcast) и [`/usr/bin/telemetry`](hi3536dv100/usr/bin/telemetry) с детектированием подключения в /usr/bin.
23 | * Добавим в [wfb.conf](hi3536dv100/etc/wfb.conf) новую строчку с параметром - наименованием интерфейса для ap
24 | ```
25 | tab_wlan=wlan1
26 | ```
27 | * Если мы не пользуемся отправкой потока на PC, можно закомментировать параметр `udp_addr`, это немного разгрузит регистратор.
28 | * Включаем на планшете точку доступа и перезагружаем регистратор, либо нажимаем кнопку на [front panel](nvr_gpio.md).
29 |
--------------------------------------------------------------------------------
/note-two-cameras-switched.md:
--------------------------------------------------------------------------------
1 | ## Несколько камер на одном линке
2 |
3 | У камер есть сетевой интерфейс, который в случае двух камер можно использовать даже без свича, просто соединив четыре провода интерфейса друг с другом. Этот интерфейс и будем использовать для связи между камерами.
4 | Если /etc/network/interfaces доработать примерно таким образом:
5 | ```
6 | auto eth0
7 | iface eth0 inet dhcp
8 | hwaddress ether $(fw_printenv -n ethaddr || echo 00:24:B8:FF:FF:FF)
9 |
10 | auto eth0:1
11 | iface eth0:1 inet static
12 | address $(fw_printenv -n ipaddr || echo 192.168.1.9)
13 | netmask 255.255.255.0
14 | ```
15 | то у камер появится саб-интерфейс с адресом, прописанным в переменной env `ipaddr` либо, если она пуста, указанным в address. Нам нужно, чтобы у камер были адреса из одной подсети, например пусть это будут 192.168.1.9 и 192.168.1.10 у "первой" и "второй" камер.
16 | Первая - та, на которой расположен линк wfb и wifi-свисток. От второй нужен только поток на дополнительный порт, пусть 5601 на адрес первой камеры.
17 | В случае, если на второй камере стоит openipc, нужно на ней отключить wfb через `daemon=0` в `datalink.conf` и настроить udp поток в majestic.yaml на 192.168.1.9:5601.
18 | Теперь создадим на первой камере демонстрационный скрипт переключения камер `camswitch.sh`:
19 | ```
20 | function wfb_restart {
21 | kill -9 $(pidof wfb_tx)
22 | . /etc/wfb.conf
23 | wfb_tx -p ${stream} -u ${udp_port} -K /etc/drone.key -B ${bandwidth} -M ${mcs_index} -S ${stbc} -L ${ldpc} -G ${guard_interval} -k ${fec_k} -n ${fec_n} -T ${fec_timeout} -i ${link_id} ${wlan} &
24 | }
25 |
26 | function cam_1 {
27 | # this is main cam, with wfb_tx
28 | sed -i 's/udp_port=5601/udp_port=5600/' /etc/wfb.conf
29 | wfb_restart
30 | }
31 |
32 | function cam_2 {
33 | # set '- udp: cam1ip:5601' in /etc/majestic.yaml on cam2
34 | sed -i 's/udp_port=5600/udp_port=5601/' /etc/wfb.conf
35 | wfb_restart
36 | }
37 |
38 | cam_$1
39 | ```
40 | Дадим ему права на выполнение через `chmod +x camswitch.sh` и теперь мы можем переключаться между камерами, вызывая `camswitch.sh 1` или `camswitch.sh 2`.
41 | Скрипт останавливает wfb_tx, заменяет в его конфиге udp_port (основная камера шлет на 5600 а вторая на 5601) и запускает заново, таким образом переключаясь между потоками.
42 | Можно подключить вызов скрипта например к [channels.sh](notes_cam_control.md) и управлять переключением с какого то канала RC.
43 |
--------------------------------------------------------------------------------
/note_nvr_wdt.md:
--------------------------------------------------------------------------------
1 | ## Отключение watchdog на регистраторе
2 |
3 | Загрузчик на регистраторе запускает собаку, которая раз в полчаса перезагружает его. Для отключения копируем [`wdt.ko`](hi3536dv100/lib/wdt.ko) в `/lib` и добавляем в [`/etc/init.d/S95hisilicon`](hi3536dv100/etc/init.d/S95hisilicon) к загрузкам модулей, тут же выгружая:
4 | ```
5 | insmod /lib/wdt.ko
6 | rmmod /lib/wdt.ko
7 | ```
8 |
9 | Перезагружаемся, watchdog больше не должен срабатывать.
10 |
--------------------------------------------------------------------------------
/note_telemetry_baud.md:
--------------------------------------------------------------------------------
1 | ## Заметка об отличной от 115200 скорости uart для телеметрии
2 |
3 | TipoMan столкнулся с проблемой: камера зависала при подаче на uart телеметрии на скорости, отличной от 115200. Решение: установка нужной скорости в `/etc/inittab`.
4 |
5 | 
6 |
--------------------------------------------------------------------------------
/notes_cam_control.md:
--------------------------------------------------------------------------------
1 | ### Управление камерой с земли
2 |
3 | В качестве эксперимента [`mavfwd`](mavfwd) был дополнен парсером mavlink-пакета RC_CHANNELS (значения RC каналов, отправленные с любого RC-линка, например с наземной станции [(джойстика)](https://github.com/whoim2/arduremote) через [Mission Planner joystick](https://ardupilot.org/copter/docs/common-joystick.html)) или с [подключенного](rcjoystick.md) к регистратору джойстика.
4 |
5 | Он мониторит изменения в указанном в аргументе `--channels X` или `-c X`каналах, считая после первых 4х, и при их наличии вызывает скрипт [`/root/channels.sh`](gk7205v200/root), передавая в него два параметра (номер канала и значение), и который производит необходимые операции. Например, `-c 1` будет мониторить только 5й канал, а `-c 4` будет мониторить 5,6,7,8 каналы. В текущем [примере](gk7205v200/root/channels.sh) это изменение режима работы камеры (1080p@30fsp / 720p@5-fps) на 5-м канале, смена luminance на 7м (трехпозиционный переключатель) и переключатель ircut (поляризационного фильтра). По умолчанию `-c 0`, т.е. отключен.
6 |
7 | Для установки его на камеру замените в `/usr/sbin/` штатный mavfwd на [измененный](mavfwd/mavfwd), и добавьте параметр `-c` в [`/usr/bin/telemetry`](gk7205v200/usr/bin/telemetry#L39). Заодно получите возможность установить скорость телеметрии для связи с полетником выше чем 115200, конечно на свой страх и риск!
8 | Приветствуются идеи и пожелания по этому поводу, которые можно высказать [здесь](https://t.me/+BMyMoolVOpkzNWUy).
9 |
10 | upd 31.03.2023 Добавил распознавание mavlink 2 протокола.
11 |
12 |
--------------------------------------------------------------------------------
/notes_files/IMG_20230323_081622_212.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/IMG_20230323_081622_212.jpg
--------------------------------------------------------------------------------
/notes_files/OpenIPC_telemetry.csv:
--------------------------------------------------------------------------------
1 | text,type,typeId,Description
2 | ,Rectangle,creately.basic.rectangle,
3 | GROUND (NVR),Text,creately.basic.text,
4 | WIFI,WiFi,creately.material-icons.wifi_twotone_2,
5 | rtl8812au,Rectangle,creately.basic.rectangle,
6 | wifi adapter driver in monitor mode,Rectangle,creately.basic.rectangle,
7 | wfb-rx,Rectangle,creately.basic.rectangle,
8 | LAN / WLAN or usb network,Ellipse,creately.basic.ellipse,
9 | ,Rectangle,creately.basic.rectangle,
10 | PC or Pocket,Text,creately.basic.text,
11 | GS telemetry program,Computer,creately.material-icons.computer_twotone_2,
12 | udp:14551,Text,creately.basic.text,
13 | udp:14550,Text,creately.basic.text,
14 | ,Rectangle,creately.basic.rectangle,
15 | CAM,Text,creately.basic.text,
16 | mavfwd,Rectangle,creately.basic.rectangle,
17 | wfb-tx,Rectangle,creately.basic.rectangle,
18 | wfb-rx,Rectangle,creately.basic.rectangle,
19 | udp:14550,Text,creately.basic.text,
20 | udp:14551,Text,creately.basic.text,
21 | FC > cam uart,Rectangle,creately.basic.rectangle,
22 | wifi adapter driver in monitor mode,Rectangle,creately.basic.rectangle,
23 | rtl8812au,Rectangle,creately.basic.rectangle,
24 | WIFI,WiFi,creately.material-icons.wifi_twotone_2,
25 | wfb-rx,Rectangle,creately.basic.rectangle,
26 | mavlink-routerd,Rectangle,creately.basic.rectangle,
27 | udp:14550,Text,creately.basic.text,
--------------------------------------------------------------------------------
/notes_files/OpenIPC_video.csv:
--------------------------------------------------------------------------------
1 | text,type,typeId,Description
2 | ,Rectangle,creately.basic.rectangle,
3 | sensor,Rectangle,creately.basic.rectangle,
4 | CAM,Text,creately.basic.text,
5 | majestic or vencoder,Rectangle,creately.basic.rectangle,
6 | wfb-tx,Rectangle,creately.basic.rectangle,
7 | wifi adapter driver in monitor mode,Rectangle,creately.basic.rectangle,
8 | isp,Text,creately.basic.text,
9 | rtp:5600,Text,creately.basic.text,
10 | rtl8812au,Rectangle,creately.basic.rectangle,
11 | WIFI,WiFi,creately.material-icons.wifi_twotone_2,
12 | ,Rectangle,creately.basic.rectangle,
13 | GROUND (NVR),Text,creately.basic.text,
14 | WIFI,WiFi,creately.material-icons.wifi_twotone_2,
15 | rtl8812au,Rectangle,creately.basic.rectangle,
16 | wifi adapter driver in monitor mode,Rectangle,creately.basic.rectangle,
17 | wfb-rx,Rectangle,creately.basic.rectangle,
18 | LAN / WLAN or usb network,Ellipse,creately.basic.ellipse,
19 | ,Rectangle,creately.basic.rectangle,
20 | PC or Pocket,Text,creately.basic.text,
21 | videoplayer or GS program,Computer,creately.material-icons.computer_twotone_2,
22 | ,To Right Arrow,creately.arrows.torightarrow,
23 | ,To Right Arrow,creately.arrows.torightarrow,
24 | rtp:5600,Text,creately.basic.text,
25 | rtp:5600,Text,creately.basic.text,
26 | wfb-rx,Rectangle,creately.basic.rectangle,
27 | vdecoder,Rectangle,creately.basic.rectangle,
28 | HDMI,Rectangle,creately.basic.rectangle,
29 | udp:5000,Text,creately.basic.text,
--------------------------------------------------------------------------------
/notes_files/Screenshot_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/Screenshot_1.png
--------------------------------------------------------------------------------
/notes_files/Screenshot_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/Screenshot_2.png
--------------------------------------------------------------------------------
/notes_files/ZTNCUI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/ZTNCUI.png
--------------------------------------------------------------------------------
/notes_files/baud38400.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/baud38400.jpg
--------------------------------------------------------------------------------
/notes_files/gk7205v200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/gk7205v200.png
--------------------------------------------------------------------------------
/notes_files/hi3536ev100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/hi3536ev100.png
--------------------------------------------------------------------------------
/notes_files/hi3536ev100_pinout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/hi3536ev100_pinout.png
--------------------------------------------------------------------------------
/notes_files/link_hw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/link_hw.png
--------------------------------------------------------------------------------
/notes_files/mp_h265.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/mp_h265.png
--------------------------------------------------------------------------------
/notes_files/photo_2023-03-23_02-12-40.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/photo_2023-03-23_02-12-40.jpg
--------------------------------------------------------------------------------
/notes_files/qgc-udp-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/qgc-udp-settings.png
--------------------------------------------------------------------------------
/notes_files/telemetry.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/telemetry.png
--------------------------------------------------------------------------------
/notes_files/usb-ethernet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/usb-ethernet.png
--------------------------------------------------------------------------------
/notes_files/video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/notes_files/video.png
--------------------------------------------------------------------------------
/notes_imx335_gk7205v300.md:
--------------------------------------------------------------------------------
1 | ## Заметки о использовании камеры gk7205v300 с сенсором imx335
2 |
3 | В главном работа с камерой ничем не отличается от прочих камер gk. Точно так же прошивается lite или fpv, либо lite обновляется до fpv.
4 | Наличие и расположение пинов для USB и UART нужно смотреть на странице продавца. Для примера, камера купленная по [ссылке ](https://aliexpress.ru/item/1005005492432144.html) имеет USB
5 | на разъеме для шлейфа FPC и названы в описании WIFI_DP и WIFI_DN (USB DP/DN).
6 |
7 | Нюансы касаются настройки разрешения. Режим 1080p (установка size: 1920x1080 в majestic.yaml) выдает 15 кадров / секунду, что конечно неприемлимо. Необходимо в файле `/etc/sensors/imx335_i2c_4M.ini`
8 | закомментировать (через `;`) строчку `clock=27MHz` и установить `Isp_FrameRate=30`, после чего перезагрузить камеру. Исправленные файлы лежат в каталоге [imx335_gk7205v300](/imx335_gk7205v300).
9 | Также работает режим `size: 2592x1520` и выдает 20fps, но угол обзора картинки не меняется, что наводит на мысли об интерполяции. Но неизвестно, из какого разрешения - в какое. По факту задержка в 1520p@20 ниже и составляет около 165мс, в 1080p@30 - 185мс.
10 |
11 | Также необходим [gkrcparams](gkrcparams.md) для более плавной картинки.
12 |
--------------------------------------------------------------------------------
/notes_start_hi3536ev100.md:
--------------------------------------------------------------------------------
1 | ### Заметки о прошивке NVR hi3536ev100 на OpenIPC для целей FPV
2 | [EN](en_notes_start_hi3536ev100.md)
3 |
4 | Данная статья неактуальна в части прошивки, используйте https://github.com/OpenIPC/wiki/blob/master/en/fpv-nvr.md, эта же статья может быть полезна отдельными моментами.
5 |
6 |
7 |
8 | Как устроена память
9 | Для начала, следует разобраться, как устроена память регистратора (да и камеры тоже) и что нужно прошивать. Данные хранятся на spi-flash 16mb в виде блоков mtd:
10 |
11 | ```
12 | cat /proc/cmdline
13 | mem=150M console=ttyAMA0,115200 panic=20 root=/dev/mtdblock3 rootfstype=squashfs init=/init mtdparts=hi_sfc:256k(boot),64k(env),2048k(kernel),8192k(rootfs),-(rootfs_data)
14 | ls /dev/mtdb*
15 | /dev/mtdblock0 /dev/mtdblock1 /dev/mtdblock2 /dev/mtdblock3 /dev/mtdblock4
16 | ```
17 | Как следует из вывода, нулевой блок это загрузчик u-boot; далее идет блок для хранения переменных окружения (`printenv`, `setenv` команды пишут в ОЗУ, а `saveenv` сохраняет именно в этот блок); следом ядро uImage; потом rootfs.squashfs (неизменяемый образ файловой системы); и наконец rootfs_data или он же overlay - изменяемая часть, куда пишутся отличия от rootfs если вы изменяете какие-либо файлы. Таким образом, очистив overlay, мы "скинем" файловую систему до "дефолта":
18 | ```
19 | sf probe 0 #выбираем устройство
20 | sf erase 0xA50000 0x500000 #производим очистку
21 | reset #перезагрузка
22 | ```
23 | Еще проще сбросить до "заводских" прошивки командой `firstboot`.
24 |
25 | Калькулятор адресов для команд доступен [здесь](https://openipc.org/tools/firmware-partitions-calculation). В нашем случае раздел rootfs: 8192kB, значит адрес начала overlay будет 0xA50000. Для камеры, у которой flash 8mB, размер rootfs 5120kB, адреса будут другие, включая переменные окружения!
26 |
27 |
28 | Загрузчик у этого регистратора не имеет пароля, и в него можно попасть через uart/115200 бод, нажав при старте несколько раз Ctrl+C будучи подключенным к порту debug-uart регистратора через адаптер usb-uart 3v3 (ftdi, ch340). Debug uart расположен напротив разъема VGA на противоположном краю платы и подписан как gnd/tx/rx. Загрузчик нам прошивать не требуется, burn не нужен. ENV (переменные окружения) у нас отличаются от заводских, но их проще установить прямо из загрузчика построчно:
29 | ```
30 | setenv ipaddr '192.168.0.222' #тут ip в вашей подсети из свободных
31 | setenv serverip '192.168.0.107' #адрес ПК с tftp сервером
32 | setenv netmask '255.255.255.0'
33 | setenv bootcmd 'sf probe 0; sf read 0x82000000 0x50000 0x200000; bootm 0x82000000'
34 | setenv uk 'mw.b 0x82000000 ff 1000000;tftp 0x82000000 uImage.${soc}; sf probe 0; sf erase 0x50000 0x200000; sf write 0x82000000 0x50000 ${filesize}'
35 | setenv ur 'mw.b 0x82000000 ff 1000000;tftp 0x82000000 rootfs.squashfs.${soc}; sf probe 0; sf erase 0x250000 0x800000; sf write 0x82000000 0x250000 ${filesize}'
36 | setenv bootargs 'mem=192M console=ttyAMA0,115200 panic=20 root=/dev/mtdblock3 rootfstype=squashfs init=/init mtdparts=hi_sfc:256k(boot),64k(env),2048k(kernel),8192k(rootfs),-(rootfs_data)'
37 | setenv osmem '192M'
38 | setenv totalmem '256M'
39 | setenv soc 'hi3536dv100'
40 | #тут очищаем ненужные далее переменные
41 | setenv da; setenv du; setenv dr; setenv dw; setenv dl; setenv dc; setenv up; setenv tk; setenv dd; setenv de; setenv jpeg_addr; setenv jpeg_size; setenv vobuf; setenv loadlogo; setenv appVideoStandard; setenv appSystemLanguage; setenv appCloudExAbility
42 | saveenv #сохраняем новое окружение переменных
43 | printenv #смотрим, все ли в порядке
44 | ```
45 | Оригинальные env и полный дамп микросхемы (бекап заводской прошивки 16mb на случай восстановления) доступны [здесь](https://github.com/OpenIPC/sandbox-fpv/tree/master/hi3536dv100/original_firmware).
46 |
47 | Как вы могли заметить, в переменных uk и ur хранятся макросы для прошивки uImage и rootfs с загрузкой их с [tftp сервера](https://pjo2.github.io/tftpd64/), указанного в переменной serverip. Все адреса соответствуют переменной bootargs, содержимое которой и задает разметку файловой системы для ядра при загрузке. Разметка отличается от привычных для камер goke/hisilicone, ядро у нас как и у lite/fpv размером 2мб, однако файловая система размером 8мб, как у ultimate. Оставшиеся ~5мб используются оверлеем (вашими изменениями файлов относительно оригинальной rootfs). Для прошивки используйте официальные сборки со страницы релизов [openipc/firmware](https://github.com/OpenIPC/firmware/releases/download/latest/openipc.hi3536dv100-nor-fpv.tgz). Архив содержит ядро и файловую систему.
48 |
49 | Итак, после установки переменных можно приступать к прошивке оставшейся части. Запустите tftpd сервер, положите в его корень uImage.hi3536dv100 и rootfs.squashfs.hi3536dv100, выберите соответствующий сетевой интерфейс и в загрузчике запустите макрос: `run uk`. Должен выполниться ряд команд, из вывода которых должно следовать, что файл uImage скачался и прошился во flash. Аналогично выполните `run ur` для прошивки rootfs. Если адреса установлены верно, но скачивание застревает на "Downloading", смените адрес регистратора на соседний свободный: `setenv ipaddr '192.168.0.223'`.
50 | Если все прошло без ошибок, делайте `reset` и грузитесь в операционную систему, логин root, пароль 12345.
51 |
52 | Конфиги из каталога hi3536dv100 неактуальны, однако могут представлять интерес касаемо подключения планшета по usb/wifi/ethernet hotspot, вы можете перенести их по аналогии в конфиги официальной прошивки или оформить отдельными bash-скриптами. Обычно суть этих изменений в определении адреса подключаемого планшета (который является для регистратора шлюзом в случаях, если планшет у нас dhcp-сервер) и указании этого адреса в дополнительном экземпляре wfb_rx для видеопотока и для телеметрийных потоков.
53 |
54 | Обновление прошивки происходит через интернет командой `sysupgrade -r -k -n`.
55 |
56 |
57 | Обновление без интернета из /tmp
58 | В дальнейшем прошивку регистратора можно делать, залив в него через WinSCP ядро и rootfs в каталог `/tmp` и выполнив `sysupgrade --kernel=/tmp/uImage.hi3536dv100 --rootfs=/tmp/rootfs.squashfs.hi3536dv100 -z`. Параметр `-z` нужен если у вас нет подключения к интернету (не обновляет скрипт sysupgrade), `-n` очистит пользовательскую fs (overlay).
59 |
60 |
--------------------------------------------------------------------------------
/notes_start_ivg-g2s.md:
--------------------------------------------------------------------------------
1 | ## Заметки по прошивке камеры IVG-G2S прошивкой OpenIPC.
2 |
3 | ВНИМАНИЕ! Большая часть информации из этой статьи безнадежно устарела, все дополнительные помимо прошивки шаги уже неактуальны - они внесены в прошивку, и все работает из коробки, необходимо лишь произвести копирование ключа gs.key с камеры на наземную станцию и указать правильно каналы на обоих.
4 |
5 |
6 | Цель этой заметки - помочь привлечь внимание к крайне перспективной теме запуска digital fpv на дешевых камерах без одноплатника на борту.
7 | Разработчикам **ОЧЕНЬ** важны отзывы, при наличии популярности проект будет развиваться с их помощью значительно быстрее.
8 | Переходите в специально созданный для этой темы [телеграмм-чат](https://t.me/+BMyMoolVOpkzNWUy), задавайте вопросы которые не описаны тут и по ссылкам ниже, публикуйте информацию о своих успехах и запрашивайте помощь в решении проблем.
9 | Еще раз - фидбеки крайне важны, даже если у вас все получилось и работает - пожалуйста, не поленитесь описать свой сетап и опубликуйте в чате отзыв. Это позволит развиваться проекту с участием разработчиков.
10 |
11 | * [Основная страница по OpenIPC + FPV теме, обязательна к прочтению](https://github.com/OpenIPC/wiki/blob/master/ru/fpv.md)
12 | * [Основная wiki проекта](https://github.com/OpenIPC/wiki) (на текущий момент EN версия содержит больше информации)
13 | * [Генератор инструкций на сайте](https://openipc.org/supported-hardware/featured)
14 |
15 |
16 | ### Термины
17 |
18 | * Flash - в данном контексте SPI-flash, микросхема памяти.
19 | * U-Boot - загрузчик. Есть "родной", есть от OpenIPC. Родной запаролен. Нам нужен скачанный из генератора инструкций.
20 | * uImage - ядро Embedded Linux, в виде bin файла.
21 | * Root-FS - файловая система выбранной версии (lite, ultimate, fpv), в виде squash-fs файла [https://ru.wikipedia.org/wiki/Squashfs]. uImage и rootfs нужно добывать через конструктор инструкций, раздельная прошивка u-boot и root-fs.
22 | * Shell - командная строка linux камеры, доступна через uart и ssh (программа putty). Также есть shell загрузчика, только uart. Логин root, пароля нет.
23 | * Majestic - утилита - стример потоков видео, из комплекта прошивки OpenIPC.
24 |
25 | Платы оснащаются обычно spi-flash размером 8 или 16 мб. Версия ultimate требует 16, можно перепаять. Для fpv целей достаточно 8мб.
26 |
27 | Если у вас нет кабеля ethernet для подключения камеры к вашему свичу/роутеру, его можно сделать из половинки обычного патч-корда и разъема jst xh1.25 8pin. Такие использовались в полетниках Omnibus F4 и много где еще.
28 | Распиновки камеры и коннектора легко гуглятся, соединять необходимо 4 линии: rx+, rx-, tx+, tx- на кабеле и камере. На тот же разъем подается питание от 5 до 12в на пины 7(gnd) и 8(vcc).
29 |
30 | Рекомендую сначала прошить lite, поскольку в ней разблокирован shell через uart (в файле /etc/inittab) и это позволит подключаться в нештатных ситуациях, например при отсутствии сети.
31 |
32 | Существует три способа прошить камеру ivg-g2s на OpenIPC. В порядке усложнения: coupler, burn, программатор.
33 |
34 | - Coupler [https://github.com/OpenIPC/coupler] - это загрузка ядра и rootfs одним файлом через родной веб-интерфейс камеры. Минусы - не меняется родной запароленный
35 | загрузчик, можно выполнить только один раз, откат или смена прошивок только через прочие способы.
36 | Алгоритм: выяснить в родном веб-интерфейсе версию, на ее основании скачать прошивку, загрузить как обновление в родном вебинтерфейсе. Для ivg-g2s/659A7 есть [прошивка с загрузчиком](gk7205v200/659A7_OpenIPC_FPV.bin).
37 |
38 | - Burn [https://github.com/OpenIPC/burn] - загрузка незапароленного загрузчика u-boot от OpenIPC через uart камеры и uart-usb адаптер (например, ch340) и дальнейшая работа в загрузчике, согласно конструктору инструкций OpenIPC.
39 | Минусов нет, меняется загрузчик которым в любой момент можно загрузить с tftpf сервера [https://pjo2.github.io/tftpd64/] нужный образ и прошить во flash.
40 | Алгоритм описан видеоинструкциями на канале OpenIPC [https://www.youtube.com/@openipc/videos]. Далее, загрузив в RAM загрузчик (только [выбираем свой](gk7205v200_u-boot-7502v200-for-telemetry.md) ввиду нюансов), работаем через конструктор инструкций. uImage и root-fs распаковываем и кладем в каталог tftpd.
41 | Я пробовал пробросить usb-uart в archlinux под virtualbox и ипользовать burn оттуда, но загрузка не проходила, связь с uart была в одну сторону, только на чтение. Из под windows 7 все прошло штатно.
42 | Используйте короткие провода как от usb порта до адаптера, так и от адаптера до камеры. Распиновка uart на камере есть в первой статье из списка выше, соединять необходимо "накрест" - tx адаптера на rx камеры и rx адаптера на tx камеры.
43 | Если все в порядке, но tftp не загружает файл - попробуйте сменить адрес камере на соседний свободный, `setenv ipaddr '192.168.0.223'`.
44 |
45 | - Программатор - выпаивание флеш или одной ноги и подключение к программатору, прошивка всего через программатор.
46 | Самый сложный способ, это единственный минус.
47 |
48 | При первой загрузке необходимо выполнить команду firstboot.
49 | Если камера циклично перезагружается - это срабатывает watchdog от majestic (стримера). Скорее всего нужно снять колпачок объектива и включить свет. Отключается в /etc/majestic.yaml, убить процесс быстро: `killall majestic`.
50 |
51 | Управлять параметрами конфига с сохранением можно через утилиту cli шелла:
52 | ```
53 | cli -s .image.contrast 50
54 | cli -s .image.luminance 50
55 | cli -s .video0.codec h264
56 | cli -s .hls.enabled false
57 | cli -s .isp.sensorConfig /etc/sensors/imx307_i2c_2l_1080p.ini
58 | cli -s .video0.size 1920x1080
59 | cli -s .video0.fps 30
60 | ```
61 | Рекомендую выполнить эти команды, это настроит majestic для первоначальных попыток.
62 |
63 | Перейти на версию FPV с обновлением. Внимание! В версии FPV отключен shell через uart (освобожден для работы телеметрии), после загрузки, остается только сетевой доступ. Сам загрузчик, конечно, работает через uart.
64 | ```
65 | sed -i 's/BUILD_OPTION=lite/BUILD_OPTION=fpv/' /etc/os-release
66 | sysupgrade --force_ver -k -r -n
67 | ```
68 | Если вы не собираетесь использовать телеметрию сквозь этот видеолинк, можете включить его назад:
69 | ```
70 | sed -i 's/#console::respawn:\/sbin\/getty/console::respawn:\/sbin\/getty/' /etc/inittab
71 | reboot
72 | ```
73 | Если flash заблокирована (вы как то прошили ядро предыдущих версий, которые не умеют разблокировать флеш), то эта и любые прочие команды выполнены не будут.
74 |
75 | Пример вывода `dmesg | grep bsp-sfc` для определения блокировки флешки:
76 |
77 | Разблокирована
78 | ```
79 | bsp-sfc bsp_spi_nor.0: SR1:[02]->[00]
80 | bsp-sfc bsp_spi_nor.0: SR2:[02]->[00]
81 | bsp-sfc bsp_spi_nor.0: all blocks are unlocked.
82 | bsp-sfc bsp_spi_nor.0: Winbond: SR1 [], SR2 [QE], SR3 [DRV0,DRV1]
83 | ```
84 |
85 | Заблокирована
86 | ```
87 | bsp-sfc bsp_spi_nor.0: SR1:[02]->[00]
88 | bsp-sfc bsp_spi_nor.0: SR2:[02]->[00]
89 | bsp-sfc bsp_spi_nor.0: all blocks are unlocked.
90 | bsp-sfc bsp_spi_nor.0: Winbond: SR1 [TB], SR2 [QE], SR3 [WPS,DRV0,DRV1]
91 | ```
92 |
93 | Попытка разблокировать флеш из shell (мне не помогла)
94 | ```
95 | devmem 0x10010024 32 0x06;devmem 0x10010030 32 0;devmem 0x1001003C 32 0x81;devmem 0x14000000 16 0x0000;devmem 0x10010024 32 0x01;devmem 0x10010030 32 0;devmem 0x10010038 32 2;devmem 0x1001003C 32 0xA1
96 | #
97 | sysupgrade --force_ver -k -r -n
98 | ```
99 |
100 | Путь к разблокировке flash лежит через загрузку свежего ядра, распакованного архиватором из tgz файла с ядром и rootfs, взятого из конструктора инструкций. Загрузившись, оно автоматически разблокирует flash. Делается из загрузчика, залитого в ram через burn.
101 |
102 | ```
103 | # Устанавливаем адрес камеры и адрес сервера tftpd
104 | setenv ipaddr 192.168.0.222; setenv serverip 192.168.0.107
105 |
106 | # Устанавливаем аргументы окружения (env)
107 | setenv bootargs 'mem=32M console=ttyAMA0,115200 panic=20 rootfstype=squashfs root=/dev/mtdblock3 init=/init mtdparts=sfc:256k(boot),64k(env),2048k(kernel),5120k(rootfs),-(rootfs_data)'
108 |
109 | # Очищаем область оперативной памяти для скачивания ядра
110 | mw.b 0x42000000 ff 1000000
111 |
112 | # Загружаем ядро uImage.gk7205v200 с tftpd сервера
113 | tftpboot 0x42000000 uImage.${soc}
114 |
115 | # Запускаем ядро
116 | bootm 0x42000000
117 | ```
118 |
--------------------------------------------------------------------------------
/nvr_gpio.md:
--------------------------------------------------------------------------------
1 | ## Настройка кнопок со своим функционалом на регистраторе
2 |
3 | 
4 |
5 | Регистратор имеет на борту разъем для подключения фронт-панели с кнопками, ir-ресивером:
6 |
7 | 
8 |
9 | Разъем cn5 подписан с обратной стороны. С назначением +3.3в и GND понятно, IR задействовать не удалось, остальные пины ведут на GPIO процессора:
10 | ```
11 | Y2 ^17
12 | Y1 ^6
13 | X2 ^13
14 | Y3 ^8
15 | X1 ^7
16 | ALARM 10
17 | REC 11
18 | ```
19 |
20 | Символ `^` означает подтяжку резистором к +3.3, значит кнопкой эти пины надо замыкать на GND и ловить значение 0. Это реализовано в файле [`root/gpio_monitor.sh`](hi3536dv100/root/gpio_monitor.sh).
21 | По замыканию пина Y1 на землю он производит рестарт сервиса [wfb](hi3536dv100/etc/init.d/S98wfb), который следом рестартует [телеметрию](hi3536dv100/usr/bin/telemetry), для более удобного подключения смартфона или планшета [по USB](usb-tethering.md), или после смены wifi-адаптера. Скрипт мониторинга ведет лог нажатий, который можно наблюдать по `tail -f /tmp/gpio.log`.
22 | Примеры использования GPIO на выход можно посмотреть в [`testgpio.sh`](hi3536dv100/root/testgpio.sh), и можно подключить пин ALARM или REC к малмощному светодиоду с резистором для индикации процессов, например перезапуска wfb-ng как сделано в `gpio_monitor.sh`.
23 |
24 | Для запуска монитора как системного демона создадим файл [`/etc/init.d/S99gpio_monitor`](hi3536dv100/etc/init.d/S99gpio_monitor) откуда и будем запускать наш [`root/gpio_monitor.sh`](hi3536dv100/root/gpio_monitor.sh):
25 | ```
26 | #!/bin/sh
27 | #
28 | # Start gpio monitor
29 | #
30 |
31 | case "$1" in
32 | start)
33 | echo "Starting gpio_monitor daemon..."
34 | /root/gpio_monitor.sh &
35 | ;;
36 | stop)
37 | echo "Stopping gpio_monitor daemon..."
38 | kill -9 $(pidof {exe} ash /root/gpio_monitor.sh)
39 | ;;
40 | *)
41 | echo "Usage: $0 {start|stop}"
42 | exit 1
43 | esac
44 | ```
45 |
46 | Перезагружаемся без wifi адаптера и/или usb modem, активируем их уже после загрузки и убеждаемся, что по нажатию кнопки (хотя бы полсекунды подержите) сервисы запускаются.
47 | Список запущенных процессов всегда можно посмотреть командой `ps axww`.
48 |
--------------------------------------------------------------------------------
/rcjoystick.md:
--------------------------------------------------------------------------------
1 | ## Использование аппаратуры как джойстика для передачи каналов RC через mavlink
2 |
3 | ### Теория
4 | Программы наземных станций, такие как Mission Planner или QGroundControl, способны распознавать подключенные джойстики либо аппаратуры в режиме usb-джойстика и
5 | передавать на полетный контроллер значения осей в пакете RC_CHANNELS_OVERRIDE (#70). Однако, QGC передает только первые 4 канала (две оси), остальное можно назначить только на кнопки,
6 | а MP может это делать только под Windows, что не всегда удобно. Я написал простейшее приложение для регистратора, которое распознает подключенный джойстик и отправляет пакеты [RC_CHANNELS_OVERRIDE](https://mavlink.io/en/messages/common.html#RC_CHANNELS_OVERRIDE) в версии протокола mavlink 2 для поддержки 18 каналов напрямую в порт telemetry_tx, который обычно опубликован на 127.0.0.1:14650 регистратора. Порт, адрес, время между отправками пакетов, число осей и устройство в системе можно переназначить, смотрите `rcjoystick -h`.
7 |
8 | ```
9 | Usage:
10 | [-v] verbose;
11 | [-d device] default '/dev/input/js0';
12 | [-a addr] ip address send to, default 127.0.0.1;
13 | [-p port] udp port send to, default 14650;
14 | [-t time] update RC_CHANNEL_OVERRIDE time in ms, default 50;
15 | [-x axes_count] 2..9 axes, default 5, other channels mapping to js buttons from button 0;
16 | [-r rssi_channel] store rx packets per second value to this channel, default 0 (disabled);
17 | [-i interface] wlan interface for rx packets statistics, default wlan0;
18 |
19 | ```
20 |
21 | Например, отправлять можно не в telemetry_tx, а в mavlink_routerd, если вам так нужно. Пакет для сборки в buildroot от OpenIPC [тут](rcjoystick).
22 |
23 | ### Запускаем
24 | Нам необходимо ядро и rootfs с поддержкой usb-hid на регистраторе. Для этого [прошейте](notes_start_hi3536ev100) их из [`/hi3536dv100`](hi3536dv100) каталога.
25 | ~~Необходимо обеспечить запуск модуля `hid-generic.ko`, для этого добавьте `modprobe hid-generic.ko` в [`S95hisilicon`](hi3536dv100/etc/init.d/S95hisilicon).~~ В свежесобранном ядре модуль `hid-generic.ko` загружается автоматически.
26 |
27 | Далее нужно скопировать бинарник [`rcjoystick`](hi3536dv100/usr/bin/rcjoystick) в /usr/bin регистратора, через WinSCP и назначить права на исполнение: `chmod +x /usr/bin/rcjoystick`.
28 | Перезагружаемся, подключаем аппаратуру к регистратору по usb и пробуем в консоли запустить `rcjoystick -v`. Если все прошло хорошо, то на экране мы должны увидеть значения осей при изменении положения стиков и переключателей, а в программе телеметрии, например в QGC (analyse tools > Mavlink inspector > RC_CHANNELS_RAW) должны изменяться каналы. Для запуска на постоянную можно прописать его в отдельный сервис [`S99rcjoystick`](hi3536dv100/etc/init.d/S99rcjoystick), главное чтобы он запускался после wifibroadcast.
29 |
30 | ### RSSI
31 |
32 | Также в rcjoystick была добавлена функция инжекции аналога rssi (числа полученных от воздушной части пакетов в секунду) для хоть какого то индикатора качества приема, так как отдельный сервис для этого заводить нет желания и смысла, учитывая невысокий уровень регистратора. В rcjoystick уже есть большая часть необходимого для инжекции.
33 |
34 | Указываем `-r 16` и, если интерфейс wfb не wlan0, то и его `-i wlanX` и в указанный канал будет попадать число принятых наземкой пакетов в секунду. У меня оно в районе 800, вы можете увидеть свое применив ключ verbose (`-v`). Далее указываем на полетнике:
35 | ```
36 | RSSI_TYPE 2
37 | RSSI_CHANNEL 16
38 | RSSI_CHAN_LOW 0
39 | RSSI_CHAN_HIGH 800 //ваше обычное значение, примерно среднее, не максимальное и не минимальное.
40 | ```
41 | Значение будет отправлено на полетник, где он его обработает и установит 0..99 в rssi.
42 |
43 | Проект пока в стадии тестирования, поэтому [присылайте](https://t.me/+BMyMoolVOpkzNWUy) свои отзывы о попытках и пожелания.
44 |
45 | ### Текущие проблемы
46 | Иногда наблюдаются кратковременные фризы, если активно долбить оба стика во всех направлениях. Дебаг говорит, что от драйвера не приходят в это время события о перемещении. Этот эффект не наблюдается, если использовать ["радиоудлинитель" джойстика](sbus-to-usb-joystick) в виде arduino pro micro, которая парсит SBUS от вашего приемника и переводит в usb-hid-joystick.
47 |
--------------------------------------------------------------------------------
/rcjoystick/Config.in:
--------------------------------------------------------------------------------
1 | config BR2_PACKAGE_RCJOYSTICK
2 | bool "rcjoystick"
3 | help
4 | joystick /dev/input/js0 to mavlink rc_channels_override udp 127.0.0.1:14550
5 |
6 | https://github.com/whoim2/rcjoystick
7 |
--------------------------------------------------------------------------------
/rcjoystick/rcjoystick.mk:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | #
3 | # rcjoystick
4 | #
5 | ################################################################################
6 |
7 | RCJOYSTICK_LICENSE = GPL-2.0
8 |
9 | define RCJOYSTICK_EXTRACT_CMDS
10 | cp -avr ../general/package/rcjoystick/src/* $(@D)/
11 | endef
12 |
13 | RCJOYSTICK_MAKE_OPTS = \
14 | CC="$(TARGET_CC)"
15 |
16 | define RCJOYSTICK_BUILD_CMDS
17 | $(MAKE) $(RCJOYSTICK_MAKE_OPTS) -C $(@D)
18 | endef
19 |
20 | define RCJOYSTICK_INSTALL_TARGET_CMDS
21 | install -m 0755 -D $(@D)/rcjoystick $(TARGET_DIR)/usr/bin/rcjoystick
22 | endef
23 |
24 | $(eval $(generic-package))
25 |
--------------------------------------------------------------------------------
/rcjoystick/src/Makefile:
--------------------------------------------------------------------------------
1 | CFLAGS=-O1 -g -fno-omit-frame-pointer -Wall -Wextra
2 | LDFLAGS=-g
3 | #LDLIBS=-levent_core
4 |
5 | rcjoystick:
--------------------------------------------------------------------------------
/rcjoystick/src/checksum.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #if defined(MAVLINK_USE_CXX_NAMESPACE)
4 | namespace mavlink {
5 | #elif defined(__cplusplus)
6 | extern "C" {
7 | #endif
8 |
9 | // Visual Studio versions before 2010 don't have stdint.h, so we just error out.
10 | #if (defined _MSC_VER) && (_MSC_VER < 1600)
11 | #error "The C-MAVLink implementation requires Visual Studio 2010 or greater"
12 | #endif
13 |
14 | #include
15 |
16 | /**
17 | *
18 | * CALCULATE THE CHECKSUM
19 | *
20 | */
21 |
22 | #define X25_INIT_CRC 0xffff
23 | #define X25_VALIDATE_CRC 0xf0b8
24 |
25 | #ifndef HAVE_CRC_ACCUMULATE
26 | /**
27 | * @brief Accumulate the CRC16_MCRF4XX checksum by adding one char at a time.
28 | *
29 | * The checksum function adds the hash of one char at a time to the
30 | * 16 bit checksum (uint16_t).
31 | *
32 | * @param data new char to hash
33 | * @param crcAccum the already accumulated checksum
34 | **/
35 | static inline void crc_accumulate(uint8_t data, uint16_t *crcAccum)
36 | {
37 | /*Accumulate one byte of data into the CRC*/
38 | uint8_t tmp;
39 |
40 | tmp = data ^ (uint8_t)(*crcAccum &0xff);
41 | tmp ^= (tmp<<4);
42 | *crcAccum = (*crcAccum>>8) ^ (tmp<<8) ^ (tmp <<3) ^ (tmp>>4);
43 | }
44 | #endif
45 |
46 |
47 | /**
48 | * @brief Initialize the buffer for the MCRF4XX CRC16
49 | *
50 | * @param crcAccum the 16 bit MCRF4XX CRC16
51 | */
52 | static inline void crc_init(uint16_t* crcAccum)
53 | {
54 | *crcAccum = X25_INIT_CRC;
55 | }
56 |
57 |
58 | /**
59 | * @brief Calculates the CRC16_MCRF4XX checksum on a byte buffer
60 | *
61 | * @param pBuffer buffer containing the byte array to hash
62 | * @param length length of the byte array
63 | * @return the checksum over the buffer bytes
64 | **/
65 | static inline uint16_t crc_calculate(const uint8_t* pBuffer, uint16_t length)
66 | {
67 | uint16_t crcTmp;
68 | crc_init(&crcTmp);
69 | while (length--) {
70 | crc_accumulate(*pBuffer++, &crcTmp);
71 | }
72 | return crcTmp;
73 | }
74 |
75 |
76 | /**
77 | * @brief Accumulate the MCRF4XX CRC16 by adding an array of bytes
78 | *
79 | * The checksum function adds the hash of one char at a time to the
80 | * 16 bit checksum (uint16_t).
81 | *
82 | * @param data new bytes to hash
83 | * @param crcAccum the already accumulated checksum
84 | **/
85 | static inline void crc_accumulate_buffer(uint16_t *crcAccum, const char *pBuffer, uint16_t length)
86 | {
87 | const uint8_t *p = (const uint8_t *)pBuffer;
88 | while (length--) {
89 | crc_accumulate(*p++, crcAccum);
90 | }
91 | }
92 |
93 | #if defined(MAVLINK_USE_CXX_NAMESPACE) || defined(__cplusplus)
94 | }
95 | #endif
96 |
--------------------------------------------------------------------------------
/rcjoystick/src/common/mavlink.h:
--------------------------------------------------------------------------------
1 | /** @file
2 | * @brief MAVLink comm protocol built from common.xml
3 | * @see http://mavlink.org
4 | */
5 | #pragma once
6 | #ifndef MAVLINK_H
7 | #define MAVLINK_H
8 |
9 | #define MAVLINK_PRIMARY_XML_HASH 7898611588819456034
10 |
11 | #ifndef MAVLINK_STX
12 | #define MAVLINK_STX 253
13 | #endif
14 |
15 | #ifndef MAVLINK_ENDIAN
16 | #define MAVLINK_ENDIAN MAVLINK_LITTLE_ENDIAN
17 | #endif
18 |
19 | #ifndef MAVLINK_ALIGNED_FIELDS
20 | #define MAVLINK_ALIGNED_FIELDS 1
21 | #endif
22 |
23 | #ifndef MAVLINK_CRC_EXTRA
24 | #define MAVLINK_CRC_EXTRA 1
25 | #endif
26 |
27 | #ifndef MAVLINK_COMMAND_24BIT
28 | #define MAVLINK_COMMAND_24BIT 1
29 | #endif
30 |
31 | #include "version.h"
32 | #include "common.h"
33 |
34 | #endif // MAVLINK_H
35 |
--------------------------------------------------------------------------------
/rcjoystick/src/common/version.h:
--------------------------------------------------------------------------------
1 | /** @file
2 | * @brief MAVLink comm protocol built from common.xml
3 | * @see http://mavlink.org
4 | */
5 | #pragma once
6 |
7 | #ifndef MAVLINK_VERSION_H
8 | #define MAVLINK_VERSION_H
9 |
10 | #define MAVLINK_BUILD_DATE "Mon Mar 27 2023"
11 | #define MAVLINK_WIRE_PROTOCOL_VERSION "2.0"
12 | #define MAVLINK_MAX_DIALECT_PAYLOAD_SIZE 255
13 |
14 | #endif // MAVLINK_VERSION_H
15 |
--------------------------------------------------------------------------------
/rcjoystick/src/mavlink_conversions.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifndef MAVLINK_NO_CONVERSION_HELPERS
4 |
5 | /* enable math defines on Windows */
6 | #ifdef _MSC_VER
7 | #ifndef _USE_MATH_DEFINES
8 | #define _USE_MATH_DEFINES
9 | #endif
10 | #endif
11 | #include
12 |
13 | #ifndef M_PI_2
14 | #define M_PI_2 ((float)asin(1))
15 | #endif
16 |
17 | /**
18 | * @file mavlink_conversions.h
19 | *
20 | * These conversion functions follow the NASA rotation standards definition file
21 | * available online.
22 | *
23 | * Their intent is to lower the barrier for MAVLink adopters to use gimbal-lock free
24 | * (both rotation matrices, sometimes called DCM, and quaternions are gimbal-lock free)
25 | * rotation representations. Euler angles (roll, pitch, yaw) will be phased out of the
26 | * protocol as widely as possible.
27 | *
28 | * @author James Goppert
29 | * @author Thomas Gubler
30 | */
31 |
32 |
33 | /**
34 | * Converts a quaternion to a rotation matrix
35 | *
36 | * @param quaternion a [w, x, y, z] ordered quaternion (null-rotation being 1 0 0 0)
37 | * @param dcm a 3x3 rotation matrix
38 | */
39 | MAVLINK_HELPER void mavlink_quaternion_to_dcm(const float quaternion[4], float dcm[3][3])
40 | {
41 | double a = (double)quaternion[0];
42 | double b = (double)quaternion[1];
43 | double c = (double)quaternion[2];
44 | double d = (double)quaternion[3];
45 | double aSq = a * a;
46 | double bSq = b * b;
47 | double cSq = c * c;
48 | double dSq = d * d;
49 | dcm[0][0] = aSq + bSq - cSq - dSq;
50 | dcm[0][1] = 2 * (b * c - a * d);
51 | dcm[0][2] = 2 * (a * c + b * d);
52 | dcm[1][0] = 2 * (b * c + a * d);
53 | dcm[1][1] = aSq - bSq + cSq - dSq;
54 | dcm[1][2] = 2 * (c * d - a * b);
55 | dcm[2][0] = 2 * (b * d - a * c);
56 | dcm[2][1] = 2 * (a * b + c * d);
57 | dcm[2][2] = aSq - bSq - cSq + dSq;
58 | }
59 |
60 |
61 | /**
62 | * Converts a rotation matrix to euler angles
63 | *
64 | * @param dcm a 3x3 rotation matrix
65 | * @param roll the roll angle in radians
66 | * @param pitch the pitch angle in radians
67 | * @param yaw the yaw angle in radians
68 | */
69 | MAVLINK_HELPER void mavlink_dcm_to_euler(const float dcm[3][3], float* roll, float* pitch, float* yaw)
70 | {
71 | float phi, theta, psi;
72 | theta = asinf(-dcm[2][0]);
73 |
74 | if (fabsf(theta - (float)M_PI_2) < 1.0e-3f) {
75 | phi = 0.0f;
76 | psi = (atan2f(dcm[1][2] - dcm[0][1],
77 | dcm[0][2] + dcm[1][1]) + phi);
78 |
79 | } else if (fabsf(theta + (float)M_PI_2) < 1.0e-3f) {
80 | phi = 0.0f;
81 | psi = atan2f(dcm[1][2] - dcm[0][1],
82 | dcm[0][2] + dcm[1][1] - phi);
83 |
84 | } else {
85 | phi = atan2f(dcm[2][1], dcm[2][2]);
86 | psi = atan2f(dcm[1][0], dcm[0][0]);
87 | }
88 |
89 | *roll = phi;
90 | *pitch = theta;
91 | *yaw = psi;
92 | }
93 |
94 |
95 | /**
96 | * Converts a quaternion to euler angles
97 | *
98 | * @param quaternion a [w, x, y, z] ordered quaternion (null-rotation being 1 0 0 0)
99 | * @param roll the roll angle in radians
100 | * @param pitch the pitch angle in radians
101 | * @param yaw the yaw angle in radians
102 | */
103 | MAVLINK_HELPER void mavlink_quaternion_to_euler(const float quaternion[4], float* roll, float* pitch, float* yaw)
104 | {
105 | float dcm[3][3];
106 | mavlink_quaternion_to_dcm(quaternion, dcm);
107 | mavlink_dcm_to_euler((const float(*)[3])dcm, roll, pitch, yaw);
108 | }
109 |
110 |
111 | /**
112 | * Converts euler angles to a quaternion
113 | *
114 | * @param roll the roll angle in radians
115 | * @param pitch the pitch angle in radians
116 | * @param yaw the yaw angle in radians
117 | * @param quaternion a [w, x, y, z] ordered quaternion (null-rotation being 1 0 0 0)
118 | */
119 | MAVLINK_HELPER void mavlink_euler_to_quaternion(float roll, float pitch, float yaw, float quaternion[4])
120 | {
121 | float cosPhi_2 = cosf(roll / 2);
122 | float sinPhi_2 = sinf(roll / 2);
123 | float cosTheta_2 = cosf(pitch / 2);
124 | float sinTheta_2 = sinf(pitch / 2);
125 | float cosPsi_2 = cosf(yaw / 2);
126 | float sinPsi_2 = sinf(yaw / 2);
127 | quaternion[0] = (cosPhi_2 * cosTheta_2 * cosPsi_2 +
128 | sinPhi_2 * sinTheta_2 * sinPsi_2);
129 | quaternion[1] = (sinPhi_2 * cosTheta_2 * cosPsi_2 -
130 | cosPhi_2 * sinTheta_2 * sinPsi_2);
131 | quaternion[2] = (cosPhi_2 * sinTheta_2 * cosPsi_2 +
132 | sinPhi_2 * cosTheta_2 * sinPsi_2);
133 | quaternion[3] = (cosPhi_2 * cosTheta_2 * sinPsi_2 -
134 | sinPhi_2 * sinTheta_2 * cosPsi_2);
135 | }
136 |
137 |
138 | /**
139 | * Converts a rotation matrix to a quaternion
140 | * Reference:
141 | * - Shoemake, Quaternions,
142 | * http://www.cs.ucr.edu/~vbz/resources/quatut.pdf
143 | *
144 | * @param dcm a 3x3 rotation matrix
145 | * @param quaternion a [w, x, y, z] ordered quaternion (null-rotation being 1 0 0 0)
146 | */
147 | MAVLINK_HELPER void mavlink_dcm_to_quaternion(const float dcm[3][3], float quaternion[4])
148 | {
149 | float tr = dcm[0][0] + dcm[1][1] + dcm[2][2];
150 | if (tr > 0.0f) {
151 | float s = sqrtf(tr + 1.0f);
152 | quaternion[0] = s * 0.5f;
153 | s = 0.5f / s;
154 | quaternion[1] = (dcm[2][1] - dcm[1][2]) * s;
155 | quaternion[2] = (dcm[0][2] - dcm[2][0]) * s;
156 | quaternion[3] = (dcm[1][0] - dcm[0][1]) * s;
157 | } else {
158 | /* Find maximum diagonal element in dcm
159 | * store index in dcm_i */
160 | int dcm_i = 0;
161 | int i;
162 | for (i = 1; i < 3; i++) {
163 | if (dcm[i][i] > dcm[dcm_i][dcm_i]) {
164 | dcm_i = i;
165 | }
166 | }
167 |
168 | int dcm_j = (dcm_i + 1) % 3;
169 | int dcm_k = (dcm_i + 2) % 3;
170 |
171 | float s = sqrtf((dcm[dcm_i][dcm_i] - dcm[dcm_j][dcm_j] -
172 | dcm[dcm_k][dcm_k]) + 1.0f);
173 | quaternion[dcm_i + 1] = s * 0.5f;
174 | s = 0.5f / s;
175 | quaternion[dcm_j + 1] = (dcm[dcm_i][dcm_j] + dcm[dcm_j][dcm_i]) * s;
176 | quaternion[dcm_k + 1] = (dcm[dcm_k][dcm_i] + dcm[dcm_i][dcm_k]) * s;
177 | quaternion[0] = (dcm[dcm_k][dcm_j] - dcm[dcm_j][dcm_k]) * s;
178 | }
179 | }
180 |
181 |
182 | /**
183 | * Converts euler angles to a rotation matrix
184 | *
185 | * @param roll the roll angle in radians
186 | * @param pitch the pitch angle in radians
187 | * @param yaw the yaw angle in radians
188 | * @param dcm a 3x3 rotation matrix
189 | */
190 | MAVLINK_HELPER void mavlink_euler_to_dcm(float roll, float pitch, float yaw, float dcm[3][3])
191 | {
192 | float cosPhi = cosf(roll);
193 | float sinPhi = sinf(roll);
194 | float cosThe = cosf(pitch);
195 | float sinThe = sinf(pitch);
196 | float cosPsi = cosf(yaw);
197 | float sinPsi = sinf(yaw);
198 |
199 | dcm[0][0] = cosThe * cosPsi;
200 | dcm[0][1] = -cosPhi * sinPsi + sinPhi * sinThe * cosPsi;
201 | dcm[0][2] = sinPhi * sinPsi + cosPhi * sinThe * cosPsi;
202 |
203 | dcm[1][0] = cosThe * sinPsi;
204 | dcm[1][1] = cosPhi * cosPsi + sinPhi * sinThe * sinPsi;
205 | dcm[1][2] = -sinPhi * cosPsi + cosPhi * sinThe * sinPsi;
206 |
207 | dcm[2][0] = -sinThe;
208 | dcm[2][1] = sinPhi * cosThe;
209 | dcm[2][2] = cosPhi * cosThe;
210 | }
211 |
212 | #endif // MAVLINK_NO_CONVERSION_HELPERS
213 |
--------------------------------------------------------------------------------
/rcjoystick/src/mavlink_get_info.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifdef MAVLINK_USE_MESSAGE_INFO
4 | #define MAVLINK_HAVE_GET_MESSAGE_INFO
5 |
6 | /*
7 | return the message_info struct for a message
8 | */
9 | MAVLINK_HELPER const mavlink_message_info_t *mavlink_get_message_info_by_id(uint32_t msgid)
10 | {
11 | static const mavlink_message_info_t mavlink_message_info[] = MAVLINK_MESSAGE_INFO;
12 | /*
13 | use a bisection search to find the right entry. A perfect hash may be better
14 | Note that this assumes the table is sorted with primary key msgid
15 | */
16 | const uint32_t count = sizeof(mavlink_message_info)/sizeof(mavlink_message_info[0]);
17 | if (count == 0) {
18 | return NULL;
19 | }
20 | uint32_t low=0, high=count-1;
21 | while (low < high) {
22 | uint32_t mid = (low+high)/2;
23 | if (msgid < mavlink_message_info[mid].msgid) {
24 | high = mid;
25 | continue;
26 | }
27 | if (msgid > mavlink_message_info[mid].msgid) {
28 | low = mid+1;
29 | continue;
30 | }
31 | return &mavlink_message_info[mid];
32 | }
33 | if (mavlink_message_info[low].msgid == msgid) {
34 | return &mavlink_message_info[low];
35 | }
36 | return NULL;
37 | }
38 |
39 | /*
40 | return the message_info struct for a message
41 | */
42 | MAVLINK_HELPER const mavlink_message_info_t *mavlink_get_message_info(const mavlink_message_t *msg)
43 | {
44 | return mavlink_get_message_info_by_id(msg->msgid);
45 | }
46 |
47 | /*
48 | return the message_info struct for a message
49 | */
50 | MAVLINK_HELPER const mavlink_message_info_t *mavlink_get_message_info_by_name(const char *name)
51 | {
52 | static const struct { const char *name; uint32_t msgid; } mavlink_message_names[] = MAVLINK_MESSAGE_NAMES;
53 | /*
54 | use a bisection search to find the right entry. A perfect hash may be better
55 | Note that this assumes the table is sorted with primary key name
56 | */
57 | const uint32_t count = sizeof(mavlink_message_names)/sizeof(mavlink_message_names[0]);
58 | if (count == 0) {
59 | return NULL;
60 | }
61 | uint32_t low=0, high=count-1;
62 | while (low < high) {
63 | uint32_t mid = (low+high)/2;
64 | int cmp = strcmp(mavlink_message_names[mid].name, name);
65 | if (cmp > 0) {
66 | high = mid;
67 | continue;
68 | }
69 | if (cmp < 0) {
70 | low = mid+1;
71 | continue;
72 | }
73 | low = mid;
74 | break;
75 | }
76 | if (strcmp(mavlink_message_names[low].name, name) == 0) {
77 | return mavlink_get_message_info_by_id(mavlink_message_names[low].msgid);
78 | }
79 | return NULL;
80 | }
81 | #endif // MAVLINK_USE_MESSAGE_INFO
82 |
83 |
84 |
--------------------------------------------------------------------------------
/rcjoystick/src/mavlink_sha256.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 | sha-256 implementation for MAVLink based on Heimdal sources, with
5 | modifications to suit mavlink headers
6 | */
7 | /*
8 | * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
9 | * (Royal Institute of Technology, Stockholm, Sweden).
10 | * All rights reserved.
11 | *
12 | * Redistribution and use in source and binary forms, with or without
13 | * modification, are permitted provided that the following conditions
14 | * are met:
15 | *
16 | * 1. Redistributions of source code must retain the above copyright
17 | * notice, this list of conditions and the following disclaimer.
18 | *
19 | * 2. Redistributions in binary form must reproduce the above copyright
20 | * notice, this list of conditions and the following disclaimer in the
21 | * documentation and/or other materials provided with the distribution.
22 | *
23 | * 3. Neither the name of the Institute nor the names of its contributors
24 | * may be used to endorse or promote products derived from this software
25 | * without specific prior written permission.
26 | *
27 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 | * SUCH DAMAGE.
38 | */
39 |
40 | /*
41 | allow implementation to provide their own sha256 with the same API
42 | */
43 | #ifndef HAVE_MAVLINK_SHA256
44 |
45 | #ifdef MAVLINK_USE_CXX_NAMESPACE
46 | namespace mavlink {
47 | #endif
48 |
49 | #ifndef MAVLINK_HELPER
50 | #define MAVLINK_HELPER
51 | #endif
52 |
53 | typedef struct {
54 | uint32_t sz[2];
55 | uint32_t counter[8];
56 | union {
57 | unsigned char save_bytes[64];
58 | uint32_t save_u32[16];
59 | } u;
60 | } mavlink_sha256_ctx;
61 |
62 | #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
63 | #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
64 |
65 | #define ROTR(x,n) (((x)>>(n)) | ((x) << (32 - (n))))
66 |
67 | #define Sigma0(x) (ROTR(x,2) ^ ROTR(x,13) ^ ROTR(x,22))
68 | #define Sigma1(x) (ROTR(x,6) ^ ROTR(x,11) ^ ROTR(x,25))
69 | #define sigma0(x) (ROTR(x,7) ^ ROTR(x,18) ^ ((x)>>3))
70 | #define sigma1(x) (ROTR(x,17) ^ ROTR(x,19) ^ ((x)>>10))
71 |
72 | static const uint32_t mavlink_sha256_constant_256[64] = {
73 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
74 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
75 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
76 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
77 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
78 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
79 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
80 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
81 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
82 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
83 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
84 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
85 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
86 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
87 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
88 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
89 | };
90 |
91 | MAVLINK_HELPER void mavlink_sha256_init(mavlink_sha256_ctx *m)
92 | {
93 | m->sz[0] = 0;
94 | m->sz[1] = 0;
95 | m->counter[0] = 0x6a09e667;
96 | m->counter[1] = 0xbb67ae85;
97 | m->counter[2] = 0x3c6ef372;
98 | m->counter[3] = 0xa54ff53a;
99 | m->counter[4] = 0x510e527f;
100 | m->counter[5] = 0x9b05688c;
101 | m->counter[6] = 0x1f83d9ab;
102 | m->counter[7] = 0x5be0cd19;
103 | }
104 |
105 | static inline void mavlink_sha256_calc(mavlink_sha256_ctx *m, uint32_t *in)
106 | {
107 | uint32_t AA, BB, CC, DD, EE, FF, GG, HH;
108 | uint32_t data[64];
109 | int i;
110 |
111 | AA = m->counter[0];
112 | BB = m->counter[1];
113 | CC = m->counter[2];
114 | DD = m->counter[3];
115 | EE = m->counter[4];
116 | FF = m->counter[5];
117 | GG = m->counter[6];
118 | HH = m->counter[7];
119 |
120 | for (i = 0; i < 16; ++i)
121 | data[i] = in[i];
122 | for (i = 16; i < 64; ++i)
123 | data[i] = sigma1(data[i-2]) + data[i-7] +
124 | sigma0(data[i-15]) + data[i - 16];
125 |
126 | for (i = 0; i < 64; i++) {
127 | uint32_t T1, T2;
128 |
129 | T1 = HH + Sigma1(EE) + Ch(EE, FF, GG) + mavlink_sha256_constant_256[i] + data[i];
130 | T2 = Sigma0(AA) + Maj(AA,BB,CC);
131 |
132 | HH = GG;
133 | GG = FF;
134 | FF = EE;
135 | EE = DD + T1;
136 | DD = CC;
137 | CC = BB;
138 | BB = AA;
139 | AA = T1 + T2;
140 | }
141 |
142 | m->counter[0] += AA;
143 | m->counter[1] += BB;
144 | m->counter[2] += CC;
145 | m->counter[3] += DD;
146 | m->counter[4] += EE;
147 | m->counter[5] += FF;
148 | m->counter[6] += GG;
149 | m->counter[7] += HH;
150 | }
151 |
152 | MAVLINK_HELPER void mavlink_sha256_update(mavlink_sha256_ctx *m, const void *v, uint32_t len)
153 | {
154 | const unsigned char *p = (const unsigned char *)v;
155 | uint32_t old_sz = m->sz[0];
156 | uint32_t offset;
157 |
158 | m->sz[0] += len * 8;
159 | if (m->sz[0] < old_sz)
160 | ++m->sz[1];
161 | offset = (old_sz / 8) % 64;
162 | while(len > 0){
163 | uint32_t l = 64 - offset;
164 | if (len < l) {
165 | l = len;
166 | }
167 | memcpy(m->u.save_bytes + offset, p, l);
168 | offset += l;
169 | p += l;
170 | len -= l;
171 | if(offset == 64){
172 | int i;
173 | uint32_t current[16];
174 | const uint32_t *u = m->u.save_u32;
175 | for (i = 0; i < 16; i++){
176 | const uint8_t *p1 = (const uint8_t *)&u[i];
177 | uint8_t *p2 = (uint8_t *)¤t[i];
178 | p2[0] = p1[3];
179 | p2[1] = p1[2];
180 | p2[2] = p1[1];
181 | p2[3] = p1[0];
182 | }
183 | mavlink_sha256_calc(m, current);
184 | offset = 0;
185 | }
186 | }
187 | }
188 |
189 | /*
190 | get first 48 bits of final sha256 hash
191 | */
192 | MAVLINK_HELPER void mavlink_sha256_final_48(mavlink_sha256_ctx *m, uint8_t result[6])
193 | {
194 | unsigned char zeros[72];
195 | unsigned offset = (m->sz[0] / 8) % 64;
196 | unsigned int dstart = (120 - offset - 1) % 64 + 1;
197 | uint8_t *p = (uint8_t *)&m->counter[0];
198 |
199 | *zeros = 0x80;
200 | memset (zeros + 1, 0, sizeof(zeros) - 1);
201 | zeros[dstart+7] = (m->sz[0] >> 0) & 0xff;
202 | zeros[dstart+6] = (m->sz[0] >> 8) & 0xff;
203 | zeros[dstart+5] = (m->sz[0] >> 16) & 0xff;
204 | zeros[dstart+4] = (m->sz[0] >> 24) & 0xff;
205 | zeros[dstart+3] = (m->sz[1] >> 0) & 0xff;
206 | zeros[dstart+2] = (m->sz[1] >> 8) & 0xff;
207 | zeros[dstart+1] = (m->sz[1] >> 16) & 0xff;
208 | zeros[dstart+0] = (m->sz[1] >> 24) & 0xff;
209 |
210 | mavlink_sha256_update(m, zeros, dstart + 8);
211 |
212 | // this ordering makes the result consistent with taking the first
213 | // 6 bytes of more conventional sha256 functions. It assumes
214 | // little-endian ordering of m->counter
215 | result[0] = p[3];
216 | result[1] = p[2];
217 | result[2] = p[1];
218 | result[3] = p[0];
219 | result[4] = p[7];
220 | result[5] = p[6];
221 | }
222 |
223 | // prevent conflicts with users of the header
224 | #undef Ch
225 | #undef ROTR
226 | #undef Sigma0
227 | #undef Sigma1
228 | #undef sigma0
229 | #undef sigma1
230 |
231 | #ifdef MAVLINK_USE_CXX_NAMESPACE
232 | } // namespace mavlink
233 | #endif
234 |
235 | #endif // HAVE_MAVLINK_SHA256
236 |
--------------------------------------------------------------------------------
/rcjoystick/src/minimal/mavlink.h:
--------------------------------------------------------------------------------
1 | /** @file
2 | * @brief MAVLink comm protocol built from minimal.xml
3 | * @see http://mavlink.org
4 | */
5 | #pragma once
6 | #ifndef MAVLINK_H
7 | #define MAVLINK_H
8 |
9 | #define MAVLINK_PRIMARY_XML_HASH 3620580151627289427
10 |
11 | #ifndef MAVLINK_STX
12 | #define MAVLINK_STX 253
13 | #endif
14 |
15 | #ifndef MAVLINK_ENDIAN
16 | #define MAVLINK_ENDIAN MAVLINK_LITTLE_ENDIAN
17 | #endif
18 |
19 | #ifndef MAVLINK_ALIGNED_FIELDS
20 | #define MAVLINK_ALIGNED_FIELDS 1
21 | #endif
22 |
23 | #ifndef MAVLINK_CRC_EXTRA
24 | #define MAVLINK_CRC_EXTRA 1
25 | #endif
26 |
27 | #ifndef MAVLINK_COMMAND_24BIT
28 | #define MAVLINK_COMMAND_24BIT 1
29 | #endif
30 |
31 | #include "version.h"
32 | #include "minimal.h"
33 |
34 | #endif // MAVLINK_H
35 |
--------------------------------------------------------------------------------
/rcjoystick/src/minimal/testsuite.h:
--------------------------------------------------------------------------------
1 | /** @file
2 | * @brief MAVLink comm protocol testsuite generated from minimal.xml
3 | * @see https://mavlink.io/en/
4 | */
5 | #pragma once
6 | #ifndef MINIMAL_TESTSUITE_H
7 | #define MINIMAL_TESTSUITE_H
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif
12 |
13 | #ifndef MAVLINK_TEST_ALL
14 | #define MAVLINK_TEST_ALL
15 |
16 | static void mavlink_test_minimal(uint8_t, uint8_t, mavlink_message_t *last_msg);
17 |
18 | static void mavlink_test_all(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg)
19 | {
20 |
21 | mavlink_test_minimal(system_id, component_id, last_msg);
22 | }
23 | #endif
24 |
25 |
26 |
27 |
28 | static void mavlink_test_heartbeat(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg)
29 | {
30 | #ifdef MAVLINK_STATUS_FLAG_OUT_MAVLINK1
31 | mavlink_status_t *status = mavlink_get_channel_status(MAVLINK_COMM_0);
32 | if ((status->flags & MAVLINK_STATUS_FLAG_OUT_MAVLINK1) && MAVLINK_MSG_ID_HEARTBEAT >= 256) {
33 | return;
34 | }
35 | #endif
36 | mavlink_message_t msg;
37 | uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
38 | uint16_t i;
39 | mavlink_heartbeat_t packet_in = {
40 | 963497464,17,84,151,218,3
41 | };
42 | mavlink_heartbeat_t packet1, packet2;
43 | memset(&packet1, 0, sizeof(packet1));
44 | packet1.custom_mode = packet_in.custom_mode;
45 | packet1.type = packet_in.type;
46 | packet1.autopilot = packet_in.autopilot;
47 | packet1.base_mode = packet_in.base_mode;
48 | packet1.system_status = packet_in.system_status;
49 | packet1.mavlink_version = packet_in.mavlink_version;
50 |
51 |
52 | #ifdef MAVLINK_STATUS_FLAG_OUT_MAVLINK1
53 | if (status->flags & MAVLINK_STATUS_FLAG_OUT_MAVLINK1) {
54 | // cope with extensions
55 | memset(MAVLINK_MSG_ID_HEARTBEAT_MIN_LEN + (char *)&packet1, 0, sizeof(packet1)-MAVLINK_MSG_ID_HEARTBEAT_MIN_LEN);
56 | }
57 | #endif
58 | memset(&packet2, 0, sizeof(packet2));
59 | mavlink_msg_heartbeat_encode(system_id, component_id, &msg, &packet1);
60 | mavlink_msg_heartbeat_decode(&msg, &packet2);
61 | MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
62 |
63 | memset(&packet2, 0, sizeof(packet2));
64 | mavlink_msg_heartbeat_pack(system_id, component_id, &msg , packet1.type , packet1.autopilot , packet1.base_mode , packet1.custom_mode , packet1.system_status );
65 | mavlink_msg_heartbeat_decode(&msg, &packet2);
66 | MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
67 |
68 | memset(&packet2, 0, sizeof(packet2));
69 | mavlink_msg_heartbeat_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg , packet1.type , packet1.autopilot , packet1.base_mode , packet1.custom_mode , packet1.system_status );
70 | mavlink_msg_heartbeat_decode(&msg, &packet2);
71 | MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
72 |
73 | memset(&packet2, 0, sizeof(packet2));
74 | mavlink_msg_to_send_buffer(buffer, &msg);
75 | for (i=0; iflags & MAVLINK_STATUS_FLAG_OUT_MAVLINK1) && MAVLINK_MSG_ID_PROTOCOL_VERSION >= 256) {
97 | return;
98 | }
99 | #endif
100 | mavlink_message_t msg;
101 | uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
102 | uint16_t i;
103 | mavlink_protocol_version_t packet_in = {
104 | 17235,17339,17443,{ 151, 152, 153, 154, 155, 156, 157, 158 },{ 175, 176, 177, 178, 179, 180, 181, 182 }
105 | };
106 | mavlink_protocol_version_t packet1, packet2;
107 | memset(&packet1, 0, sizeof(packet1));
108 | packet1.version = packet_in.version;
109 | packet1.min_version = packet_in.min_version;
110 | packet1.max_version = packet_in.max_version;
111 |
112 | mav_array_memcpy(packet1.spec_version_hash, packet_in.spec_version_hash, sizeof(uint8_t)*8);
113 | mav_array_memcpy(packet1.library_version_hash, packet_in.library_version_hash, sizeof(uint8_t)*8);
114 |
115 | #ifdef MAVLINK_STATUS_FLAG_OUT_MAVLINK1
116 | if (status->flags & MAVLINK_STATUS_FLAG_OUT_MAVLINK1) {
117 | // cope with extensions
118 | memset(MAVLINK_MSG_ID_PROTOCOL_VERSION_MIN_LEN + (char *)&packet1, 0, sizeof(packet1)-MAVLINK_MSG_ID_PROTOCOL_VERSION_MIN_LEN);
119 | }
120 | #endif
121 | memset(&packet2, 0, sizeof(packet2));
122 | mavlink_msg_protocol_version_encode(system_id, component_id, &msg, &packet1);
123 | mavlink_msg_protocol_version_decode(&msg, &packet2);
124 | MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
125 |
126 | memset(&packet2, 0, sizeof(packet2));
127 | mavlink_msg_protocol_version_pack(system_id, component_id, &msg , packet1.version , packet1.min_version , packet1.max_version , packet1.spec_version_hash , packet1.library_version_hash );
128 | mavlink_msg_protocol_version_decode(&msg, &packet2);
129 | MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
130 |
131 | memset(&packet2, 0, sizeof(packet2));
132 | mavlink_msg_protocol_version_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg , packet1.version , packet1.min_version , packet1.max_version , packet1.spec_version_hash , packet1.library_version_hash );
133 | mavlink_msg_protocol_version_decode(&msg, &packet2);
134 | MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
135 |
136 | memset(&packet2, 0, sizeof(packet2));
137 | mavlink_msg_to_send_buffer(buffer, &msg);
138 | for (i=0; i
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/examples/ArcadeStickExample/ArcadeStickExample.ino:
--------------------------------------------------------------------------------
1 | // Simple arcade stick example that demonstrates how to read twelve
2 | // Arduino Pro Micro digital pins and map them to the
3 | // Arduino Joystick library.
4 | //
5 |
6 | // The digital pins 2 - 20 are grounded when they are pressed.
7 | // Pin 10, A10, Red = UP
8 | // Pin 15, D15, Yellow = RIGHT
9 | // Pin 16, D16, Orange = DOWN
10 | // Pin 14, D14, Green = LEFT
11 |
12 | // Pin 9, A9 = Button 1
13 | // Pin 8, A8 = Button 2
14 | // Pin 7, D7 = Button 3
15 | // Pin 3, D3 = Button 4
16 | // Pin 2, D2 = Button 5
17 | // Pin 4, A6 = Button 6
18 |
19 | // Pin 20, A2 = Select Button 1
20 | // Pin 19, A1 = Start Button 2
21 |
22 | // Pin 5, D5 = Other Button
23 | // Pin 6, A7 = Other Button
24 | // Pin 18, A0 = Other Button
25 | // Pin 21, A3 = Other Button
26 |
27 | // NOTE: This sketch file is for use with Arduino Pro Micro only.
28 | //
29 | // Original gamepad example by Matthew Heironimus
30 | // 2016-11-24
31 | // Adapted for arcade machine setup by Ben Parmeter
32 | // 2019-05-20
33 | //--------------------------------------------------------------------
34 |
35 | #include
36 |
37 | Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
38 | 8, 0, // Button Count, Hat Switch Count
39 | true, true, false, // X and Y, but no Z Axis
40 | false, false, false, // No Rx, Ry, or Rz
41 | false, false, // No rudder or throttle
42 | false, false, false); // No accelerator, brake, or steering
43 |
44 | void setup() {
45 | // Initialize Button Pins
46 | pinMode(2, INPUT_PULLUP);
47 | pinMode(3, INPUT_PULLUP);
48 | pinMode(4, INPUT_PULLUP);
49 | pinMode(5, INPUT_PULLUP);
50 | pinMode(6, INPUT_PULLUP);
51 | pinMode(7, INPUT_PULLUP);
52 | pinMode(8, INPUT_PULLUP);
53 | pinMode(9, INPUT_PULLUP);
54 | pinMode(10, INPUT_PULLUP);
55 | pinMode(14, INPUT_PULLUP);
56 | pinMode(15, INPUT_PULLUP);
57 | pinMode(16, INPUT_PULLUP);
58 | pinMode(18, INPUT_PULLUP);
59 | pinMode(19, INPUT_PULLUP);
60 | pinMode(20, INPUT_PULLUP);
61 | pinMode(21, INPUT_PULLUP);
62 |
63 | // Initialize Joystick Library
64 | Joystick.begin();
65 | Joystick.setXAxisRange(-1, 1);
66 | Joystick.setYAxisRange(-1, 1);
67 | }
68 |
69 | // Last state of the buttons
70 | int lastButtonState[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
71 | int buttonMap[16] = {10,15,16,14,9,8,7,3,2,4,20,19,5,6,18,21};
72 |
73 | // ButtonMap = 0, Pin 10 = UP
74 | // ButtonMap = 1, Pin 15 = RIGHT
75 | // ButtonMap = 2, Pin 16 = DOWN
76 | // ButtonMap = 3, Pin 14 = LEFT
77 |
78 | // ButtonMap = 4, Pin 9 = Button 1
79 | // ButtonMap = 5, Pin 8 = Button 2
80 | // ButtonMap = 6, Pin 7 = Button 3
81 | // ButtonMap = 7, Pin 3 = Button 4
82 | // ButtonMap = 8, Pin 2 = Button 5
83 | // ButtonMap = 9, Pin 4 = Button 6
84 |
85 | // ButtonMap = 10, Pin 20 = Select Button 1
86 | // ButtonMap = 11, Pin 19 = Start Button 2
87 |
88 | // ButtonMap = 12, Pin 5 = Other Button
89 | // ButtonMap = 13, Pin 6 = Other Button
90 | // ButtonMap = 14, Pin 18 = Other Button
91 | // ButtonMap = 15, Pin 21 = Other Button
92 |
93 |
94 | void loop() {
95 |
96 | // Read pin values
97 | for (int index = 0; index < 16; index++)
98 | {
99 | int currentButtonState = !digitalRead(buttonMap[index]);
100 | if (currentButtonState != lastButtonState[index])
101 | {
102 | switch (index) {
103 | case 0: // UP
104 | if (currentButtonState == 1) {
105 | Joystick.setYAxis(-1);
106 | } else {
107 | Joystick.setYAxis(0);
108 | }
109 | break;
110 | case 1: // RIGHT
111 | if (currentButtonState == 1) {
112 | Joystick.setXAxis(1);
113 | } else {
114 | Joystick.setXAxis(0);
115 | }
116 | break;
117 | case 2: // DOWN
118 | if (currentButtonState == 1) {
119 | Joystick.setYAxis(1);
120 | } else {
121 | Joystick.setYAxis(0);
122 | }
123 | break;
124 | case 3: // LEFT
125 | if (currentButtonState == 1) {
126 | Joystick.setXAxis(-1);
127 | } else {
128 | Joystick.setXAxis(0);
129 | }
130 | break;
131 | case 4: // Black Button 1
132 | Joystick.setButton(0, currentButtonState);
133 | break;
134 | case 5: // Black Button 2
135 | Joystick.setButton(1, currentButtonState);
136 | break;
137 | case 6: // Black Button 3
138 | Joystick.setButton(2, currentButtonState);
139 | break;
140 | case 7: // Black Button 4
141 | Joystick.setButton(3, currentButtonState);
142 | break;
143 | case 8: // Black Button 5
144 | Joystick.setButton(4, currentButtonState);
145 | break;
146 | case 9: // Black Button 6
147 | Joystick.setButton(5, currentButtonState);
148 | break;
149 | case 10: // Select Button
150 | Joystick.setButton(6, currentButtonState);
151 | break;
152 | case 11: // Start Button
153 | Joystick.setButton(7, currentButtonState);
154 | break;
155 | case 12: // Other Button 1
156 | Joystick.setButton(8, currentButtonState);
157 | break;
158 | case 13: // Other Button 2
159 | Joystick.setButton(9, currentButtonState);
160 | break;
161 | case 14: // Other Button 3
162 | Joystick.setButton(10, currentButtonState);
163 | break;
164 | case 15: // Other Button 4
165 | Joystick.setButton(11, currentButtonState);
166 | break;
167 | }
168 | lastButtonState[index] = currentButtonState;
169 | }
170 | }
171 |
172 | delay(10);
173 | }
174 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/examples/DrivingControllerTest/DrivingControllerTest.ino:
--------------------------------------------------------------------------------
1 | // Program used to test the driving simulator functions on
2 | // the USB Joystick object on the Arduino Leonardo or
3 | // Arduino Micro.
4 | //
5 | // Matthew Heironimus
6 | // 2016-05-29 Original version.
7 | //------------------------------------------------------------
8 |
9 | #include "Joystick.h"
10 |
11 | Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
12 | JOYSTICK_TYPE_MULTI_AXIS, 4, 0,
13 | false, false, false, false, false, false,
14 | false, false, true, true, true);
15 |
16 | // Set to true to test "Auto Send" mode or false to test "Manual Send" mode.
17 | //const bool testAutoSendMode = true;
18 | const bool testAutoSendMode = false;
19 |
20 | const unsigned long gcCycleDelta = 1000;
21 | const unsigned long gcButtonDelta = 500;
22 | const unsigned long gcAnalogDelta = 25;
23 | unsigned long gNextTime = 0;
24 | unsigned int gCurrentStep = 0;
25 |
26 | void testSingleButtonPush(unsigned int button)
27 | {
28 | if (button > 0)
29 | {
30 | Joystick.releaseButton(button - 1);
31 | }
32 | if (button < 4)
33 | {
34 | Joystick.pressButton(button);
35 | }
36 | }
37 |
38 | void testMultiButtonPush(unsigned int currentStep)
39 | {
40 | for (int button = 0; button < 4; button++)
41 | {
42 | if ((currentStep == 0) || (currentStep == 2))
43 | {
44 | if ((button % 2) == 0)
45 | {
46 | Joystick.pressButton(button);
47 | } else if (currentStep != 2)
48 | {
49 | Joystick.releaseButton(button);
50 | }
51 | } // if ((currentStep == 0) || (currentStep == 2))
52 | if ((currentStep == 1) || (currentStep == 2))
53 | {
54 | if ((button % 2) != 0)
55 | {
56 | Joystick.pressButton(button);
57 | } else if (currentStep != 2)
58 | {
59 | Joystick.releaseButton(button);
60 | }
61 | } // if ((currentStep == 1) || (currentStep == 2))
62 | if (currentStep == 3)
63 | {
64 | Joystick.releaseButton(button);
65 | } // if (currentStep == 3)
66 | } // for (int button = 0; button < 32; button++)
67 | }
68 |
69 | void testAcceleratorBrake(int value)
70 | {
71 | Joystick.setAccelerator(value);
72 | Joystick.setBrake(260 - value);
73 | }
74 |
75 | void testSteering(int value)
76 | {
77 | if (value < 300) {
78 | Joystick.setSteering(value);
79 | } else {
80 | Joystick.setSteering(600 - value);
81 | }
82 | }
83 |
84 | void setup() {
85 |
86 | Joystick.setAcceleratorRange(0, 260);
87 | Joystick.setBrakeRange(0, 260);
88 | Joystick.setSteeringRange(0, 300);
89 |
90 | if (testAutoSendMode)
91 | {
92 | Joystick.begin();
93 | }
94 | else
95 | {
96 | Joystick.begin(false);
97 | }
98 |
99 | pinMode(A0, INPUT_PULLUP);
100 | pinMode(LED_BUILTIN, OUTPUT);
101 | }
102 |
103 | void loop() {
104 |
105 | // System Disabled
106 | if (digitalRead(A0) != 0)
107 | {
108 | // Turn indicator light off.
109 | digitalWrite(LED_BUILTIN, 0);
110 | return;
111 | }
112 |
113 | // Turn indicator light on.
114 | digitalWrite(LED_BUILTIN, 1);
115 |
116 | if (millis() >= gNextTime)
117 | {
118 |
119 | if (gCurrentStep < 4)
120 | {
121 | gNextTime = millis() + gcButtonDelta;
122 | testSingleButtonPush(gCurrentStep);
123 | }
124 | else if (gCurrentStep < 9)
125 | {
126 | gNextTime = millis() + gcButtonDelta;
127 | testMultiButtonPush(gCurrentStep - 5);
128 | }
129 | else if (gCurrentStep < (9 + 260))
130 | {
131 | gNextTime = millis() + gcAnalogDelta;
132 | testAcceleratorBrake(gCurrentStep - 9);
133 | }
134 | else if (gCurrentStep < (9 + 260 + 600))
135 | {
136 | gNextTime = millis() + gcAnalogDelta;
137 | testSteering(gCurrentStep - (9 + 260));
138 | }
139 |
140 | if (testAutoSendMode == false)
141 | {
142 | Joystick.sendState();
143 | }
144 |
145 | gCurrentStep++;
146 | if (gCurrentStep >= (9 + 260 + 600))
147 | {
148 | gNextTime = millis() + gcCycleDelta;
149 | gCurrentStep = 0;
150 | }
151 | }
152 | }
153 |
154 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/examples/FlightControllerTest/FlightControllerTest.ino:
--------------------------------------------------------------------------------
1 | // Program used to test the USB Joystick library when used as
2 | // a Flight Controller on the Arduino Leonardo or Arduino
3 | // Micro.
4 | //
5 | // Matthew Heironimus
6 | // 2016-05-29 - Original Version
7 | //------------------------------------------------------------
8 |
9 | #include "Joystick.h"
10 |
11 | Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
12 | JOYSTICK_TYPE_MULTI_AXIS, 32, 0,
13 | true, true, false, false, false, false,
14 | true, true, false, false, false);
15 |
16 | // Set to true to test "Auto Send" mode or false to test "Manual Send" mode.
17 | //const bool testAutoSendMode = true;
18 | const bool testAutoSendMode = false;
19 |
20 | const unsigned long gcCycleDelta = 1000;
21 | const unsigned long gcAnalogDelta = 25;
22 | const unsigned long gcButtonDelta = 500;
23 | unsigned long gNextTime = 0;
24 | unsigned int gCurrentStep = 0;
25 |
26 | void testSingleButtonPush(unsigned int button)
27 | {
28 | if (button > 0)
29 | {
30 | Joystick.releaseButton(button - 1);
31 | }
32 | if (button < 32)
33 | {
34 | Joystick.pressButton(button);
35 | }
36 | }
37 |
38 | void testMultiButtonPush(unsigned int currentStep)
39 | {
40 | for (int button = 0; button < 32; button++)
41 | {
42 | if ((currentStep == 0) || (currentStep == 2))
43 | {
44 | if ((button % 2) == 0)
45 | {
46 | Joystick.pressButton(button);
47 | } else if (currentStep != 2)
48 | {
49 | Joystick.releaseButton(button);
50 | }
51 | } // if ((currentStep == 0) || (currentStep == 2))
52 | if ((currentStep == 1) || (currentStep == 2))
53 | {
54 | if ((button % 2) != 0)
55 | {
56 | Joystick.pressButton(button);
57 | } else if (currentStep != 2)
58 | {
59 | Joystick.releaseButton(button);
60 | }
61 | } // if ((currentStep == 1) || (currentStep == 2))
62 | if (currentStep == 3)
63 | {
64 | Joystick.releaseButton(button);
65 | } // if (currentStep == 3)
66 | } // for (int button = 0; button < 32; button++)
67 | }
68 |
69 | void testXYAxis(unsigned int currentStep)
70 | {
71 | int xAxis;
72 | int yAxis;
73 |
74 | if (currentStep < 256)
75 | {
76 | xAxis = currentStep - 127;
77 | yAxis = -127;
78 | Joystick.setXAxis(xAxis);
79 | Joystick.setYAxis(yAxis);
80 | }
81 | else if (currentStep < 512)
82 | {
83 | yAxis = currentStep - 256 - 127;
84 | Joystick.setYAxis(yAxis);
85 | }
86 | else if (currentStep < 768)
87 | {
88 | xAxis = 128 - (currentStep - 512);
89 | Joystick.setXAxis(xAxis);
90 | }
91 | else if (currentStep < 1024)
92 | {
93 | yAxis = 128 - (currentStep - 768);
94 | Joystick.setYAxis(yAxis);
95 | }
96 | else if (currentStep < 1024 + 128)
97 | {
98 | xAxis = currentStep - 1024 - 127;
99 | Joystick.setXAxis(xAxis);
100 | Joystick.setYAxis(xAxis);
101 | }
102 | }
103 |
104 | void testThrottleRudder(unsigned int value)
105 | {
106 | Joystick.setThrottle(value);
107 | Joystick.setRudder(255 - value);
108 | }
109 |
110 | void setup() {
111 |
112 | Joystick.setXAxisRange(-127, 127);
113 | Joystick.setYAxisRange(-127, 127);
114 | Joystick.setZAxisRange(-127, 127);
115 | Joystick.setThrottleRange(0, 255);
116 | Joystick.setRudderRange(0, 255);
117 |
118 | if (testAutoSendMode)
119 | {
120 | Joystick.begin();
121 | }
122 | else
123 | {
124 | Joystick.begin(false);
125 | }
126 |
127 | pinMode(A0, INPUT_PULLUP);
128 | pinMode(LED_BUILTIN, OUTPUT);
129 | }
130 |
131 | void loop() {
132 |
133 | // System Disabled
134 | if (digitalRead(A0) != 0)
135 | {
136 | // Turn indicator light off.
137 | digitalWrite(LED_BUILTIN, 0);
138 | return;
139 | }
140 |
141 | // Turn indicator light on.
142 | digitalWrite(LED_BUILTIN, 1);
143 |
144 | if (millis() >= gNextTime)
145 | {
146 |
147 | if (gCurrentStep < 33)
148 | {
149 | gNextTime = millis() + gcButtonDelta;
150 | testSingleButtonPush(gCurrentStep);
151 | }
152 | else if (gCurrentStep < 37)
153 | {
154 | gNextTime = millis() + gcButtonDelta;
155 | testMultiButtonPush(gCurrentStep - 33);
156 | }
157 | else if (gCurrentStep < (37 + 256))
158 | {
159 | gNextTime = millis() + gcAnalogDelta;
160 | testThrottleRudder(gCurrentStep - 37);
161 | }
162 | else if (gCurrentStep < (37 + 256 + 1024 + 128))
163 | {
164 | gNextTime = millis() + gcAnalogDelta;
165 | testXYAxis(gCurrentStep - (37 + 256));
166 | }
167 |
168 | if (testAutoSendMode == false)
169 | {
170 | Joystick.sendState();
171 | }
172 |
173 | gCurrentStep++;
174 | if (gCurrentStep >= (37 + 256 + 1024 + 128))
175 | {
176 | gNextTime = millis() + gcCycleDelta;
177 | gCurrentStep = 0;
178 | }
179 | }
180 | }
181 |
182 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/examples/FunduinoJoystickShield/FunduinoJoystickShield.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | const uint8_t buttonCount = 7;
4 | Joystick_ controller(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, buttonCount,
5 | 0, true, true, false,
6 | false, false, false,
7 | false, false, false,
8 | false, false);
9 |
10 | int const BTN_A_PIN = 2;
11 | int const BTN_B_PIN = 3;
12 | int const BTN_C_PIN = 4;
13 | int const BTN_D_PIN = 5;
14 | int const BTN_E_PIN = 6;
15 | int const BTN_F_PIN = 7;
16 | int const BTN_K_PIN = 8;
17 | int const AXIS_X_PIN = A0;
18 | int const AXIS_Y_PIN = A1;
19 |
20 | int const buttonPins[buttonCount] = {
21 | BTN_A_PIN,
22 | BTN_B_PIN,
23 | BTN_C_PIN,
24 | BTN_D_PIN,
25 | BTN_E_PIN,
26 | BTN_F_PIN,
27 | BTN_K_PIN
28 | };
29 | int lastButtonValue[buttonCount];
30 | int lastXAxisValue = -1;
31 | int lastYAxisValue = -1;
32 |
33 | void setup()
34 | {
35 | controller.setYAxisRange(0, 1023);
36 | controller.setYAxisRange(1023, 0);
37 | controller.begin(false);
38 |
39 | for (int i = 0; i < buttonCount; i++)
40 | {
41 | pinMode(buttonPins[i], INPUT_PULLUP);
42 | lastButtonValue[i] = -1;
43 | }
44 |
45 | pinMode(LED_BUILTIN, OUTPUT);
46 | digitalWrite(LED_BUILTIN, LOW);
47 | }
48 |
49 | void loop()
50 | {
51 | bool sendUpdate = false;
52 | for (int i = 0; i < buttonCount; i++)
53 | {
54 | const int buttonValue = digitalRead(buttonPins[i]);
55 |
56 | if (buttonValue != lastButtonValue[i])
57 | {
58 | controller.setButton(i, !buttonValue);
59 | lastButtonValue[i] = buttonValue;
60 | sendUpdate = true;
61 | }
62 | }
63 |
64 | const int currentXAxisValue = analogRead(AXIS_X_PIN);
65 | if (currentXAxisValue != lastXAxisValue)
66 | {
67 | controller.setXAxis(currentXAxisValue);
68 | lastXAxisValue = currentXAxisValue;
69 | sendUpdate = true;
70 | }
71 |
72 | const int currentYAxisValue = analogRead(AXIS_Y_PIN);
73 | if (currentYAxisValue != lastYAxisValue)
74 | {
75 | controller.setYAxis(currentYAxisValue);
76 | lastYAxisValue = currentYAxisValue;
77 | sendUpdate = true;
78 | }
79 |
80 | if (sendUpdate)
81 | {
82 | controller.sendState();
83 | }
84 | delay(50);
85 | }
86 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/examples/GamepadExample/GamepadExample.ino:
--------------------------------------------------------------------------------
1 | // Simple gamepad example that demonstraits how to read five Arduino
2 | // digital pins and map them to the Arduino Joystick library.
3 | //
4 | // The digital pins 2 - 6 are grounded when they are pressed.
5 | // Pin 2 = UP
6 | // Pin 3 = RIGHT
7 | // Pin 4 = DOWN
8 | // Pin 5 = LEFT
9 | // Pin 6 = FIRE
10 | //
11 | // NOTE: This sketch file is for use with Arduino Leonardo and
12 | // Arduino Micro only.
13 | //
14 | // by Matthew Heironimus
15 | // 2016-11-24
16 | //--------------------------------------------------------------------
17 |
18 | #include
19 |
20 | Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
21 | 1, 0, // Button Count, Hat Switch Count
22 | true, true, false, // X and Y, but no Z Axis
23 | false, false, false, // No Rx, Ry, or Rz
24 | false, false, // No rudder or throttle
25 | false, false, false); // No accelerator, brake, or steering
26 |
27 | void setup() {
28 | // Initialize Button Pins
29 | pinMode(2, INPUT_PULLUP);
30 | pinMode(3, INPUT_PULLUP);
31 | pinMode(4, INPUT_PULLUP);
32 | pinMode(5, INPUT_PULLUP);
33 | pinMode(6, INPUT_PULLUP);
34 |
35 | // Initialize Joystick Library
36 | Joystick.begin();
37 | Joystick.setXAxisRange(-1, 1);
38 | Joystick.setYAxisRange(-1, 1);
39 | }
40 |
41 | // Last state of the buttons
42 | int lastButtonState[5] = {0,0,0,0,0};
43 |
44 | void loop() {
45 |
46 | // Read pin values
47 | for (int index = 0; index < 5; index++)
48 | {
49 | int currentButtonState = !digitalRead(index + 2);
50 | if (currentButtonState != lastButtonState[index])
51 | {
52 | switch (index) {
53 | case 0: // UP
54 | if (currentButtonState == 1) {
55 | Joystick.setYAxis(-1);
56 | } else {
57 | Joystick.setYAxis(0);
58 | }
59 | break;
60 | case 1: // RIGHT
61 | if (currentButtonState == 1) {
62 | Joystick.setXAxis(1);
63 | } else {
64 | Joystick.setXAxis(0);
65 | }
66 | break;
67 | case 2: // DOWN
68 | if (currentButtonState == 1) {
69 | Joystick.setYAxis(1);
70 | } else {
71 | Joystick.setYAxis(0);
72 | }
73 | break;
74 | case 3: // LEFT
75 | if (currentButtonState == 1) {
76 | Joystick.setXAxis(-1);
77 | } else {
78 | Joystick.setXAxis(0);
79 | }
80 | break;
81 | case 4: // FIRE
82 | Joystick.setButton(0, currentButtonState);
83 | break;
84 | }
85 | lastButtonState[index] = currentButtonState;
86 | }
87 | }
88 |
89 | delay(10);
90 | }
91 |
92 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/examples/HatSwitchTest/HatSwitchTest.ino:
--------------------------------------------------------------------------------
1 | // Simple example application that shows how to read four Arduino
2 | // digital pins and map them to the USB Joystick library's hat switch.
3 | //
4 | // The digital pins 4, 5, 6, 7, 8, 9, 10, and 11 are grounded when
5 | // they are pressed.
6 | //
7 | // Pin Mappings:
8 | // 4 - Hat Switch #0 UP
9 | // 5 - Hat Switch #0 RIGHT
10 | // 6 - Hat Switch #0 DOWN
11 | // 7 - Hat Switch #0 LEFT
12 | // 8 - Hat Switch #1 UP
13 | // 9 - Hat Switch #1 RIGHT
14 | // 10 - Hat Switch #1 DOWN
15 | // 11 - Hat Switch #1 LEFT
16 | //
17 | // NOTE: This sketch file is for use with Arduino Leonardo and
18 | // Arduino Micro only.
19 | //
20 | // by Matthew Heironimus
21 | // 2016-05-30
22 | //--------------------------------------------------------------------
23 |
24 | #include
25 |
26 | Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
27 | JOYSTICK_TYPE_GAMEPAD, 0,
28 | JOYSTICK_DEFAULT_HATSWITCH_COUNT,
29 | false, false, false, false, false, false,
30 | false, false, false, false, false);
31 |
32 | void setup() {
33 |
34 | // Initialize Button Pins
35 | for (int index = 4; index < 12; index++)
36 | {
37 | pinMode(index, INPUT_PULLUP);
38 | }
39 |
40 | // Initialize Joystick Library
41 | Joystick.begin();
42 | }
43 |
44 | // Last state of the pins
45 | int lastButtonState[2][4] = {{0,0,0,0}, {0,0,0,0}};
46 |
47 | void loop() {
48 |
49 | bool valueChanged[2] = {false, false};
50 | int currentPin = 4;
51 |
52 | // Read pin values
53 | for (int hatSwitch = 0; hatSwitch < 2; hatSwitch++)
54 | {
55 | for (int index = 0; index < 4; index++)
56 | {
57 | int currentButtonState = !digitalRead(currentPin++);
58 | if (currentButtonState != lastButtonState[hatSwitch][index])
59 | {
60 | valueChanged[hatSwitch] = true;
61 | lastButtonState[hatSwitch][index] = currentButtonState;
62 | }
63 | }
64 | }
65 |
66 | for (int hatSwitch = 0; hatSwitch < 2; hatSwitch++)
67 | {
68 | if (valueChanged[hatSwitch]) {
69 |
70 | if ((lastButtonState[hatSwitch][0] == 0)
71 | && (lastButtonState[hatSwitch][1] == 0)
72 | && (lastButtonState[hatSwitch][2] == 0)
73 | && (lastButtonState[hatSwitch][3] == 0)) {
74 | Joystick.setHatSwitch(hatSwitch, -1);
75 | }
76 | if (lastButtonState[hatSwitch][0] == 1) {
77 | Joystick.setHatSwitch(hatSwitch, 0);
78 | }
79 | if (lastButtonState[hatSwitch][1] == 1) {
80 | Joystick.setHatSwitch(hatSwitch, 90);
81 | }
82 | if (lastButtonState[hatSwitch][2] == 1) {
83 | Joystick.setHatSwitch(hatSwitch, 180);
84 | }
85 | if (lastButtonState[hatSwitch][3] == 1) {
86 | Joystick.setHatSwitch(hatSwitch, 270);
87 | }
88 |
89 | } // if the value changed
90 |
91 | } // for each hat switch
92 |
93 | delay(50);
94 | }
95 |
96 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/examples/JoystickButton/JoystickButton.ino:
--------------------------------------------------------------------------------
1 | // Simple example application that shows how to read four Arduino
2 | // digital pins and map them to the USB Joystick library.
3 | //
4 | // Ground digital pins 9, 10, 11, and 12 to press the joystick
5 | // buttons 0, 1, 2, and 3.
6 | //
7 | // NOTE: This sketch file is for use with Arduino Leonardo and
8 | // Arduino Micro only.
9 | //
10 | // by Matthew Heironimus
11 | // 2015-11-20
12 | //--------------------------------------------------------------------
13 |
14 | #include
15 |
16 | Joystick_ Joystick;
17 |
18 | void setup() {
19 | // Initialize Button Pins
20 | pinMode(9, INPUT_PULLUP);
21 | pinMode(10, INPUT_PULLUP);
22 | pinMode(11, INPUT_PULLUP);
23 | pinMode(12, INPUT_PULLUP);
24 |
25 | // Initialize Joystick Library
26 | Joystick.begin();
27 | }
28 |
29 | // Constant that maps the phyical pin to the joystick button.
30 | const int pinToButtonMap = 9;
31 |
32 | // Last state of the button
33 | int lastButtonState[4] = {0,0,0,0};
34 |
35 | void loop() {
36 |
37 | // Read pin values
38 | for (int index = 0; index < 4; index++)
39 | {
40 | int currentButtonState = !digitalRead(index + pinToButtonMap);
41 | if (currentButtonState != lastButtonState[index])
42 | {
43 | Joystick.setButton(index, currentButtonState);
44 | lastButtonState[index] = currentButtonState;
45 | }
46 | }
47 |
48 | delay(50);
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/examples/JoystickKeyboard/JoystickKeyboard.ino:
--------------------------------------------------------------------------------
1 | // Simple example application that shows how to read four Arduino
2 | // digital pins and map them to buttons on a joystick or keys on a
3 | // keyboard uisng the Arduino Joystick and Keyboard libraries.
4 | //
5 | // The digital pins 9, 10, 11, and 12 are grounded when they are pressed.
6 | //
7 | // NOTE: This sketch file is for use with Arduino Leonardo and
8 | // Arduino Micro only.
9 | //
10 | // Pin 9 = Joystick Button 0
11 | // Pin 10 = Joystick Button 1
12 | // Pin 11 = 1 key on the Keyboard
13 | // Pin 12 = 2 key on the Keyboard
14 | //
15 | // by Matthew Heironimus
16 | // 2016-05-13
17 | //--------------------------------------------------------------------
18 |
19 | #include
20 | #include
21 |
22 | Joystick_ Joystick;
23 |
24 | void setup() {
25 | // Initialize Button Pins
26 | pinMode(9, INPUT_PULLUP);
27 | pinMode(10, INPUT_PULLUP);
28 | pinMode(11, INPUT_PULLUP);
29 | pinMode(12, INPUT_PULLUP);
30 |
31 | // Initialize Joystick Library
32 | Joystick.begin();
33 | }
34 |
35 | // Constant that maps the phyical pin to the joystick button.
36 | const int pinToButtonMap = 9;
37 |
38 | // Last state of the button
39 | int lastButtonState[4] = {0,0,0,0};
40 |
41 | void loop() {
42 |
43 | // Read pin values
44 | for (int index = 0; index < 4; index++)
45 | {
46 | int currentButtonState = !digitalRead(index + pinToButtonMap);
47 | if (currentButtonState != lastButtonState[index])
48 | {
49 | if (index < 2) {
50 | Joystick.setButton(index, currentButtonState);
51 | lastButtonState[index] = currentButtonState;
52 | } else {
53 | if (currentButtonState) {
54 | Keyboard.write(47 + index);
55 | delay(500);
56 | }
57 | }
58 | }
59 | }
60 |
61 | delay(100);
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/examples/JoystickTest/JoystickTest.ino:
--------------------------------------------------------------------------------
1 | // Program used to test the USB Joystick object on the
2 | // Arduino Leonardo or Arduino Micro.
3 | //
4 | // Matthew Heironimus
5 | // 2015-03-28 - Original Version
6 | // 2015-11-18 - Updated to use the new Joystick library
7 | // written for Arduino IDE Version 1.6.6 and
8 | // above.
9 | // 2016-05-13 Updated to use new dynamic Joystick library
10 | // that can be customized.
11 | // 2022-03-29 Updated to work with version 2.1.0 of the
12 | // Joystick library.
13 | //------------------------------------------------------------
14 |
15 | #include "Joystick.h"
16 |
17 | // Create Joystick
18 | Joystick_ Joystick;
19 |
20 | // Set to true to test "Auto Send" mode or false to test "Manual Send" mode.
21 | //const bool testAutoSendMode = true;
22 | const bool testAutoSendMode = false;
23 |
24 | const unsigned long gcCycleDelta = 1000;
25 | const unsigned long gcAnalogDelta = 25;
26 | const unsigned long gcButtonDelta = 500;
27 | unsigned long gNextTime = 0;
28 | unsigned int gCurrentStep = 0;
29 |
30 | void testSingleButtonPush(unsigned int button)
31 | {
32 | if (button > 0)
33 | {
34 | Joystick.releaseButton(button - 1);
35 | }
36 | if (button < 32)
37 | {
38 | Joystick.pressButton(button);
39 | }
40 | }
41 |
42 | void testMultiButtonPush(unsigned int currentStep)
43 | {
44 | for (int button = 0; button < 32; button++)
45 | {
46 | if ((currentStep == 0) || (currentStep == 2))
47 | {
48 | if ((button % 2) == 0)
49 | {
50 | Joystick.pressButton(button);
51 | } else if (currentStep != 2)
52 | {
53 | Joystick.releaseButton(button);
54 | }
55 | } // if ((currentStep == 0) || (currentStep == 2))
56 | if ((currentStep == 1) || (currentStep == 2))
57 | {
58 | if ((button % 2) != 0)
59 | {
60 | Joystick.pressButton(button);
61 | } else if (currentStep != 2)
62 | {
63 | Joystick.releaseButton(button);
64 | }
65 | } // if ((currentStep == 1) || (currentStep == 2))
66 | if (currentStep == 3)
67 | {
68 | Joystick.releaseButton(button);
69 | } // if (currentStep == 3)
70 | } // for (int button = 0; button < 32; button++)
71 | }
72 |
73 | void testXYAxis(unsigned int currentStep)
74 | {
75 | int xAxis;
76 | int yAxis;
77 |
78 | if (currentStep < 256)
79 | {
80 | xAxis = currentStep - 127;
81 | yAxis = -127;
82 | Joystick.setXAxis(xAxis);
83 | Joystick.setYAxis(yAxis);
84 | }
85 | else if (currentStep < 512)
86 | {
87 | yAxis = currentStep - 256 - 127;
88 | Joystick.setYAxis(yAxis);
89 | }
90 | else if (currentStep < 768)
91 | {
92 | xAxis = 128 - (currentStep - 512);
93 | Joystick.setXAxis(xAxis);
94 | }
95 | else if (currentStep < 1024)
96 | {
97 | yAxis = 128 - (currentStep - 768);
98 | Joystick.setYAxis(yAxis);
99 | }
100 | else if (currentStep < 1024 + 128)
101 | {
102 | xAxis = currentStep - 1024 - 127;
103 | Joystick.setXAxis(xAxis);
104 | Joystick.setYAxis(xAxis);
105 | }
106 | }
107 |
108 | void testZAxis(unsigned int currentStep)
109 | {
110 | int z;
111 |
112 | if (currentStep < 128)
113 | {
114 | z = -currentStep;
115 | }
116 | else if (currentStep < 256 + 128)
117 | {
118 | z = currentStep - 128 - 127;
119 | }
120 | else if (currentStep < 256 + 128 + 127)
121 | {
122 | z = 127 - (currentStep - 383);
123 | }
124 |
125 | Joystick.setZAxis(z);
126 | }
127 |
128 | void testHatSwitch(unsigned int currentStep)
129 | {
130 | if (currentStep < 8)
131 | {
132 | Joystick.setHatSwitch(0, currentStep * 45);
133 | }
134 | else if (currentStep == 8)
135 | {
136 | Joystick.setHatSwitch(0, -1);
137 | }
138 | else if (currentStep < 17)
139 | {
140 | Joystick.setHatSwitch(1, (currentStep - 9) * 45);
141 | }
142 | else if (currentStep == 17)
143 | {
144 | Joystick.setHatSwitch(1, -1);
145 | }
146 | else if (currentStep == 18)
147 | {
148 | Joystick.setHatSwitch(0, 0);
149 | Joystick.setHatSwitch(1, 0);
150 | }
151 | else if (currentStep < 27)
152 | {
153 | Joystick.setHatSwitch(0, (currentStep - 18) * 45);
154 | Joystick.setHatSwitch(1, (8 - (currentStep - 18)) * 45);
155 | }
156 | else if (currentStep == 27)
157 | {
158 | Joystick.setHatSwitch(0, -1);
159 | Joystick.setHatSwitch(1, -1);
160 | }
161 | }
162 |
163 | void testThrottleRudder(unsigned int value)
164 | {
165 | Joystick.setThrottle(value);
166 | Joystick.setRudder(value);
167 | }
168 |
169 | void testXYZAxisRotation(unsigned int degree)
170 | {
171 | Joystick.setRxAxis(degree);
172 | Joystick.setRyAxis(degree);
173 | Joystick.setRzAxis(degree * 2);
174 | }
175 |
176 | void setup() {
177 |
178 | // Set Range Values
179 | Joystick.setXAxisRange(-127, 127);
180 | Joystick.setYAxisRange(-127, 127);
181 | Joystick.setZAxisRange(-127, 127);
182 | Joystick.setRxAxisRange(0, 360);
183 | Joystick.setRyAxisRange(360, 0);
184 | Joystick.setRzAxisRange(0, 720);
185 | Joystick.setThrottleRange(0, 255);
186 | Joystick.setRudderRange(255, 0);
187 |
188 | if (testAutoSendMode)
189 | {
190 | Joystick.begin();
191 | }
192 | else
193 | {
194 | Joystick.begin(false);
195 | }
196 |
197 | pinMode(A0, INPUT_PULLUP);
198 | pinMode(LED_BUILTIN, OUTPUT);
199 | }
200 |
201 | void loop() {
202 |
203 | // System Disabled
204 | if (digitalRead(A0) != 0)
205 | {
206 | // Turn indicator light off.
207 | digitalWrite(LED_BUILTIN, 0);
208 | return;
209 | }
210 |
211 | // Turn indicator light on.
212 | digitalWrite(LED_BUILTIN, 1);
213 |
214 | if (millis() >= gNextTime)
215 | {
216 |
217 | if (gCurrentStep < 33)
218 | {
219 | gNextTime = millis() + gcButtonDelta;
220 | testSingleButtonPush(gCurrentStep);
221 | }
222 | else if (gCurrentStep < 37)
223 | {
224 | gNextTime = millis() + gcButtonDelta;
225 | testMultiButtonPush(gCurrentStep - 33);
226 | }
227 | else if (gCurrentStep < (37 + 256))
228 | {
229 | gNextTime = millis() + gcAnalogDelta;
230 | testThrottleRudder(gCurrentStep - 37);
231 | }
232 | else if (gCurrentStep < (37 + 256 + 1024 + 128))
233 | {
234 | gNextTime = millis() + gcAnalogDelta;
235 | testXYAxis(gCurrentStep - (37 + 256));
236 | }
237 | else if (gCurrentStep < (37 + 256 + 1024 + 128 + 510))
238 | {
239 | gNextTime = millis() + gcAnalogDelta;
240 | testZAxis(gCurrentStep - (37 + 256 + 1024 + 128));
241 | }
242 | else if (gCurrentStep < (37 + 256 + 1024 + 128 + 510 + 28))
243 | {
244 | gNextTime = millis() + gcButtonDelta;
245 | testHatSwitch(gCurrentStep - (37 + 256 + 1024 + 128 + 510));
246 | }
247 | else if (gCurrentStep < (37 + 256 + 1024 + 128 + 510 + 28 + 360))
248 | {
249 | gNextTime = millis() + gcAnalogDelta;
250 | testXYZAxisRotation(gCurrentStep - (37 + 256 + 1024 + 128 + 510 + 28));
251 | }
252 |
253 | if (testAutoSendMode == false)
254 | {
255 | Joystick.sendState();
256 | }
257 |
258 | gCurrentStep++;
259 | if (gCurrentStep == (37 + 256 + 1024 + 128 + 510 + 28 + 360))
260 | {
261 | gNextTime = millis() + gcCycleDelta;
262 | gCurrentStep = 0;
263 | }
264 | }
265 | }
266 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/examples/MultipleJoystickTest/MultipleJoystickTest.ino:
--------------------------------------------------------------------------------
1 | // Program used to test using the Arduino Joystick Library
2 | // to create multiple Joystick objects on a single Arduino
3 | // Leonardo or Arduino Micro.
4 | //
5 | // Each joystick has a unique configuration.
6 | //
7 | // Matthew Heironimus
8 | // 2016-05-13 - Original Version
9 | // 2022-03-29 - Updated to work with Joystick Library v2.1.0
10 | //------------------------------------------------------------
11 | #include
12 |
13 | #define JOYSTICK_COUNT 4
14 |
15 | Joystick_ Joystick[JOYSTICK_COUNT] = {
16 | Joystick_(0x03, JOYSTICK_TYPE_JOYSTICK, 4, 2, true, true, false, false, false, false, false, false, false, false, false),
17 | Joystick_(0x04, JOYSTICK_TYPE_JOYSTICK, 8, 1, true, true, true, true, false, false, false, false, false, false, false),
18 | Joystick_(0x05, JOYSTICK_TYPE_JOYSTICK, 16, 0, false, true, false, true, false, false, true, true, false, false, false),
19 | Joystick_(0x06, JOYSTICK_TYPE_JOYSTICK, 32, 1, true, true, false, true, true, false, false, false, false, false, false)
20 | };
21 |
22 | // Set to true to test "Auto Send" mode or false to test "Manual Send" mode.
23 | //const bool testAutoSendMode = true;
24 | const bool testAutoSendMode = false;
25 |
26 | const unsigned long gcCycleDelta = 1000;
27 | const unsigned long gcAnalogDelta = 25;
28 | const unsigned long gcButtonDelta = 500;
29 | unsigned long gNextTime = 0;
30 | unsigned int gCurrentStep = 0;
31 | int gJoystickId = 0;
32 |
33 | void testSingleButtonPush(int joystickId, unsigned int button)
34 | {
35 | if (button > 0)
36 | {
37 | Joystick[joystickId].releaseButton(button - 1);
38 | }
39 | if (button < 16)
40 | {
41 | Joystick[joystickId].pressButton(button);
42 | }
43 | }
44 |
45 | void testMultiButtonPush(int joystickId, unsigned int currentStep)
46 | {
47 | for (int button = 0; button < 16; button++)
48 | {
49 | if ((currentStep == 0) || (currentStep == 2))
50 | {
51 | if ((button % 2) == 0)
52 | {
53 | Joystick[joystickId].pressButton(button);
54 | } else if (currentStep != 2)
55 | {
56 | Joystick[joystickId].releaseButton(button);
57 | }
58 | } // if ((currentStep == 0) || (currentStep == 2))
59 | if ((currentStep == 1) || (currentStep == 2))
60 | {
61 | if ((button % 2) != 0)
62 | {
63 | Joystick[joystickId].pressButton(button);
64 | } else if (currentStep != 2)
65 | {
66 | Joystick[joystickId].releaseButton(button);
67 | }
68 | } // if ((currentStep == 1) || (currentStep == 2))
69 | if (currentStep == 3)
70 | {
71 | Joystick[joystickId].releaseButton(button);
72 | } // if (currentStep == 3)
73 | } // for (int button = 0; button < 32; button++)
74 | }
75 |
76 | void testXYAxis(int joystickId, unsigned int currentStep)
77 | {
78 | int x;
79 | int y;
80 |
81 | if (currentStep < 255)
82 | {
83 | x = currentStep - 127;
84 | y = -127;
85 | }
86 | else if (currentStep < 510)
87 | {
88 | x = 127;
89 | y = currentStep - 255 - 127;
90 | }
91 | else if (currentStep < 765)
92 | {
93 | x = 127 - (currentStep - 510);
94 | y = 127;
95 | }
96 | else if (currentStep < 1020)
97 | {
98 | x = -127;
99 | y = 127 - (currentStep - 765);
100 | }
101 | else if (currentStep <= 1020 + 127)
102 | {
103 | x = currentStep - 1020 - 127;
104 | y = currentStep - 1020 - 127;
105 | }
106 |
107 | Joystick[joystickId].setXAxis(x);
108 | Joystick[joystickId].setYAxis(y);
109 | }
110 |
111 | void setup() {
112 |
113 | for (int index = 0; index < JOYSTICK_COUNT; index++)
114 | {
115 | Joystick[index].setXAxisRange(-127, 127);
116 | Joystick[index].setYAxisRange(-127, 127);
117 |
118 | if (testAutoSendMode)
119 | {
120 | Joystick[index].begin();
121 | }
122 | else
123 | {
124 | Joystick[index].begin(false);
125 | }
126 | }
127 |
128 | pinMode(A0, INPUT_PULLUP);
129 | pinMode(LED_BUILTIN, OUTPUT);
130 | }
131 |
132 | void loop() {
133 |
134 | // System Disabled
135 | if (digitalRead(A0) != 0)
136 | {
137 | digitalWrite(LED_BUILTIN, 0);
138 | return;
139 | }
140 |
141 | // Turn indicator light on.
142 | digitalWrite(LED_BUILTIN, 1);
143 |
144 | if (millis() >= gNextTime)
145 | {
146 |
147 | if (gCurrentStep < 17)
148 | {
149 | gNextTime = millis() + gcButtonDelta;
150 | testSingleButtonPush(gJoystickId, gCurrentStep);
151 | }
152 | else if (gCurrentStep < (17 + 4))
153 | {
154 | gNextTime = millis() + gcButtonDelta;
155 | testMultiButtonPush(gJoystickId, gCurrentStep - 17);
156 | }
157 | else if (gCurrentStep < (17 + 4 + 1024 + 128))
158 | {
159 | gNextTime = millis() + gcAnalogDelta;
160 | testXYAxis(gJoystickId, gCurrentStep - (17 + 4));
161 | }
162 |
163 | if (testAutoSendMode == false)
164 | {
165 | Joystick[gJoystickId].sendState();
166 | }
167 |
168 | gCurrentStep++;
169 | if (gCurrentStep == (17 + 4 + 1024 + 128))
170 | {
171 | gNextTime = millis() + gcCycleDelta;
172 | gCurrentStep = 0;
173 |
174 | if (++gJoystickId >= JOYSTICK_COUNT)
175 | {
176 | gJoystickId = 0;
177 | }
178 | }
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/library.properties:
--------------------------------------------------------------------------------
1 | name=Joystick
2 | version=2.1.1
3 | author=Matthew Heironimus
4 | maintainer=Matthew Heironimus
5 | sentence=Allows an Arduino board with USB capabilities (e.g. Leonardo, Arduino Micro, Arudino Due, etc.) to appear as a Joystick or Gamepad.
6 | paragraph=This library is built on the PluggableUSB library. It can be used with or without other HID-based libraries (Mouse, Keyboard, etc.).
7 | category=Device Control
8 | url=https://github.com/MHeironimus/ArduinoJoystickLibrary
9 | architectures=avr,sam
10 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/src/DynamicHID/DynamicHID.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Modified by Matthew Heironimus to support HID Report Descriptors to be in
3 | standard RAM in addition to program memory (PROGMEM).
4 |
5 | Copyright (c) 2015, Arduino LLC
6 | Original code (pre-library): Copyright (c) 2011, Peter Barrett
7 |
8 | Permission to use, copy, modify, and/or distribute this software for
9 | any purpose with or without fee is hereby granted, provided that the
10 | above copyright notice and this permission notice appear in all copies.
11 |
12 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 | WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
15 | BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
16 | OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
17 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
18 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
19 | SOFTWARE.
20 | */
21 |
22 | #include "DynamicHID.h"
23 |
24 | #if defined(USBCON)
25 |
26 | #ifdef _VARIANT_ARDUINO_DUE_X_
27 | #define USB_SendControl USBD_SendControl
28 | #define USB_Send USBD_Send
29 | #endif
30 |
31 | DynamicHID_& DynamicHID()
32 | {
33 | static DynamicHID_ obj;
34 | return obj;
35 | }
36 |
37 | int DynamicHID_::getInterface(uint8_t* interfaceCount)
38 | {
39 | *interfaceCount += 1; // uses 1
40 | DYNAMIC_HIDDescriptor hidInterface = {
41 | D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, DYNAMIC_HID_SUBCLASS_NONE, DYNAMIC_HID_PROTOCOL_NONE),
42 | D_HIDREPORT(descriptorSize),
43 | D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01)
44 | };
45 | return USB_SendControl(0, &hidInterface, sizeof(hidInterface));
46 | }
47 |
48 | int DynamicHID_::getDescriptor(USBSetup& setup)
49 | {
50 | // Check if this is a HID Class Descriptor request
51 | if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; }
52 | if (setup.wValueH != DYNAMIC_HID_REPORT_DESCRIPTOR_TYPE) { return 0; }
53 |
54 | // In a HID Class Descriptor wIndex cointains the interface number
55 | if (setup.wIndex != pluggedInterface) { return 0; }
56 |
57 | int total = 0;
58 | DynamicHIDSubDescriptor* node;
59 | for (node = rootNode; node; node = node->next) {
60 | int res = USB_SendControl((node->inProgMem ? TRANSFER_PGM : 0), node->data, node->length);
61 | if (res == -1)
62 | return -1;
63 | total += res;
64 | }
65 |
66 | // Reset the protocol on reenumeration. Normally the host should not assume the state of the protocol
67 | // due to the USB specs, but Windows and Linux just assumes its in report mode.
68 | protocol = DYNAMIC_HID_REPORT_PROTOCOL;
69 |
70 | return total;
71 | }
72 |
73 | uint8_t DynamicHID_::getShortName(char *name)
74 | {
75 | name[0] = 'H';
76 | name[1] = 'I';
77 | name[2] = 'D';
78 | name[3] = 'A' + (descriptorSize & 0x0F);
79 | name[4] = 'A' + ((descriptorSize >> 4) & 0x0F);
80 | return 5;
81 | }
82 |
83 | void DynamicHID_::AppendDescriptor(DynamicHIDSubDescriptor *node)
84 | {
85 | if (!rootNode) {
86 | rootNode = node;
87 | } else {
88 | DynamicHIDSubDescriptor *current = rootNode;
89 | while (current->next) {
90 | current = current->next;
91 | }
92 | current->next = node;
93 | }
94 | descriptorSize += node->length;
95 | }
96 |
97 | int DynamicHID_::SendReport(uint8_t id, const void* data, int len)
98 | {
99 | uint8_t p[len + 1];
100 | p[0] = id;
101 | memcpy(&p[1], data, len);
102 | return USB_Send(pluggedEndpoint | TRANSFER_RELEASE, p, len + 1);
103 | }
104 |
105 | bool DynamicHID_::setup(USBSetup& setup)
106 | {
107 | if (pluggedInterface != setup.wIndex) {
108 | return false;
109 | }
110 |
111 | uint8_t request = setup.bRequest;
112 | uint8_t requestType = setup.bmRequestType;
113 |
114 | if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
115 | {
116 | if (request == DYNAMIC_HID_GET_REPORT) {
117 | // TODO: DYNAMIC_HID_GetReport();
118 | return true;
119 | }
120 | if (request == DYNAMIC_HID_GET_PROTOCOL) {
121 | // TODO: Send8(protocol);
122 | return true;
123 | }
124 | if (request == DYNAMIC_HID_GET_IDLE) {
125 | // TODO: Send8(idle);
126 | }
127 | }
128 |
129 | if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
130 | {
131 | if (request == DYNAMIC_HID_SET_PROTOCOL) {
132 | // The USB Host tells us if we are in boot or report mode.
133 | // This only works with a real boot compatible device.
134 | protocol = setup.wValueL;
135 | return true;
136 | }
137 | if (request == DYNAMIC_HID_SET_IDLE) {
138 | idle = setup.wValueL;
139 | return true;
140 | }
141 | if (request == DYNAMIC_HID_SET_REPORT)
142 | {
143 | //uint8_t reportID = setup.wValueL;
144 | //uint16_t length = setup.wLength;
145 | //uint8_t data[length];
146 | // Make sure to not read more data than USB_EP_SIZE.
147 | // You can read multiple times through a loop.
148 | // The first byte (may!) contain the reportID on a multreport.
149 | //USB_RecvControl(data, length);
150 | }
151 | }
152 |
153 | return false;
154 | }
155 |
156 | DynamicHID_::DynamicHID_(void) : PluggableUSBModule(1, 1, epType),
157 | rootNode(NULL), descriptorSize(0),
158 | protocol(DYNAMIC_HID_REPORT_PROTOCOL), idle(1)
159 | {
160 | epType[0] = EP_TYPE_INTERRUPT_IN;
161 | PluggableUSB().plug(this);
162 | }
163 |
164 | int DynamicHID_::begin(void)
165 | {
166 | return 0;
167 | }
168 |
169 | #endif /* if defined(USBCON) */
170 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/ArduinoJoystickLibrary/src/DynamicHID/DynamicHID.h:
--------------------------------------------------------------------------------
1 | /*
2 | Modified by Matthew Heironimus to support HID Report Descriptors to be in
3 | standard RAM in addition to program memory (PROGMEM).
4 |
5 | Copyright (c) 2015, Arduino LLC
6 | Original code (pre-library): Copyright (c) 2011, Peter Barrett
7 |
8 | Permission to use, copy, modify, and/or distribute this software for
9 | any purpose with or without fee is hereby granted, provided that the
10 | above copyright notice and this permission notice appear in all copies.
11 |
12 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 | WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
15 | BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
16 | OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
17 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
18 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
19 | SOFTWARE.
20 | */
21 |
22 | #ifndef DYNAMIC_HID_h
23 | #define DYNAMIC_HID_h
24 |
25 | #include
26 | #include
27 |
28 | #ifdef _VARIANT_ARDUINO_DUE_X_
29 | // The following values are the same as AVR's USBAPI.h
30 | // Reproduced here because SAM doesn't have these in
31 | // its own USBAPI.H
32 | #define USB_EP_SIZE 64
33 | #define TRANSFER_PGM 0x80
34 |
35 | #include "USB/PluggableUSB.h"
36 | #else
37 | #include "PluggableUSB.h"
38 | #endif
39 |
40 | #if defined(USBCON)
41 |
42 | #define _USING_DYNAMIC_HID
43 |
44 | // DYNAMIC_HID 'Driver'
45 | // ------------
46 | #define DYNAMIC_HID_GET_REPORT 0x01
47 | #define DYNAMIC_HID_GET_IDLE 0x02
48 | #define DYNAMIC_HID_GET_PROTOCOL 0x03
49 | #define DYNAMIC_HID_SET_REPORT 0x09
50 | #define DYNAMIC_HID_SET_IDLE 0x0A
51 | #define DYNAMIC_HID_SET_PROTOCOL 0x0B
52 |
53 | #define DYNAMIC_HID_DESCRIPTOR_TYPE 0x21
54 | #define DYNAMIC_HID_REPORT_DESCRIPTOR_TYPE 0x22
55 | #define DYNAMIC_HID_PHYSICAL_DESCRIPTOR_TYPE 0x23
56 |
57 | // HID subclass HID1.11 Page 8 4.2 Subclass
58 | #define DYNAMIC_HID_SUBCLASS_NONE 0
59 | #define DYNAMIC_HID_SUBCLASS_BOOT_INTERFACE 1
60 |
61 | // HID Keyboard/Mouse bios compatible protocols HID1.11 Page 9 4.3 Protocols
62 | #define DYNAMIC_HID_PROTOCOL_NONE 0
63 | #define DYNAMIC_HID_PROTOCOL_KEYBOARD 1
64 | #define DYNAMIC_HID_PROTOCOL_MOUSE 2
65 |
66 | // Normal or bios protocol (Keyboard/Mouse) HID1.11 Page 54 7.2.5 Get_Protocol Request
67 | // "protocol" variable is used for this purpose.
68 | #define DYNAMIC_HID_BOOT_PROTOCOL 0
69 | #define DYNAMIC_HID_REPORT_PROTOCOL 1
70 |
71 | // HID Request Type HID1.11 Page 51 7.2.1 Get_Report Request
72 | #define DYNAMIC_HID_REPORT_TYPE_INPUT 1
73 | #define DYNAMIC_HID_REPORT_TYPE_OUTPUT 2
74 | #define DYNAMIC_HID_REPORT_TYPE_FEATURE 3
75 |
76 | typedef struct
77 | {
78 | uint8_t len; // 9
79 | uint8_t dtype; // 0x21
80 | uint8_t addr;
81 | uint8_t versionL; // 0x101
82 | uint8_t versionH; // 0x101
83 | uint8_t country;
84 | uint8_t desctype; // 0x22 report
85 | uint8_t descLenL;
86 | uint8_t descLenH;
87 | } DYNAMIC_HIDDescDescriptor;
88 |
89 | typedef struct
90 | {
91 | InterfaceDescriptor hid;
92 | DYNAMIC_HIDDescDescriptor desc;
93 | EndpointDescriptor in;
94 | } DYNAMIC_HIDDescriptor;
95 |
96 | class DynamicHIDSubDescriptor {
97 | public:
98 | DynamicHIDSubDescriptor *next = NULL;
99 | DynamicHIDSubDescriptor(const void *d, const uint16_t l, const bool ipm = true) : data(d), length(l), inProgMem(ipm) { }
100 |
101 | const void* data;
102 | const uint16_t length;
103 | const bool inProgMem;
104 | };
105 |
106 | class DynamicHID_ : public PluggableUSBModule
107 | {
108 | public:
109 | DynamicHID_(void);
110 | int begin(void);
111 | int SendReport(uint8_t id, const void* data, int len);
112 | void AppendDescriptor(DynamicHIDSubDescriptor* node);
113 |
114 | protected:
115 | // Implementation of the PluggableUSBModule
116 | int getInterface(uint8_t* interfaceCount);
117 | int getDescriptor(USBSetup& setup);
118 | bool setup(USBSetup& setup);
119 | uint8_t getShortName(char* name);
120 |
121 | private:
122 | #ifdef _VARIANT_ARDUINO_DUE_X_
123 | uint32_t epType[1];
124 | #else
125 | uint8_t epType[1];
126 | #endif
127 |
128 | DynamicHIDSubDescriptor* rootNode;
129 | uint16_t descriptorSize;
130 |
131 | uint8_t protocol;
132 | uint8_t idle;
133 | };
134 |
135 | // Replacement for global singleton.
136 | // This function prevents static-initialization-order-fiasco
137 | // https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
138 | DynamicHID_& DynamicHID();
139 |
140 | #define D_HIDREPORT(length) { 9, 0x21, 0x01, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) }
141 |
142 | #endif // USBCON
143 |
144 | #endif // DYNAMIC_HID_h
145 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/photo_2023-03-30_04-58-32.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/sbus-to-usb-joystick/photo_2023-03-30_04-58-32.jpg
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/readme.md:
--------------------------------------------------------------------------------
1 | ## USB-джойстик из обычной радиоапппаратуры с приемником SBUS на arduino pro micro
2 |
3 | 
4 |
5 | Сигнал SBUS от приемника подключать на rx, нужен неинвертированный. Если у вас "обычный" инвертированный, вам придется использовать транзистор для инверсии.
6 |
7 | 
8 |
9 | Я использую "цифровые" транзисторы dtc144eka или bcr533 и не ставлю резистор в базу. В качестве передатчика и приемника sbus я использую qczek, вы можете использовать любой приемник.
10 | Его задача - передать значения каналов от аппаратуры до USB регистратора через [arduino](https://docs.arduino.cc/hardware/micro) на 32u4 ([ali](https://aliexpress.ru/item/1005003622414316.html)), которая определяется как hid-usb-joystick. При этом немного вырастает задержка за счет дополнительного
11 | процесса по приему и передаче значений, но вы не привязаны к регистратору проводом, что удобно.
12 |
13 | Скетч, доработанная под 10 каналов осей библиотека джойстика (остальные каналы заполняются кнопками), [тут](https://github.com/OpenIPC/sandbox-fpv/tree/master/sbus-to-usb-joystick).
14 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/sbus-inverter-diagram-schematics.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/sbus-to-usb-joystick/sbus-inverter-diagram-schematics.jpg
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/sbus-to-usb-joystick.ino:
--------------------------------------------------------------------------------
1 | #include "sbus.h"
2 | #include
3 |
4 | //#define SERIAL_DEBUG
5 |
6 | //Joystic settings
7 | Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_JOYSTICK,
8 | 32, 2, // Button Count, Hat Switch Count
9 | true, true, true, // X and Y, Z Axis
10 | true, true, true, // Rx, Ry, Rz
11 | true, true, true, true, // slider, dial, rudder and throttle
12 | false, false, false); // accelerator, brake, and steering
13 |
14 | bfs::SbusRx sbus_rx(&Serial1);
15 | bfs::SbusData data;
16 |
17 | void setup() {
18 | #ifdef SERIAL_DEBUG
19 | Serial.begin(115200);
20 | while (!Serial) {}
21 | Serial.println("Started");
22 | #else
23 | Joystick.begin();
24 | //range
25 | Joystick.setXAxisRange(0, 2000);
26 | Joystick.setYAxisRange(0, 2000);
27 | Joystick.setZAxisRange(0, 2000);
28 | Joystick.setRxAxisRange(0, 2000);
29 | Joystick.setRyAxisRange(0, 2000);
30 | Joystick.setRzAxisRange(0, 2000);
31 | Joystick.setSliderRange(0, 2000);
32 | Joystick.setDialRange(0, 2000);
33 | Joystick.setRudderRange(0, 2000);
34 | Joystick.setThrottleRange(0, 2000);
35 | //default
36 | //Joystick.setRudder(1500);
37 | //Joystick.setAccelerator(0);
38 | //Joystick.setBrake(1500);
39 | //Joystick.setSteering(1500);
40 | #endif
41 | sbus_rx.Begin();
42 | }
43 |
44 | void loop() {
45 | if (sbus_rx.Read()) {
46 | data = sbus_rx.data();
47 |
48 | #ifdef SERIAL_DEBUG
49 | for (int8_t i = 0; i < data.NUM_CH; i++) {
50 | Serial.print(data.ch[i]);
51 | Serial.print("\t");
52 | }
53 | Serial.println();
54 | #else
55 | Joystick.setXAxis (data.ch[0]);
56 | Joystick.setYAxis (data.ch[1]);
57 | Joystick.setZAxis (data.ch[2]);
58 | Joystick.setRxAxis (data.ch[3]);
59 | Joystick.setRyAxis (data.ch[4]);
60 | Joystick.setRzAxis (data.ch[5]);
61 | Joystick.setSlider (data.ch[6]);
62 | Joystick.setRudder (data.ch[7]);
63 | Joystick.setThrottle (data.ch[8]);
64 | Joystick.setDial (data.ch[9]);
65 | if(data.ch[10] > 1490) Joystick.setButton(0, 255); else Joystick.setButton(0, 0);
66 | if(data.ch[11] > 1490) Joystick.setButton(1, 255); else Joystick.setButton(1, 0);
67 | if(data.ch[12] > 1490) Joystick.setButton(2, 255); else Joystick.setButton(2, 0);
68 | if(data.ch[13] > 1490) Joystick.setButton(3, 255); else Joystick.setButton(3, 0);
69 | if(data.ch[14] > 1490) Joystick.setButton(4, 255); else Joystick.setButton(4, 0);
70 | Joystick.sendState();
71 | #endif
72 | } //sbus_rx.Read
73 | }
74 |
--------------------------------------------------------------------------------
/sbus-to-usb-joystick/sbus.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Brian R Taylor
3 | * brian.taylor@bolderflight.com
4 | *
5 | * Copyright (c) 2022 Bolder Flight Systems Inc
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the “Software”), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef SRC_SBUS_H_
27 | #define SRC_SBUS_H_
28 |
29 | #if defined(ARDUINO)
30 | #include
31 | #else
32 | #include
33 | #include
34 | #include "core/core.h"
35 | #endif
36 |
37 | namespace bfs {
38 |
39 | struct SbusData {
40 | bool lost_frame;
41 | bool failsafe;
42 | bool ch17, ch18;
43 | static constexpr int8_t NUM_CH = 16;
44 | int16_t ch[NUM_CH];
45 | };
46 |
47 | class SbusRx {
48 | public:
49 | #if defined(ESP32)
50 | SbusRx(HardwareSerial *bus, const int8_t rxpin, const int8_t txpin,
51 | const bool inv) : uart_(bus), inv_(inv), rxpin_(rxpin), txpin_(txpin)
52 | {}
53 | SbusRx(HardwareSerial *bus, const int8_t rxpin, const int8_t txpin,
54 | const bool inv, const bool fast) : uart_(bus), inv_(inv), fast_(fast),
55 | rxpin_(rxpin), txpin_(txpin) {}
56 | #else
57 | explicit SbusRx(HardwareSerial *bus) : uart_(bus) {}
58 | SbusRx(HardwareSerial *bus, const bool inv) : uart_(bus), inv_(inv) {}
59 | SbusRx(HardwareSerial *bus, const bool inv, const bool fast) : uart_(bus),
60 | inv_(inv),
61 | fast_(fast) {}
62 | #endif
63 | void Begin();
64 | bool Read();
65 | inline SbusData data() const {return data_;}
66 |
67 | private:
68 | /* Communication */
69 | HardwareSerial *uart_;
70 | bool inv_ = true;
71 | bool fast_ = false;
72 | #if defined(ESP32)
73 | int8_t rxpin_, txpin_;
74 | #endif
75 | int32_t baud_ = 100000;
76 | /* Message len */
77 | static constexpr int8_t PAYLOAD_LEN_ = 23;
78 | static constexpr int8_t HEADER_LEN_ = 1;
79 | static constexpr int8_t FOOTER_LEN_ = 1;
80 | /* SBUS message defs */
81 | static constexpr int8_t NUM_SBUS_CH_ = 16;
82 | static constexpr uint8_t HEADER_ = 0x0F;
83 | static constexpr uint8_t FOOTER_ = 0x00;
84 | static constexpr uint8_t FOOTER2_ = 0x04;
85 | static constexpr uint8_t CH17_MASK_ = 0x01;
86 | static constexpr uint8_t CH18_MASK_ = 0x02;
87 | static constexpr uint8_t LOST_FRAME_MASK_ = 0x04;
88 | static constexpr uint8_t FAILSAFE_MASK_ = 0x08;
89 | /* Parsing state tracking */
90 | int8_t state_ = 0;
91 | uint8_t prev_byte_ = FOOTER_;
92 | uint8_t cur_byte_;
93 | /* Buffer for storing messages */
94 | uint8_t buf_[25];
95 | /* Data */
96 | bool new_data_;
97 | SbusData data_;
98 | bool Parse();
99 | };
100 |
101 | class SbusTx {
102 | public:
103 | #if defined(ESP32)
104 | SbusTx(HardwareSerial *bus, const int8_t rxpin, const int8_t txpin,
105 | const bool inv) : uart_(bus), inv_(inv), rxpin_(rxpin), txpin_(txpin)
106 | {}
107 | SbusTx(HardwareSerial *bus, const int8_t rxpin, const int8_t txpin,
108 | const bool inv, const bool fast) : uart_(bus), inv_(inv), fast_(fast),
109 | rxpin_(rxpin), txpin_(txpin) {}
110 | #else
111 | explicit SbusTx(HardwareSerial *bus) : uart_(bus) {}
112 | SbusTx(HardwareSerial *bus, const bool inv) : uart_(bus), inv_(inv) {}
113 | SbusTx(HardwareSerial *bus, const bool inv, const bool fast) : uart_(bus),
114 | inv_(inv),
115 | fast_(fast) {}
116 | #endif
117 | void Begin();
118 | void Write();
119 | inline void data(const SbusData &data) {data_ = data;}
120 | inline SbusData data() const {return data_;}
121 |
122 | private:
123 | /* Communication */
124 | HardwareSerial *uart_;
125 | bool inv_ = true;
126 | bool fast_ = false;
127 | #if defined(ESP32)
128 | int8_t rxpin_, txpin_;
129 | #endif
130 | int32_t baud_ = 100000;
131 | /* Message len */
132 | static constexpr int8_t BUF_LEN_ = 25;
133 | /* SBUS message defs */
134 | static constexpr int8_t NUM_SBUS_CH_ = 16;
135 | static constexpr uint8_t HEADER_ = 0x0F;
136 | static constexpr uint8_t FOOTER_ = 0x00;
137 | static constexpr uint8_t FOOTER2_ = 0x04;
138 | static constexpr uint8_t CH17_MASK_ = 0x01;
139 | static constexpr uint8_t CH18_MASK_ = 0x02;
140 | static constexpr uint8_t LOST_FRAME_MASK_ = 0x04;
141 | static constexpr uint8_t FAILSAFE_MASK_ = 0x08;
142 | /* Data */
143 | uint8_t buf_[BUF_LEN_];
144 | SbusData data_;
145 | };
146 |
147 | } // namespace bfs
148 |
149 | #endif // SRC_SBUS_H_
150 |
--------------------------------------------------------------------------------
/sigmastar/.dot:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/sigmastar/ssc338q-nand.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/sigmastar/ssc338q-nand.bin
--------------------------------------------------------------------------------
/sigmastar/ssc338q_initramfs.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/sigmastar/ssc338q_initramfs.zip
--------------------------------------------------------------------------------
/usb-eth-modem.md:
--------------------------------------------------------------------------------
1 | ## Подключение планшета или телефона по usb-ethernet устройству.
2 |
3 | Устройство являет собой сетевую карту, подключаемую по usb к планшету, и выглядит примерно так:
4 |
5 | 
6 |
7 | Оно подключается к регистратору посредством ethernet-кабеля, после чего в [`/etc/wfb.conf`](hi3536dv100/etc/wfb.conf) указывается `udp_addr=auto` взамен фиксированного адреса. На самом планшете нужно включить функцию "Ethernet-modem"
8 | в настройках "Сеть и интернет > Точка доступа и модем".
9 |
10 | Далее все сделают сервисы [`/usr/bin/wifibroadcast`](hi3536dv100/usr/bin/wifibroadcast) и [`/usr/bin/telemetry`](hi3536dv100/usr/bin/telemetry) при загрузке регистратора или перезапуске с [front-panel](nvr_gpio.md).
11 |
--------------------------------------------------------------------------------
/usb-modeswitch.md:
--------------------------------------------------------------------------------
1 | ### Установка usb_modeswitch на камеру с прошивкой fpv, lite и NVR hi3536[ed]v100
2 |
3 | Проверяем с модемом e3372h.
4 |
5 | Камера:
6 | ```
7 | curl -o /usr/sbin/usb_modeswitch http://fpv.openipc.net/files/usb-modeswitch/musl/usb_modeswitch && chmod +x /usr/sbin/usb_modeswitch
8 | curl -o /usr/lib/libusb-1.0.so.0.3.0 http://fpv.openipc.net/files/usb-modeswitch/musl/libusb-1.0.so.0.3.0 && chmod +x /usr/lib/libusb-1.0.so.0.3.0
9 | ln -s -f /usr/lib/libusb-1.0.so.0.3.0 /usr/lib/libusb-1.0.so
10 | ln -s -f /usr/lib/libusb-1.0.so.0.3.0 /usr/lib/libusb-1.0.so.0
11 | ```
12 | NVR:
13 | ```
14 | ntpd -Nnq
15 | curl -k -L -o /usr/sbin/usb_modeswitch https://github.com/OpenIPC/sandbox-fpv/raw/master/usb-modeswitch/musl/usb_modeswitch && chmod +x /usr/sbin/usb_modeswitch
16 | curl -k -L -o /usr/lib/libusb-1.0.so.0.3.0 https://github.com/OpenIPC/sandbox-fpv/raw/master/usb-modeswitch/musl/libusb-1.0.so.0.3.0 && chmod +x /usr/lib/libusb-1.0.so.0.3.0
17 | ln -s -f /usr/lib/libusb-1.0.so.0.3.0 /usr/lib/libusb-1.0.so
18 | ln -s -f /usr/lib/libusb-1.0.so.0.3.0 /usr/lib/libusb-1.0.so.0
19 | ln -s -f /lib/libc-2.32.so /lib/libc.so
20 | ```
21 |
22 |
23 |
24 | альтернативное хранилище
25 |
26 | ```
27 |
28 | curl -o /usr/sbin/usb_modeswitch http://fpv.openipc.net/files/usb-modeswitch/glibc/usb_modeswitch && chmod +x /usr/sbin/usb_modeswitch
29 | curl -o /usr/lib/libusb-1.0.so.0.3.0 http://fpv.openipc.net/files/usb-modeswitch/glibc/libusb-1.0.so.0.3.0 && chmod +x /usr/lib/libusb-1.0.so.0.3.0
30 | ln -s -f /usr/lib/libusb-1.0.so.0.3.0 /usr/lib/libusb-1.0.so
31 | ln -s -f /usr/lib/libusb-1.0.so.0.3.0 /usr/lib/libusb-1.0.so.0
32 | ln -s -f /lib/libc-2.32.so /lib/libc.so
33 | ```
34 |
35 |
36 |
37 |
38 | Вносим этот текст для e3372h в файл `/etc/network/interfaces.d/eth1` (создадим файл если отсутствует):
39 | ```
40 | auto eth1
41 | iface eth1 inet dhcp
42 | pre-up sleep 4
43 | pre-up if [ ! -z "`lsusb | grep 12d1:1f01`" ]; then usb_modeswitch -v 0x12d1 -p 0x1f01 -J; fi
44 | pre-up if [ ! -z "`lsusb | grep 12d1:14dc`" ]; then modprobe usbserial vendor=0x12d1 product=0x14dc; fi
45 | pre-up modprobe rndis_host
46 | pre-up sleep 2
47 | ```
48 |
49 | Передергиваем модем, пробуем `ifup eth1` или перезагружаем. Если сетевая поднялась (есть eth1 в `ip a`), в interfaces можем manual заменить на auto.
50 |
51 | #### Проблемы
52 | Если usb_modeswitch произвел переключение модема в cdc_ethernet, то при перезагрузке системы например через reboot интерфейс не поднимается - ошибка ip: SIOCGIFFLAGS: No such device. Поэтому если нужно полностью перегрузить систему чтобы модем заработал, нужно рвать питание модема перед перезагрузкой.
53 |
54 | ### Результат
55 | Модем e3372h с прошивкой hilink должен отобразиться сетевым интерфейсом eth1 и при вставленной работоспособной sim-карте раздавать интернет на камеру:
56 | ```
57 | Trying to send message 1 to endpoint 0x01 ...
58 | OK, message successfully sent
59 | Read the response to message 1 (CSW) ...
60 | Device seems to have vanished after reading. Good.
61 | Device is gone, skip any further commands
62 | -> Run lsusb to note any changes. Bye!
63 |
64 | udhcpc: started, v1.36.0
65 | udhcpc: broadcasting discover
66 | udhcpc: broadcasting discover
67 | udhcpc: broadcasting discover
68 | udhcpc: broadcasting discover
69 | udhcpc: broadcasting select for 192.168.8.100, server 192.168.8.1
70 | udhcpc: lease of 192.168.8.100 obtained from 192.168.8.1, lease time 86400
71 | deleting routers
72 | adding dns 192.168.8.1
73 | adding dns 192.168.8.1
74 | OK
75 | ```
76 | ifconfig:
77 | ```
78 | eth1 Link encap:Ethernet HWaddr 0C:5B:8F:27:9A:64
79 | inet addr:192.168.8.100 Bcast:192.168.8.255 Mask:255.255.255.0
80 | inet6 addr: fe80::e5b:8fff:fe27:9a64/64 Scope:Link
81 | UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
82 | RX packets:34 errors:0 dropped:0 overruns:0 frame:0
83 | TX packets:806 errors:0 dropped:0 overruns:0 carrier:0
84 | collisions:0 txqueuelen:1000
85 | RX bytes:4557 (4.4 KiB) TX bytes:822513 (803.2 KiB)
86 |
87 | ```
88 |
--------------------------------------------------------------------------------
/usb-modeswitch/glibc/libusb-1.0.so.0.3.0:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/usb-modeswitch/glibc/libusb-1.0.so.0.3.0
--------------------------------------------------------------------------------
/usb-modeswitch/glibc/usb_modeswitch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/usb-modeswitch/glibc/usb_modeswitch
--------------------------------------------------------------------------------
/usb-modeswitch/musl/libusb-1.0.so.0.3.0:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/usb-modeswitch/musl/libusb-1.0.so.0.3.0
--------------------------------------------------------------------------------
/usb-modeswitch/musl/usb_modeswitch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/usb-modeswitch/musl/usb_modeswitch
--------------------------------------------------------------------------------
/usb-tethering.md:
--------------------------------------------------------------------------------
1 | ## Подключение смартфона или планшета на android для FPV-VR и прочих программ GS к NVR по usb
2 |
3 | USB Tethering, он же USB Ethernet - функция ОС Android для использования телефона в качестве USB-модема, представляющегося сетевой картой. Нам это дает возможность соединить телефон и NVR обычным usb-проводом и получить между ними быструю сеть. К сожалению, в большинстве случаев usb terhering доступен только на планшетах с модулем sim-карты. Если у вас его нет, и usb-модем не активируется, придется подключаться по [usb-ethernet](usb-eth-modem.md) или [wifi](note-nvr-tab-ap.md).
4 |
5 | Нужно [установить](notes_start_hi3536ev100.md#L47) [ядро](hi3536dv100/uImage.hi3536dv100) и [rootfs](hi3536dv100/rootfs.squashfs.hi3536dv100) с поддержкой rndis_host и залить [`/usr/bin/wifibroadcast`](hi3536dv100/usr/bin/wifibroadcast), [`/usr/bin/telemetry`](hi3536dv100/usr/bin/telemetry), и добавить в [`interfaces`](hi3536dv100/etc/network/interfaces) следующее:
6 | ```
7 | #USB Tethering
8 | auto usb0
9 | iface usb0 inet dhcp
10 | pre-up modprobe rndis_host
11 | pre-up sleep 4
12 | ```
13 |
14 | Для включения нужно:
15 | * Подключить смартфон или планшет кабелем к отключенному регистратору
16 | * Зайти в настройки - Сеть и Интернет - Точка доступа и модем
17 | * Включить регистратор
18 | * Как только в меню android появится активным пункт USB-модем, включить его.
19 | * Запустить FPV-VR, выбрать в настройках секцию Manually (stream), установить настройки видео на используемый кодек (rtp/264, rtp/265) и настройки телеметрии на mavlink.
20 | * Выйти из настроек и запустить "Start video and osd".
21 |
22 | Альтернативно, можно использовать приложение QOpenHD с аналогичным функционалом.
23 |
24 | Также доступен [вариант без перезапуска](nvr_gpio.md) регистратора.
25 |
26 |
--------------------------------------------------------------------------------
/user_TipoMan/.dot:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/user_TipoMan/gkrcparams:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/user_TipoMan/gkrcparams
--------------------------------------------------------------------------------
/user_TipoMan/mavfwd_mavlink2.tar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/user_TipoMan/mavfwd_mavlink2.tar
--------------------------------------------------------------------------------
/wfb.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/wfb.zip
--------------------------------------------------------------------------------
/wfbopenhd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenIPC/sandbox-fpv/0c0325b5536ab6dce07427b58326a3b45bf2b1fe/wfbopenhd.zip
--------------------------------------------------------------------------------