Problem in IR_EMITTERS ... Help

Hello

Excuse the English, I am Brazilian and I do not know much English.

I’m programming my 3pi to participate in a competition, but I have to add 2 sensors (QTR-1RC), I’m using PC5 and PD0, PD0 not had the problem, but not the right PC5, after many tests, I found that if I he is put IR_EMITTERS_OFF ok, but the programming of the PID not funcina, already did several tests but I can not.

what should I do? … help … please.

Hello.

Can you get things working if you use PD1 instead of PC5? To use PC5, you need to make sure you’ve removed the PC5 jumper, and you need to use the function:

pololu_3pi_init_disable_emitter_pin(timeout);

to initialize your 3pi’s five integrated sensors in a way that keeps them from using pin PC5. You do not want to use the parameter IR_EMITTERS_OFF, since then the 3pi’s line sensors won’t be able to see.

- Ben

hello

PC5 is actually more difficult, since removed the jumper, still not sure of, so if I put IR_EMITTER_OFF oh yeah …
this code:
pololu_3pi_init_disable_emitter_pin (timeout);
of error, this function does not exist.

I would like to use the PD1, but I can not …

Agenor.

Hello,
Can you tell us which version of the library you have? The latest version, 090605, is available at the download page. If you downloaded the library before 5 June 2009, you have an old version that does not support this function. If you have the latest version, can you please post the smallest possible code that gives the error and the EXACT error message that you received when compiling it?

Also, keep in mind that the C version of the library only supports a single set of QTR sensors, so if you want to add 2 more sensors to your 3pi and use the functions in qtr.h to access them, you will need to use orangutan.h instead of 3pi.h and set up an array of QTR sensors containing all 7 sensors.

-Paul

hello

I’m using the latest version, 090605.
and error message is:

I added this line:

unsigned int pololu_3pi_init_disable_emitter_pin (timeout);

I am also using this code:

DDRD &= ~(1 << PD1);
PORTD |= (1 << PD1);

thanks

Hello,

To call a function in C, use just pololu_3pi_init_disable_emitter_pin (timeout); without the “unsigned int” part. Also, are you trying to use PD1 or PC5? What did you expect the code to do with PD1?

-Paul

hello

Well, actually I have to use 2 sensors more because the rules of competition, there are 2 marks, one at the beginning of the path where you start counting the time, and the other end of the route terminates the time, but the robot has to stop so cross to second overall, so I’m using more than 2 sensors, these sensors have the function of indicating whether the robot is at an intersection or in such marks.

In one of the sensors I’m using PD0, ja the other sensor can use both the PD1 or PC5, I just can not read the sign, the problem I’m finding is that the PC5 have to use this code "IR_EMITTER_OFF, but the robot does not recognize the line … he is spinning non-stop … ja no PD1 could not even read the signal from the sensor …

Thanks

It’s very important to do this one step at a time. If your sensors are not working yet, you shouldn’t be using the motors at all! Could you please simplify your program to the shortest possible file that you think should work, and post it here? Then I can give you some suggestions.

-Paul

Hello

I just need to recognize the PD1 sensor.
This is the simplest code possible that this working:

#include <pololu/3pi.h>
#include <avr/pgmspace.h>

int main()
{

     DDRD &= ~(1 << PD0);
     PORTD |= (1 << PD0);
     DDRD &= ~(1 << PD1);
     PORTD |= (1 << PD1);
	
	while(1)
	{
   	 if(PIND & (1 << PD0)) {
     left_led(0);
    
     } 
     else 
     left_led(1);
	 
     
	 if(PIND & (1 << PD1)) {
      right_led(0);
    
     } 
     else 
     right_led(1);
     
	}
}

Only PD0 is working, what should I do with the PD1 …

Thanks for the help.

Agenor.

Thanks, that makes it clear. Your main problem is that you are treating the QTR sensor as a sensor with a direct digital output, but it is not like that. The fact that PD0 works for you is basically an accident (since the pull-up resistor on the AVR happens to be well-matched to the phototransistor), but if the digital signal you are getting now is really good enough for you, I recommend switching to PC5 instead of PD1. PC5 will probably work just as well as PD0. PD1 is probably going to give you trouble no matter what because it is also connected to an LED that will strongly pull the pin to ground no matter what the sensor sees. You are adding to the problem by activating that LED with the left_led() function calls, which will override your settings for PD1!

