diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/DJI_RC-N1_SIMULATOR_FLY_DCL.iml b/.idea/DJI_RC-N1_SIMULATOR_FLY_DCL.iml
new file mode 100644
index 0000000..d0876a7
--- /dev/null
+++ b/.idea/DJI_RC-N1_SIMULATOR_FLY_DCL.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..d56657a
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..2ea9f7b
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DJI-RC-N1-Remote-Controller.png b/DJI-RC-N1-Remote-Controller.png
new file mode 100644
index 0000000..b6e20cb
Binary files /dev/null and b/DJI-RC-N1-Remote-Controller.png differ
diff --git a/README.md b/README.md
index 5b07840..9f61a51 100644
--- a/README.md
+++ b/README.md
@@ -1,77 +1,66 @@
-mDjiController
+DJI RC-N1
===============
- - Connect your DJI Remote Controller to your PC and use it to play simulators.
- - Currently confirmed working controllers: DJI Phantom 2
+Discussion thread: coming soon...
+
+Donate:
+
+
+
+
+
+- https://send.monobank.ua/jar/87uNmHPh5v
+- https://www.buymeacoffee.com/ivanyakymenko
+
+-----------------------------------------------------------------------------
+Latest version V3.0.0 (26.09.2023)
+ - critical fix, com port open error on some PC's
+-----------------------------------------------------------------------------
+
+ - Connect your DJI Remote Controller to your PC and use it to play simulators
+ - Confirmed DJI Mavic 3 RC231
- For Mavic Mini or a Python interface, take a look at [justin97530/miniDjiController](https://github.com/justin97530/miniDjiController)
- For DJI Mini 2 or a Python interface, take a look at [usatenko/DjiMini2RCasJoystick](https://github.com/usatenko/DjiMini2RCasJoystick)
- For DJI Phantom 3 take a look at [mishavoloshchuk/mDjiController](https://github.com/mishavoloshchuk/mDjiController)
-----------------------------------------------------------------------------
-This is a program that connects to your DJI Phantom Remote Controller (RC),
-reads the stick positions and tells Windows that position. A simplified, wannabe driver.
+This is a program that connects to your DJI Mavic 3 Remote Controller (RC-N1) as a XBox360 gamepad,
+reads the stick positions and tells Windows that position.
-In use:
-
-
-Here I'm flying a DJI Phantom in HELI-X5 using mDjiController. Open up the image in big version to see the controller configuration.
+
+-----------------------------------------------------------------------------
Installation / Usage
-------------
-
-### For a thorough guide on how to get started, see this blog post: [Using a Phantom 2 DJI Controller in AirSim](https://timebutt.github.io/static/using-a-phantom-dji-controller-in-airsim/)
-
-### UPDATE: Slaterbbx has added more features to this, you should also check out his fork of this here: https://github.com/slaterbbx/mDjiController
+- Install packages before usage:
+- dji-assistant-2-consumer-drones-series and close it after installation https://www.dji.com/downloads/softwares/dji-assistant-2-consumer-drones-series
+- python 3.9 or 3.x
+- pip3 install vgamepad
+- pip3 install pyserial
-In order for it to work, the original drivers from DJI must be installed, and something called vJoy.
+- Power on RC-N1
+- Connect via bottom type-C
+- run main.py
+- run yor simulator
-* Download mDjiController.zip from above ( https://github.com/Matsemann/mDjiController/blob/master/mDjiController.zip?raw=true )
-* Download DJI WIN Driver Installer from here: http://www.dji.com/product/phantom-2/download
-* Download vJoy from here: http://vjoystick.sourceforge.net/site/index.php/download-a-install/72-download
+
-* Install both.
-* Then connect your RC to your computer via USB and turn it on.
+for restart game or recover drone: use camera wheel, left scroll
-* Run mDjiController.exe, and select the correct COM port. By default you should try writing "3".
-* For vJoy, write 1 unless you use vJoy already and have different configurations.
+
-Then open a simulator and calibrate the controller.
-How does it work?
------------------
+TROUBLESHOOTING
+-----------------------------------------------------------------------------
+App searching by itself for the serial port with description "DJI USB VCOM For Protocol"
+make sure your device attached via bottom Type-C connector
+
-* It is possible to ask the controller for its status when it's connected. So this program continuously
- reads the status. It connects through COM. The output from the controller is just a list of numbers,
- but sampling many enough such lists it's easy to see a pattern for which number means what. The biggest issue
- was that the numbers are little endian encoded and uses two's complement, so it took some time to understand how
- each number behaved.
-
-* vJoy is a virtual joystick that can be installed on your computer. Windows think it's a normal joystick. mDjiController
- takes the stick positions from the controller and tells Windows that this virtual joystick has the same positions.
+[Tested with DCL - The game](https://store.steampowered.com/app/964570/DCL__The_Game/)
+ Preset:
+ Mode 2
+ Acro
+ Zero throttle at stick center
-TROUBLESHOOTING
----------------
-* If something doesn't work, make sure you have enabled logging, it may tell you the error.
-
-* COM can't connect
- Try with other numbers instead of 3. Open up device-manager.
- You should see a category named "Ports (COM & LPT) and then a device named "DJI USB Virtual COM (COMX)"
- The X should be the number you should use.
- If there is nothing there, the driver from DJI is not installed correctly.
-
- If you have any of the DJI Assistant Software installed, make sure they are not running, as this program
- cannot connect then.
-
-* vJoy can't connect
- The error message should tell you if it's installed or not. Install the vJoy driver if it's not there.
-
-* Not all sticks or buttons work
- *If they look correct in the log:*
- Your vJoy configuration may be wrong. Open "Configure vJoy" and reset configuration 1, or make a new one
- and tell mDjiController.exe to use that configuration.
- *If they are NOT correct in the log:*
- Your controller sends in a different format, so you need to figure that out, edit the code and recompile.
- (A bit advanced)
-
-
+
+
diff --git a/btc.jpg b/btc.jpg
new file mode 100644
index 0000000..56ace87
Binary files /dev/null and b/btc.jpg differ
diff --git a/connect.png b/connect.png
new file mode 100644
index 0000000..49d1140
Binary files /dev/null and b/connect.png differ
diff --git a/connect_ok.png b/connect_ok.png
new file mode 100644
index 0000000..48d6150
Binary files /dev/null and b/connect_ok.png differ
diff --git a/control.png b/control.png
new file mode 100644
index 0000000..ad7d491
Binary files /dev/null and b/control.png differ
diff --git a/in_use.png b/in_use.png
deleted file mode 100644
index 5c8774b..0000000
Binary files a/in_use.png and /dev/null differ
diff --git a/inc/vjoyinterface.h b/inc/vjoyinterface.h
deleted file mode 100644
index f92d8d5..0000000
--- a/inc/vjoyinterface.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// The following ifdef block is the standard way of creating macros which make exporting
-// from a DLL simpler. All files within this DLL are compiled with the VJOYINTERFACE_EXPORTS
-// symbol defined on the command line. this symbol should not be defined on any project
-// that uses this DLL. This way any other project whose source files include this file see
-// VJOYINTERFACE_API functions as being imported from a DLL, whereas this DLL sees symbols
-// defined with this macro as being exported.
-#ifdef VJOYINTERFACE_EXPORTS
-#define VJOYINTERFACE_API __declspec(dllexport)
-#else
-#define VJOYINTERFACE_API __declspec(dllimport)
-#endif
-
-///////////////////////////// vJoy device (collection) status ////////////////////////////////////////////
-#ifndef VJDSTAT
-#define VJDSTAT
-enum VjdStat /* Declares an enumeration data type called BOOLEAN */
-{
- VJD_STAT_OWN, // The vJoy Device is owned by this application.
- VJD_STAT_FREE, // The vJoy Device is NOT owned by any application (including this one).
- VJD_STAT_BUSY, // The vJoy Device is owned by another application. It cannot be acquired by this application.
- VJD_STAT_MISS, // The vJoy Device is missing. It either does not exist or the driver is down.
- VJD_STAT_UNKN // Unknown
-};
-#endif
-extern "C" {
-///////////////////////////// vJoy device (collection) Control interface /////////////////////////////////
-/*
- These functions allow writing feeders and other applications that interface with vJoy
- It is assumed that only one vJoy top-device (= Raw PDO) exists.
- This top-level device can have up to 16 siblings (=top-level Reports/collections)
- Each sibling is refered to as a "vJoy Device" and is attributed a unique Report ID (Range: 1-16).
-
- Naming convetion:
- VJD = vJoy Device
- rID = Report ID
-*/
-
-///// General driver data
-VJOYINTERFACE_API SHORT __cdecl GetvJoyVersion(void);
-VJOYINTERFACE_API BOOL __cdecl vJoyEnabled(void);
-VJOYINTERFACE_API PVOID __cdecl GetvJoyProductString(void);
-VJOYINTERFACE_API PVOID __cdecl GetvJoyManufacturerString(void);
-VJOYINTERFACE_API PVOID __cdecl GetvJoySerialNumberString(void);
-
-
-///// vJoy Device properties
-VJOYINTERFACE_API int __cdecl GetVJDButtonNumber(UINT rID); // Get the number of buttons defined in the specified VDJ
-VJOYINTERFACE_API int __cdecl GetVJDDiscPovNumber(UINT rID); // Get the number of descrete-type POV hats defined in the specified VDJ
-VJOYINTERFACE_API int __cdecl GetVJDContPovNumber(UINT rID); // Get the number of descrete-type POV hats defined in the specified VDJ
-VJOYINTERFACE_API BOOL __cdecl GetVJDAxisExist(UINT rID, UINT Axis); // Test if given axis defined in the specified VDJ
-VJOYINTERFACE_API BOOL __cdecl GetVJDAxisMax(UINT rID, UINT Axis, LONG * Max); // Get logical Maximum value for a given axis defined in the specified VDJ
-VJOYINTERFACE_API BOOL __cdecl GetVJDAxisMin(UINT rID, UINT Axis, LONG * Min); // Get logical Minimum value for a given axis defined in the specified VDJ
-
-///// Write access to vJoy Device - Basic
-VJOYINTERFACE_API BOOL __cdecl AcquireVJD(UINT rID); // Acquire the specified vJoy Device.
-VJOYINTERFACE_API VOID __cdecl RelinquishVJD(UINT rID); // Relinquish the specified vJoy Device.
-VJOYINTERFACE_API BOOL __cdecl UpdateVJD(UINT rID, PVOID pData); // Update the position data of the specified vJoy Device.
-VJOYINTERFACE_API enum VjdStat __cdecl GetVJDStatus(UINT rID); // Get the status of the specified vJoy Device.
-
-///// Write access to vJoy Device - Modifyiers
-// This group of functions modify the current value of the position data
-// They replace the need to create a structure of position data then call UpdateVJD
-
-//// Reset functions
-VJOYINTERFACE_API BOOL __cdecl ResetVJD(UINT rID); // Reset all controls to predefined values in the specified VDJ
-VJOYINTERFACE_API VOID __cdecl ResetAll(void); // Reset all controls to predefined values in all VDJ
-VJOYINTERFACE_API BOOL __cdecl ResetButtons(UINT rID); // Reset all buttons (To 0) in the specified VDJ
-VJOYINTERFACE_API BOOL __cdecl ResetPovs(UINT rID); // Reset all POV Switches (To -1) in the specified VDJ
-
-// Write data
-VJOYINTERFACE_API BOOL __cdecl SetAxis(LONG Value, UINT rID, UINT Axis); // Write Value to a given axis defined in the specified VDJ
-VJOYINTERFACE_API BOOL __cdecl SetBtn(BOOL Value, UINT rID, UCHAR nBtn); // Write Value to a given button defined in the specified VDJ
-VJOYINTERFACE_API BOOL __cdecl SetDiscPov(int Value, UINT rID, UCHAR nPov); // Write Value to a given descrete POV defined in the specified VDJ
-VJOYINTERFACE_API BOOL __cdecl SetContPov(DWORD Value, UINT rID, UCHAR nPov); // Write Value to a given continuous POV defined in the specified VDJ
-
-} // extern "C"
\ No newline at end of file
diff --git a/lib/amd64/vJoyInterface.dll b/lib/amd64/vJoyInterface.dll
deleted file mode 100644
index 5db1ed5..0000000
Binary files a/lib/amd64/vJoyInterface.dll and /dev/null differ
diff --git a/lib/amd64/vJoyInterface.lib b/lib/amd64/vJoyInterface.lib
deleted file mode 100644
index af63eb4..0000000
Binary files a/lib/amd64/vJoyInterface.lib and /dev/null differ
diff --git a/lib/amd64/vJoyInterface.pdb b/lib/amd64/vJoyInterface.pdb
deleted file mode 100644
index 1a1550a..0000000
Binary files a/lib/amd64/vJoyInterface.pdb and /dev/null differ
diff --git a/lib/vJoyInterface.dll b/lib/vJoyInterface.dll
deleted file mode 100644
index f1e7b0a..0000000
Binary files a/lib/vJoyInterface.dll and /dev/null differ
diff --git a/lib/vJoyInterface.lib b/lib/vJoyInterface.lib
deleted file mode 100644
index 7752ec4..0000000
Binary files a/lib/vJoyInterface.lib and /dev/null differ
diff --git a/lib/vJoyInterface.pdb b/lib/vJoyInterface.pdb
deleted file mode 100644
index 551de22..0000000
Binary files a/lib/vJoyInterface.pdb and /dev/null differ
diff --git a/mDjiController.zip b/mDjiController.zip
deleted file mode 100644
index 39cb146..0000000
Binary files a/mDjiController.zip and /dev/null differ
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..7eaae01
--- /dev/null
+++ b/main.py
@@ -0,0 +1,255 @@
+import argparse
+import struct
+import time
+from threading import Thread
+
+import serial.tools.list_ports
+import vgamepad as vg
+
+parser = argparse.ArgumentParser(description='DJI Mavic 3 RC231, RC-N1)')
+parser.add_argument('-p', '--port', help='RC Serial Port', default="COM9")
+
+args = parser.parse_args()
+gamepad = vg.VX360Gamepad()
+camera = 0
+
+events = (
+ gamepad.left_trigger,
+ gamepad.left_joystick(-16384, 16384),
+ gamepad.right_joystick(-16384, 16384),
+ )
+
+gamepad.reset()
+time.sleep(1)
+
+def calc_checksum(packet, plength):
+
+ crc = [0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+ 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+ 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+ 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+ 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+ 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+ 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+ 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+ 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+ 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+ 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+ 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+ 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+ 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+ 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+ 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+ 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+ 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+ 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+ 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+ 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+ 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+ 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+ 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+ 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+ 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+ 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+ 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+ 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+ 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+ 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+ 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78]
+
+ # Seeds
+ # v = 0x1012 #Naza M
+ # v = 0x1013 #Phantom 2
+ # v = 0x7000 #Naza M V2
+ v = 0x3692 #P3/P4/Mavic
+
+ for i in range(0, plength):
+ vv = v >> 8
+ v = vv ^ crc[((packet[i] ^ v) & 0xFF)]
+ return v
+
+def calc_pkt55_hdr_checksum(seed, packet, plength):
+ arr_2A103 = [0x00,0x5E,0xBC,0xE2,0x61,0x3F,0xDD,0x83,0xC2,0x9C,0x7E,0x20,0xA3,0xFD,0x1F,0x41,
+ 0x9D,0xC3,0x21,0x7F,0xFC,0xA2,0x40,0x1E,0x5F,0x01,0xE3,0xBD,0x3E,0x60,0x82,0xDC,
+ 0x23,0x7D,0x9F,0xC1,0x42,0x1C,0xFE,0xA0,0xE1,0xBF,0x5D,0x03,0x80,0xDE,0x3C,0x62,
+ 0xBE,0xE0,0x02,0x5C,0xDF,0x81,0x63,0x3D,0x7C,0x22,0xC0,0x9E,0x1D,0x43,0xA1,0xFF,
+ 0x46,0x18,0xFA,0xA4,0x27,0x79,0x9B,0xC5,0x84,0xDA,0x38,0x66,0xE5,0xBB,0x59,0x07,
+ 0xDB,0x85,0x67,0x39,0xBA,0xE4,0x06,0x58,0x19,0x47,0xA5,0xFB,0x78,0x26,0xC4,0x9A,
+ 0x65,0x3B,0xD9,0x87,0x04,0x5A,0xB8,0xE6,0xA7,0xF9,0x1B,0x45,0xC6,0x98,0x7A,0x24,
+ 0xF8,0xA6,0x44,0x1A,0x99,0xC7,0x25,0x7B,0x3A,0x64,0x86,0xD8,0x5B,0x05,0xE7,0xB9,
+ 0x8C,0xD2,0x30,0x6E,0xED,0xB3,0x51,0x0F,0x4E,0x10,0xF2,0xAC,0x2F,0x71,0x93,0xCD,
+ 0x11,0x4F,0xAD,0xF3,0x70,0x2E,0xCC,0x92,0xD3,0x8D,0x6F,0x31,0xB2,0xEC,0x0E,0x50,
+ 0xAF,0xF1,0x13,0x4D,0xCE,0x90,0x72,0x2C,0x6D,0x33,0xD1,0x8F,0x0C,0x52,0xB0,0xEE,
+ 0x32,0x6C,0x8E,0xD0,0x53,0x0D,0xEF,0xB1,0xF0,0xAE,0x4C,0x12,0x91,0xCF,0x2D,0x73,
+ 0xCA,0x94,0x76,0x28,0xAB,0xF5,0x17,0x49,0x08,0x56,0xB4,0xEA,0x69,0x37,0xD5,0x8B,
+ 0x57,0x09,0xEB,0xB5,0x36,0x68,0x8A,0xD4,0x95,0xCB,0x29,0x77,0xF4,0xAA,0x48,0x16,
+ 0xE9,0xB7,0x55,0x0B,0x88,0xD6,0x34,0x6A,0x2B,0x75,0x97,0xC9,0x4A,0x14,0xF6,0xA8,
+ 0x74,0x2A,0xC8,0x96,0x15,0x4B,0xA9,0xF7,0xB6,0xE8,0x0A,0x54,0xD7,0x89,0x6B,0x35]
+
+ chksum = seed
+ for i in range(0, plength):
+ chksum = arr_2A103[((packet[i] ^ chksum) & 0xFF)];
+ return chksum
+
+def send_duml(s, source, target, cmd_type, cmd_set, cmd_id, payload = None):
+ global sequence_number
+ sequence_number = 0x34eb
+ packet = bytearray.fromhex(u'55')
+ length = 13
+ if payload is not None:
+ length = length + len(payload)
+
+ if length > 0x3ff:
+ print("Packet too large")
+ exit(1)
+
+ packet += struct.pack('B', length & 0xff)
+ packet += struct.pack('B', (length >> 8) | 0x4) # MSB of length and protocol version
+ hdr_crc = calc_pkt55_hdr_checksum(0x77, packet, 3)
+ packet += struct.pack('B', hdr_crc)
+ packet += struct.pack('B', source)
+ packet += struct.pack('B', target)
+ packet += struct.pack(' (min 0, center 16384, max 32768)
+def parseInput(input, name):
+ output = (int.from_bytes(input, byteorder='little') - 1024) * 2 * 4096 // 165
+ if output >= 32768:
+ output = 32767
+
+# print(output, "test")
+
+ return output
+
+st = {"rh": 0, "rv": 0, "lh": 0, "lv": 0}
+
+def threaded_function():
+ while(True):
+ time.sleep(0.1)
+ #print("working ...")
+ gamepad.left_joystick(int(st["lh"]), int(st["lv"]))
+ gamepad.right_joystick(int(st["rh"]), int(st["rv"]))
+ if camera > 32000:
+ gamepad.press_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_Y) #restart race
+ if camera < -32000:
+ gamepad.press_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_B) #recover drone
+ if camera == 0:
+ gamepad.release_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_Y)
+ gamepad.release_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_B)
+ gamepad.update()
+
+thread = Thread(target = threaded_function, args = ())
+thread.start()
+#thread.join()
+
+try:
+ # enable simulator mode for RC (without this stick positions are sent very slow by RC)
+ send_duml(s, 0x0a, 0x06, 0x40, 0x06, 0x24, bytearray.fromhex('01'))
+
+ while True:
+
+ #time.sleep(0.1)
+ # read channel values
+ send_duml(s, 0x0a, 0x06, 0x40, 0x06, 0x01, bytearray.fromhex(''))
+ #s.write(bytearray.fromhex('55 0d 04 33 0a 06 eb 34 40 06 01 74 24'))
+ # Don't write to a new line every time.
+# print('\rPinged. ', end='')
+
+ # read duml
+ buffer = bytearray.fromhex('')
+ while True:
+ b = s.read(1)
+ if b == bytearray.fromhex('55'):
+ buffer.extend(b)
+ ph = s.read(2)
+ buffer.extend(ph)
+ ph = struct.unpack('> 10
+ pc = s.read(1)
+ buffer.extend(pc)
+ pd = s.read(pl - 4)
+ buffer.extend(pd)
+ break
+ else:
+ break
+ data = buffer
+# print(' '.join(format(x, '02x') for x in data))
+# time.sleep(0.5)
+
+ # Reverse-engineered. Controller input seems to always be len 38.
+ if len(data) == 38:
+ # Reverse-engineered
+ st["rh"] = parseInput(data[13:15], 'lv')
+ st["rv"] = parseInput(data[16:18], 'lh')
+
+ st["lv"] = parseInput(data[19:21], 'rv')
+ st["lh"] = parseInput(data[22:24], 'rh')
+
+ camera = parseInput(data[25:27], 'cam')
+
+ #print(data)
+ #with uinput.Device(events) as device:
+ #time.sleep(1)
+ #else:
+ # print(len(data))
+
+ # Log to console.
+ #print('L: H{0:06d},V{1:06d}; R: H{2:06d},V{3:06d}, CAM: {4:06d}\n'.format(left_horizontal, left_vertical, right_horizontal, right_vertical, camera), end='')
+except serial.SerialException as e:
+ # Stylistic: Newline to stop data update and spacing.
+ print('\n\nCould not read/write:', e)
+except KeyboardInterrupt:
+ # Stylistic: Newline to stop data update and spacing.
+ print('\n\nDetected keyboard interrupt.')
+
+ pass
+
+print('Stopping.')
diff --git a/monoQR.jpg b/monoQR.jpg
new file mode 100644
index 0000000..6f37012
Binary files /dev/null and b/monoQR.jpg differ
diff --git a/preset1.png b/preset1.png
new file mode 100644
index 0000000..b43a380
Binary files /dev/null and b/preset1.png differ
diff --git a/preset2.png b/preset2.png
new file mode 100644
index 0000000..2b68657
Binary files /dev/null and b/preset2.png differ
diff --git a/src/Joystick.cpp b/src/Joystick.cpp
deleted file mode 100644
index 659cf1a..0000000
--- a/src/Joystick.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-#include "Joystick.h"
-#include "vjoyinterface.h"
-
-Joystick::Joystick(int id, int logging)
-{
- interfaceId = id;
- if (logging == 0) {
- log = true;
- }
-
- printf("Creating vJoy connection\n");
-
- if (!vJoyEnabled()) {
- printf("vJoy driver not enabled: Failed Getting vJoy attributes.\n");
- return;
- } else {
- printf("Driver found:\nVendor:%S, Product:%S, Ver:%S\n", TEXT(GetvJoyManufacturerString()), TEXT(GetvJoyProductString()), TEXT(GetvJoySerialNumberString()));
- };
-
- VjdStat status = GetVJDStatus(interfaceId);
- switch (status)
- {
- case VJD_STAT_OWN:
- printf("vJoy Device %d is already owned by this feeder\n", interfaceId);
- break;
- case VJD_STAT_FREE:
- printf("vJoy Device %d is free\n", interfaceId);
- break;
- case VJD_STAT_BUSY:
- printf("vJoy Device %d is already owned by another feeder\nCannot continue\n", interfaceId);
- return;
- case VJD_STAT_MISS:
- printf("vJoy Device %d is not installed or disabled\nCannot continue\n", interfaceId);
- return;
- default:
- printf("vJoy Device %d general error\nCannot continue\n", interfaceId);
- return;
- };
-
- if (!AcquireVJD(interfaceId)) {
- printf("Failed to acquire vJoy Interface number %d\n", interfaceId);
- return;
- }
- else {
- ResetVJD(interfaceId);
- connected = true;
- printf("Acquired vJoy Interface number %d\n", interfaceId);
- }
-}
-
-void Joystick::update(int l_hor, int l_ver, int r_hor, int r_ver, int lever_left, int lever_right, int camera)
-{
- // Values must be between 0x0 and 0x8000
- // The values from the controller are between -1000 and 1000, so we just scale them between 0 and 16000 (maximum range in vJoyMonitor)
- l_hor += 1000;
- l_ver += 1000;
- r_hor += 1000;
- r_ver += 1000;
- camera -= 1000;
-
- l_hor *= 16;
- l_ver *= 16;
- r_hor *= 16;
- r_ver *= 16;
- camera *= -16; // negative multiplication to make the value feel natural (left = negative | right = positive)
-
- // Read values from left lever
- // -780 = 'OFF' position | 0 = 'CL' position | 780 = 'HL' position
- if (lever_left == -780) {
- button_1 = true;
- button_2 = false;
- button_3 = false;
- }
- else if (lever_left == 780) {
- button_1 = false;
- button_2 = false;
- button_3 = true;
- } // else remain as before, sometimes this value is a bit weird
- else if (lever_left == 0) {
- button_1 = false;
- button_2 = true;
- button_3 = false;
- }
-
- // Read values from right lever
- // -780 = 'GPS' position | 0 = 'ATTI' position | 780 = 'ATTI' position
- if (lever_right == -780) {
- button_4 = true;
- button_5 = false;
- button_6 = false;
- }
- else if (lever_right == 780) {
- button_4 = false;
- button_5 = false;
- button_6 = true;
- } // else remain as before, sometimes this value is a bit weird
- else {
- button_4 = false;
- button_5 = true;
- button_6 = false;
- }
-
- if (log)
- printf("L vert: %-5d | L hori: %-5d | R vert: %-5d | R hori: %-5d | btn1: %-d | btn2: %-d | btn3: %-d | btn4: %-d | btn5: %-d | btn6: %-d | camera: %-d\n", l_ver, l_hor, r_ver, r_hor, button_1, button_2, button_3, button_4, button_5, button_6, camera);
-
- // Send stick values to vJoy
- SetAxis(l_hor, interfaceId, HID_USAGE_X);
- SetAxis(l_ver, interfaceId, HID_USAGE_Y);
- SetAxis(r_hor, interfaceId, HID_USAGE_Z);
- SetAxis(r_ver, interfaceId, HID_USAGE_RX);
- SetAxis(camera, interfaceId, HID_USAGE_RY);
-
- // Send button values to vJoy
- SetBtn(button_1, interfaceId, 1);
- SetBtn(button_2, interfaceId, 2);
- SetBtn(button_3, interfaceId, 3);
- SetBtn(button_4, interfaceId, 4);
- SetBtn(button_5, interfaceId, 5);
- SetBtn(button_6, interfaceId, 6);
-}
-
-Joystick::~Joystick()
-{
- RelinquishVJD(interfaceId);
- printf("Disconnected from joystick\n");
-}
\ No newline at end of file
diff --git a/src/Joystick.h b/src/Joystick.h
deleted file mode 100644
index fbcaa5e..0000000
--- a/src/Joystick.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include
-#include
-
-#define HID_USAGE_X 0x30
-#define HID_USAGE_Y 0x31
-#define HID_USAGE_Z 0x32
-#define HID_USAGE_RX 0x33
-#define HID_USAGE_RY 0x34
-#define HID_USAGE_RZ 0x35
-
-class Joystick
-{
-private:
- bool button_1, button_2, button_3, button_4, button_5, button_6;
- bool connected;
- unsigned int interfaceId;
- bool log = false;
-public:
- Joystick(int interfaceId, int logging);
- ~Joystick();
- void update(int l_hor, int l_ver, int r_hor, int r_ver, int toggle_left, int toggle_right, int camera);
- bool isConnected() { return connected; }
-};
\ No newline at end of file
diff --git a/src/Main.cpp b/src/Main.cpp
deleted file mode 100644
index faca1e5..0000000
--- a/src/Main.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-
-#include
-#include
-#include
-#include
-
-#include "Serial.h"
-#include "Joystick.h"
-
-
-
-short littleEndiansToShort(int first, int second) {
- if (first < 0) {
- first = 256 + first;
- }
-
- short combined = second << 8 | first;
- return combined;
-
-}
-
-void run(char* portName, int stickId, int logging) {
-
- char initData[] = { 0x55, 0xaa, 0x55, 0xaa, 0x1e, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x80, 0x00, 0x04, 0x04, 0x74, 0x94, 0x35, 0x00, 0xd8, 0xc0, 0x41, 0x00, 0x30, 0xf6, 0x08, 0x00, 0x00, 0xf6, 0x69, 0x9c, 0x01, 0xe8};
- char pingData[] = { 0x55, 0xaa, 0x55, 0xaa, 0x1e, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x80, 0x00, 0x06, 0x01, 0x28, 0x97, 0xae, 0x03, 0x28, 0x36, 0xa4, 0x03, 0x28, 0x36, 0xa4, 0x03, 0xab, 0xa7, 0x30, 0x00, 0x03, 0x53};
-
- char incomingData[256] = "";
- int dataLength = 256;
- int readResult = 0;
- bool shouldRun = true;
-
-
- Joystick j(stickId, logging);
- if (!j.isConnected()) {
- printf("Couldn't connect to vJoy, quitting...\n");
- return;
- }
- printf("\n");
-
- Serial s(portName);
- if (!s.IsConnected()) {
- printf("Couldn't connect to COM port, quitting...\n");
- return;
- }
-
- printf("\nEverything is ready\n\n");
- s.WriteData(initData, 34);
-
- printf("Running...\nPress ESC to quit\n");
- Sleep(2000);
-
- while (s.IsConnected() && shouldRun)
- {
- s.WriteData(pingData, 34); // write this once in a while, otherwise it stops sending? :O
- readResult = s.ReadData(incomingData, dataLength);
-
- if (readResult == 76 && incomingData[0] == 0x55) { // probably positioning data
- short left_vertical = littleEndiansToShort(incomingData[39], incomingData[40]);
- short left_horizontal = littleEndiansToShort(incomingData[43], incomingData[44]);
-
- short right_horizontal = littleEndiansToShort(incomingData[31], incomingData[32]);
- short right_vertical = littleEndiansToShort(incomingData[35], incomingData[36]);
-
- short left_lever = littleEndiansToShort(incomingData[47], incomingData[48]);
- short right_lever = littleEndiansToShort(incomingData[51], incomingData[52]);
-
- short camera = littleEndiansToShort(incomingData[55], incomingData[56]);
-
- // update our virtual joystick
- j.update(left_horizontal, left_vertical, right_horizontal, right_vertical, left_lever, right_lever, camera);
- }
-
-
- if (GetAsyncKeyState(VK_ESCAPE)) {
- shouldRun = false;
- printf("\n\nDetected ESC, quitting...\n");
- }
-
- Sleep(10);
- }
-
-}
-
-int main() {
- std::string in;
- int portNr, stickId, logging;
-
-
- printf("Select port number (default COM \"3\"): ");
- std::getline(std::cin, in);
- portNr = atoi(in.c_str());
-
- if (portNr < 1) {
- portNr = 3;
- }
-
- char port[100];
- sprintf_s(port, "COM%d", portNr);
-
-
- printf("Select vJoy configuration (default \"1\"): ");
- std::getline(std::cin, in);
- stickId = atoi(in.c_str());
-
- if (stickId < 1) {
- stickId = 1;
- }
-
-
- printf("Disable logging? 1 for off (default \"0\"): ");
- std::getline(std::cin, in);
- logging = atoi(in.c_str());
-
- if (logging != 0) {
- logging = 1;
- }
-
- printf("Starting...\n\n");
- run(port, stickId, logging);
- printf("Closing down...\n\n");
-
-
- system("pause");
- return 0;
-}
\ No newline at end of file
diff --git a/src/Serial.cpp b/src/Serial.cpp
deleted file mode 100644
index bdf3b02..0000000
--- a/src/Serial.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-#include "Serial.h"
-
-/*
- * Adopted from http://playground.arduino.cc/Interfacing/CPPWindows
- */
-
-Serial::Serial(char *portName)
-{
- printf("Creating serial connection\n");
- //We're not yet connected
- this->connected = false;
-
- //Try to connect to the given port through CreateFile
- this->hSerial = CreateFile(portName,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
- //Check if the connection was successful
- if (this->hSerial == INVALID_HANDLE_VALUE)
- {
- //If not success full display an Error
- if (GetLastError() == ERROR_FILE_NOT_FOUND){
-
- //Print Error if necessary
- printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName);
-
- }
- else
- {
- printf("Couldn't connect to COM port, unknown why..\n");
- }
- }
- else
- {
- printf("Found serial port\n");
- //If connected we try to set the comm parameters
- DCB dcbSerialParams = { 0 };
-
- //Try to get the current
- if (!GetCommState(this->hSerial, &dcbSerialParams))
- {
- //If impossible, show an error
- printf("failed to get current serial parameters!\n");
- }
- else
- {
- //Define serial connection parameters for the Arduino board
- dcbSerialParams.BaudRate = 115200;
- dcbSerialParams.ByteSize = 8;
- dcbSerialParams.StopBits = ONESTOPBIT;
- dcbSerialParams.Parity = NOPARITY;
-
- //Set the parameters and check for their proper application
- if (!SetCommState(hSerial, &dcbSerialParams))
- {
- printf("ALERT: Could not set Serial Port parameters\n");
- }
- else
- {
- printf("Connected to serial port\n");
- //If everything went fine we're connected
- this->connected = true;
- //Sleep(200);
- }
- }
- }
-
-}
-
-Serial::~Serial()
-{
- //Check if we are connected before trying to disconnect
- if (this->connected)
- {
- //We're no longer connected
- this->connected = false;
- //Close the serial handler
- CloseHandle(this->hSerial);
- printf("Closed serial connection\n");
- }
-}
-
-int Serial::ReadData(char *buffer, unsigned int nbChar)
-{
- //Number of bytes we'll have read
- DWORD bytesRead;
- //Number of bytes we'll really ask to read
- unsigned int toRead;
-
- //Use the ClearCommError function to get status info on the Serial port
- ClearCommError(this->hSerial, &this->errors, &this->status);
-
- //Check if there is something to read
- if (this->status.cbInQue>0)
- {
- //If there is we check if there is enough data to read the required number
- //of characters, if not we'll read only the available characters to prevent
- //locking of the application.
- if (this->status.cbInQue>nbChar)
- {
- toRead = nbChar;
- }
- else
- {
- toRead = this->status.cbInQue;
- }
-
- //Try to read the require number of chars, and return the number of read bytes on success
- if (ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0)
- {
- return bytesRead;
- }
-
- }
-
- //If nothing has been read, or that an error was detected return -1
- return -1;
-
-}
-
-
-bool Serial::WriteData(char *buffer, unsigned int nbChar)
-{
- DWORD bytesSend;
-
- //Try to write the buffer on the Serial port
- if (!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0))
- {
- //In case it don't work get comm error and return false
- ClearCommError(this->hSerial, &this->errors, &this->status);
-
- return false;
- }
- else
- return true;
-}
-
-bool Serial::IsConnected()
-{
- //Simply return the connection status
- return this->connected;
-}
\ No newline at end of file
diff --git a/src/Serial.h b/src/Serial.h
deleted file mode 100644
index 6f29ea7..0000000
--- a/src/Serial.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-
-/*
-* Adopted from http://playground.arduino.cc/Interfacing/CPPWindows
-*/
-
-class Serial
-{
-private:
- HANDLE hSerial;
- bool connected;
- COMSTAT status;
- DWORD errors;
-
-public:
- Serial(char *portName);
- ~Serial();
- int ReadData(char *buffer, unsigned int nbChar);
- bool WriteData(char *buffer, unsigned int nbChar);
- bool IsConnected();
-};
diff --git a/start.bat b/start.bat
new file mode 100644
index 0000000..7a84f97
--- /dev/null
+++ b/start.bat
@@ -0,0 +1 @@
+python main.py
\ No newline at end of file