Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

OrangutanPulseIn and PololuWheelEncoders


#1

Hi!

I would like to use:

reading the avr_library_commands i noticed that:

  • OrangutanPulseIn and PololuWheelEncoders

would conflict because both of them use pin-change interrupts. Specifically, they use AVR’s PCINT0, PCINT1 and PCINT2 and i checked this useful table from PololuWheelEncoders.cpp in github:

AVR pin…PCINT #…PCI #

PD0 - PD7…PCINT16 - PCINT23…PCI2
PB0 - PB5…PCINT0 - PCINT5…PCI0
PC0 - PC5 …PCINT8 - PCINT13…PCI1

and i am thinking to use PCI1 and PCI2 for WheelEncoders and PCI0 for the 3 ultrasonic sensors, but i would like to know if that’s possible making some modifications to the source code of:

  • OrangutanPulseIn.cpp and
  • PololuWheelEncoders.cpp

because i’ve already tried to implement some code with the library as it is but i get the followings errors:

Error	4	ld returned 1 exit status	collect2.exe	0	0	PING_HC-SR04_MOTOR_RIGHT

Error	1	multiple definition of `__vector_3'	/home/david/libpololu-avr/devices/atmega328p/../../src/PololuWheelEncoders/../../src/PololuWheelEncoders/PololuWheelEncoders.cpp	256	1	PING_HC-SR04_MOTOR_RIGHT

Error	2	multiple definition of `__vector_4'	/home/david/libpololu-avr/devices/atmega328p/../../src/PololuWheelEncoders/../../src/PololuWheelEncoders/PololuWheelEncoders.cpp	259	1	PING_HC-SR04_MOTOR_RIGHT

