示例#1
0
void menu_rc_setup(void)
{
	uint8_t cursor = LINE0;
	uint8_t top = RCSTART;
	uint8_t temp = 0;
	int8_t values[RCITEMS];
	menu_range_t range;
	uint8_t i = 0;
	uint8_t text_link;
	
	while(button != BACK)
	{
		// Load values from eeprom
		memcpy(&values[0],&Config.TxSeq,sizeof(int8_t) * RCITEMS);

		// Print menu
		print_menu_items(top, RCSTART, &values[0], RCITEMS, (prog_uchar*)rc_menu_ranges, RCOFFSET, (prog_uchar*)RCMenuText, cursor);

		// Handle menu changes
		update_menu(RCITEMS, RCSTART, button, &cursor, &top, &temp);
		range = get_menu_range ((prog_uchar*)rc_menu_ranges, temp - RCSTART);

		if (button == ENTER)
		{
			text_link = pgm_read_byte(&RCMenuText[temp - RCSTART]);
			values[temp - RCSTART] = do_menu_item(temp, values[temp - RCSTART], range, 0, text_link);
		}

		// Update value in config structure
		memcpy(&Config.TxSeq,&values[0],sizeof(int8_t) * RCITEMS);

		// Update Ch7. mixer with source from Config.FlapChan if in Aeroplane mode
		if (Config.MixMode == AEROPLANE)
		{
			Config.Channel[CH7].source_a = Config.FlapChan;
		}

		if (button == ENTER)
		{
			// Update channel sequence
			for (i = 0; i < MAX_RC_CHANNELS; i++)
			{
				if (Config.TxSeq == JRSEQ) 
				{
					Config.ChannelOrder[i] = pgm_read_byte(&JR[i]);
				}
				else if (Config.TxSeq == FUTABASEQ)
				{
					Config.ChannelOrder[i] = pgm_read_byte(&FUTABA[i]);
				}
			}
			Save_Config_to_EEPROM(); // Save value and return
		}
	}
}
示例#2
0
void menu_battery(void)
{
	uint8_t cursor = LINE0;
	uint8_t top = BATTSTART;
	uint8_t temp = 0;
	int16_t values[BATTITEMS];
	menu_range_t range;
	uint8_t text_link = 0;
	uint8_t temp_cells = 0;
	uint16_t temp_minvoltage = 0;
	
	while(button != BACK)
	{
		// Load values from eeprom
		memcpy(&values[0],&Config.BatteryType,sizeof(int16_t) * BATTITEMS);

		// Save pre-edited values
		temp_cells = Config.BatteryCells;
		temp_minvoltage = Config.MinVoltage;

		// Print menu
		print_menu_items_16(top, BATTSTART, &values[0], (prog_uchar*)batt_menu_ranges, BATTOFFSET, (prog_uchar*)BattMenuText, cursor);

		// Handle menu changes
		update_menu(BATTITEMS, BATTSTART, button, &cursor, &top, &temp);
		range = get_menu_range ((prog_uchar*)batt_menu_ranges, temp - BATTSTART);

		if (button == ENTER)
		{
			text_link = pgm_read_byte(&BattMenuText[temp - BATTSTART]);
			values[temp - BATTSTART] = do_menu_item(temp, values[temp - BATTSTART], range, 0, text_link);
		}

		// See if cell number or min_volts has changed
		if ((temp_cells != values[1]) || (temp_minvoltage != values[4]))
		{
			values[2] = values[1] * values[4];
			Config.PowerTrigger = values[2];
		}

		// Update value in config structure
		memcpy(&Config.BatteryType,&values[0],sizeof(int16_t) * BATTITEMS);

		if (button == ENTER)
		{
			Save_Config_to_EEPROM(); // Save value and return
		}
	}
}
示例#3
0
void menu_mixer(uint8_t i)
{
	uint8_t cursor = LINE0;
	uint8_t top = MIXERSTART;
	int8_t values[MIXERITEMS];
	menu_range_t range;
	uint8_t temp = 0;
	uint8_t text_link = 0;

	while(button != BACK)
	{
		// Load values from eeprom
		memcpy(&values[0],&Config.Channel[i].source_a,sizeof(int8_t) * MIXERITEMS);

		// Print menu
		print_menu_items(top, MIXERSTART, &values[0], MIXERITEMS,(prog_uchar*)mixer_menu_ranges, MIXOFFSET, (prog_uchar*)MixerMenuText, cursor);

		// Handle menu changes
		update_menu(MIXERITEMS, MIXERSTART, button, &cursor, &top, &temp);
		range = get_menu_range ((prog_uchar*)mixer_menu_ranges, temp - MIXERSTART);

		if (button == ENTER)
		{
			text_link = pgm_read_byte(&MixerMenuText[temp - MIXERSTART]);
			values[temp - MIXERSTART] = do_menu_item(temp, values[temp - MIXERSTART], range, 0, text_link);
		}

		// Update value in config structure
		memcpy(&Config.Channel[i].source_a,&values[0],sizeof(int8_t) * MIXERITEMS);

		if (button == ENTER)
		{
			UpdateLimits();			 // Update travel limits based on percentages
			Save_Config_to_EEPROM(); // Save value and return
		}
	}
	menu_beep(1);
	_delay_ms(200);
}
示例#4
0
void menu_al_control(void)
{
	uint8_t cursor = LINE0;
	uint8_t top = AUTOSTART;
	uint8_t temp = 0;
	int8_t values[AUTOITEMS];
	menu_range_t range;
	uint8_t text_link = 0;
	
	while(button != BACK)
	{
		// Load values from eeprom
		memcpy(&values[0],&Config.AutoMode,sizeof(int8_t) * AUTOITEMS);

		// Print menu
		print_menu_items(top, AUTOSTART, &values[0], AUTOITEMS, (prog_uchar*)auto_menu_ranges, AUTOOFFSET, (prog_uchar*)AutoMenuText, cursor);

		// Handle menu changes
		update_menu(AUTOITEMS, AUTOSTART, button, &cursor, &top, &temp);
		range = get_menu_range ((prog_uchar*)auto_menu_ranges, temp - AUTOSTART);

		if (button == ENTER)
		{
			text_link = pgm_read_byte(&AutoMenuText[temp - AUTOSTART]);
			values[temp - AUTOSTART] = do_menu_item(temp, values[temp - AUTOSTART], range, 0, text_link);
		}

		// Update value in config structure
		memcpy(&Config.AutoMode,&values[0],sizeof(int8_t) * AUTOITEMS);

		if (button == ENTER)
		{
			UpdateLimits();			 // Update I-term limits and triggers based on percentages
			Save_Config_to_EEPROM(); // Save value and return
		}
	}
}
示例#5
0
void menu_mixer(uint8_t section)
{
	static uint8_t mix_top = MIXERSTART;
	static	uint8_t old_section;
	int8_t *value_ptr;

	int8_t values[INPUTITEMS+1];
	menu_range_t range;
	uint8_t text_link = 0;
	uint8_t offset;			// Index into channel structure
	uint8_t	items;			// Items in group

	// If submenu item has changed, reset submenu positions
	if (section != old_section)
	{
		mix_top = MIXERSTART;
		old_section = section;
	}

	// Get mixer menu offsets
	// 1 = input mixer data, 2 = output mixer data
	switch(section)
	{
		case 1:
			items = INPUTITEMS+1;
			offset = 0;
			value_ptr = &values[0];
			break;
		case 2:
			items = OUTPUTITEMS+1;
			offset = INPUTITEMS+1;
			value_ptr = &values[0];
			break;
		default:
			items = INPUTITEMS+1;
			offset = 0;
			value_ptr = &values[0];
			break;
	}

	while(button != BACK)
	{
		// Load values from eeprom and insert channel number at the top of each - messy
		values[0] = Config.MenuChannel;
		if (section == 1)
		{
			memcpy(&values[1],&Config.Channel[Config.MenuChannel].source_a,(sizeof(int8_t) * INPUTITEMS));
		}
		else
		{
			memcpy(&values[1],&Config.Channel[Config.MenuChannel].switcher,(sizeof(int8_t) * OUTPUTITEMS));
		}

		// Print menu
		print_menu_items(mix_top + offset, MIXERSTART + offset, value_ptr, 1, (prog_uchar*)mixer_menu_ranges[section - 1], 0, MIXOFFSET, (prog_uchar*)MixerMenuText[section - 1], cursor);

		// Handle menu changes
		update_menu(items, MIXERSTART, offset, button, &cursor, &mix_top, &menu_temp);
		range = get_menu_range ((prog_uchar*)mixer_menu_ranges[section - 1], menu_temp - MIXERSTART - offset);

		if (button == ENTER)
		{
			text_link = pgm_read_byte(&MixerMenuText[section - 1][menu_temp - MIXERSTART - offset]);
			do_menu_item(menu_temp, value_ptr + (menu_temp - MIXERSTART - offset), 1, range, 0, text_link, false, 0);
		}

		// Save modified data back to Config
		// Copy channel number back to global
		switch(section)
		{
			case 1:
				memcpy(&Config.Channel[Config.MenuChannel].source_a,&values[1],(sizeof(int8_t) * INPUTITEMS));
				Config.MenuChannel = values[0];
				break;
			case 2:
				memcpy(&Config.Channel[Config.MenuChannel].switcher,&values[1],(sizeof(int8_t) * OUTPUTITEMS));
				Config.MenuChannel = values[0];
				break;
			default:
				break;
		}

		// Save and exit
		if (button == ENTER)
		{
			UpdateLimits();			 // Update travel limits based on percentages
			Save_Config_to_EEPROM(); // Save value and return
		}

	}
	_delay_ms(200);
}
示例#6
0
void menu_rc_setup(uint8_t section)
{
	int8_t *value_ptr;
	menu_range_t range;
	uint8_t text_link;
	uint8_t i = 0;
	uint8_t mult = 1;		// Multiplier
	uint8_t offset;			// Index into channel structure
	uint8_t	items;			// Items in group

	// If submenu item has changed, reset submenu positions
	if (menu_flag)
	{
		sub_top = RCSTART;
		menu_flag = 0;
	}

	while(button != BACK)
	{
		// Get menu offsets and load values from eeprom
		// 1 = RC, 2 = Failsafe, 3 = General
		switch(section)
		{
			case 1:				// RC setup menu
				offset = 0;
				items = RCITEMS;
				value_ptr = &Config.RxModeIn;
				mult = 1;
				break;
			case 2:				// Failsafe menu
				offset = RCITEMS;
				items = FSITEMS;
				value_ptr = &Config.FailsafeType;
				mult = 1;
				break;
			case 3:				// General menu
				offset = RCITEMS + FSITEMS;
				items = GENERALITEMS;
				value_ptr = &Config.MixMode;
				mult = 1;
				break;
			default:
				offset = 0;
				items = RCITEMS;
				value_ptr = &Config.RxModeIn;
				mult = 1;
				break;
		}
		// Save pre-edited values
		int8_t temp_type = Config.MixMode;
		int8_t temp_flapchan = Config.FlapChan;
		int8_t temp_RxModeIn = Config.RxModeIn;

		// Print menu
		print_menu_items(sub_top + offset, RCSTART + offset, value_ptr, mult, (const unsigned char*)rc_menu_ranges[section - 1], 0, RCOFFSET, (const unsigned char*)RCMenuText[section - 1], cursor);

		// Handle menu changes
		update_menu(items, RCSTART, offset, button, &cursor, &sub_top, &menu_temp);
		range = get_menu_range ((const unsigned char*)rc_menu_ranges[section - 1], (menu_temp - RCSTART - offset)); 

		if (button == ENTER)
		{
			text_link = pgm_read_byte(&RCMenuText[section - 1][menu_temp - RCSTART - offset]);
			do_menu_item(menu_temp, value_ptr + (menu_temp - RCSTART - offset), mult, range, 0, text_link, false, 0);
		}

		if (button == ENTER)
		{
			// Update Ch5. mixer with source from Config.FlapChan if in Aeroplane mode and source changed
			if ((Config.MixMode == AEROPLANE) && (Config.FlapChan != temp_flapchan))
			{
				Config.Channel[CH5].source_a = Config.FlapChan;
			}

			// Reset serial in channel masks every time the input type is changed
			if (temp_RxModeIn != Config.RxModeIn)
			{
				Xtreme_Chanmask = 0;
				Xtreme_RSS = 0;
				Spektrum_Chanmask_0 = 0;	
				Spektrum_Chanmask_1 = 0;		
				Spektrum_frameloss = 0;
				SBUS_Flags = 0;
				
				// Clear channel data
				for (i = 0; i < MAX_RC_CHANNELS; i++)
				{
					RxChannel[i] = 0;
					
					// Unused Spektrum channels set to NULL
					if (Config.RxModeOut == SPEKTRUM)
					{
						ExtChannel[i] = 0xFFFF;
					}	
					// Unused channels set to mid-way
					else if (Config.RxModeOut == SBUS)
					{
						ExtChannel[i] = 0x400;
					}
					// Xtreme doesn't care
					else
					{
						ExtChannel[i] = 0;
					}
				}
			}

			// If model type has changed, reload preset
			if ((section == 3) && (temp_type != Config.MixMode)) 
			{
				switch(Config.MixMode)  // Load selected mix
				{
					case AEROPLANE:
						get_preset_mix(AEROPLANE_MIX);
						break;	
					case FWING:
						get_preset_mix(FLYING_WING_MIX);
						break;
					case MANUAL:
						// Clear all channel info
						memset(&Config.Channel[0].value,0,(sizeof(channel_t) * MAX_OUTPUTS));

						// Preset important settings
						for (i = 0; i < MAX_OUTPUTS; i++)
						{
							Config.Channel[i].source_a = i;			// Set to mirror the inputs
							Config.Channel[i].source_a_volume = 100;
							Config.Channel[i].source_b = NOCHAN;
							Config.Channel[i].output_b = UNUSED;
							Config.Channel[i].output_c = UNUSED;
						}

						break;
					default:
						break;
				}
			}

			init_int();				// In case RC type has changed, reinitialise interrupts
			init_uart();			// and UART
			UpdateLimits();			// Update I-term limits and triggers based on percentages

#ifdef KK21
			// Update MPU6050 LPF
			writeI2Cbyte(MPU60X0_DEFAULT_ADDRESS, MPU60X0_RA_CONFIG, (6 - Config.MPU6050_LPF));
#endif
			// Update channel sequence
			for (i = 0; i < MAX_RC_CHANNELS; i++)
			{
				if (Config.TxSeq == FUTABASEQ)
				{
					Config.ChannelOrder[i] = pgm_read_byte(&FUTABA[i]);
				}
				else
				{
					Config.ChannelOrder[i] = pgm_read_byte(&JR[i]);
				}
			}

			Save_Config_to_EEPROM(); // Save value and return
			
			Wait_BUTTON4();			 // Wait for user's finger off the button
		}
	}
}
void menu_rc_setup(uint8_t section)
{
	static uint8_t rc_top = RCSTART;

	int8_t *value_ptr;

	menu_range_t range;
	uint8_t text_link;
	uint8_t i = 0;
	uint8_t mult = 1;		// Multiplier
	uint8_t offset;			// Index into channel structure
	uint8_t	items;			// Items in group
	uint16_t temp16_1;

	// If submenu item has changed, reset submenu positions
	if (menu_flag)
	{
		rc_top = RCSTART;
		menu_flag = 0;
	}

	while(button != BACK)
	{
		// Get menu offsets and load values from eeprom
		// 1 = RC, 2 = Failsafe, 3 = General, 4 = Battery
		switch(section)
		{
			case 1:				// RC setup menu
				offset = 0;
				items = RCITEMS;
				value_ptr = &Config.RxMode;
				mult = 1;
				break;
			case 2:				// Failsafe menu
				offset = RCITEMS;
				items = FSITEMS;
				value_ptr = &Config.FailsafeType;
				mult = 1;
				break;
			case 3:				// General menu
				offset = RCITEMS + FSITEMS;
				items = GENERALITEMS;
				value_ptr = &Config.MixMode;
				mult = 1;
				break;
			case 4:				// Battery menu
				offset = RCITEMS + FSITEMS + GENERALITEMS;
				items = BATTITEMS;
				value_ptr = &Config.BatteryType;
				mult = 4;
				break;
			default:
				offset = 0;
				items = RCITEMS;
				value_ptr = &Config.RxMode;
				mult = 1;
				break;
		}
		// Save pre-edited values
		int8_t temp_type = Config.MixMode;
		int8_t temp_cells = Config.BatteryCells;
		int8_t temp_minvoltage = Config.MinVoltage;
		int8_t temp_flapchan = Config.FlapChan;

		// Print menu
		print_menu_items(rc_top + offset, RCSTART + offset, value_ptr, mult, (prog_uchar*)rc_menu_ranges[section - 1], 0, RCOFFSET, (prog_uchar*)RCMenuText[section - 1], cursor);

		// Handle menu changes
		update_menu(items, RCSTART, offset, button, &cursor, &rc_top, &menu_temp);
		range = get_menu_range ((prog_uchar*)rc_menu_ranges[section - 1], (menu_temp - RCSTART - offset)); 

		if (button == ENTER)
		{
			text_link = pgm_read_byte(&RCMenuText[section - 1][menu_temp - RCSTART - offset]);
			do_menu_item(menu_temp, value_ptr + (menu_temp - RCSTART - offset), mult, range, 0, text_link, false, 0);
		}

		if (button == ENTER)
		{
			// Update Ch7. mixer with source from Config.FlapChan if in Aeroplane mode and source changed
			if ((Config.MixMode == AEROPLANE) && (Config.FlapChan != temp_flapchan))
			{
				Config.Channel[CH7].source_a = Config.FlapChan;
			}

			// See if cell number or min_volts has changed
			if ((temp_cells != Config.BatteryCells) || (temp_minvoltage != Config.MinVoltage))
			{
				// Recalculate if more cells
				temp16_1 = Config.MinVoltage;
				temp16_1 = temp16_1 * Config.BatteryCells;
				temp16_1 = temp16_1 / 10;
				Config.PowerTrigger = (int8_t)temp16_1;
			}

			// If model type has changed, reload preset
			if ((section == 3) && (temp_type != Config.MixMode)) 
			{
				switch(Config.MixMode)  // Load selected mix
				{
					case AEROPLANE:
						get_preset_mix(AEROPLANE_MIX);
						break;	
					case FWING:
						get_preset_mix(FLYING_WING_MIX);
						break;
					case CAMSTAB:
						get_preset_mix(CAM_STAB);
						break;
					case MANUAL:
						// Clear all channel info
						memset(&Config.Channel[0].value,0,(sizeof(channel_t) * PSUEDO_OUTPUTS));

						// Preset important settings
						for (i = 0; i < PSUEDO_OUTPUTS; i++)
						{
							Config.Channel[i].source_a = NOCHAN;
							Config.Channel[i].source_b = NOCHAN;
							Config.Channel[i].output_b = UNUSED;
							Config.Channel[i].output_c = UNUSED;
							Config.Channel[i].output_d = UNUSED;
						}

						break;
					default:
						break;
				}
			}

			init_int();				// In case RC type has changed, reinitialise interrupts
			init_uart();			// and UART

			UpdateIMUvalues();		// Update IMU variables
			UpdateLimits();			// Update I-term limits and triggers based on percentages

#ifdef KK21
			// Update MPU6050 LPF
			writeI2Cbyte(MPU60X0_DEFAULT_ADDRESS, MPU60X0_RA_CONFIG, Config.MPU6050_LPF);
#endif
			// Update channel sequence
			for (i = 0; i < MAX_RC_CHANNELS; i++)
			{
				if (Config.TxSeq == FUTABASEQ)
				{
					Config.ChannelOrder[i] = (uint8_t)pgm_read_byte(&FUTABA[i]);
				}
				else
				{
					Config.ChannelOrder[i] = (uint8_t)pgm_read_byte(&JR[i]);
				}
			}

			Save_Config_to_EEPROM(); // Save value and return
		}
	}
}
void menu_servo_setup(uint8_t section)
{
	int8_t *value_ptr = &Config.Servo_reverse[0];

	menu_range_t range;
	uint8_t text_link;
	uint8_t i = 0;
	bool	servo_enable = false;
	bool	zero_setting = false;

	// If submenu item has changed, reset submenu positions
	if (menu_flag)
	{
		sub_top = SERVOSTART;
		menu_flag = 0;
	}

	// Get menu offsets
	// 1 = Reverse, 2 = Min, 3 = Max
	while(button != BACK)
	{
		// Load values from eeprom
		for (i = 0; i < SERVOITEMS; i++)
		{
			switch(section)
			{
				case 1:
					break;
				case 2:
					value_ptr = &Config.min_travel[0];
					servo_enable = true;
					zero_setting = true;
					break;
				case 3:
					value_ptr = &Config.max_travel[0];
					servo_enable = true;
					zero_setting = true;
					break;
				default:
					break;
			}
		}

		// Print menu
		print_menu_items(sub_top, SERVOSTART, value_ptr, 1, (const unsigned char*)servo_menu_ranges[section - 1], 1, SERVOOFFSET, (const unsigned char*)ServoMenuText[section - 1], cursor);

		// Handle menu changes
		update_menu(SERVOITEMS, SERVOSTART, 0, button, &cursor, &sub_top, &menu_temp);
		range = get_menu_range ((const unsigned char*)servo_menu_ranges[section - 1], 0);

		if (button == ENTER)
		{
			text_link = pgm_read_byte(&ServoMenuText[section - 1][menu_temp - SERVOSTART]);

			// Zero limits if adjusting
			if (zero_setting)
			{
				value_ptr[menu_temp - SERVOSTART] = 0;
			}

			// Do not allow servo enable for throttle if in CPPM mode
			if ((Config.Channel[menu_temp - SERVOSTART].P1_source_a == THROTTLE) && (Config.RxMode == CPPM_MODE))
			{
				servo_enable = false;
			}

			do_menu_item(menu_temp, value_ptr + (menu_temp - SERVOSTART), 1, range, 0, text_link, servo_enable, (menu_temp - SERVOSTART));
		}

		// Disable servos
		servo_enable = false;

		if (button == ENTER)
		{
			UpdateLimits();				// Update actual servo trims
			Save_Config_to_EEPROM();	// Save value and return
		}
	}
}
void menu_flight(uint8_t mode)
{
    int8_t *value_ptr;
    menu_range_t range;
    uint8_t text_link;
    int8_t temp_gyro_roll = 0;
    int8_t temp_gyro_pitch = 0;
    int8_t temp_gyro_yaw = 0;

    // If submenu item has changed, reset submenu positions
    if (menu_flag)
    {
        sub_top = FLIGHTSTART;
        menu_flag = 0;
    }

    while(button != BACK)
    {
        value_ptr = &Config.FlightMode[mode-1].StabMode;

        // Save pre-edited value for gyro types
        temp_gyro_roll = Config.FlightMode[mode - 1].Roll_type;
        temp_gyro_pitch = Config.FlightMode[mode - 1].Pitch_type;
        temp_gyro_yaw = Config.FlightMode[mode - 1].Yaw_type;

        // Print menu
        print_menu_items(sub_top, FLIGHTSTART, value_ptr, 1, (const unsigned char*)flight_menu_ranges, 0, FLIGHTOFFSET, (const unsigned char*)FlightMenuText, cursor);

        // Handle menu changes
        update_menu(FLIGHTITEMS, FLIGHTSTART, 0, button, &cursor, &sub_top, &menu_temp);
        range = get_menu_range ((const unsigned char*)flight_menu_ranges, (menu_temp - FLIGHTSTART));

        if (button == ENTER)
        {
            text_link = pgm_read_byte(&FlightMenuText[menu_temp - FLIGHTSTART]);
            do_menu_item(menu_temp, value_ptr + (menu_temp - FLIGHTSTART), 1, range, 0, text_link, false, 0);
        }

        // Preset I-limits when gyro mode changes
        if (button == ENTER)
        {
            // If roll gyro type has changed, reset to an appropriate start point
            if (temp_gyro_roll != Config.FlightMode[mode-1].Roll_type)
            {
                // Use Gyro type value to preset limits
                if(Config.FlightMode[mode-1].Roll_type == LOCK)
                {
                    Config.FlightMode[mode - 1].Roll_limit = 125;
                }
                else
                {
                    Config.FlightMode[mode - 1].Roll_limit = 0;
                }
            }

            if (temp_gyro_pitch != Config.FlightMode[mode-1].Pitch_type)
            {
                if(Config.FlightMode[mode-1].Pitch_type == LOCK)
                {
                    Config.FlightMode[mode - 1].Pitch_limit = 125;
                }
                else
                {
                    Config.FlightMode[mode - 1].Pitch_limit = 0;
                }
            }

            if (temp_gyro_yaw != Config.FlightMode[mode-1].Yaw_type)
            {
                if(Config.FlightMode[mode-1].Yaw_type == LOCK)
                {
                    Config.FlightMode[mode - 1].Yaw_limit = 125;
                }
                else
                {
                    Config.FlightMode[mode - 1].Yaw_limit = 0;
                }
            }

            UpdateLimits();			 // Update I-term limits and triggers based on percentages

            Save_Config_to_EEPROM(); // Save value and return

            Wait_BUTTON4();			 // Wait for user's finger off the button
        }
    }
}