Strange behaviour in set_motors

Hi all,

I’m trying to make the 3pi-linefollower example work. I successfully compiled the program. I’m using the latest libpololu-avr-100607.zip. I use the Makefile provided with the example code (modified to find the libraries in my local installation path). Everything seems fine. However, at the beginning of the program, the robot moves forward and backwards instead of doing it to the right and to the left (trying to find the "line). I even wrote a very simple program:

#include <stdio.h>
#include <string.h>
#include <pololu/3pi.h>
#include <util/delay.h>


/* Program entry point */
int main(int argc, char **arv)
{
	/* The map */
	for(;;) {
		set_motors(128, 128);
		_delay_ms(3000);
		set_motors(0, 0);
		_delay_ms(3000);
	}

	/* Back to system */
	return 0;
}

In this case, one wheel turns clockwise and the other one does it counter clockwise. However if I write something like set_motors(x, -x), both wheels turn in the same direction.

What am I doing wrong? I remember I had this problem before, but it was fixed by disabling optimizations. This “fix” doesn’t work for me in this case.
I’m using:

  • avr-binutils-2.20_1
  • avr-gcc-4.3.4_2
  • avr-libc-1.6.8_2,1
  • avrdude-5.10

Any help is appreciated. Thanks in advance.

Hello,

Did your 3pi ever drive correctly before, or was the optimization problem from a previous 3pi?

-Paul

Yes, it did. The first time I tried, I was a bit puzzled until I searched the forums and knew about the compiler bug. I disabled optimizations and it was able to follow a line (this was with avr-gcc 4.3.0 IIRC). After that I didn’t play with the pololu for a while and now (after a couple of updates in my system, including avr-gcc) I get the same behavior.
How can I see if it is a software problem or a hardware one? Does anybody have a similar setup?

Thanks.

Hm, that is really weird. I have a vague memory of some avr-gcc optimization-related issues involving treating small integers as char types instead of int - can you try your test using a speed of 127 instead of 128, just to see if that could be the problem?

-Paul

Hi Paul,

I tried, but it didn’t work :confused:
How can I tell if the generated code is ok? Which is the avr-XXX command to get the assembly code or something useful I could post here?

Thanks in advance.

Hello,

Can you try one of our pre-compiled hex files included in the pololu avr library download within “examples/atmega328/hex_files” to verify that the motor is really not just soldered backwards? It would also be useful if you could measure the voltages on all four motor pins when driving with set_motors(255, 255) and post your results here.

-Paul

Pre-compiled hex files also show this weird behavior. The 3pi-demo-program for instance when pressing A and C buttons in the “motors” tests, make M1 move forward and M2 move backwards.

I measured the voltages between every pair of motor pins. I got ~9.30 V for M1 and ~9.33 for M2

This is the result of avr-objdump -d motor_test.obj (the program I posted previously I used to set motors at 255):

avr-objdump -d test.obj 

test.obj:     file format elf32-avr


Disassembly of section .text:

00000000 <__vectors>:
   0:	33 c0       	rjmp	.+102    	; 0x68 <__ctors_end>
   2:	00 00       	nop
   4:	4c c0       	rjmp	.+152    	; 0x9e <__bad_interrupt>
   6:	00 00       	nop
   8:	4a c0       	rjmp	.+148    	; 0x9e <__bad_interrupt>
   a:	00 00       	nop
   c:	48 c0       	rjmp	.+144    	; 0x9e <__bad_interrupt>
   e:	00 00       	nop
  10:	46 c0       	rjmp	.+140    	; 0x9e <__bad_interrupt>
  12:	00 00       	nop
  14:	44 c0       	rjmp	.+136    	; 0x9e <__bad_interrupt>
  16:	00 00       	nop
  18:	42 c0       	rjmp	.+132    	; 0x9e <__bad_interrupt>
  1a:	00 00       	nop
  1c:	40 c0       	rjmp	.+128    	; 0x9e <__bad_interrupt>
  1e:	00 00       	nop
  20:	3e c0       	rjmp	.+124    	; 0x9e <__bad_interrupt>
  22:	00 00       	nop
  24:	3c c0       	rjmp	.+120    	; 0x9e <__bad_interrupt>
  26:	00 00       	nop
  28:	3a c0       	rjmp	.+116    	; 0x9e <__bad_interrupt>
  2a:	00 00       	nop
  2c:	38 c0       	rjmp	.+112    	; 0x9e <__bad_interrupt>
  2e:	00 00       	nop
  30:	36 c0       	rjmp	.+108    	; 0x9e <__bad_interrupt>
  32:	00 00       	nop
  34:	34 c0       	rjmp	.+104    	; 0x9e <__bad_interrupt>
  36:	00 00       	nop
  38:	32 c0       	rjmp	.+100    	; 0x9e <__bad_interrupt>
  3a:	00 00       	nop
  3c:	30 c0       	rjmp	.+96     	; 0x9e <__bad_interrupt>
  3e:	00 00       	nop
  40:	2e c0       	rjmp	.+92     	; 0x9e <__bad_interrupt>
  42:	00 00       	nop
  44:	2c c0       	rjmp	.+88     	; 0x9e <__bad_interrupt>
  46:	00 00       	nop
  48:	2a c0       	rjmp	.+84     	; 0x9e <__bad_interrupt>
  4a:	00 00       	nop
  4c:	28 c0       	rjmp	.+80     	; 0x9e <__bad_interrupt>
  4e:	00 00       	nop
  50:	26 c0       	rjmp	.+76     	; 0x9e <__bad_interrupt>
  52:	00 00       	nop
  54:	24 c0       	rjmp	.+72     	; 0x9e <__bad_interrupt>
  56:	00 00       	nop
  58:	22 c0       	rjmp	.+68     	; 0x9e <__bad_interrupt>
  5a:	00 00       	nop
  5c:	20 c0       	rjmp	.+64     	; 0x9e <__bad_interrupt>
  5e:	00 00       	nop
  60:	1e c0       	rjmp	.+60     	; 0x9e <__bad_interrupt>
  62:	00 00       	nop
  64:	1c c0       	rjmp	.+56     	; 0x9e <__bad_interrupt>
	...

00000068 <__ctors_end>:
  68:	11 24       	eor	r1, r1
  6a:	1f be       	out	0x3f, r1	; 63
  6c:	cf ef       	ldi	r28, 0xFF	; 255
  6e:	d4 e0       	ldi	r29, 0x04	; 4
  70:	de bf       	out	0x3e, r29	; 62
  72:	cd bf       	out	0x3d, r28	; 61

00000074 <__do_copy_data>:
  74:	11 e0       	ldi	r17, 0x01	; 1
  76:	a0 e0       	ldi	r26, 0x00	; 0
  78:	b1 e0       	ldi	r27, 0x01	; 1
  7a:	e4 e6       	ldi	r30, 0x64	; 100
  7c:	f2 e0       	ldi	r31, 0x02	; 2
  7e:	02 c0       	rjmp	.+4      	; 0x84 <.do_copy_data_start>

00000080 <.do_copy_data_loop>:
  80:	05 90       	lpm	r0, Z+
  82:	0d 92       	st	X+, r0

00000084 <.do_copy_data_start>:
  84:	a0 30       	cpi	r26, 0x00	; 0
  86:	b1 07       	cpc	r27, r17
  88:	d9 f7       	brne	.-10     	; 0x80 <.do_copy_data_loop>

0000008a <__do_clear_bss>:
  8a:	11 e0       	ldi	r17, 0x01	; 1
  8c:	a0 e0       	ldi	r26, 0x00	; 0
  8e:	b1 e0       	ldi	r27, 0x01	; 1
  90:	01 c0       	rjmp	.+2      	; 0x94 <.do_clear_bss_start>

00000092 <.do_clear_bss_loop>:
  92:	1d 92       	st	X+, r1

00000094 <.do_clear_bss_start>:
  94:	a1 30       	cpi	r26, 0x01	; 1
  96:	b1 07       	cpc	r27, r17
  98:	e1 f7       	brne	.-8      	; 0x92 <.do_clear_bss_loop>
  9a:	02 d0       	rcall	.+4      	; 0xa0 <main>
  9c:	e1 c0       	rjmp	.+450    	; 0x260 <_exit>

0000009e <__bad_interrupt>:
  9e:	b0 cf       	rjmp	.-160    	; 0x0 <__vectors>

000000a0 <main>:
  a0:	cf 93       	push	r28
  a2:	df 93       	push	r29
  a4:	c8 ec       	ldi	r28, 0xC8	; 200
  a6:	d0 e0       	ldi	r29, 0x00	; 0
  a8:	8f ef       	ldi	r24, 0xFF	; 255
  aa:	90 e0       	ldi	r25, 0x00	; 0
  ac:	6f ef       	ldi	r22, 0xFF	; 255
  ae:	70 e0       	ldi	r23, 0x00	; 0
  b0:	d5 d0       	rcall	.+426    	; 0x25c <set_motors>
  b2:	20 e3       	ldi	r18, 0x30	; 48
  b4:	35 e7       	ldi	r19, 0x75	; 117
  b6:	ce 01       	movw	r24, r28
  b8:	01 97       	sbiw	r24, 0x01	; 1
  ba:	f1 f7       	brne	.-4      	; 0xb8 <main+0x18>
  bc:	21 50       	subi	r18, 0x01	; 1
  be:	30 40       	sbci	r19, 0x00	; 0
  c0:	d1 f7       	brne	.-12     	; 0xb6 <main+0x16>
  c2:	80 e0       	ldi	r24, 0x00	; 0
  c4:	90 e0       	ldi	r25, 0x00	; 0
  c6:	60 e0       	ldi	r22, 0x00	; 0
  c8:	70 e0       	ldi	r23, 0x00	; 0
  ca:	c8 d0       	rcall	.+400    	; 0x25c <set_motors>
  cc:	20 e3       	ldi	r18, 0x30	; 48
  ce:	35 e7       	ldi	r19, 0x75	; 117
  d0:	ce 01       	movw	r24, r28
  d2:	01 97       	sbiw	r24, 0x01	; 1
  d4:	f1 f7       	brne	.-4      	; 0xd2 <main+0x32>
  d6:	21 50       	subi	r18, 0x01	; 1
  d8:	30 40       	sbci	r19, 0x00	; 0
  da:	d1 f7       	brne	.-12     	; 0xd0 <main+0x30>
  dc:	e5 cf       	rjmp	.-54     	; 0xa8 <main+0x8>

000000de <_ZN16OrangutanDigital9setOutputEhh>:
  de:	28 2f       	mov	r18, r24
  e0:	88 30       	cpi	r24, 0x08	; 8
  e2:	68 f4       	brcc	.+26     	; 0xfe <_ZN16OrangutanDigital9setOutputEhh+0x20>
  e4:	81 e0       	ldi	r24, 0x01	; 1
  e6:	90 e0       	ldi	r25, 0x00	; 0
  e8:	02 c0       	rjmp	.+4      	; 0xee <_ZN16OrangutanDigital9setOutputEhh+0x10>
  ea:	88 0f       	add	r24, r24
  ec:	99 1f       	adc	r25, r25
  ee:	2a 95       	dec	r18
  f0:	e2 f7       	brpl	.-8      	; 0xea <_ZN16OrangutanDigital9setOutputEhh+0xc>
  f2:	28 2f       	mov	r18, r24
  f4:	aa e2       	ldi	r26, 0x2A	; 42
  f6:	b0 e0       	ldi	r27, 0x00	; 0
  f8:	eb e2       	ldi	r30, 0x2B	; 43
  fa:	f0 e0       	ldi	r31, 0x00	; 0
  fc:	29 c0       	rjmp	.+82     	; 0x150 <_ZN16OrangutanDigital9setOutputEhh+0x72>
  fe:	8e 30       	cpi	r24, 0x0E	; 14
 100:	80 f4       	brcc	.+32     	; 0x122 <_ZN16OrangutanDigital9setOutputEhh+0x44>
 102:	30 e0       	ldi	r19, 0x00	; 0
 104:	28 50       	subi	r18, 0x08	; 8
 106:	30 40       	sbci	r19, 0x00	; 0
 108:	81 e0       	ldi	r24, 0x01	; 1
 10a:	90 e0       	ldi	r25, 0x00	; 0
 10c:	02 c0       	rjmp	.+4      	; 0x112 <_ZN16OrangutanDigital9setOutputEhh+0x34>
 10e:	88 0f       	add	r24, r24
 110:	99 1f       	adc	r25, r25
 112:	2a 95       	dec	r18
 114:	e2 f7       	brpl	.-8      	; 0x10e <_ZN16OrangutanDigital9setOutputEhh+0x30>
 116:	28 2f       	mov	r18, r24
 118:	a4 e2       	ldi	r26, 0x24	; 36
 11a:	b0 e0       	ldi	r27, 0x00	; 0
 11c:	e5 e2       	ldi	r30, 0x25	; 37
 11e:	f0 e0       	ldi	r31, 0x00	; 0
 120:	17 c0       	rjmp	.+46     	; 0x150 <_ZN16OrangutanDigital9setOutputEhh+0x72>
 122:	85 31       	cpi	r24, 0x15	; 21
 124:	30 f0       	brcs	.+12     	; 0x132 <_ZN16OrangutanDigital9setOutputEhh+0x54>
 126:	20 e0       	ldi	r18, 0x00	; 0
 128:	a0 e0       	ldi	r26, 0x00	; 0
 12a:	b0 e0       	ldi	r27, 0x00	; 0
 12c:	e0 e0       	ldi	r30, 0x00	; 0
 12e:	f0 e0       	ldi	r31, 0x00	; 0
 130:	0f c0       	rjmp	.+30     	; 0x150 <_ZN16OrangutanDigital9setOutputEhh+0x72>
 132:	30 e0       	ldi	r19, 0x00	; 0
 134:	2e 50       	subi	r18, 0x0E	; 14
 136:	30 40       	sbci	r19, 0x00	; 0
 138:	81 e0       	ldi	r24, 0x01	; 1
 13a:	90 e0       	ldi	r25, 0x00	; 0
 13c:	02 c0       	rjmp	.+4      	; 0x142 <_ZN16OrangutanDigital9setOutputEhh+0x64>
 13e:	88 0f       	add	r24, r24
 140:	99 1f       	adc	r25, r25
 142:	2a 95       	dec	r18
 144:	e2 f7       	brpl	.-8      	; 0x13e <_ZN16OrangutanDigital9setOutputEhh+0x60>
 146:	28 2f       	mov	r18, r24
 148:	a7 e2       	ldi	r26, 0x27	; 39
 14a:	b0 e0       	ldi	r27, 0x00	; 0
 14c:	e8 e2       	ldi	r30, 0x28	; 40
 14e:	f0 e0       	ldi	r31, 0x00	; 0
 150:	6f 3f       	cpi	r22, 0xFF	; 255
 152:	19 f4       	brne	.+6      	; 0x15a <_ZN16OrangutanDigital9setOutputEhh+0x7c>
 154:	80 81       	ld	r24, Z
 156:	82 27       	eor	r24, r18
 158:	09 c0       	rjmp	.+18     	; 0x16c <_ZN16OrangutanDigital9setOutputEhh+0x8e>
 15a:	66 23       	and	r22, r22
 15c:	19 f0       	breq	.+6      	; 0x164 <_ZN16OrangutanDigital9setOutputEhh+0x86>
 15e:	80 81       	ld	r24, Z
 160:	82 2b       	or	r24, r18
 162:	04 c0       	rjmp	.+8      	; 0x16c <_ZN16OrangutanDigital9setOutputEhh+0x8e>
 164:	90 81       	ld	r25, Z
 166:	82 2f       	mov	r24, r18
 168:	80 95       	com	r24
 16a:	89 23       	and	r24, r25
 16c:	80 83       	st	Z, r24
 16e:	8c 91       	ld	r24, X
 170:	82 2b       	or	r24, r18
 172:	8c 93       	st	X, r24
 174:	08 95       	ret

00000176 <_ZN15OrangutanMotors5init2Ev>:
 176:	e0 eb       	ldi	r30, 0xB0	; 176
 178:	f0 e0       	ldi	r31, 0x00	; 0
 17a:	83 ef       	ldi	r24, 0xF3	; 243
 17c:	80 83       	st	Z, r24
 17e:	80 81       	ld	r24, Z
 180:	84 bd       	out	0x24, r24	; 36
 182:	e1 eb       	ldi	r30, 0xB1	; 177
 184:	f0 e0       	ldi	r31, 0x00	; 0
 186:	82 e0       	ldi	r24, 0x02	; 2
 188:	80 83       	st	Z, r24
 18a:	80 81       	ld	r24, Z
 18c:	85 bd       	out	0x25, r24	; 37
 18e:	e4 eb       	ldi	r30, 0xB4	; 180
 190:	f0 e0       	ldi	r31, 0x00	; 0
 192:	10 82       	st	Z, r1
 194:	80 81       	ld	r24, Z
 196:	e3 eb       	ldi	r30, 0xB3	; 179
 198:	f0 e0       	ldi	r31, 0x00	; 0
 19a:	80 83       	st	Z, r24
 19c:	80 81       	ld	r24, Z
 19e:	88 bd       	out	0x28, r24	; 40
 1a0:	88 b5       	in	r24, 0x28	; 40
 1a2:	87 bd       	out	0x27, r24	; 39
 1a4:	86 e0       	ldi	r24, 0x06	; 6
 1a6:	60 e0       	ldi	r22, 0x00	; 0
 1a8:	9a df       	rcall	.-204    	; 0xde <_ZN16OrangutanDigital9setOutputEhh>
 1aa:	85 e0       	ldi	r24, 0x05	; 5
 1ac:	60 e0       	ldi	r22, 0x00	; 0
 1ae:	97 df       	rcall	.-210    	; 0xde <_ZN16OrangutanDigital9setOutputEhh>
 1b0:	8b e0       	ldi	r24, 0x0B	; 11
 1b2:	60 e0       	ldi	r22, 0x00	; 0
 1b4:	94 df       	rcall	.-216    	; 0xde <_ZN16OrangutanDigital9setOutputEhh>
 1b6:	83 e0       	ldi	r24, 0x03	; 3
 1b8:	60 e0       	ldi	r22, 0x00	; 0
 1ba:	91 cf       	rjmp	.-222    	; 0xde <_ZN16OrangutanDigital9setOutputEhh>

000001bc <_ZN15OrangutanMotors4initEv>:
 1bc:	80 91 00 01 	lds	r24, 0x0100
 1c0:	88 23       	and	r24, r24
 1c2:	21 f4       	brne	.+8      	; 0x1cc <_ZN15OrangutanMotors4initEv+0x10>
 1c4:	81 e0       	ldi	r24, 0x01	; 1
 1c6:	80 93 00 01 	sts	0x0100, r24
 1ca:	d5 cf       	rjmp	.-86     	; 0x176 <_ZN15OrangutanMotors5init2Ev>
 1cc:	08 95       	ret

000001ce <_ZN15OrangutanMotors10setM1SpeedEi>:
 1ce:	cf 93       	push	r28
 1d0:	df 93       	push	r29
 1d2:	ec 01       	movw	r28, r24
 1d4:	f3 df       	rcall	.-26     	; 0x1bc <_ZN15OrangutanMotors4initEv>
 1d6:	d7 fd       	sbrc	r29, 7
 1d8:	02 c0       	rjmp	.+4      	; 0x1de <_ZN15OrangutanMotors10setM1SpeedEi+0x10>
 1da:	20 e0       	ldi	r18, 0x00	; 0
 1dc:	04 c0       	rjmp	.+8      	; 0x1e6 <_ZN15OrangutanMotors10setM1SpeedEi+0x18>
 1de:	d0 95       	com	r29
 1e0:	c1 95       	neg	r28
 1e2:	df 4f       	sbci	r29, 0xFF	; 255
 1e4:	21 e0       	ldi	r18, 0x01	; 1
 1e6:	ce 01       	movw	r24, r28
 1e8:	cf 3f       	cpi	r28, 0xFF	; 255
 1ea:	d1 05       	cpc	r29, r1
 1ec:	19 f0       	breq	.+6      	; 0x1f4 <_ZN15OrangutanMotors10setM1SpeedEi+0x26>
 1ee:	14 f0       	brlt	.+4      	; 0x1f4 <_ZN15OrangutanMotors10setM1SpeedEi+0x26>
 1f0:	8f ef       	ldi	r24, 0xFF	; 255
 1f2:	90 e0       	ldi	r25, 0x00	; 0
 1f4:	22 23       	and	r18, r18
 1f6:	19 f0       	breq	.+6      	; 0x1fe <_ZN15OrangutanMotors10setM1SpeedEi+0x30>
 1f8:	18 bc       	out	0x28, r1	; 40
 1fa:	87 bd       	out	0x27, r24	; 39
 1fc:	02 c0       	rjmp	.+4      	; 0x202 <_ZN15OrangutanMotors10setM1SpeedEi+0x34>
 1fe:	88 bd       	out	0x28, r24	; 40
 200:	17 bc       	out	0x27, r1	; 39
 202:	df 91       	pop	r29
 204:	cf 91       	pop	r28
 206:	08 95       	ret

00000208 <_ZN15OrangutanMotors10setM2SpeedEi>:
 208:	cf 93       	push	r28
 20a:	df 93       	push	r29
 20c:	ec 01       	movw	r28, r24
 20e:	d6 df       	rcall	.-84     	; 0x1bc <_ZN15OrangutanMotors4initEv>
 210:	d7 fd       	sbrc	r29, 7
 212:	02 c0       	rjmp	.+4      	; 0x218 <_ZN15OrangutanMotors10setM2SpeedEi+0x10>
 214:	20 e0       	ldi	r18, 0x00	; 0
 216:	04 c0       	rjmp	.+8      	; 0x220 <_ZN15OrangutanMotors10setM2SpeedEi+0x18>
 218:	d0 95       	com	r29
 21a:	c1 95       	neg	r28
 21c:	df 4f       	sbci	r29, 0xFF	; 255
 21e:	21 e0       	ldi	r18, 0x01	; 1
 220:	ce 01       	movw	r24, r28
 222:	cf 3f       	cpi	r28, 0xFF	; 255
 224:	d1 05       	cpc	r29, r1
 226:	19 f0       	breq	.+6      	; 0x22e <_ZN15OrangutanMotors10setM2SpeedEi+0x26>
 228:	14 f0       	brlt	.+4      	; 0x22e <_ZN15OrangutanMotors10setM2SpeedEi+0x26>
 22a:	8f ef       	ldi	r24, 0xFF	; 255
 22c:	90 e0       	ldi	r25, 0x00	; 0
 22e:	22 23       	and	r18, r18
 230:	29 f0       	breq	.+10     	; 0x23c <_ZN15OrangutanMotors10setM2SpeedEi+0x34>
 232:	10 92 b4 00 	sts	0x00B4, r1
 236:	80 93 b3 00 	sts	0x00B3, r24
 23a:	04 c0       	rjmp	.+8      	; 0x244 <_ZN15OrangutanMotors10setM2SpeedEi+0x3c>
 23c:	80 93 b4 00 	sts	0x00B4, r24
 240:	10 92 b3 00 	sts	0x00B3, r1
 244:	df 91       	pop	r29
 246:	cf 91       	pop	r28
 248:	08 95       	ret

0000024a <_ZN15OrangutanMotors9setSpeedsEii>:
 24a:	0f 93       	push	r16
 24c:	1f 93       	push	r17
 24e:	8b 01       	movw	r16, r22
 250:	be df       	rcall	.-132    	; 0x1ce <_ZN15OrangutanMotors10setM1SpeedEi>
 252:	c8 01       	movw	r24, r16
 254:	d9 df       	rcall	.-78     	; 0x208 <_ZN15OrangutanMotors10setM2SpeedEi>
 256:	1f 91       	pop	r17
 258:	0f 91       	pop	r16
 25a:	08 95       	ret

0000025c <set_motors>:
 25c:	f6 cf       	rjmp	.-20     	; 0x24a <_ZN15OrangutanMotors9setSpeedsEii>
 25e:	08 95       	ret

00000260 <_exit>:
 260:	f8 94       	cli

00000262 <__stop_program>:
 262:	ff cf       	rjmp	.-2      	; 0x262 <__stop_program>

Any ideas? :frowning:

Hello,

Hm. It sounds like your motor is probably just soldered backwards, and if it worked before, you had a bug back then. I recommend that you just define an inline function my_set_motors that calls set_motors(m1, -m2) and use that instead of the original set_motors().

-Paul