Error	3	multiple definition of `__vector_5'	/home/david/libpololu-avr/devices/atmega328p/../../src/PololuWheelEncoders/../../src/PololuWheelEncoders/PololuWheelEncoders.cpp	259	1	PING_HC-SR04_MOTOR_RIGHT

when compiling with Atmel Studio 6.0 the next code:

#include <pololu/orangutan.h>

//Front PING sensor
#define SIG IO_B5		//PING signal
//Left HC-SR04 pins
#define E2 IO_B2		//receive pulse
#define T2 IO_B4		//send pulse
#define buffer_size 6
#define m2a IO_C3		//LEFT MOTOR as pcb and connected to test in protoboard
#define m2b IO_C2		//			 as pcb and connected to test in protoboard
#define m1a	IO_D7		//RIGHT motor not connected when tested
#define m1b IO_D4

char send_buffer[buffer_size];
uint16_t duration_left, duration_front;
uint8_t npp = 2;				//number of pulse pins
int left_enc_cnt;
int left_speed = 30;
int left_stop = 0;

void wait_for_sending_to_finish(){		//avr_library_commands Section 10
	while(!serial_send_buffer_empty());	//pololu_avr_library Section 3.h
}

void send_data(uint16_t data){
	wait_for_sending_to_finish();
	send_buffer[3] = data % 10 + 48;				//unidades
	if(data < 10){									//decenas, centenas y miles son cero
		send_buffer[0] = 0 + 48;					//miles
		send_buffer[1] = 0 + 48;					//centenas
		send_buffer[2] = 0 + 48;					//decenas
	}
	else if(data < 100){
		send_buffer[0] = 0 + 48;					//miles
		send_buffer[1] = 0 + 48;					//centenas
		send_buffer[2] = (data / 10) % 10 + 48;		//decenas
	}
	else if(data < 1000){
		send_buffer[0] = 0 + 48;					//miles
		send_buffer[1] = (data / 100) % 10 + 48;			//centenas
		send_buffer[2] = (data / 10) % 10 + 48;		//decenas
	}
	else if(data < 10000){
		send_buffer[0] = (data / 1000) % 10 + 48;			//miles
		send_buffer[1] = (data / 100) % 10 + 48;			//centenas
		send_buffer[2] = (data / 10) % 10 + 48;		//decenas
	}
	else if(data < 100000){
		send_buffer[0] = (data / 10000) % 10 + 48;			//decenas de millar
		send_buffer[0] = (data / 1000) % 10 + 48;			//millar
		send_buffer[1] = (data / 100) % 10 + 48;			//centenas
		send_buffer[2] = (data / 10) % 10 + 48;				//decenas
	}
	else{
		
	}
	
	send_buffer[4] = 10;	//Salto de linea
	send_buffer[5] = 13;	//Retorno de carro
	serial_send(send_buffer, buffer_size);
}

int main(){
	serial_set_baud_rate(115200);			//Default baud rate comm in HC-05 after configuration
	encoders_init(m1a, m1b, m2a, m2b);
	set_m2_speed(left_speed);
	
	while(1){
		left_enc_cnt = encoders_get_counts_m2();
		send_data(left_enc_cnt);
		
		set_digital_output(SIG, LOW);
		set_digital_output(T2, LOW);
		delay_us(2);
		set_digital_output(SIG, HIGH);
		set_digital_output(T2, HIGH);
		delay_us(5);
		set_digital_output(SIG, LOW);
		set_digital_output(T2, LOW);
		
		pulse_in_start((unsigned char[]){SIG, E2}, npp);
		set_digital_input(SIG, HIGH_IMPEDANCE);
		set_digital_input(T2, HIGH_IMPEDANCE);
		delay_us(2150);						//2150, long de pulso maximo de 1512
		duration_front = pulse_to_microseconds(get_last_high_pulse(0));
		duration_left = pulse_to_microseconds(get_last_high_pulse(1));
		
		send_data(duration_front);
		send_data(duration_left);
		left_enc_cnt = encoders_get_counts_m2();
		send_data(left_enc_cnt);
		send_data(0);
		delay_ms(1000);
		
	}
}

Is it possible to modify the code in order to achive what i’m looking for?

If so, could you tell where i can find the source code after the libpololu-avr is installed?

I’ve checked in:

C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\avr\include\pololu

but there is only the .h files not the .cpp :’( (The installation of the library was so easy with the .exe that you provide that i didn’t know what it did)

Thanks in advance :slight_smile:


#2

Hello.

Yes, you can modify and combine the OrangutanPulseIn and PololuWheelEncoders libraries for your application. The source code for those libraries can be found under C:\libpololu-avr or in the AVR library source code repository.

It is not clear to me what you mean by “i’ve already tried to implement some code with the library as it is”. Can you elaborate? How did you modify the library files? Can you attach your entire project as a ZIP file, containing the configuration files as well as the files you modified (e.g. PololuWheelEncoders.cpp and OrangutanPulseIn.cpp)?

- Amanda


#3

Hello Amanda

Thanks for the location of the libraries.

As i hadn’t found the libraries location, i just wrote the code without making any modifications to the libraries. But now that you have told me where they are i’m goint to make some modifications to use PCI1 and PCI2 for WheelEncoders and PCI0 for the 3 ultrasonic sensors. I’ll keep you posted.

Any recommendation before making the modifications?
Thanks


#4

No, we do not have any specific recommendations.

If you run into any issues, you can post the error messages that you get (if any) along with your entire project file as I described in my previous post, and we would be happy to take a look at it.

- Amanda


#5

Thanks Amanda, i decided to make a maze robot with the VL6180X sensors instead of the Ultrasonic sensors

but i’ll also try to modify the library later.

Right now i’m having the same question about the
Pulsein function and the wheel encoders but for the A-star 32U4. Do you know if they interfer with each other programming the uC with Arduino IDE?


#6

Unfortunately, the OrangutanPulseIn and the PololuWheelEncoders will not work on the A-Star, since the functions in the OrangutanPulseIn library are not available within the Arduino environment and the PololuWheelEncoders library does not support the ATmega 32U4. Instead, you can use the Arduino’s pulseIn function and a different encoder library. For more information about the Arduino’s pulseIn function, see the PulseIn page on the Arduino website. To find some existing encoder libraries, see the Reading Rotary Encoders page (which is also on the Arduino website). You might consider using this encoder library, which is one of the encoder libraries listed on that page. There shouldn’t be any conflicts between using that encoder library and the Arduino’s pulseIn function.

- Amanda