3pi speed problem

Hello,

I received my pololu 3pi from a local dealer. Firstly, I used the preloaded program and understand the parts device. After that I used the simple line follower code from examples. Works fine. Then I used the simple line follower pid. It works fine too. I changed its pid values randomly still no problem.

What I want was adjusting speed with buttons and after adjusting it pid values should adjusts its self. I found a code similar to that purpose. Here it is:

[code]/*

*/

#include <pololu/3pi.h>

#include <avr/pgmspace.h>
#include <avr/eeprom.h>

// Introductory messages. The “PROGMEM” identifier causes the data to
// go into program space.
const char welcome_line1[] PROGMEM = " Pololu";
const char welcome_line2[] PROGMEM = “3\xf7 Robot”;
const char demo_name_line1[] PROGMEM = “PID Opt”;
const char demo_name_line2[] PROGMEM = “follower”;
const char main_menu1[] PROGMEM = “Main”;
const char main_menu2[] PROGMEM = “G S C”;

// set-up parameters for PID functions
uint8_t mot_high;
#define EE_mot_high (uint8_t*)0

uint8_t prop_f = 100;
#define EE_prop_f (uint8_t*)1

uint8_t integ_f;
#define EE_integ_f (uint8_t*)2

uint8_t der_f;
#define EE_der_f (uint8_t*)3

char is_on = 0;

// A couple of simple tunes, stored in program space.
const char welcome[] PROGMEM = “>g32>>c32”;
const char go[] PROGMEM = “L16 cdegreg4”;

void initialize(void);
void edit_param(char param_num);
void button_a(void);
void button_b(void);
void button_c(void);
void bat_test(void);
void main_menu(void);

// This is the main function, where the code starts. All C programs
// must have a main() function defined somewhere.
int main()
{
unsigned int sensors[5]; // an array to hold sensor values
unsigned int last_proportional=0;
long integral=0;

// set up the 3pi
initialize();

main_menu();

// This is the "main loop" - it will run forever.
for(;;)
{
    // is a button pressed?
    if(!button_is_pressed(ALL_BUTTONS))
    {
        // is the robot in line following mode?
        if(is_on)
        {
    		// Get the position of the line.  Note that we *must* provide
    		// the "sensors" argument to read_line() here, even though we
    		// are not interested in the individual sensor readings.
    		unsigned int position = read_line(sensors,IR_EMITTERS_ON);

    		// The "proportional" term should be 0 when we are on the line.
    		int proportional = ((int)position) - 2000;

    		// Compute the derivative (change) and integral (sum) of the
    		// position.
    		int derivative = proportional - last_proportional;
    		integral += proportional;

    		// Remember the last position.
    		last_proportional = proportional;

    		// Compute the difference between the two motor power settings,
    		// m1 - m2.  If this is a positive number the robot will turn
    		// to the right.  If it is a negative number, the robot will
    		// turn to the left, and the magnitude of the number determines
    		// the sharpness of the turn.
    		//int power_difference = proportional/20 + integral/10000 + derivative*3/2;
    		int power_difference = 
    		    (prop_f/100) * (proportional/20) + 
    		    (integ_f/100) * (integral/10000) + 
    		    (der_f/100) * derivative*3/2;
    		    

    		// Compute the actual motor settings.  We never set either motor
    		// to a negative value.
    		//mot_high = 60;
    		if(power_difference > mot_high)
    		{
    			power_difference = mot_high;
			}
    		if(power_difference < -mot_high)
    		{
    			power_difference = -mot_high;
            }
    		if(power_difference < 0)
    		{
    			set_motors(mot_high+power_difference, mot_high);
			}
    		else
    		{
    			set_motors(mot_high, mot_high-power_difference);
    		}
		}
	}
	// start line following
	else if(button_is_pressed(BUTTON_A))
	{
	    button_a();
	    bat_test();
	    main_menu();
	}
	// stop line following
	else if(button_is_pressed(BUTTON_B))
	{
	    button_b();
	    main_menu();
	    last_proportional=0;
        integral=0;
	}
	// enter menu to change parameters
	else if(button_is_pressed(BUTTON_C))
	{
	    button_c();
	    main_menu();
	    last_proportional=0;
        integral=0;
	}
}

}