Take a look at the product page for a description of how these sensors work. The correct way to use them will give you a full range of values out instead of a digital signal, just like all of the other sensors on your 3pi. To get it working this way, carefully read over the QTR sensor library documentation and modify your program to include orangutan.h instead of 3pi.h. You will need to configure the QTR settings yourself to have all 7 sensors instead of just the 5 standard ones, and call qtr_read() instead of the 3pi-specific read_line_sensors().

If you continue to have trouble after trying one of these methods, please post your complete, simplest code again, and I will help you out.

-Paul

Hello, thanks for the help.

Well … I’m almost giving up … I have a big problem with the English ligua …
But let it …

PC5 is really the easiest to use, I already could read the sign, since the IR_EMITTER is OFF, but if I use this code the PID does not work …
Following is the code:

int main()
{
	unsigned int sensors[5]; 
	unsigned int last_proportional=0;
	

	
	long integral=0;
    int x = 0;
	int y = 0;
	int m = 0;
	
	initialize();
     DDRD &= ~(1 << PD0);
     PORTD |= (1 << PD0);
	 DDRC &= ~(1 << PC5);
     PORTC |= (1 << PC5);
     
	while(1)
	{
        
        

		
		unsigned int position = read_line_white(sensors,IR_EMITTERS_ON);
		int proportional = ((int)position) - 2000;

		
		int derivative = proportional - last_proportional;
		integral += proportional;

		
		last_proportional = proportional;

		
		int power_difference = proportional/9 + integral/10000 + derivative*3/2;

		
		const int max = 180;
		if(power_difference > max)
			power_difference = max;
		if(power_difference < -max)
			power_difference = -max;

		if(power_difference < 0)
			set_motors(max+power_difference, max);
		else
			set_motors(max, max-power_difference);
     
	 
	    lcd_goto_xy(0,1);
        print_long(x);
        
      

	 if((PINC & (1 << PC5))&&(!(PIND & (1 << PD0)))){
	 left_led(1);
	 right_led(1);
     m=0;
     
         } 
     else{ 
	
	 left_led(0);
	 right_led(0);
	   if (m!=1){
	 x=x+1;
	 m=1;}

	 }


	  if (x == 5)
	   {
	    y=y+1;
		if (y > 200){
	    set_motors(50,-50);
		lcd_goto_xy(0,0);
        print("FIM");
        
	    play_from_program_space(go);
	    while(is_playing());

		}
	    
		}
        
	
	 
    	 
   	 
}	 		 	

I think this code is …
Thanks

If you disconnect the PC5-LEDON jumper, the LEDs will be on, not off. You can verify this with your cell phone camera, which can probably see the light from the IR emitters.

You haven’t posted your entire source code, and you haven’t tried simplifying it to the simplest thing possible. You should do both of those you give up. That means no motors and no music for now! If you think your main sensors aren’t working, you should also remove all of the code relating to PD0 and PC5 for now.

-Paul

Hello

The code without the PD0 and PC5 is working perfectly, just the PD0 that works well, the problem is that the sensor will trigger the same intersection, I have to change the code on the event.

The IR’s are working well, already tried with the phone.

I’ve done many tests, and PC5 works well if I get the IR_EMITTERS_ON, the following code:

#include <pololu/3pi.h>

int main()
{
	
     DDRD &= ~(1 << PD0);
     PORTD |= (1 << PD0);
	 DDRC &= ~(1 << PC5);
     PORTC |= (1 << PC5);


	while(1)
	{
		if(PIND & (1 << PD0))
        left_led(1);
             
        else 
        left_led(0);
      

		if(PINC & (1 << PC5))
        right_led(1);
		       
        else 
        right_led(0);
         
	}


}

I’m using the same program “3pi-Linefollower-pid” and so would like to add that code I sent you.

Thank you.

Agenor.

Hello,
Does the code you just posted work or not? If not, what does it do?
-Paul

Hello.

This code I sent this worked, so I did it to see if the sensors worked, is actually a simple code, so the sensor is triggered the LED lights.
Both the PD0 and PC5 are running this code … but once I put this command in my code of Line_Follower_PID the PC5 does not work …

Thank you.

That is probably because you have not modified the program to use the function

pololu_3pi_init_disable_emitter_pin(timeout);

that Ben recommended. Can you verify that you have done this, then, if it still isn’t working, please post your entire source code?

-Paul

Hello …

I already used this code: pololu_3pi_init_disable_emitter_pin (timeout);
but giving this error … already checked the 3pi.h and the newest version …
Following is the full code:

#include <pololu/3pi.h>
#include <avr/pgmspace.h>



const char welcome_line1[] PROGMEM = " Triton";
const char welcome_line2[] PROGMEM = " Robos";
const char demo_name_line1[] PROGMEM = "Seguidor";
const char demo_name_line2[] PROGMEM = "de Linha";
const char welcome[] PROGMEM = ">g32>>c32";
const char go[] PROGMEM = "L16 cdegreg4";
const char levels[] PROGMEM = {

	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111,
	0b11111
};


void load_custom_characters()
{
	lcd_load_custom_character(levels+0,0); 
	lcd_load_custom_character(levels+1,1); 
	lcd_load_custom_character(levels+2,2); 
	lcd_load_custom_character(levels+3,3);
	lcd_load_custom_character(levels+4,4);
	lcd_load_custom_character(levels+5,5);
	lcd_load_custom_character(levels+6,6);
	clear(); 
}


void display_readings(const unsigned int *calibrated_values)
{
	unsigned char i;

	for(i=0;i<5;i++) {
		
		const char display_characters[10] = {' ',0,0,1,2,3,4,5,6,255};
		char c = display_characters[calibrated_values[i]/101];

		
		print_character(c);
	}
}


void initialize()
{
	unsigned int counter; 
	unsigned int sensors[5]; 

    pololu_3pi_init_disable_emitter_pin(timeout);
    
	load_custom_characters(); 
	
		
    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);

	
	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);
	}

	
	wait_for_button_release(BUTTON_B);
	delay_ms(1000);

	
	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);

	
	while(!button_is_pressed(BUTTON_B))
	{
		
		unsigned int position = read_line_white(sensors,IR_EMITTERS_ON);

		clear();
		print_long(position);
		lcd_goto_xy(0,1);
		display_readings(sensors);

		delay_ms(100);
	}
	wait_for_button_release(BUTTON_B);

	clear();

	print("Go!");		

	
	play_from_program_space(go);
	while(is_playing());
}


