Wild Orangutan

A few fellow students and I have picked up a MicroMouse project that was handed down by some of our graduates. We acquired an Orangutan X2 (ATmega644P) with VNH3 and LCD. The previous team had limited success navigating the maze but otherwise the hardware functioned nominally. However, they did not attach the LCD because they couldn’t get it working. We soon realized that the plug on the LCD was reversed. Once we attached the LCD in the correct direction we could print to the display…HOWEVER, there are some interesting problems:

  1. When the LCD is attached, multiple LEDs light in a seemingly random pattern. The pattern will change with output to the LCD but in particular order. Some of the LEDs are only dimly lit. We assume there is a short but there is no visible scarring on the cord or plugs and no LEDs are lit when the program memory is erased.
  2. When using the digital pins, the ISR on PCINT2 is ignored UNLESS the LCD is attached and printed to in the while() loop. All other functions seem to execute normally. We set motor speeds, read from analog pins, etc. but it ignores the change on the digital pins. I have scoped the encoders and the output is good. I have tried using the Pololu Wheel Encoder functions to initialize and analyze the signals with no change on the count. I created my own ISR for a single digital pin with a simple counter and still nothing. When I plug in the LCD and don’t print…nothing. When I plug in the LCD and print outside the while loop…nothing. But like magic, when the LCD is attached and I include even a single print command inside the while() loop…viola! Everything works normally. But I don’t need or want to attach an LCD to the mouse (unless absolutely necessary). Also, using the print command with LCD detached doesn’t work.

If anyone has any ideas, it would be much appreciated.

Hello.

The LED behavior you are describing is normal. If you look at the X2 schematic, you can see that the LEDs are on the LCD data lines, so they will flicker in response to LCD activity. You can minimize this behavior by adding code to the beginning of your program that actively turns the LEDs off by driving the LED pins low (or using the LED functions from the Pololu AVR library). Whenever you write to the LCD, the LCD library code briefly takes control of the LCD lines as necessary and then restores them to their previous state.

I don’t really follow your description of your second problem. Can you post the simplest code that demonstrates the problem along with a description of what you expect to happen and what actually happens?

- Ben

Thanks for reassuring that the LEDs are intentionally flashing. The second issue is the stranger phenomenon. If I make a simple code:

#include <pololu/orangutan.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>

static unsigned char rPin;
static unsigned char lPin;
static unsigned int rCount;
static unsigned int lCount;
static unsigned char rV_old;
static unsigned char lV_old;

inline unsigned char get_val(unsigned char pin) {	
	return (PIND >> pin) & 1;    
}
ISR(PCINT2_vect) {
	unsigned char rV = get_val(rPin);
	unsigned char lV = get_val(lPin);
	if(rV && !rV_old)
		rCount += 1;
	if(lV && !lV_old)
		lCount += 1;
	rV_old = rV;
	lV_old = lV;
}
static void enableInt(unsigned char p) {
	PCICR |= 1 << PCIE2;
	DDRD &= ~(1 << p);
	PCMSK2 |= 1 << p;
}
void EncodeInit(unsigned char Rpin, unsigned char Lpin) {
	rPin = Rpin;
	lPin = Lpin;
	cli();
	enableInt(Rpin);
	enableInt(Lpin);
	rCount = 0;
	lCount = 0;
	rV_old = get_val(Rpin);
	lV_old = get_val(Lpin);
	PCIFR |= (1 << PCIF2);
	sei();
}

int main() {
      //clear();
      EncodeInit((unsigned char)0,(unsigned char)1);
      set_motors(10,10);
      while(1) {
            if(rCount > 12) {
                  set_motors(0,0);
                  break;
            }
            //lcd_goto_xy(0,0);
            //print_long(rCount);
      }
      return 0;
}

The motors start and never stop. But if I un-comment the three lines regarding the LCD and attach the LCD, the wheel makes one revolution (12 teeth) and stops. Any help would be much appreciated. Thanks.

Hello, YSU_MicroMouse.

It looks like your main function returns. This is very bad because in avr-gcc, when your main function returns you will get undefined behavior. I recommend replacing “return 0;” with “while(1);” and seeing if that fixes up any of the weird behavior your are seeing.

–David

I’ve changed the code so as not to let main return but this hasn’t helped the issue. The problem seems to be that without the LCD code, the ISR doesn’t trigger (the count is always zero). Anything else I put in the loop works fine. I can add analog conversion from the PA0-7 pins and use them to control the motors, etc. But when I use the wheel count, it just sits at zero. As soon as I add a little LCD communication, my encoder code works perfectly. The output from the encoder hardware scoped the same with and without the LCD attached so I doubt that it’s a power/hardware issue. After reading through the LCD code, I was wondering if the delays had something to do with it? Or maybe there is something in there that initializes a pin-change register? I don’t understand the issue. Can somebody help me out? Thanks.

Yes, probably our LCD code is initializing something important that you need to have in your encoder code.

I have two suggestions:

  1. Narrow down the cause of the effect you are seeing. Do the encoders work if you just call “clear” and no other LCD functions? If so, I would look at the source code of clear() in the OrangutanLCD section of our library and see what it’s doing that might cause your encoder functions to work. You could make your own version of the clear() function in your program and see if that causes the encoders to work. Start removing lines of code from it until the encoders stop working.

  2. Look at the source of the PololuWheelEncoders section of our library (PololuWheelEncoders.cpp, PololuWheelEncoders.h) and see if we’re doing something differently from your encoder code.

–David