Full Tutorial and Flight Footage:
VTOL is notoriously difficult to get working in the RC world due to flight controller limitations. But I wrote my own easy to understand flight controller code, dRehmFlight VTOL, that this project uses: https://github.com/nickrehm/dRehmFlight
Tutorials to set up your flight controller hardware and hook up your radio receiver to talk to the flight controller are available here: https://www.youtube.com/playlist?list=PLTSCOv-lGtMax-oA4Pnq8OTxd4fTucrjQ
While the code is fairly easy to modify for this platform, I am also providing the exact same modified version of dRehmFlight that I fly on my F-35. You should only need to change some of the servo offset variables in the control mixer to level the surfaces prior to flight. Control gains have already been tuned to fly well. Available here: https://github.com/nickrehm/dRehmFlight-F-35
~~~THIS AIRPLANE WILL NOT BE ABLE TO HOVER OR TAKEOFF VERTICALLY WITHOUT THE FLIGHT CONTROLLER~~~
Parts I've used and recommend:
Motors: https://amzn.to/3qXXIU7
Propellers: https://amzn.to/3dMu52E
Battery: https://amzn.to/2TEVEEp
Servos: https://amzn.to/3AO9s0V
Teensy 4.0: https://amzn.to/3i5Zwqn
This project is released under the CERN open hardware license (strongly reciprocal): Home | CERN Open Hardware Licence
By using this project or files contained within, you agree to adhere to the terms within the CERN-OHL-S license.
I built a F35 and will be using a Teensy with a MPU6050 when I compile the code I get errors like the following. I am not a programmer. any help would be approached here are the errors;
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino: In function 'void calculate_IMU_error()':
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:593:35: warning: unused variable 'MgX' [-Wunused-variable]
593 | int16_t AcX,AcY,AcZ,GyX,GyY,GyZ,MgX,MgY,MgZ;
| ^~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:593:39: warning: unused variable 'MgY' [-Wunused-variable]
593 | int16_t AcX,AcY,AcZ,GyX,GyY,GyZ,MgX,MgY,MgZ;
| ^~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:593:43: warning: unused variable 'MgZ' [-Wunused-variable]
593 | int16_t AcX,AcY,AcZ,GyX,GyY,GyZ,MgX,MgY,MgZ;
| ^~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino: In function 'void Madgwick(float, float, float, float, float, float, float, float, float, float)':
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:661:9: warning: unused variable 'mholder' [-Wunused-variable]
661 | float mholder;
| ^~~~~~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino: In function 'void controlMixer()':
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:1124:21: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses]
1124 | if (channel_6_pwm < 1700 & channel_6_pwm > 1300) {
| ~~~~~~~~~~~~~~^~~~~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino: In function 'float switchRollYaw(int, int)':
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:1458:1: warning: no return statement in function returning non-void [-Wreturn-type]
1458 | }
| ^
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino: In function 'float invSqrt(float)':
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:1738:35: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
1738 | unsigned int i = 0x5F1F1412 - (*(unsigned int*)&x >> 1);
| ^~~~~~~~~~~~~~~~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:1739:16: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
1739 | float tmp = *(float*)&i;
| ^~~~~~~~~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino: In function 'void getIMUdata()':
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:570:13: warning: 'MgX' is used uninitialized [-Wuninitialized]
570 | MagX = MgX/6.0; //uT
| ~~~^~~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:571:13: warning: 'MgY' is used uninitialized [-Wuninitialized]
571 | MagY = MgY/6.0;
| ~~~^~~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:572:13: warning: 'MgZ' is used uninitialized [-Wuninitialized]
572 | MagZ = MgZ/6.0;
| ~~~^~~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino: In function 'float invSqrt(float)':
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:1739:9: warning: 'i' is used uninitialized [-Wuninitialized]
1739 | float tmp = *(float*)&i;
| ^~~
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover.ino:1738:16: note: 'i' declared here
1738 | unsigned int i = 0x5F1F1412 - (*(unsigned int*)&x >> 1);
| ^
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\radioComm.ino: In function 'long unsigned int getRadioPWM(int)':
E:\VTOL\f-35 code\dRehmFlight-F-35-main (1)\dRehmFlight-F-35-main\dRehmFlight_Teensy_BETA_1.2_F-35VTOL_AngleHover\radioComm.ino:75:10: warning: 'returnPWM' may be used uninitialized in this function [-Wmaybe-uninitialized]
75 | return returnPWM;
| ^~~~~~~~~
Memory Usage on Teensy 4.0:
FLASH: code:24360, data:5304, headers:8220 free for files:1993732
RAM1: variables:6336, code:22192, padding:10576 free for local variables:485184
RAM2: variables:12416 free for malloc/new:511872