Once the quadcopter is fully assembled and you’ve been able to verify that you can communicate with
Once the quadcopter is fully assembled and you’ve been able to verify that you can communicate with the flight controller, you’ll likely want to make sure all your soldering actually worked, and you can command the motors to move.
The following code sketch can be used to perform a simple motor test by manually commanding their PWM value through the APM flight controller. This can also be useful if you would like to calibrate the ESCs without having a RC receiver connected to the flight controller. Generally the PWM range of the motors is usually 1000-2000. However you’ll likely notice that each motor may have a slightly different minimum PWM value for which it starts to rotate. These will need to be accounted for later on when we build the full flight controller. For reference, my 4 motors’ minimum PWM values were: [1045, 1150, 1050, 1150].
Instructions for calibrating the ESCs are included (for the ESCs I used) in the comments section of the code.
Also: be sure to take off the propellers before running these tests! For obvious reasons.
#include <AP_Common.h> #include <AP_Math.h> #include <AP_Param.h> #include <AP_Progmem.h> #include <StorageManager.h> #include <AP_HAL.h> #include <AP_HAL_AVR.h> const AP_HAL::HAL& hal = AP_HAL_BOARD_DRIVER; /* MotorTest_USB: This script may be used to manually command PWM values to specific motors individually or all four at once for testing. For ESC calibration follow these steps: 1. Connect USB to flight controller with battery DISCONNECTED 2. Load this script to flight controller 3. Select option (5) to command all motors 4. Input the maximum PWM input (2000) and press Enter --Console should state [All motors] currently commanded to 2000 5. Connect the battery to power ESCs --Two beep sounds should be emitted, means top range of throttle has been confirmed and saved 6. Input the minimum PWM input (1000) and press Enter within 2 seconds --A long beep sound should be emitted, means the bottom range of throttle has been detected --Several beep tones should be emitted to present the amount of battery cells 7. Self test is finished a 'melody 1 2 3' tune should be emitted 8. Verify range is set by inputting a value within throttle range (such as 1300) * These steps are based on "EMAX User Instruction for SimonK Series ESC" different steps may be needed for ESCs from different manufacturers ** When calibrating all four ESCs at once it may be hard to hear the specific number of beeps as described above. I recommend just listening for some aural feedback where appropriate then proeeding to the next step. */ int pwmValue = 0; void setup (void) { //Set baud rate to 57600 in order to transmit over SIK Radio hal.uartA->begin(map_baudrate(57600)); // Enable all motor channels and set frequency for commands for (int j=0; j<4; j++) { hal.rcout->enable_ch(j); } hal.rcout->set_freq(0xFF, 490); } void loop (void) { int motorSelected = 0; // reset all motor commands to zero pwmValue = 0; hal.rcout->write(0,0); hal.rcout->write(1,0); hal.rcout->write(2,0); hal.rcout->write(3,0); // main menu hal.console->printf_P(PSTR("\n\n" "Select which motor to command:\n" " 1) Front Right (CCW)\n" " 2) Back Left (CCW)\n" " 3) Front Left (CW)\n" " 4) Back Right (CW)\n" " 5) All motors\n")); // wait for user input while( !hal.console->available() ) { hal.scheduler->delay(20); } // read in user input while( hal.console->available() ) { uint8_t asciiInput = hal.console->read(); // Individual Motor: ASCII between 49-52 equates to keys 1-4 if (asciiInput >= 49 && asciiInput <=52){ motorSelected = asciiInput - 48; //Convert from ASCII to integer } // All Motors if (asciiInput == 53){ motorSelected = 5; // all motors } } if (motorSelected >=1 && motorSelected <=5){ //Check for valid menu selection motorMenu(motorSelected); } } void motorMenu(int motorSelected){ int valueInput = 0; // Remain with the selected motor until user requests to command different motor while (valueInput >= 0){ if (motorSelected <= 4){ //Individual Motor Menu hal.console->printf_P(PSTR("\n\n" "Current PWM command for [Motor %d] = %d\n" "Enter new PWM command or enter 'x' to return to motor select menu\n"), motorSelected,pwmValue); } if (motorSelected == 5){ //All Motors Menu hal.console->printf_P(PSTR("\n\n" "Current PWM command for [All motors] = %d\n" "Enter new PWM command or enter 'x' to return to motor select menu\n") ,pwmValue); } // wait for user input while( !hal.console->available() ) { hal.scheduler->delay(20); } int valueInput = 0; // read in user input while( hal.console->available() ) { uint8_t asciiInput = hal.console->read(); if (asciiInput == 88 || asciiInput == 120){ //ASCII for x, X valueInput = -1; return; // Return to motor select main menu } // ASCII for 0 is 48 if (asciiInput >= 48 && asciiInput <=57){ // is a key 0-9 valueInput = valueInput*10 + asciiInput - 48; } } // Command motor(s) to valueInput if (valueInput >= 0){ pwmValue = valueInput; if (motorSelected <= 4){ hal.rcout->write(motorSelected - 1, pwmValue); } if (motorSelected == 5){ hal.rcout->write(0,pwmValue); hal.rcout->write(1,pwmValue); hal.rcout->write(2,pwmValue); hal.rcout->write(3,pwmValue); } } } //end while (valueInput >= 0) } AP_HAL_MAIN();