MultiWii pro

Discussie in 'Multicopters' gestart door Michaëlp, 27 jun 2013.

  1. KeesvR

    KeesvR

    Lid geworden:
    25 jul 2010
    Berichten:
    482
    Locatie:
    Meteren
    Met de sketch die Vertigo aangeeft zou hij moeten werken mits het datzelfde bordje is.
    Voordat je deze nieuwe sketch laad kun je het beste eerst een Eeprom clear uitvoeren.
    Deze vind je onder Bestand/Voorbeelden/Eeprom even uploaden en klaar voor een verse start.

    Het verbaast mij trouwens dat je met de door jou gegeven 2.1 versie hebt kunnen vliegen, er is namelijk geen controler of losse sensor geselecteerd.
     
  2. Vertigo

    Vertigo

    Lid geworden:
    9 mei 2013
    Berichten:
    447
    Locatie:
    Mol, Belgie
    Die sketch is wel voor een quad, OP heeft een hexa. Andere zaken kunnen ook best fout staan, maar ik zou ook denken dat de GPS moet werken.

    Jawel hoor

    #define FFIMUv2 //

    En dat is correct.

    Ik heb overigens net dezelfde controller+gps besteld, dus ik hoop dat je het aan de praat krijgt :)
     
  3. KeesvR

    KeesvR

    Lid geworden:
    25 jul 2010
    Berichten:
    482
    Locatie:
    Meteren
    Inderdaad verkeerd gekeken.
     
  4. Michaëlp

    Michaëlp

    Lid geworden:
    27 jun 2013
    Berichten:
    39
    Dank Kees en Vertigo,

    Ik heb de Eeprom gewist zoals Kees zei, en nu doet de GPS het wel.
    Nu doet de Gimbal nog niets.
    En de volgende zin begrijp ik niet Vertigo: ACC= standaard instelling (geen angle of horizon)
    Vroeger kon ik die aan en uit zetten, maar ik zie nu geen ACC meer of Level.
    Ik heb alleen maar de Aux instellingen: arm, angle, horizon, baro, mag, headfree, headadj, gpshome en gps hold.
    Wat is het verschil overigens tussen headfree en headadj?
     
  5. Vertigo

    Vertigo

    Lid geworden:
    9 mei 2013
    Berichten:
    447
    Locatie:
    Mol, Belgie
    Zie ook post #10 in deze draad.

    ACC was de naam voor acro/accelerometers. Dat betekende dat je geen gyro's gebruikte, en dus geen autostabilisatie. Dat is nu nog steeds de standaard modus, al verschijnt die naam niet in de GUI. Als Angle en Horizon uit staan, ben je in "acc". Angle en horizon zijn 2 verschillende modi die de gyro's gebruiken voor autostab. Angle is wat vroeger "level" noemde, horizon is nieuw in 2.2 en iets tussen angle en acc. Zie ook weer de links in post 10 voor details en voor meer info ivm headfree.

    Camera stabilisatie, tja, dan heb je toch nog niet hard gezocht :)

    /*********************** Cam Stabilisation ***********************/
    /* The following lines apply only for a pitch/roll tilt stabilization system. Uncomment the first or second line to activate it */
    //#define SERVO_MIX_TILT
    //#define SERVO_TILT
     
  6. Michaëlp

    Michaëlp

    Lid geworden:
    27 jun 2013
    Berichten:
    39
    Dank je, ik ga morgen weer verder :)
     
  7. KeesvR

    KeesvR

    Lid geworden:
    25 jul 2010
    Berichten:
    482
    Locatie:
    Meteren
    Even een correctie op wat jij hier stelt, je wisselt de gyro en acc om.
    Gyro mode is acro en dus standaard zonder enige hulpmiddelen.
    Acc was level mode, deze word gebruikt bij angle mode en horizon.
    Angle is wat eerst level was.
    Horizon is nieuw in 2.2 en is een mix van angle en acro mode, boven een bepaalde stick uitslag word de Acc sensor uitgeschakeld.
     
  8. Michaëlp

    Michaëlp

    Lid geworden:
    27 jun 2013
    Berichten:
    39
    Ja, dat ACC was ik ook al mee in de war, maar ik heb nu ergens gevonden dat ACC, stabiele, level en hoek allemaal hetzelfde is.
    Volgens mij heb ik nu het meeste werkend in 2.2, alhoewel ik er nog niet in de praktijk mee gevlogen heb.
    Ik heb de Gimbal ook aan de praat, maar daar zit een of andere rare mix in, die er in de 2.1 ready made code ook al in zat, maar daar komn ik het onder de kolom output vinden onder, Bledi Experimentals, wat met een gimbal werkt die door 2 sevo's links en rechts gestuurd wordt, maar ik heb een gewone gimbal die een x en een y servo moet hebben.
    Ik kom er niet echt uit waar dat nou precies staat.

    IK doe de output instellingen erbij, misschien dat een van jullie weet waar dat zit.

    /**************************************************************************************/
    /*************** Motor Pin order ********************/
    /**************************************************************************************/
    // since we are uing the PWM generation in a direct way, the pin order is just to inizialie the right pins
    // its not possible to change a PWM output pin just by changing the order
    #if defined(PROMINI)
    uint8_t PWM_PIN[8] = {9,10,11,3,6,5,A2,12}; //for a quad+: rear,right,left,front
    #endif
    #if defined(PROMICRO)
    #if !defined(HWPWM6)
    #if !defined(TEENSY20)
    uint8_t PWM_PIN[8] = {9,10,5,6,4,A2,SW_PWM_P3,SW_PWM_P4}; //for a quad+: rear,right,left,front
    #else
    uint8_t PWM_PIN[8] = {14,15,9,12,22,18,16,17}; //for a quad+: rear,right,left,front
    #endif
    #else
    #if !defined(TEENSY20)
    uint8_t PWM_PIN[8] = {9,10,5,6,11,13,SW_PWM_P3,SW_PWM_P4}; //for a quad+: rear,right,left,front
    #else
    uint8_t PWM_PIN[8] = {14,15,9,12,4,10,16,17}; //for a quad+: rear,right,left,front
    #endif
    #endif
    #endif
    #if defined(MEGA)
    uint8_t PWM_PIN[8] = {3,5,6,2,7,8,9,10}; //for a quad+: rear,right,left,front //+ for y6: 7:under right 8:under left
    #endif

    /**************************************************************************************/
    /*************** Software PWM & Servo variables ********************/
    /**************************************************************************************/
    #if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6)) || (defined(MEGA) && defined(MEGA_HW_PWM_SERVOS))
    #if defined(SERVO)
    #if defined(AIRPLANE)|| defined(HELICOPTER)
    // To prevent motor to start at reset. atomicServo[7]=5 or 249 if reversed servo
    volatile uint8_t atomicServo[8] = {125,125,125,125,125,125,125,5};
    #else
    volatile uint8_t atomicServo[8] = {125,125,125,125,125,125,125,125};
    #endif
    #endif
    #if (NUMBER_MOTOR > 4)
    //for HEX Y6 and HEX6/HEX6X/HEX6H flat for promini
    volatile uint8_t atomicPWM_PIN5_lowState;
    volatile uint8_t atomicPWM_PIN5_highState;
    volatile uint8_t atomicPWM_PIN6_lowState;
    volatile uint8_t atomicPWM_PIN6_highState;
    #endif
    #if (NUMBER_MOTOR > 6)
    //for OCTO on promini
    volatile uint8_t atomicPWM_PINA2_lowState;
    volatile uint8_t atomicPWM_PINA2_highState;
    volatile uint8_t atomicPWM_PIN12_lowState;
    volatile uint8_t atomicPWM_PIN12_highState;
    #endif
    #else
    #if defined(SERVO)
    #if defined(AIRPLANE)|| defined(HELICOPTER)
    // To prevent motor to start at reset. atomicServo[7]=5 or 249 if reversed servo
    volatile uint16_t atomicServo[8] = {8000,8000,8000,8000,8000,8000,8000,320};
    #else
    volatile uint16_t atomicServo[8] = {8000,8000,8000,8000,8000,8000,8000,8000};
    #endif
    #endif
    #if (NUMBER_MOTOR > 4)
    //for HEX Y6 and HEX6/HEX6X/HEX6H and for Promicro
    volatile uint16_t atomicPWM_PIN5_lowState;
    volatile uint16_t atomicPWM_PIN5_highState;
    volatile uint16_t atomicPWM_PIN6_lowState;
    volatile uint16_t atomicPWM_PIN6_highState;
    #endif
    #if (NUMBER_MOTOR > 6)
    //for OCTO on Promicro
    volatile uint16_t atomicPWM_PINA2_lowState;
    volatile uint16_t atomicPWM_PINA2_highState;
    volatile uint16_t atomicPWM_PIN12_lowState;
    volatile uint16_t atomicPWM_PIN12_highState;
    #endif
    #endif

    /**************************************************************************************/
    /*************** Writes the Servos values to the needed format ********************/
    /**************************************************************************************/

    /**************** Cam stabilize Sevos ******************/
    #if defined(SERVO_TILT)
    #if defined(A0_A1_PIN_HEX) && (NUMBER_MOTOR == 6) && defined(PROMINI)
    #define S_PITCH servo[2]
    #define S_ROLL servo[3]
    #else
    #define S_PITCH servo[0]
    #define S_ROLL servo[1]
    #endif
    S_PITCH = TILT_PITCH_MIDDLE + rcData[AUX3]-1500;
    S_ROLL = TILT_ROLL_MIDDLE + rcData[AUX4]-1500;
    if (rcOptions[BOXCAMSTAB]) {
    S_PITCH += TILT_PITCH_PROP * angle[PITCH] /16 ;
    S_ROLL += TILT_ROLL_PROP * angle[ROLL] /16 ;
    }
    S_PITCH = constrain(S_PITCH, TILT_PITCH_MIN, TILT_PITCH_MAX);
    S_ROLL = constrain(S_ROLL , TILT_ROLL_MIN, TILT_ROLL_MAX );
    #endif

    /**************************************************************************************/
    /************ Writes the Motors values to the PWM compare register ******************/
    /**************************************************************************************/
    void writeMotors() { // [1000;2000] => [125;250]
    /**************** Specific PWM Timers & Registers for the MEGA's *******************/
    #if defined(MEGA)// [1000:2000] => [8000:16000] for timer 3 & 4 for mega
    #if (NUMBER_MOTOR > 0)
    #ifndef EXT_MOTOR_RANGE
    OCR3C = motor[0]<<3; // pin 3
    #else
    OCR3C = ((motor[0]<<4) - 16000) + 128;
    #endif
    #endif
    #if (NUMBER_MOTOR > 1)
    #ifndef EXT_MOTOR_RANGE
    OCR3A = motor[1]<<3; // pin 5
    #else
    OCR3A = ((motor[1]<<4) - 16000) + 128;
    #endif
    #endif
    #if (NUMBER_MOTOR > 2)
    #ifndef EXT_MOTOR_RANGE
    OCR4A = motor[2]<<3; // pin 6
    #else
    OCR4A = ((motor[2]<<4) - 16000) + 128;
    #endif
    #endif
    #if (NUMBER_MOTOR > 3)
    #ifndef EXT_MOTOR_RANGE
    OCR3B = motor[3]<<3; // pin 2
    #else
    OCR3B = ((motor[3]<<4) - 16000) + 128;
    #endif
    #endif
    #if (NUMBER_MOTOR > 4)
    #ifndef EXT_MOTOR_RANGE
    OCR4B = motor[4]<<3; // pin 7
    OCR4C = motor[5]<<3; // pin 8
    #else
    OCR4B = ((motor[4]<<4) - 16000) + 128;
    OCR4C = ((motor[5]<<4) - 16000) + 128;
    #endif
    #endif
    #if (NUMBER_MOTOR > 6)
    #ifndef EXT_MOTOR_RANGE
    OCR2B = motor[6]>>3; // pin 9
    OCR2A = motor[7]>>3; // pin 10
    #else
    OCR2B = (motor[6]>>2) - 250;
    OCR2A = (motor[7]>>2) - 250;
    #endif
    #endif
    #endif

    /******** Specific PWM Timers & Registers for the atmega32u4 (Promicro) ************/
    #if defined(PROMICRO)
    #if (NUMBER_MOTOR > 0) // Timer 1 A & B [1000:2000] => [8000:16000]
    #ifndef EXT_MOTOR_RANGE
    OCR1A = motor[0]<<3; // pin 9
    #else
    OCR1A = ((motor[0]<<4) - 16000) + 128;
    #endif
    #endif
    #if (NUMBER_MOTOR > 1)
    #ifndef EXT_MOTOR_RANGE
    OCR1B = motor[1]<<3; // pin 10
    #else
    OCR1B = ((motor[1]<<4) - 16000) + 128;
    #endif
    #endif
    #if (NUMBER_MOTOR > 2) // Timer 4 A & D [1000:2000] => [1000:2000]
    #if !defined(HWPWM6)
    // to write values > 255 to timer 4 A/B we need to split the bytes
    #ifndef EXT_MOTOR_RANGE
    TC4H = (2047-motor[2])>>8; OCR4A = ((2047-motor[2])&0xFF); // pin 5
    #else
    TC4H = 2047-(((motor[2]-1000)<<1)+16)>>8; OCR4A = (2047-(((motor[2]-1000)<<1)+16)&0xFF); // pin 5
    #endif
    #else
    #ifndef EXT_MOTOR_RANGE
    OCR3A = motor[2]<<3; // pin 5
    #else
    OCR3A = ((motor[2]<<4) - 16000) + 128;
    #endif
    #endif
    #endif
    #if (NUMBER_MOTOR > 3)
    #ifndef EXT_MOTOR_RANGE
    TC4H = motor[3]>>8; OCR4D = (motor[3]&0xFF); // pin 6
    #else
    TC4H = (((motor[3]-1000)<<1)+16)>>8; OCR4D = ((((motor[3]-1000)<<1)+16)&0xFF); // pin 6
    #endif
    #endif
    #if (NUMBER_MOTOR > 4)
    #if !defined(HWPWM6)
    #if (NUMBER_MOTOR == 6) && !defined(SERVO)
    atomicPWM_PIN5_highState = motor[4]<<3;
    atomicPWM_PIN5_lowState = 16383-atomicPWM_PIN5_highState;
    atomicPWM_PIN6_highState = motor[5]<<3;
    atomicPWM_PIN6_lowState = 16383-atomicPWM_PIN6_highState;
    #else
    atomicPWM_PIN5_highState = ((motor[4]-1000)<<4)+320;
    atomicPWM_PIN5_lowState = 15743-atomicPWM_PIN5_highState;
    atomicPWM_PIN6_highState = ((motor[5]-1000)<<4)+320;
    atomicPWM_PIN6_lowState = 15743-atomicPWM_PIN6_highState;
    #endif
    #else
    #ifndef EXT_MOTOR_RANGE
    OCR1C = motor[4]<<3; // pin 11
    TC4H = motor[5]>>8; OCR4A = (motor[5]&0xFF); // pin 13
    #else
    OCR1C = ((motor[4]<<4) - 16000) + 128;
    TC4H = (((motor[5]-1000)<<1)+16)>>8; OCR4A = ((((motor[5]-1000)<<1)+16)&0xFF); // pin 13
    #endif
    #endif
    #endif
    #if (NUMBER_MOTOR > 6)
    #if !defined(HWPWM6)
    atomicPWM_PINA2_highState = ((motor[6]-1000)<<4)+320;
    atomicPWM_PINA2_lowState = 15743-atomicPWM_PINA2_highState;
    atomicPWM_PIN12_highState = ((motor[7]-1000)<<4)+320;
    atomicPWM_PIN12_lowState = 15743-atomicPWM_PIN12_highState;
    #else
    atomicPWM_PINA2_highState = ((motor[6]-1000)>>2)+5;
    atomicPWM_PINA2_lowState = 245-atomicPWM_PINA2_highState;
    atomicPWM_PIN12_highState = ((motor[7]-1000)>>2)+5;
    atomicPWM_PIN12_lowState = 245-atomicPWM_PIN12_highState;
    #endif
    #endif
    #endif

    /******** Specific PWM Timers & Registers for the atmega328P (Promini) ************/
    #if defined(PROMINI)
    #if (NUMBER_MOTOR > 0)
    #ifndef EXT_MOTOR_RANGE
    OCR1A = motor[0]>>3; // pin 9
    #else
    OCR1A = ((motor[0]>>2) - 250);
    #endif
    #endif
    #if (NUMBER_MOTOR > 1)
    #ifndef EXT_MOTOR_RANGE
    OCR1B = motor[1]>>3; // pin 10
    #else
    OCR1B = ((motor[1]>>2) - 250);
    #endif
    #endif
    #if (NUMBER_MOTOR > 2)
    #ifndef EXT_MOTOR_RANGE
    OCR2A = motor[2]>>3; // pin 11
    #else
    OCR2A = ((motor[2]>>2) - 250);
    #endif
    #endif
    #if (NUMBER_MOTOR > 3)
    #ifndef EXT_MOTOR_RANGE
    OCR2B = motor[3]>>3; // pin 3
    #else
    OCR2B = ((motor[3]>>2) - 250);
    #endif
    #endif
    #if (NUMBER_MOTOR > 4)
    #if (NUMBER_MOTOR == 6) && !defined(SERVO)
    #ifndef EXT_MOTOR_RANGE
    atomicPWM_PIN6_highState = motor[4]>>3;
    atomicPWM_PIN5_highState = motor[5]>>3;
    #else
    atomicPWM_PIN6_highState = (motor[4]>>2) - 250;
    atomicPWM_PIN5_highState = (motor[5]>>2) - 250;
    #endif
    atomicPWM_PIN6_lowState = 255-atomicPWM_PIN6_highState;
    atomicPWM_PIN5_lowState = 255-atomicPWM_PIN5_highState;
    #else //note: EXT_MOTOR_RANGE not possible here
    atomicPWM_PIN6_highState = ((motor[4]-1000)>>2)+5;
    atomicPWM_PIN6_lowState = 245-atomicPWM_PIN6_highState;
    atomicPWM_PIN5_highState = ((motor[5]-1000)>>2)+5;
    atomicPWM_PIN5_lowState = 245-atomicPWM_PIN5_highState;
    #endif
    #endif
    #if (NUMBER_MOTOR > 6) //note: EXT_MOTOR_RANGE not possible here
    atomicPWM_PINA2_highState = ((motor[6]-1000)>>2)+5;
    atomicPWM_PINA2_lowState = 245-atomicPWM_PINA2_highState;
    atomicPWM_PIN12_highState = ((motor[7]-1000)>>2)+5;
    atomicPWM_PIN12_lowState = 245-atomicPWM_PIN12_highState;
    #endif
    #endif
    }

    /**************************************************************************************/
    /************ Writes the mincommand to all Motors ******************/
    /**************************************************************************************/
    void writeAllMotors(int16_t mc) { // Sends commands to all motors
    for (uint8_t i =0;i<NUMBER_MOTOR;i++) {
    motor=mc;
    }
    writeMotors();
    }

    /**************************************************************************************/
    /************ Initialize the PWM Timers and Registers ******************/
    /**************************************************************************************/
    void initOutput() {
    /**************** mark all PWM pins as Output ******************/
    for(uint8_t i=0;i<NUMBER_MOTOR;i++) {
    pinMode(PWM_PIN,OUTPUT);
    }

    /**************** Specific PWM Timers & Registers for the MEGA's ******************/
    #if defined(MEGA)
    #if (NUMBER_MOTOR > 0)
    // init 16bit timer 3
    TCCR3A |= (1<<WGM31); // phase correct mode
    TCCR3A &= ~(1<<WGM30);
    TCCR3B |= (1<<WGM33);
    TCCR3B &= ~(1<<CS31); // no prescaler
    ICR3 |= 0x3FFF; // TOP to 16383;

    TCCR3A |= _BV(COM3C1); // connect pin 3 to timer 3 channel C
    #endif
    #if (NUMBER_MOTOR > 1)
    TCCR3A |= _BV(COM3A1); // connect pin 5 to timer 3 channel A
    #endif
    #if (NUMBER_MOTOR > 2)
    // init 16bit timer 4
    TCCR4A |= (1<<WGM41); // phase correct mode
    TCCR4A &= ~(1<<WGM40);
    TCCR4B |= (1<<WGM43);
    TCCR4B &= ~(1<<CS41); // no prescaler
    ICR4 |= 0x3FFF; // TOP to 16383;

    TCCR4A |= _BV(COM4A1); // connect pin 6 to timer 4 channel A
    #endif
    #if (NUMBER_MOTOR > 3)
    TCCR3A |= _BV(COM3B1); // connect pin 2 to timer 3 channel B
    #endif
    #if (NUMBER_MOTOR > 4)
    TCCR4A |= _BV(COM4B1); // connect pin 7 to timer 4 channel B
    TCCR4A |= _BV(COM4C1); // connect pin 8 to timer 4 channel C
    #endif
    #if (NUMBER_MOTOR > 6)
    // timer 2 is a 8bit timer so we cant change its range
    TCCR2A |= _BV(COM2B1); // connect pin 9 to timer 2 channel B
    TCCR2A |= _BV(COM2A1); // connect pin 10 to timer 2 channel A
    #endif
    #endif

    /******** Specific PWM Timers & Registers for the atmega32u4 (Promicro) ************/
    #if defined(PROMICRO)
    #if (NUMBER_MOTOR > 0)
    TCCR1A |= (1<<WGM11); // phase correct mode & no prescaler
    TCCR1A &= ~(1<<WGM10);
    TCCR1B &= ~(1<<WGM12) & ~(1<<CS11) & ~(1<<CS12);
    TCCR1B |= (1<<WGM13) | (1<<CS10);
    ICR1 |= 0x3FFF; // TOP to 16383;
    TCCR1A |= _BV(COM1A1); // connect pin 9 to timer 1 channel A
    #endif
    #if (NUMBER_MOTOR > 1)
    TCCR1A |= _BV(COM1B1); // connect pin 10 to timer 1 channel B
    #endif
    #if (NUMBER_MOTOR > 2)
    #if !defined(HWPWM6) // timer 4A
    TCCR4E |= (1<<ENHC4); // enhanced pwm mode
    TCCR4B &= ~(1<<CS41); TCCR4B |= (1<<CS42)|(1<<CS40); // prescaler to 16
    TCCR4D |= (1<<WGM40); TC4H = 0x3; OCR4C = 0xFF; // phase and frequency correct mode & top to 1023 but with enhanced pwm mode we have 2047
    TCCR4A |= (1<<COM4A0)|(1<<PWM4A); // connect pin 5 to timer 4 channel A
    #else // timer 3A
    TCCR3A |= (1<<WGM31); // phase correct mode & no prescaler
    TCCR3A &= ~(1<<WGM30);
    TCCR3B &= ~(1<<WGM32) & ~(1<<CS31) & ~(1<<CS32);
    TCCR3B |= (1<<WGM33) | (1<<CS30);
    ICR3 |= 0x3FFF; // TOP to 16383;
    TCCR3A |= _BV(COM3A1); // connect pin 5 to timer 3 channel A
    #endif
    #endif
    #if (NUMBER_MOTOR > 3)
    #if defined(HWPWM6)
    TCCR4E |= (1<<ENHC4); // enhanced pwm mode
    TCCR4B &= ~(1<<CS41); TCCR4B |= (1<<CS42)|(1<<CS40); // prescaler to 16
    TCCR4D |= (1<<WGM40); TC4H = 0x3; OCR4C = 0xFF; // phase and frequency correct mode & top to 1023 but with enhanced pwm mode we have 2047
    #endif
    TCCR4C |= (1<<COM4D1)|(1<<PWM4D); // connect pin 6 to timer 4 channel D
    #endif
    #if (NUMBER_MOTOR > 4)
    #if defined(HWPWM6)
    TCCR1A |= _BV(COM1C1); // connect pin 11 to timer 1 channel C
    TCCR4A |= (1<<COM4A1)|(1<<PWM4A); // connect pin 13 to timer 4 channel A
    #else
    initializeSoftPWM();
    #endif
    #endif
    #if (NUMBER_MOTOR > 6)
    #if defined(HWPWM6)
    initializeSoftPWM();
    #endif
    #endif
    #endif

    /******** Specific PWM Timers & Registers for the atmega328P (Promini) ************/
    #if defined(PROMINI)
    #if (NUMBER_MOTOR > 0)
    TCCR1A |= _BV(COM1A1); // connect pin 9 to timer 1 channel A
    #endif
    #if (NUMBER_MOTOR > 1)
    TCCR1A |= _BV(COM1B1); // connect pin 10 to timer 1 channel B
    #endif
    #if (NUMBER_MOTOR > 2)
    TCCR2A |= _BV(COM2A1); // connect pin 11 to timer 2 channel A
    #endif
    #if (NUMBER_MOTOR > 3)
    TCCR2A |= _BV(COM2B1); // connect pin 3 to timer 2 channel B
    #endif
    #if (NUMBER_MOTOR > 5) // PIN 5 & 6 or A0 & A1
    initializeSoftPWM();
    #if defined(A0_A1_PIN_HEX) || (NUMBER_MOTOR > 6)
    pinMode(5,INPUT);pinMode(6,INPUT); // we reactivate the INPUT affectation for these two PINs
    pinMode(A0,OUTPUT);pinMode(A1,OUTPUT);
    #endif
    #endif
    #endif

    /******** special version of MultiWii to calibrate all attached ESCs ************/
    #if defined(ESC_CALIB_CANNOT_FLY)
    writeAllMotors(ESC_CALIB_HIGH);
    delay(3000);
    writeAllMotors(ESC_CALIB_LOW);
    delay(500);
    while (1) {
    delay(5000);
    blinkLED(2,20, 2);
    #if defined(BUZZER)
    alarmArray[7] = 2;
    #endif
    }
    exit; // statement never reached
    #endif

    writeAllMotors(MINCOMMAND);
    delay(300);
    #if defined(SERVO)
    initializeServo();
    #endif
    }


    #if defined(SERVO)
    /**************************************************************************************/
    /************ Initialize the PWM Servos ******************/
    /**************************************************************************************/
    void initializeServo() {
    #if (PRI_SERVO_FROM == 1) || (SEC_SERVO_FROM == 1)
    SERVO_1_PINMODE;
    #endif
    #if (PRI_SERVO_FROM <= 2 && PRI_SERVO_TO >= 2) || (SEC_SERVO_FROM <= 2 && SEC_SERVO_TO >= 2)
    SERVO_2_PINMODE;
    #endif
    #if (PRI_SERVO_FROM <= 3 && PRI_SERVO_TO >= 3) || (SEC_SERVO_FROM <= 3 && SEC_SERVO_TO >= 3)
    SERVO_3_PINMODE;
    #endif
    #if (PRI_SERVO_FROM <= 4 && PRI_SERVO_TO >= 4) || (SEC_SERVO_FROM <= 4 && SEC_SERVO_TO >= 4)
    SERVO_4_PINMODE;
    #endif
    #if (PRI_SERVO_FROM <= 5 && PRI_SERVO_TO >= 5) || (SEC_SERVO_FROM <= 5 && SEC_SERVO_TO >= 5)
    SERVO_5_PINMODE;
    #endif
    #if (PRI_SERVO_FROM <= 6 && PRI_SERVO_TO >= 6) || (SEC_SERVO_FROM <= 6 && SEC_SERVO_TO >= 6)
    SERVO_6_PINMODE;
    #endif
    #if (PRI_SERVO_FROM <= 7 && PRI_SERVO_TO >= 7) || (SEC_SERVO_FROM <= 7 && SEC_SERVO_TO >= 7)
    SERVO_7_PINMODE;
    #endif
    #if (PRI_SERVO_FROM <= 8 && PRI_SERVO_TO >= 8) || (SEC_SERVO_FROM <= 8 && SEC_SERVO_TO >= 8)
    SERVO_8_PINMODE;
    #endif

    #if defined(SERVO_1_HIGH)
    #if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6)) // uses timer 0 Comperator A (8 bit)
    TCCR0A = 0; // normal counting mode
    TIMSK0 |= (1<<OCIE0A); // Enable CTC interrupt
    #define SERVO_ISR TIMER0_COMPA_vect
    #define SERVO_CHANNEL OCR0A
    #define SERVO_1K_US 250
    #endif
    #if (defined(PROMICRO) && !defined(HWPWM6)) // uses timer 3 Comperator A (11 bit)
    TCCR3A &= ~(1<<WGM30) & ~(1<<WGM31); //normal counting & no prescaler
    TCCR3B &= ~(1<<WGM32) & ~(1<<CS31) & ~(1<<CS32) & ~(1<<WGM33);
    TCCR3B |= (1<<CS30);
    TIMSK3 |= (1<<OCIE3A); // Enable CTC interrupt
    #define SERVO_ISR TIMER3_COMPA_vect
    #define SERVO_CHANNEL OCR3A
    #define SERVO_1K_US 16000
    #endif
    #if defined(MEGA) // uses timer 5 Comperator A (11 bit)
    TCCR5A &= ~(1<<WGM50) & ~(1<<WGM51); //normal counting & no prescaler
    TCCR5B &= ~(1<<WGM52) & ~(1<<CS51) & ~(1<<CS52) & ~(1<<WGM53);
    TCCR5B |= (1<<CS50);
    TIMSK5 |= (1<<OCIE5A); // Enable CTC interrupt
    #define SERVO_ISR TIMER5_COMPA_vect
    #define SERVO_CHANNEL OCR5A
    #define SERVO_1K_US 16000
    #endif
    #endif
    // init Timer 1 and 5 of the mega for hw PWM gimbal servos
    #if defined(MEGA) && defined(MEGA_HW_PWM_SERVOS)
    TIMSK5 &= ~(1<<OCIE5A); // Disable software PWM
    TCCR5A |= (1<<WGM51); // phase correct mode & prescaler to 8
    TCCR5A &= ~(1<<WGM50);
    TCCR5B &= ~(1<<WGM52) & ~(1<<CS50) & ~(1<<CS52);
    TCCR5B |= (1<<WGM53) | (1<<CS51);
    pinMode(44,OUTPUT);
    TCCR5A |= (1<<COM5C1); // pin 44
    pinMode(45,OUTPUT);
    TCCR5A |= (1<<COM5B1); // pin 45
    pinMode(46,OUTPUT);
    TCCR5A |= (1<<COM5A1); // pin 46
    TCCR1A |= (1<<WGM11); // phase correct mode & prescaler to 8
    TCCR1A &= ~(1<<WGM10);
    TCCR1B &= ~(1<<WGM12) & ~(1<<CS10) & ~(1<<CS12);
    TCCR1B |= (1<<WGM13) | (1<<CS11);
    pinMode(11,OUTPUT);
    TCCR1A |= (1<<COM1A1); // pin 11
    pinMode(12,OUTPUT);
    TCCR1A |= (1<<COM1B1); // pin 12
    #if defined(SERVO_RFR_50HZ)
    ICR1 = 16700; // TOP to 16700;
    ICR5 = 16700; // TOP to 16700;
    #endif
    #if defined(SERVO_RFR_160HZ)
    ICR1 = 6200; // TOP to 6200;
    ICR5 = 6200; // TOP to 6200;
    #endif
    #if defined(SERVO_RFR_300HZ)
    ICR1 = 3330; // TOP to 3330;
    ICR5 = 3330; // TOP to 3330;
    #endif
    #endif
    }

    /**************************************************************************************/
    /************ Servo software PWM generation ******************/
    /**************************************************************************************/

    // prescaler is set by default to 64 on Timer0
    // Duemilanove : 16MHz / 64 => 4 us
    // 256 steps = 1 counter cycle = 1024 us

    // for servo 2-8
    // its almost the same as for servo 1
    #if defined(SERVO_1_HIGH)
    #define SERVO_PULSE(PIN_HIGH,ACT_STATE,SERVO_NUM,LAST_PIN_LOW) \
    }else if(state == ACT_STATE){ \
    LAST_PIN_LOW; \
    PIN_HIGH; \
    SERVO_CHANNEL+=SERVO_1K_US; \
    state++; \
    }else if(state == ACT_STATE+1){ \
    SERVO_CHANNEL+=atomicServo[SERVO_NUM]; \
    state++; \

    ISR(SERVO_ISR) {
    static uint8_t state = 0; // indicates the current state of the chain
    if(state == 0){
    SERVO_1_HIGH; // set servo 1's pin high
    SERVO_CHANNEL+=SERVO_1K_US; // wait 1000us
    state++; // count up the state
    }else if(state==1){
    SERVO_CHANNEL+=atomicServo[SERVO_1_ARR_POS]; // load the servo's value (0-1000us)
    state++; // count up the state
    #if defined(SERVO_2_HIGH)
    SERVO_PULSE(SERVO_2_HIGH,2,SERVO_2_ARR_POS,SERVO_1_LOW); // the same here
    #endif
    #if defined(SERVO_3_HIGH)
    SERVO_PULSE(SERVO_3_HIGH,4,SERVO_3_ARR_POS,SERVO_2_LOW);
    #endif
    #if defined(SERVO_4_HIGH)
    SERVO_PULSE(SERVO_4_HIGH,6,SERVO_4_ARR_POS,SERVO_3_LOW);
    #endif
    #if defined(SERVO_5_HIGH)
    SERVO_PULSE(SERVO_5_HIGH,8,SERVO_5_ARR_POS,SERVO_4_LOW);
    #endif
    #if defined(SERVO_6_HIGH)
    SERVO_PULSE(SERVO_6_HIGH,10,SERVO_6_ARR_POS,SERVO_5_LOW);
    #endif
    #if defined(SERVO_7_HIGH)
    SERVO_PULSE(SERVO_7_HIGH,12,SERVO_7_ARR_POS,SERVO_6_LOW);
    #endif
    #if defined(SERVO_8_HIGH)
    SERVO_PULSE(SERVO_8_HIGH,14,SERVO_8_ARR_POS,SERVO_7_LOW);
    #endif
    }else{
    LAST_LOW;
    #if defined(SERVO_RFR_300HZ)
    #if defined(SERVO_3_HIGH) // if there are 3 or more servos we dont need to slow it down
    SERVO_CHANNEL+=(SERVO_1K_US>>3); // 0 would be better but it causes bad jitter
    state=0;
    #else // if there are less then 3 servos we need to slow it to not go over 300Hz (the highest working refresh rate for the digital servos for what i know..)
    SERVO_CHANNEL+=SERVO_1K_US;
    if(state<4){
    state+=2;
    }else{
    state=0;
    }
    #endif
    #endif
    #if defined(SERVO_RFR_160HZ)
    #if defined(SERVO_4_HIGH) // if there are 4 or more servos we dont need to slow it down
    SERVO_CHANNEL+=(SERVO_1K_US>>3); // 0 would be better but it causes bad jitter
    state=0;
    #else // if there are less then 4 servos we need to slow it to not go over ~170Hz (the highest working refresh rate for analog servos)
    SERVO_CHANNEL+=SERVO_1K_US;
    if(state<8){
    state+=2;
    }else{
    state=0;
    }
    #endif
    #endif
    #if defined(SERVO_RFR_50HZ) // to have ~ 50Hz for all servos
    SERVO_CHANNEL+=SERVO_1K_US;
    if(state<30){
    state+=2;
    }else{
    state=0;
    }
    #endif
    }
    }
    #endif
    #endif

    /**************************************************************************************/
    /************ Motor software PWM generation ******************/
    /**************************************************************************************/
    // SW PWM is only used if there are not enough HW PWM pins (for exampe hexa on a promini)

    #if (NUMBER_MOTOR > 4) && (defined(PROMINI) || defined(PROMICRO))

    /**************** Pre define the used ISR's and Timerchannels ******************/
    #if !defined(PROMICRO)
    #define SOFT_PWM_ISR1 TIMER0_COMPB_vect
    #define SOFT_PWM_ISR2 TIMER0_COMPA_vect
    #define SOFT_PWM_CHANNEL1 OCR0B
    #define SOFT_PWM_CHANNEL2 OCR0A
    #elif !defined(HWPWM6)
    #define SOFT_PWM_ISR1 TIMER3_COMPB_vect
    #define SOFT_PWM_ISR2 TIMER3_COMPC_vect
    #define SOFT_PWM_CHANNEL1 OCR3B
    #define SOFT_PWM_CHANNEL2 OCR3C
    #else
    #define SOFT_PWM_ISR2 TIMER0_COMPB_vect
    #define SOFT_PWM_CHANNEL2 OCR0B
    #endif

    /**************** Initialize Timers and PWM Channels ******************/
    void initializeSoftPWM() {
    #if !defined(PROMICRO)
    TCCR0A = 0; // normal counting mode
    #if (NUMBER_MOTOR > 4) && !defined(HWPWM6)
    TIMSK0 |= (1<<OCIE0B); // Enable CTC interrupt
    #endif
    #if (NUMBER_MOTOR > 6) || ((NUMBER_MOTOR == 6) && !defined(SERVO))
    TIMSK0 |= (1<<OCIE0A);
    #endif
    #else
    #if !defined(HWPWM6)
    TCCR3A &= ~(1<<WGM30) & ~(1<<WGM31); //normal counting & no prescaler
    TCCR3B &= ~(1<<WGM32) & ~(1<<CS31) & ~(1<<CS32) & ~(1<<WGM33);
    TCCR3B |= (1<<CS30);
    TIMSK3 |= (1<<OCIE3B); // Enable CTC interrupt
    #if (NUMBER_MOTOR > 6) || ((NUMBER_MOTOR == 6) && !defined(SERVO))
    TIMSK3 |= (1<<OCIE3C);
    #endif
    #else
    TCCR0A = 0; // normal counting mode
    TIMSK0 |= (1<<OCIE0B); // Enable CTC interrupt
    #endif
    #endif
    }

    /**************** Motor SW PWM ISR's ******************/
    // hexa with old but sometimes better SW PWM method
    // for setups without servos
    #if (NUMBER_MOTOR == 6) && (!defined(SERVO) && !defined(HWPWM6))
    ISR(SOFT_PWM_ISR1) {
    static uint8_t state = 0;
    if(state == 0){
    if (atomicPWM_PIN5_highState>0) SOFT_PWM_1_PIN_HIGH;
    SOFT_PWM_CHANNEL1 += atomicPWM_PIN5_highState;
    state = 1;
    }else if(state == 1){
    SOFT_PWM_CHANNEL1 += atomicPWM_PIN5_highState;
    state = 2;
    }else if(state == 2){
    SOFT_PWM_1_PIN_LOW;
    SOFT_PWM_CHANNEL1 += atomicPWM_PIN5_lowState;
    state = 3;
    }else if(state == 3){
    SOFT_PWM_CHANNEL1 += atomicPWM_PIN5_lowState;
    state = 0;
    }
    }
    ISR(SOFT_PWM_ISR2) {
    static uint8_t state = 0;
    if(state == 0){
    if (atomicPWM_PIN6_highState>0) SOFT_PWM_2_PIN_HIGH;
    SOFT_PWM_CHANNEL2 += atomicPWM_PIN6_highState;
    state = 1;
    }else if(state == 1){
    SOFT_PWM_CHANNEL2 += atomicPWM_PIN6_highState;
    state = 2;
    }else if(state == 2){
    SOFT_PWM_2_PIN_LOW;
    SOFT_PWM_CHANNEL2 += atomicPWM_PIN6_lowState;
    state = 3;
    }else if(state == 3){
    SOFT_PWM_CHANNEL2 += atomicPWM_PIN6_lowState;
    state = 0;
    }
    }
    #else
    #if (NUMBER_MOTOR > 4) && !defined(HWPWM6)
    // HEXA with just OCR0B
    ISR(SOFT_PWM_ISR1) {
    static uint8_t state = 0;
    if(state == 0){
    SOFT_PWM_1_PIN_HIGH;
    SOFT_PWM_CHANNEL1 += atomicPWM_PIN5_highState;
    state = 1;
    }else if(state == 1){
    SOFT_PWM_2_PIN_LOW;
    SOFT_PWM_CHANNEL1 += atomicPWM_PIN6_lowState;
    state = 2;
    }else if(state == 2){
    SOFT_PWM_2_PIN_HIGH;
    SOFT_PWM_CHANNEL1 += atomicPWM_PIN6_highState;
    state = 3;
    }else if(state == 3){
    SOFT_PWM_1_PIN_LOW;
    SOFT_PWM_CHANNEL1 += atomicPWM_PIN5_lowState;
    state = 0;
    }
    }
    #endif
    //the same with digital PIN A2 & 12 OCR0A counter for OCTO
    #if (NUMBER_MOTOR > 6)
    ISR(SOFT_PWM_ISR2) {
    static uint8_t state = 0;
    if(state == 0){
    SOFT_PWM_3_PIN_HIGH;
    SOFT_PWM_CHANNEL2 += atomicPWM_PINA2_highState;
    state = 1;
    }else if(state == 1){
    SOFT_PWM_4_PIN_LOW;
    SOFT_PWM_CHANNEL2 += atomicPWM_PIN12_lowState;
    state = 2;
    }else if(state == 2){
    SOFT_PWM_4_PIN_HIGH;
    SOFT_PWM_CHANNEL2 += atomicPWM_PIN12_highState;
    state = 3;
    }else if(state == 3){
    SOFT_PWM_3_PIN_LOW;
    SOFT_PWM_CHANNEL2 += atomicPWM_PINA2_lowState;
    state = 0;
    }
    }
    #endif
    #endif
    #endif


    /**************************************************************************************/
    /********** Mixes the Computed stabilize values to the Motors & Servos ***************/
    /**************************************************************************************/
    void mixTable() {
    int16_t maxMotor;
    uint8_t i;

    #define PIDMIX(X,Y,Z) rcCommand[THROTTLE] + axisPID[ROLL]*X + axisPID[PITCH]*Y + YAW_DIRECTION * axisPID[YAW]*Z

    #if NUMBER_MOTOR > 3
    //prevent "yaw jump" during yaw correction
    axisPID[YAW] = constrain(axisPID[YAW],-100-abs(rcCommand[YAW]),+100+abs(rcCommand[YAW]));
    #endif
    /**************** main Mix Table ******************/
    #ifdef MY_PRIVATE_MIXING
    #include MY_PRIVATE_MIXING
    #else
    #ifdef BI
    motor[0] = PIDMIX(+1, 0, 0); //LEFT
    motor[1] = PIDMIX(-1, 0, 0); //RIGHT
    servo[4] = constrain(1500 + (YAW_DIRECTION * axisPID[YAW]) + (BI_PITCH_DIRECTION * axisPID[PITCH]), 1020, 2000); //LEFT
    servo[5] = constrain(1500 + (YAW_DIRECTION * axisPID[YAW]) - (BI_PITCH_DIRECTION * axisPID[PITCH]), 1020, 2000); //RIGHT
    #endif
    #ifdef TRI
    motor[0] = PIDMIX( 0,+4/3, 0); //REAR
    motor[1] = PIDMIX(-1,-2/3, 0); //RIGHT
    motor[2] = PIDMIX(+1,-2/3, 0); //LEFT
    servo[5] = constrain(conf.tri_yaw_middle + YAW_DIRECTION * axisPID[YAW], TRI_YAW_CONSTRAINT_MIN, TRI_YAW_CONSTRAINT_MAX); //REAR
    #endif
    #ifdef QUADP
    motor[0] = PIDMIX( 0,+1,-1); //REAR
    motor[1] = PIDMIX(-1, 0,+1); //RIGHT
    motor[2] = PIDMIX(+1, 0,+1); //LEFT
    motor[3] = PIDMIX( 0,-1,-1); //FRONT
    #endif
    #ifdef QUADX
    motor[0] = PIDMIX(-1,+1,-1); //REAR_R
    motor[1] = PIDMIX(-1,-1,+1); //FRONT_R
    motor[2] = PIDMIX(+1,+1,+1); //REAR_L
    motor[3] = PIDMIX(+1,-1,-1); //FRONT_L
    #endif
    #ifdef Y4
    motor[0] = PIDMIX(+0,+1,-1); //REAR_1 CW
    motor[1] = PIDMIX(-1,-1, 0); //FRONT_R CCW
    motor[2] = PIDMIX(+0,+1,+1); //REAR_2 CCW
    motor[3] = PIDMIX(+1,-1, 0); //FRONT_L CW
    #endif
    #ifdef Y6
    motor[0] = PIDMIX(+0,+4/3,+1); //REAR
    motor[1] = PIDMIX(-1,-2/3,-1); //RIGHT
    motor[2] = PIDMIX(+1,-2/3,-1); //LEFT
    motor[3] = PIDMIX(+0,+4/3,-1); //UNDER_REAR
    motor[4] = PIDMIX(-1,-2/3,+1); //UNDER_RIGHT
    motor[5] = PIDMIX(+1,-2/3,+1); //UNDER_LEFT
    #endif
    #ifdef HEX6
    motor[0] = PIDMIX(-7/8,+1/2,+1); //REAR_R
    motor[1] = PIDMIX(-7/8,-1/2,-1); //FRONT_R
    motor[2] = PIDMIX(+7/8,+1/2,+1); //REAR_L
    motor[3] = PIDMIX(+7/8,-1/2,-1); //FRONT_L
    motor[4] = PIDMIX(+0 ,-1 ,+1); //FRONT
    motor[5] = PIDMIX(+0 ,+1 ,-1); //REAR
    #endif
    #ifdef HEX6X
    motor[0] = PIDMIX(-1/2,+7/8,+1); //REAR_R
    motor[1] = PIDMIX(-1/2,-7/8,+1); //FRONT_R
    motor[2] = PIDMIX(+1/2,+7/8,-1); //REAR_L
    motor[3] = PIDMIX(+1/2,-7/8,-1); //FRONT_L
    motor[4] = PIDMIX(-1 ,+0 ,-1); //RIGHT
    motor[5] = PIDMIX(+1 ,+0 ,+1); //LEFT
    #endif
    #ifdef HEX6H
    motor[0] = PIDMIX(-1,+1,-1); //REAR_R
    motor[1] = PIDMIX(-1,-1,+1); //FRONT_R
    motor[2] = PIDMIX(+ 1,+1,+1); //REAR_L
    motor[3] = PIDMIX(+ 1,-1,-1); //FRONT_L
    motor[4] = PIDMIX(0 ,0 ,0); //RIGHT
    motor[5] = PIDMIX(0 ,0 ,0); //LEFT
    #endif
    #ifdef OCTOX8
    motor[0] = PIDMIX(-1,+1,-1); //REAR_R
    motor[1] = PIDMIX(-1,-1,+1); //FRONT_R
    motor[2] = PIDMIX(+1,+1,+1); //REAR_L
    motor[3] = PIDMIX(+1,-1,-1); //FRONT_L
    motor[4] = PIDMIX(-1,+1,+1); //UNDER_REAR_R
    motor[5] = PIDMIX(-1,-1,-1); //UNDER_FRONT_R
    motor[6] = PIDMIX(+1,+1,-1); //UNDER_REAR_L
    motor[7] = PIDMIX(+1,-1,+1); //UNDER_FRONT_L
    #endif
    #ifdef OCTOFLATP
    motor[0] = PIDMIX(+7/10,-7/10,+1); //FRONT_L
    motor[1] = PIDMIX(-7/10,-7/10,+1); //FRONT_R
    motor[2] = PIDMIX(-7/10,+7/10,+1); //REAR_R
    motor[3] = PIDMIX(+7/10,+7/10,+1); //REAR_L
    motor[4] = PIDMIX(+0 ,-1 ,-1); //FRONT
    motor[5] = PIDMIX(-1 ,+0 ,-1); //RIGHT
    motor[6] = PIDMIX(+0 ,+1 ,-1); //REAR
    motor[7] = PIDMIX(+1 ,+0 ,-1); //LEFT
    #endif
    #ifdef OCTOFLATX
    motor[0] = PIDMIX(+1 ,-1/2,+1); //MIDFRONT_L
    motor[1] = PIDMIX(-1/2,-1 ,+1); //FRONT_R
    motor[2] = PIDMIX(-1 ,+1/2,+1); //MIDREAR_R
    motor[3] = PIDMIX(+1/2,+1 ,+1); //REAR_L
    motor[4] = PIDMIX(+1/2,-1 ,-1); //FRONT_L
    motor[5] = PIDMIX(-1 ,-1/2,-1); //MIDFRONT_R
    motor[6] = PIDMIX(-1/2,+1 ,-1); //REAR_R
    motor[7] = PIDMIX(+1 ,+1/2,-1); //MIDREAR_L
    #endif
    #ifdef VTAIL4
    motor[0] = PIDMIX(+0,+1, +1); //REAR_R
    motor[1] = PIDMIX(-1, -1, +0); //FRONT_R
    motor[2] = PIDMIX(+0,+1, -1); //REAR_L
    motor[3] = PIDMIX(+1, -1, -0); //FRONT_L
    #endif

    /**************** Cam stabilize Servos ******************/
    #if defined(SERVO_TILT)
    #if defined(A0_A1_PIN_HEX) && (NUMBER_MOTOR == 6) && defined(PROMINI)
    #define S_PITCH servo[2]
    #define S_ROLL servo[3]
    #else
    #define S_PITCH servo[0]
    #define S_ROLL servo[1]
    #endif
    #ifdef TILT_PITCH_AUX_CH
    S_PITCH = TILT_PITCH_MIDDLE + rcData[TILT_PITCH_AUX_CH]-1500;
    #else
    S_PITCH = TILT_PITCH_MIDDLE;
    #endif
    #ifdef TILT_ROLL_AUX_CH
    S_ROLL = TILT_ROLL_MIDDLE + rcData[TILT_ROLL_AUX_CH]-1500;
    #else
    S_ROLL = TILT_ROLL_MIDDLE;
    #endif
    if (rcOptions[BOXCAMSTAB]) {
    S_PITCH += TILT_PITCH_PROP * angle[PITCH] /16 ;
    S_ROLL += TILT_ROLL_PROP * angle[ROLL] /16 ;
    }
    S_PITCH = constrain(S_PITCH, TILT_PITCH_MIN, TILT_PITCH_MAX);
    S_ROLL = constrain(S_ROLL , TILT_ROLL_MIN, TILT_ROLL_MAX );
    #endif

    //#if defined(MEGA) && defined(MEGA_HW_PWM_SERVOS) && !defined(FIXEDWING) && !defined(HELICOPTER) && (RC_CHANS>8) //<- this part is not clean
    // servo[3] = rcData[8];
    // servo[4] = rcData[9];
    //#endif

    #ifdef SERVO_MIX_TILT
    #if defined(A0_A1_PIN_HEX) && (NUMBER_MOTOR == 6) && defined(PROMINI)
    #define S_PITCH servo[2]
    #define S_ROLL servo[3]
    #else
    #define S_PITCH servo[0]
    #define S_ROLL servo[1]
    #endif
    int16_t angleP,angleR;
    #ifdef TILT_PITCH_AUX_CH
    angleP = TILT_PITCH_MIDDLE - 1500 + rcData[TILT_PITCH_AUX_CH]-1500;
    #else
    angleP = TILT_PITCH_MIDDLE - 1500;
    #endif
    #ifdef TILT_ROLL_AUX_CH
    angleR = TILT_ROLL_MIDDLE - 1500 + rcData[TILT_ROLL_AUX_CH]-1500;
    #else
    angleR = TILT_ROLL_MIDDLE - 1500;
    #endif
    if (rcOptions[BOXCAMSTAB]) {
    angleP += TILT_PITCH_PROP * angle[PITCH] /16 ;
    angleR += TILT_ROLL_PROP * angle[ROLL] /16 ;
    }
    S_PITCH = constrain(1500+angleP-angleR, TILT_PITCH_MIN, TILT_PITCH_MAX);
    S_ROLL = constrain(1500-angleP-angleR, TILT_ROLL_MIN, TILT_ROLL_MAX);
    #endif

    #ifdef GIMBAL
    servo[0] = constrain(TILT_PITCH_MIDDLE + TILT_PITCH_PROP * angle[PITCH] /16 + rcCommand[PITCH], TILT_PITCH_MIN, TILT_PITCH_MAX);
    servo[1] = constrain(TILT_ROLL_MIDDLE + TILT_ROLL_PROP * angle[ROLL] /16 + rcCommand[ROLL], TILT_ROLL_MIN, TILT_ROLL_MAX);
    #endif

    #if defined(FLYING_WING)
    motor[0] = rcCommand[THROTTLE];
    if (f.PASSTHRU_MODE) {// do not use sensors for correction, simple 2 channel mixing
    servo[0] = PITCH_DIRECTION_L * (rcData[PITCH]-MIDRC) + ROLL_DIRECTION_L * (rcData[ROLL]-MIDRC);
    servo[1] = PITCH_DIRECTION_R * (rcData[PITCH]-MIDRC) + ROLL_DIRECTION_R * (rcData[ROLL]-MIDRC);
    } else { // use sensors to correct (gyro only or gyro+acc according to aux1/aux2 configuration
    servo[0] = PITCH_DIRECTION_L * axisPID[PITCH] + ROLL_DIRECTION_L * axisPID[ROLL];
    servo[1] = PITCH_DIRECTION_R * axisPID[PITCH] + ROLL_DIRECTION_R * axisPID[ROLL];
    }
    servo[0] = constrain(servo[0] + conf.wing_left_mid , WING_LEFT_MIN, WING_LEFT_MAX );
    servo[1] = constrain(servo[1] + conf.wing_right_mid, WING_RIGHT_MIN, WING_RIGHT_MAX);
    #endif

    /************************************************************************************************************/
    #if defined(AIRPLANE) || defined(SINGLECOPTER) || defined(DUALCOPTER)
    // Common parts for Plane and Heli
    static int16_t servoMid[8]; // Midpoint on servo
    static uint8_t servoTravel[8] = SERVO_RATES; // Rates in 0-100%
    static int8_t servoReverse[8] = SERVO_DIRECTION ; // Inverted servos
    static int16_t servoLimit[8][2]; // Holds servoLimit data

    /***************************
    * servo endpoints Airplane.
    ***************************/
    #define SERVO_MIN 1020 // limit servo travel range must be inside [1020;2000]
    #define SERVO_MAX 2000 // limit servo travel range must be inside [1020;2000]
    for(i=0; i<8; i++){ // Set rates with 0 - 100%.
    servoMid =MIDRC + conf.servoTrim;
    servoLimit[0]=servoMid-((servoMid-SERVO_MIN) *(servoTravel*0.01));
    servoLimit[1]=servoMid+((SERVO_MAX - servoMid) *(servoTravel*0.01));
    }

    // servo[7] is programmed with safty features to avoid motorstarts when ardu reset..
    // All other servos go to center at reset.. Half throttle can be dangerus
    // Only use servo[7] as motorcontrol if motor is used in the setup */
    if (!f.ARMED){
    servo[7] = MINCOMMAND; // Kill throttle when disarmed
    } else {
    servo[7] = rcData[THROTTLE];
    }

    // Flapperon Controll
    int16_t flapperons[2]={0,0};
    #if defined(FLAPPERONS) && defined(FLAPPERON_EP)
    int8_t flapinv[2] = FLAPPERON_INVERT;
    static int16_t F_Endpoint[2] = FLAPPERON_EP;
    int16_t flap =MIDRC-constrain(rcData[FLAPPERONS],F_Endpoint[0],F_Endpoint[1]);
    static int16_t slowFlaps= flap;
    #if defined(FLAPSPEED)
    if (slowFlaps < flap ){slowFlaps+=FLAPSPEED;}else if(slowFlaps > flap){slowFlaps-=FLAPSPEED;}
    #else
    slowFlaps = flap;
    #endif
    flap = MIDRC-(constrain(MIDRC-slowFlaps,F_Endpoint[0],F_Endpoint[1]));
    for(i=0; i<2; i++){flapperons = flap * flapinv ;}
    #endif

    // Traditional Flaps on A2
    #if defined(FLAPS) && defined(FLAP_EP)
    static int16_t lF_Endpoint[2] = FLAP_EP;
    int16_t lFlap = MIDRC-constrain(rcData[FLAPS],lF_Endpoint[0],lF_Endpoint[1]);
    static int16_t slow_LFlaps= lFlap;
    #if defined(FLAPSPEED)
    if (slow_LFlaps < lFlap ){slow_LFlaps+=FLAPSPEED;}else if(slow_LFlaps > lFlap){slow_LFlaps-=FLAPSPEED;}
    #else
    slow_LFlaps = lFlap;
    #endif
    servo[2] = servoMid[2]+(slow_LFlaps *servoReverse[2]);
    #endif

    #if defined(AIRPLANE)
    if(f.PASSTHRU_MODE){ // Direct passthru from RX
    servo[3] = servoMid[3]+((rcCommand[ROLL] + flapperons[0]) *servoReverse[3]); // Wing 1
    servo[4] = servoMid[4]+((rcCommand[ROLL] + flapperons[1]) *servoReverse[4]); // Wing 2
    servo[5] = servoMid[5]+(rcCommand[YAW] *servoReverse[5]); // Rudder
    servo[6] = servoMid[6]+(rcCommand[PITCH] *servoReverse[6]); // Elevator
    }else{
    // Assisted modes (gyro only or gyro+acc according to AUX configuration in Gui
    servo[3] =(servoMid[3] + ((axisPID[ROLL] + flapperons[0]) *servoReverse[3])); // Wing 1
    servo[4] =(servoMid[4] + ((axisPID[ROLL] + flapperons[1]) *servoReverse[4])); // Wing 2
    servo[5] =(servoMid[5] + (axisPID[YAW] *servoReverse[5])); // Rudder
    servo[6] =(servoMid[6] + (axisPID[PITCH] *servoReverse[6])); // Elevator
    }
    #endif
    /****************** single & DualCopter **********************/
    #if defined(SINGLECOPTER)
    int8_t yawServo[4] =SINGLECOPTRER_YAW;
    int8_t scServo[4] =SINGLECOPTRER_SERVO;
    // Singlecopter
    // This is a beta requested by xuant9
    // Assisted modes (gyro only or gyro+acc according to AUX configuration in Gui
    // http://www.kkmulticopter.kr/multicopter/images/blue_single.jpg
    servo[3] = servoMid[3] + (axisPID[YAW]*yawServo[0]) + (axisPID[PITCH]*scServo[0]) ; // SideServo 5 D12
    servo[4] = servoMid[4] + (axisPID[YAW]*yawServo[1]) + (axisPID[PITCH]*scServo[1]) ; // SideServo 3 D11
    servo[5] = servoMid[5] + (axisPID[YAW]*yawServo[2]) + (axisPID[ROLL] *scServo[2]) ; // FrontServo 2 D3
    servo[6] = servoMid[6] + (axisPID[YAW]*yawServo[3]) + (axisPID[ROLL] *scServo[3]) ; // RearServo 4 D10
    motor[1] = rcData[THROTTLE] ; // Pin D10
    #endif
    #if defined(DUALCOPTER)
    int8_t dcServo[2] =DUALCOPTER_SERVO;
    // Dualcopter
    // This is a beta requested by xuant9
    // Assisted modes (gyro only or gyro+acc according to AUX configuration in Gui
    //http://www.kkmulticopter.kr/products_pic/index.html?sn=multicopter_v02_du&name=KKMultiCopter%20Flight%20Controller%20Blackboard%3Cbr%3E
    servo[5] = servoMid[5] + (axisPID[PITCH] * dcServo[0]) ; // PITCHServo 3 D12
    servo[6] = servoMid[6] + (axisPID[ROLL] * dcServo[1]) ; // ROLLServo 4 D11
    motor[0] = PIDMIX(0,0,-1); // Pin D9
    motor[1] = PIDMIX(0,0,+1); // Pin D10
    #endif

    // ServoRates
    #if !defined(USE_THROTTLESERVO)
    motor[0]= rcData[THROTTLE];
    #endif
    for(i=3;i<8;i++){
    servo = map(servo, SERVO_MIN, SERVO_MAX,servoLimit[0],servoLimit[1]);
    servo = constrain( servo, SERVO_MIN, SERVO_MAX);
    }

    #endif // AIRPLANE || SINGLECOPTER || DUALCOPTER

    /************************************************************************************************************/
    #ifdef HELICOPTER
    // Common controlls for Helicopters
    int16_t heliRoll,heliNick;
    int16_t collRange[3] = COLLECTIVE_RANGE;
    static int16_t collective;
    static int16_t servoEndpiont[8][2];
    static int16_t servoHigh[8] = SERVO_ENDPOINT_HIGH; // HIGHpoint on servo
    static int16_t servoLow[8] = SERVO_ENDPOINT_LOW ; // LOWpoint on servo
    #ifdef GOVERNOR_P
    static int16_t last_collective = 0, delta_collective = 0, governorThrottle = 0;
    #endif
    /***************************
    * servo settings Heli.
    ***************************/
    for(i=0; i<8; i++){ // Set rates using endpoints.
    servoEndpiont[i][0] = servoLow[i]; //Min
    servoEndpiont[i][1] = servoHigh[i]; //Max
    }

    // Limit Collective range up/down
    int16_t collect = rcData[COLLECTIVE_PITCH] - (1500 + collRange[1]);
    if (collect>0) {
    collective = collect * (collRange[2]*0.01);
    } else{
    collective = collect * (collRange[0]*0.01);
    }
    #ifdef GOVERNOR_P
    delta_collective = collective - last_collective;
    last_collective = collective;
    if (! f.ARMED || ! rcOptions[BOXGOV] || (rcData[THROTTLE] < conf.minthrottle) )
    governorThrottle = 0; // clear subito
    else if (delta_collective > 0) {
    governorThrottle += delta_collective * conf.governorP; // attack
    // avoid overshooting governor (would result in overly long decay phase)
    if (rcData[THROTTLE] + governorThrottle > MAXTHROTTLE) governorThrottle = MAXTHROTTLE - rcData[THROTTLE];
    } else {
    static uint8_t d = 0;
    if (! (++d % conf.governorD)) governorThrottle -= 10; // decay; signal stepsize 10 should be smooth on most ESCs
    }
    if (governorThrottle < 0) governorThrottle = 0; // always beware of negative impact of governor on throttle
    #endif

    if(f.PASSTHRU_MODE){ // Use Rcdata Without sensors
    heliRoll= rcCommand[ROLL] ;
    heliNick= rcCommand[PITCH];
    } else{ // Assisted modes
    heliRoll= axisPID[ROLL];
    heliNick= axisPID[PITCH];
    }

    // Limit Maximum Rates for Heli
    int16_t cRange[2] = CONTROL_RANGE;
    heliRoll*=cRange[0]*0.01;
    heliNick*=cRange[1]*0.01;

    // Yaw is common for Heli 90 & 120
    uint16_t yawControll = YAW_CENTER + (axisPID[YAW]*YAW_DIRECTION) + conf.servoTrim[5];

    /* Throttle & YAW
    ********************
    Handeled in common functions for Heli */
    if (!f.ARMED){
    servo[7] = 900; // Kill throttle when disarmed
    if (YAWMOTOR){servo[5] = MINCOMMAND;} else {servo[5] = yawControll; } // Kill YAWMOTOR when disarmed
    }else {
    servo[7] = rcData[THROTTLE]; // 50hz ESC or servo
    #ifdef GOVERNOR_P
    servo[7] += governorThrottle;
    #endif
    if (YAWMOTOR && rcData[THROTTLE] < conf.minthrottle){servo[5] = MINCOMMAND;}
    else{ servo[5] = yawControll; } // YawSero
    }
    #ifndef HELI_USE_SERVO_FOR_THROTTLE
    motor[0] = servo[7]; // use real motor output - ESC capable
    #endif


    // ( Collective, Pitch/Nick, Roll ) Change sign to invert
    /************************************************************************************************************/
    #define HeliXPIDMIX(Z,Y,X) 1500 + (collRange[1]*Z + collective*Z + heliNick*Y + heliRoll*X)/10
    // original #define HeliXPIDMIX(Z,Y,X) collRange[1]+collective*Z + heliNick*Y + heliRoll*X

    #ifdef HELI_120_CCPM
    static int8_t nickMix[3] =SERVO_NICK;
    static int8_t leftMix[3] =SERVO_LEFT;
    static int8_t rightMix[3]=SERVO_RIGHT;

    servo[3] = HeliXPIDMIX( ( nickMix[0]), nickMix[1], nickMix[2]) + conf.servoTrim[3] ; // NICK servo
    servo[4] = HeliXPIDMIX( ( leftMix[0]), leftMix[1], leftMix[2]) + conf.servoTrim[4] ; // LEFT servo
    servo[6] = HeliXPIDMIX( (rightMix[0]),rightMix[1],rightMix[2]) + conf.servoTrim[6] ; // RIGHT servo
    #endif

    /************************************************************************************************************/
    #ifdef HELI_90_DEG
    static int8_t servoDir[3]=SERVO_DIRECTIONS;
    servo[3] = HeliXPIDMIX( +0, servoDir[1], -0)+conf.servoTrim[3] ; // NICK servo
    servo[4] = HeliXPIDMIX( +0, +0, servoDir[2])+conf.servoTrim[4] ; // ROLL servo
    servo[6] = HeliXPIDMIX( servoDir[0], +0, +0)+conf.servoTrim[6] ; // COLLECTIVE servo
    #endif

    for(i=3;i<8;i++){
    servo[i] = constrain( servo[i], servoEndpiont[i][0], servoEndpiont[i][1] );
    }

    #endif // HELICOPTER

    #endif //MY_PRIVATE_MIXING
    /**************** Cam trigger Sevo ******************/
    #if defined(CAMTRIG)
    static uint8_t camCycle = 0;
    static uint8_t camState = 0;
    static uint32_t camTime = 0;
    if (camCycle==1) {
    if (camState == 0) {
    servo[2] = CAM_SERVO_HIGH;
    camState = 1;
    camTime = millis();
    } else if (camState == 1) {
    if ( (millis() - camTime) > CAM_TIME_HIGH ) {
    servo[2] = CAM_SERVO_LOW;
    camState = 2;
    camTime = millis();
    }
    } else { //camState ==2
    if ( (millis() - camTime) > CAM_TIME_LOW ) {
    camState = 0;
    camCycle = 0;
    }
    }
    }
    if (rcOptions[BOXCAMTRIG]) camCycle=1;
    #endif
    /**************** neutralize Servos during calibration of gyro&acc ******************/
    #ifdef SERVO
    if ( (!f.ARMED) && ((calibratingG > 0) || (calibratingA > 0)) ) servos2Neutral();
    #endif
    /**************** Filter the Motors values ******************/
    #ifdef GOVERNOR_P
    if (rcOptions[BOXGOV] ) {
    static int8_t g[37] = { 0,3,5,8,11,14,17,19,22,25,28,31,34,38,41,44,47,51,54,58,61,65,68,72,76,79,83,87,91,95,99,104,108,112,117,121,126 };
    uint8_t v = constrain( VBATNOMINAL - constrain(vbat, conf.vbatlevel_crit, VBATNOMINAL), 0, 36);
    for (i = 0; i < NUMBER_MOTOR; i++) {
    motor[i] += ( ( (int32_t)(motor[i]-1000) * (int32_t)g[v] ) * (int32_t)conf.governorR )/ 5000;
    }
    }
    #endif
    /**************** normalize the Motors values ******************/
    #ifdef LEAVE_HEADROOM_FOR_MOTORS
    // limit this leaving room for corrections to the first #n of all motors
    maxMotor=motor[0];
    for(i=1; i < LEAVE_HEADROOM_FOR_MOTORS; i++)
    if (motor[i]>maxMotor) maxMotor=motor[i];
    if (maxMotor > MAXTHROTTLE) { // this is a way to still have good gyro corrections if at least one motor reaches its max.
    for(i=0; i < LEAVE_HEADROOM_FOR_MOTORS; i++)
    motor[i] -= maxMotor - MAXTHROTTLE;
    }
    for (i = 0; i < NUMBER_MOTOR; i++) {
    motor[i] = constrain(motor[i], conf.minthrottle, MAXTHROTTLE);
    #if defined(ALTHOLD_FAST_THROTTLE_CHANGE)
    if (rcData[THROTTLE] < MINCHECK)
    #else
    if ((rcData[THROTTLE] < MINCHECK) && !f.BARO_MODE)
    #endif
    #ifndef MOTOR_STOP
    motor[i] = conf.minthrottle;
    #else
    motor[i] = MINCOMMAND;
    #endif
    if (!f.ARMED)
    motor[i] = MINCOMMAND;
    }
    #else // LEAVE_HEADROOM_FOR_MOTORS
    maxMotor=motor[0];
    for(i=1; i< NUMBER_MOTOR; i++)
    if (motor[i]>maxMotor) maxMotor=motor[i];
    for(i=0; i< NUMBER_MOTOR; i++) {
    if (maxMotor > MAXTHROTTLE) // this is a way to still have good gyro corrections if at least one motor reaches its max.
    motor[i] -= maxMotor - MAXTHROTTLE;
    motor[i] = constrain(motor[i], conf.minthrottle, MAXTHROTTLE);
    #if defined(ALTHOLD_FAST_THROTTLE_CHANGE)
    if (rcData[THROTTLE] < MINCHECK)
    #else
    if ((rcData[THROTTLE] < MINCHECK) && !f.BARO_MODE)
    #endif
    #ifndef MOTOR_STOP
    motor[i] = conf.minthrottle;
    #else
    motor[i] = MINCOMMAND;
    #endif
    if (!f.ARMED)
    motor[i] = MINCOMMAND;
    }
    #endif // LEAVE_HEADROOM_FOR_MOTORS
    /**************** Powermeter Log ******************/
    #if (LOG_VALUES >= 3) || defined(POWERMETER_SOFT)
    uint16_t amp, ampsum;
    /* true cubic function;
    * when divided by vbat_max=126 (12.6V) for 3 cell battery this gives maximum value of ~ 500
    * when divided by no_vbat=60 (6V) for 3 cell battery this gives maximum value of ~ 1000
    * */

    static uint16_t amperes[64] = { 0, 2, 6, 15, 30, 52, 82,123,
    175,240,320,415,528,659,811,984,
    1181,1402,1648,1923,2226,2559,2924,3322,
    3755,4224,4730,5276,5861,6489,7160,7875,
    8637 ,9446 ,10304,11213,12173,13187,14256,15381,
    16564,17805,19108,20472,21900,23392,24951,26578,
    28274,30041,31879,33792,35779,37843,39984,42205,
    44507,46890,49358,51910,54549,57276,60093,63000};

    if (vbat > conf.no_vbat) { // by all means - must avoid division by zero
    ampsum = 0;
    for (i =0;i<NUMBER_MOTOR;i++) {
    amp = amperes[ ((motor[i] - 1000)>>4) ] / vbat; // range mapped from [1000:2000] => [0:1000]; then break that up into 64 ranges; lookup amp
    #if (LOG_VALUES >= 3)
    pMeter[i]+= amp; // sum up over time the mapped ESC input
    #endif
    #if defined(POWERMETER_SOFT)
    ampsum += amp; // total sum over all motors
    #endif
    }
    #if defined(POWERMETER_SOFT)
    pMeter[PMOTOR_SUM]+= ampsum; // total sum over all motors
    #endif
    }
    #endif
    }[/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i]
     
  9. Michaëlp

    Michaëlp

    Lid geworden:
    27 jun 2013
    Berichten:
    39
    Bedankt zover.
     
  10. Ridder

    Ridder

    Lid geworden:
    14 jun 2013
    Berichten:
    109
    Locatie:
    Maasland
    Ik heb een HK Multiwii Pro (met GPS) besteld voor mijn zelfbouw project.
    Nu lees ik dat het ook mogelijk zou moeten zijn om MegaPirate software er op te zetten.
    Mijn vraag is: heeft dat voordelen tov MW 2.2?
     
  11. Vertigo

    Vertigo

    Lid geworden:
    9 mei 2013
    Berichten:
    447
    Locatie:
    Mol, Belgie
    Ik zou van die output file afblijven. Heb je met deze settings al eens geexperimenteerd/

    /* The following lines apply only for a pitch/roll tilt stabilization system. Uncomment the first or second line to activate it */
    //#define SERVO_MIX_TILT
    //#define SERVO_TILT

    Probeers eens enkel de tweede lijn te uncommenten. Die eerste daar staat "mix" in :)
     
  12. Vertigo

    Vertigo

    Lid geworden:
    9 mei 2013
    Berichten:
    447
    Locatie:
    Mol, Belgie
    Ik denk dat de voordelen vooral op het gebied van GPS zit. Multiwii is hier best wel zwak in. Je hebt position hold en RTH, maar dat is het zo ongeveer. Ik heb zelfs nog niet gevonden hoe ik RTH kan doen als failsafe optie, laat staan instellen welke hoogte, autonoom landen etc. Waypoints is ook nog ver zoek.

    Ik heb nog niet te veel gelezen over Megapirate, maar ik dacht dat je daar veel en veel meer mee kon.

    ArduCopter - arducopter - Arduino-based autopilot for mulitrotor craft, from quadcopters to traditional helis - Google Project Hosting
     
  13. Rick F

    Rick F

    Lid geworden:
    17 feb 2013
    Berichten:
    45
    Locatie:
    Wierden
    Heb zelf ook een multiwii pro van HK gehad , en ook de megapirate op gezet. Het vliegt heel goed , alle functies werken al goed met de standaard PID's , zelf loiter en RTL.. Alitude mode kan iets verschillen , maar komt ook omdat je een watje / schuimpje over je barometer moet doen.
    Enige ander wijziging kan misschien de P rate zijn van stabilize mode. Heeft je multi met de eerste vlucht last van oscillatie moet je de P staps gewijs lager zetten tot het goed is

    Echter heb je alleen een probleem als je de software wilt upgraden, dit kan niet via de standaard firmware optie in de mission planner. Dit zal dan ook via Arduino moeten gebeuren. Niet dat het een probleem is want je moet het nu alsnog via Arduino doen.

    Link naar de juiste code:
    https://code.google.com/p/megapirateng/
    Versie 2.8_R3
     
  14. Michaëlp

    Michaëlp

    Lid geworden:
    27 jun 2013
    Berichten:
    39
    Ik ga het morgenavond proberen, ik heb hier geen pc waar de Arduino software op draait zonder foutmeldingen.
    Ik heb zojuist met de 2.2 software gevlogen met GPS hold aan, waarbij hij een fix had, maar toch bleef hij niet op dezelfde plaats hangen.
    Toen hij 50 meter bij mij vandaan was en dreigde de bomen te raken, wat allemaal nogal snel ging probeerde ik hem snel te landen, iets wat niet goed ging en nogal wat schade veroorzaakte.
    2 armen afgebroken en een gebarsten :-(
    Dus echt goed gaat het nog steeds niet.
    Zou de GPS hem niet juist de verkeerde kant opsturen omdat een sensor die hij aangestuurd omgekeerd moet worden, net als ik eerst bij de Yaw had waardoor hij onmiddellijk ging draaien, en welke instelling zou dat dan kunnen zijn?
    Is er overigens ook Arduino software voor Android waar ik de code mee kan veranderen?
     
  15. quadraf

    quadraf

    Lid geworden:
    16 jan 2012
    Berichten:
    44
    Locatie:
    Deurne
    Hallo,
    Ik denk dat je de magnetometer bedoeld, die moet goed afgeregeld zijn anders werkt de GPS niet goed zoals je ondervonden hebt...

    Hans
     
  16. Vertigo

    Vertigo

    Lid geworden:
    9 mei 2013
    Berichten:
    447
    Locatie:
    Mol, Belgie
    Ik denk ook dat het een goed idee is om eerst te leren vliegen, vooraleer op de gps te rekenen om je uit de penarie te helpen of houden. Ik wil niet gemeen klinken, en ik ben zelf nog niet bepaald een expert, maar als de gps je richting bomen vliegt, dan zou je geen probleem mogen hebben om hem terug de juiste kant op te sturen. Ik vermoed dat die hexa je eerste multirotor is? Mag ik je van harte aanraden om een microquad te kopen (hubsan X4, Walkera ladybird, ...) en daar zo veel mogelijk mee te oefenen? Kost niks, kan je naar hartelust mee crashen (mja, meestal toch) en is fantastisch om te leren vliegen. Is nog fun ook.
     
  17. Michaëlp

    Michaëlp

    Lid geworden:
    27 jun 2013
    Berichten:
    39
    Ja, dit is mijn eerste multirotor, heb wel ervaring met ander soort modellen, maar heb het idee dat de GPS mij onmiddellijk de verkeerde kant op brengt, dat was eerst met die Yaw instelling ook toen die verkeerd stond, die begon ook onmiddellijk de andere kant op te draaien wanneer ik probeerde tegen te sturen en dat ging met zo'n hoge snelheid dat dat bijna niet te corrigeren was, omdat die hoe harder het toestel draaide hoe harder die tegen ging sturen.
    Quadraf heeft het over de magnetometer, maar hoe wordt die in de software 2.2 dan genoemd?
    Zo'n microquad is misschien ook wel een goed idee.
    Bedankt, Michael
     
  18. Michaëlp

    Michaëlp

    Lid geworden:
    27 jun 2013
    Berichten:
    39
    Of bedoel je met magnetometer het kompas wat je moet kalibreren?
    Ik heb sowieso niet zo goed begrepen hoe je hem kalibreert, je drukt er op en moet hem dan 30 sec ronddraaien of zo?
    Is dat dan alleen in het horizontale vlak, en wanneer zijn die 30 sec voorbij, ik zie namelijk geen enkel teken wanneer hij daar mee klaar is en of hij echt wat doet.
    Bij de Yaw moest ik in de code een - voor een 1 zetten heb ik ontdekt, zou dat hier niet het geval kunnen zijn?
     
  19. quadraf

    quadraf

    Lid geworden:
    16 jan 2012
    Berichten:
    44
    Locatie:
    Deurne
    Zo:
    In de gui druk je op mag calibrate en verder draai je in alle 3 richtingen 360graden: Horizontaal, Pitch en Roll richting:
    Calibrating the Magnetometer

    Hans
     
  20. Michaëlp

    Michaëlp

    Lid geworden:
    27 jun 2013
    Berichten:
    39
    Hoi Hans bedankt,

    Dus dan druk je 1 maal op mag calibrate, en dan draai je hem vervolgens in alle 3 de richtingen achter elkaar 1 maal rond en dan druk je op write?

    Michael
     

Deel Deze Pagina