int main()
{
   unsigned int sensors[5]; 
   unsigned int last_proportional=0;
   

   
   long integral=0;
   
   
   initialize();

     DDRD &= ~(1 << PD0);
     PORTD |= (1 << PD0);
     DDRC &= ~(1 << PC5);
     PORTC |= (1 << PC5);
     
   while(1)
   {
        
        

      
      unsigned int position = read_line_white(sensors,IR_EMITTERS_ON);

      int proportional = ((int)position) - 2000;
      
      int derivative = proportional - last_proportional;
      integral += proportional;

      
      last_proportional = proportional;

      
      int power_difference = proportional/9 + integral/10000 + derivative*3/2;

      
      const int max = 180;
      if(power_difference > max)
         power_difference = max;
      if(power_difference < -max)
         power_difference = -max;

      if(power_difference < 0)
         set_motors(max+power_difference, max);
      else
         set_motors(max, max-power_difference);
     
    
      if(PIND & (1 << PD0))
        left_led(1);
             
        else 
        left_led(0);
      

      if(PINC & (1 << PC5))
        right_led(1);
             
        else 
        right_led(0);

        
       
}              


	
}

thanks

Hello,
You didn’t say what the error is, but it seems like you just copied the line, including “timeout”, which is undefined. You should use the timeout that you want; usually 2000 is a good value.

Also, you are not including avr/io.h anymore, so you won’t have pin definitions available.

If you have more trouble getting this to work after fixing those problems, please tell me exactly what the error message is!

-Paul

Hello

Good … this means complicated … every hour is a mistake …
I did everything you asked … I added the avr / io.h … 2000 put in “timeout”.

Following is the error that is giving:

test.o: In function `initialize':
../test.c:64: undefined reference to `pololu_3pi_init_disable_emitter_pin'

Thanks.

-Agenor.

Hello,
Is it possible that you installed an older version of the library and have not updated to the newest version? Can you tell me the size of libpololu_atmega328p.a in the AVR library directory (something like C:\WinAVR-xxx\avr\lib). If the file is not 243,162 bytes long, you have a different version installed. If it is, then there is something very strange going on. If that is the case, we can look into it more, but I really think that you must have the wrong version installed.

If you are still having trouble, can you post your entire source code and the entire output of the compilation, so that I can help you debug it?
-Paul