// Initializes the 3pi, displays a welcome message, calibrates, and
// plays the initial music.
void initialize()
{
unsigned int counter; // used as a simple timer
//unsigned int sensors[5]; // an array to hold sensor values

pololu_3pi_init(2000);

// set initialize parameters for PID functions
mot_high = eeprom_read_byte(EE_mot_high);
if(mot_high == 255) // set to a reasonable value if this is the first run
{
    mot_high = 60;
}

prop_f = eeprom_read_byte(EE_prop_f);
if(prop_f == 255)
{
    prop_f = 100;
}

integ_f = eeprom_read_byte(EE_integ_f);
if(integ_f == 255)
{
    integ_f = 100;
}

der_f = eeprom_read_byte(EE_der_f);
if(der_f == 255)
{
    der_f = 100;
}

// Play welcome music and display a message
print_from_program_space(welcome_line1);
lcd_goto_xy(0,1);
print_from_program_space(welcome_line2);
play_from_program_space(welcome);
delay_ms(1000);

clear();
print_from_program_space(demo_name_line1);
lcd_goto_xy(0,1);
print_from_program_space(demo_name_line2);
delay_ms(1000);

// Display battery voltage and wait for button press
while(!button_is_pressed(BUTTON_B))
{
	int bat = read_battery_millivolts();

	clear();
	print_long(bat);
	print("mV");
	lcd_goto_xy(0,1);
	print("Press B");

	delay_ms(100);
}

// Always wait for the button to be released so that 3pi doesn't
// start moving until your hand is away from it.
wait_for_button_release(BUTTON_B);
delay_ms(1000);

// Auto-calibration: turn right and left while calibrating the
// sensors.
for(counter=0;counter<80;counter++)
{
	if(counter < 20 || counter >= 60)
		set_motors(40,-40);
	else
		set_motors(-40,40);

	calibrate_line_sensors(IR_EMITTERS_ON);

	delay_ms(20);
}
set_motors(0,0);


wait_for_button_release(BUTTON_B);

clear();

print("Go!");		

// Play music and wait for it to finish before we start driving.
play_from_program_space(go);
while(is_playing());

}
void edit_param(char param_num)
{
unsigned char button_pressed;
char par_change = 0;
for(;:wink:
{
button_pressed = wait_for_button_press(ALL_BUTTONS);
switch(button_pressed)
{
// exit edit_param function
case BUTTON_A:
clear();
print(“Return”);
wait_for_button_release(BUTTON_A);
return;
// increase parameter
case BUTTON_B:
wait_for_button_release(BUTTON_B);
par_change = +1;
break;
// decrease
case BUTTON_C:
wait_for_button_release(BUTTON_C);
par_change = -1;
break;
}
// update parameter and save to eeprom
switch(param_num)
{
case 0:
mot_high += par_change;
eeprom_write_byte(EE_mot_high, mot_high);
lcd_goto_xy(0,1);
print(" “);
lcd_goto_xy(0,1);
print_long((long)mot_high);
break;
case 1:
prop_f += par_change;
eeprom_write_byte(EE_prop_f, prop_f);
lcd_goto_xy(0,1);
print(” “);
lcd_goto_xy(0,1);
print_long((long)prop_f);
break;
case 2:
integ_f += par_change;
eeprom_write_byte(EE_integ_f, integ_f);
lcd_goto_xy(0,1);
print(” “);
lcd_goto_xy(0,1);
print_long((long)integ_f);
break;
case 3:
der_f += par_change;
eeprom_write_byte(EE_der_f, der_f);
lcd_goto_xy(0,1);
print(” “);
lcd_goto_xy(0,1);
print_long((long)der_f);
break;
}
}
}
void main_menu()
{
clear();
print_from_program_space(main_menu1);
lcd_goto_xy(0,1);
print_from_program_space(main_menu2);
}
// start line following
void button_a()
{
clear();
print(” GO!!!");
is_on = 1;
wait_for_button_release(BUTTON_A);
}
// stop line following
void button_b()
{
clear();
print(" STOP!!!");
is_on = 0;
set_motors(0,0);
wait_for_button_release(BUTTON_B);
}
// menu to change parameters
void button_c()
{
unsigned char button_pressed;
char param_num = 0;
set_motors(0,0);
wait_for_button_release(BUTTON_C);
for(;:wink:
{
clear();
print(“C “);
// display current parameter
switch(param_num)
{
case 0:
print(“Speed”);
lcd_goto_xy(0,1);
print_long((long)mot_high);
break;
case 1:
print(“Prop”);
lcd_goto_xy(0,1);
print_long((long)prop_f);
break;
case 2:
print(“Integ”);
lcd_goto_xy(0,1);
print_long((long)integ_f);
break;
case 3:
print(“Der”);
lcd_goto_xy(0,1);
print_long((long)der_f);
break;
}
//
button_pressed = wait_for_button_press(ALL_BUTTONS);
switch(button_pressed)
{
// exit menu
case BUTTON_A:
clear();
print(“Return”);
wait_for_button_release(BUTTON_A);
return;
// switch to the next parameter
case BUTTON_B:
clear();
print(“C Param”);
param_num++;
if(param_num > 3)
{
param_num = 0;
}
wait_for_button_release(BUTTON_B);
break;
// change the value of the current parameter
case BUTTON_C:
wait_for_button_release(BUTTON_C);
edit_param(param_num);
}
}
}
// Displays the battery voltage.
void bat_test()
{
int bat = read_battery_millivolts();
clear();
print_long(bat);
print(” mV”);

delay_ms(2500);

}

[/code]

But my problem is, after I increase the speed value over “125”, devices shuts it self down after sensor calibration. I want to make it go around 160 - 180.

Do you have any advice for that? What can I do?

Hello.

It sounds like your battery might be discharged. Could you try replacing them with new ones or recharging the batteries you have?

- Jeremy