Code running 1.75 times then stopping

I am using a baby orangutan with a 328 and I have all the code inside a endless while loop. When I compile the code in AVR studio it compiles without any errors and only a few warnings about unused variables. When I load it onto the 328 it runs all the way thru once, runs most of the way thru a second time then it stops. Right now I have found that if I remove a line that is variablename=1; the code will keep running, but if that line is there the code will not run. I have this variable used elsewhere and it runs without problems and the variable is properly defined. Any idea what would be causing this because I am out of ideas.

Hello,

You should post your code if you have trouble with code not working. You should also reduce it to the smallest case that exhibits the unexplained behavior.

- Jan

I just had another idea of what to check and I will see if it works when I get home. If not I will post my code or send it to you in a pm. I didn’t post it before because it is about 1500 lines and confusing if I don’t explain it well.

Please don’t send me PMs that don’t need to be private. The whole point of the forum is to publicly discuss your projects. Posting 1500 lines is definitely not reasonable; you should be able to trim it down a lot (and maybe doing so will help you find the problem).

- Jan

Hello.

Strange errors that come and go when seemingly unrelated code is modified can sometimes be the sign of things like stack overflows or interrupts misbehaving.

If you are using a lot of your RAM to store data, you could be overwriting your stack with program data (or overwriting program data with your stack), which can cause your program to go haywire. A good rule of thumb is to try to leave around half of your RAM available for the stack, though on the mega328 you might be okay with 300 - 500 bytes of RAM for your stack. Just note that the more RAM you use, the more you have to pay attention to things like how deeply your functions are nested and how many local variables they use.

You can also get strange errors if you use interrupts in an unsafe way. Specifically, if you have a non-atomic (i.e. multi-step) operation that you expect to be carried out in a timely manner, an interrupt in the middle of it can break things. This type of error might only show up every few minutes/hours/days, and it can go away when you remove unrelated lines of code just because it changes the code that is executing when the interrupt happens. One example of this would be trying to read the value of an integer whose value gets set by an interrupt. In C this looks like an atomic operation, but at the machine level you actually need to read each byte from RAM. If the interrupt occurs between the byte reads and changes the value, the result of the read might not match either the previous or current value, and you’re now potentially acting on corrupted data.

I have no idea if either of these apply to your program, but if you use interrupts or a lot of RAM, it’s worth considering these as potential error sources.

- Ben

What I though of earlier was that I forgot a decimal point in some doubles. I had 0 instead of 0.0 in some places and I fixed this in my code. It still is not running right.

What I am working on is a 6 legged walker that will follow someone walking around. I have 12 servo’s controlled with your serial servo controller to move the legs. On top of the walker I have a 13th servo with 2 IR range sensors on it. I am using these sensors to scan around the robot and try and figure out what has moved. Most of the code in main is for the mapping of the enviroment and to figure out what has moved. The stuff I have commented out is not working yet or is also giving me problems and not letting the while loop continue. All the functions except maybe check_battery work. The blue/red/greeneye functions control tri color LED’s that I am calling eyes. The DIP switch that i mention in my port notes at the beginning is not in use right now, I eventually want to use it for some stuff but am not at that stage yet.

The line of code that is getting stuck is:
previousturn=1.0;

it is about 20 lines from the end of the code.

How would I go about checking if I am overloading the stack? I am thinking it is something with this or problems with memory usage. My code is below if you want to look at it.

when I compile my code I get the following for memory usage. I dont get any errors and the only warnings I get are about unused variables.

AVR Memory Usage
----------------
Device: atmega328p

Program:   13712 bytes (41.8% Full)
(.text + .data + .bootloader)

Data:        221 bytes (10.8% Full)
(.data + .bss + .noinit)
//#include <pololu/orangutan.h>
#include <avr/io.h>
#include <math.h> 
#include <pololu/analog.h>
#include <pololu/time.h>
#include <pololu/serial.h>


int step_time=400; //time for each leg to move forward in ms
int lift_time=300; //time required to lift leg before it starts moving
int scandelay=500; //time to rotate between reading
int scandegrees=18;//degrees to rotate between scanning

int turn_rate=19;//degrees rotation per step
int step_rate=4;//distance traveled every step
int error=3;//error allowed in readings


int s5forward=150;//forward angle of center left leg, set differnt to walk strait
int s6forward=150;//forward angle of center right let, set differnt to walk strait
int s4lift_up=160;//lift angle of center left leg servo, set differnt due to differnt servo
int s4lift_down=125;//lift angle of center left leg servo, set differnt due to differnt servo
int s7lift_up=160;//lift angle of center right leg servo, set differnt due to differnt servo
int s7lift_down=125;//lift angle of center right leg servo, set differnt due to differnt servo
int forward=150;	//forward angle of leg
int backward=90; //backwards angle of leg
int lift_up=156; //angle of lift leg up
int lift_down=120; //angle of lift leg down


int redledstate=0;//red led state, on or off
int greenledstate=0;//green led state, on or off
int redeyestate=0;//redeye state, on or off
int greeneyestate=0;//green eye state, on or off
int blueeyestate=0;//green eye state, on or off
int rgblinkstate=0;//rg blink state
long int redledtime=0;//time count for blinking led
long int greenledtime=0;//time count for blinking led
long int redeyetime=0;//time count for blinking red eye
long int greeneyetime=0;//time count for blinking green eye
long int blueeyetime=0;//time count for blinking green eye
long int rgblinktime=0;// rg blink time

int junk=0;//variable to dump unneaded data to
double junkd=0.0;//junk variable in double form


char hex[128]={
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F
};

///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
/*
port assignements

PB0 dip pin 1
PB1 dip pin 2
PB2 dip pin 3
PD2 dip pin 4

M1A  OCR0A 	redeye
PC5 		blueeye
PC4   		greeneye

M2A  OCR2A	green led
P2B  OCR2B  red led

PD1 serial 	transmit
PD0 serial 	send

ADC6 servo battery sense
PC0 far IR sensor
PC1 close IR sensor
PC2 processor battery sense

PD7 walk switch
*/
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////  
void motors_init()
 	{    
	 // Motor Control Macros -- pwm is an 10-bit value  
	//  (i.e. ranges from 0 to 1024)  
   
	// Motor Initialization routine -- this function must be called  
	// before you use any of the above macros  
 
	// configure for inverted PWM output on motor control pins:  
    //  set OCxx on compare match, clear on timer overflow  
    //  Timer0 and Timer2 count up from 0 to 1024  
    TCCR0A = 0xF3;  
    TCCR2A = 0xF3;
  
    // use the system clock/8 ( microprecessor = 20 MHz) as the timer clock  
    TCCR0B =  0x01;  //pwm frequency=9.8khz
  	TCCR2B =  0x01;  //pwm frequency=9.8khz
  
    // initialize all PWMs to 0% duty cycle (braking)  
    OCR0A = OCR0B = OCR2A = OCR2B = 0;  
   
    // set PWM pins as digital outputs (the PWM signals will not  
    // appear on the lines if they are digital inputs)  
    DDRB |= (1 << PORTB3);  //set B3 as outputs
    DDRD |= (1 << PORTD3);  //set D3 as outputs
    DDRD |= (1 << PORTD5);  //set D5 as outputs
    DDRD |= (1 << PORTD6);  //set D6 as outputs


	}  //end motors init().  see https://www.pololu.com/docs/0J15/5


///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
void port_init()//define port functions
{
DDRB &= ~(1 << PORTB0);//switch 1 on dip
PORTB |= (1 << PORTB0);//draw internally high 

DDRB &= ~(1 << PORTB1);//switch 2 on dip
PORTB |= (1 << PORTB1);//draw internally high

DDRB &= ~(1 << PORTB2);//switch 3 on dip
PORTB |= (1 << PORTB2);//draw internally high 

DDRD &= ~(1 << PORTD2);//switch 4 on dip
PORTD |= (1 << PORTD2);//draw internally high 

DDRD &= ~(1<<PORTD7);// switch for walinkg control
PORTD |= (1 << PORTD7); // draw internally high

DDRC |= 1 << PORTC4; // set the PC4 bit of DDRD to make output for green eye
DDRC |= 1 << PORTC5; // set the PC5 bit of DDRD to make output for blue eye



set_analog_mode(8);//set analog conversion to 8 bit


delay_ms(10);	
serial_set_baud_rate(40000);
delay_ms(10);

}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
int redeye(int pos)//0 = off, 1 =  on, 2=blink, >3 variable brightnes
{//red eye led

int power=0;
if(pos==0)//turn off
	{
	if(redeyestate==1)
		{
		power=0;
		redeyestate=0;
		}
	}

if(pos==1)//turn on
	{
	if(redeyestate==0)
		{
		power=512;
		redeyestate=1;
		}
	}

if(pos==2)
	{	
	if(redeyestate==0)//turn on led
		{
		if((redeyetime+750)<=(get_ms()))//only if long enough time
			{
			power=255;
			redeyetime=get_ms();
			redeyestate=1;
			}
		}
	
	if(redeyestate==1)//turn off led
		{
		if((redeyetime+750)<=(get_ms()))//only if long enought time
			{
			power=0;
			redeyetime=get_ms();
			redeyestate=0;
			}
		}
	}

if(pos>=3)
	{
	power=pos;
	}

if(power>=256)
	{
	power=255;
	}

if(power<=0)
	{
	power=0;
	}

OCR0A=power;

return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////

int blueeye(int pos)//0 = off, 1 =  on, 2=blink, >3 variable brightnes
{//blue eye led

if(pos==0)//turn off
	{
	if(blueeyestate==1)
		{
		PORTC &= ~(1 << PORTC5); // clear the bit to drive pin low
		blueeyestate=0;
		}
	}

if(pos==1)//turn on
	{
	if(blueeyestate==0)
		{
		PORTC |= 1 << PORTC5; // set the bit to drive pin high
		blueeyestate=1;
		}
	}

if(pos==2)
	{	
	if(blueeyestate==0)//turn on led
		{
		if((blueeyetime+750)<=(get_ms()))//only if long enough time
			{
			PORTC |= 1 << PORTC4; // set the bit to drive pin high
			blueeyetime=get_ms();
			blueeyestate=1;
			}
		}
	
	if(blueeyestate==1)//turn off led
		{
		if((blueeyetime+750)<=(get_ms()))//only if long enought time
			{
			PORTC &= ~(1 << PORTC5); // clear the bit to drive pin low
			blueeyetime=get_ms();
			blueeyestate=0;
			}
		}
	}

return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
int greeneye(int pos)//0 = off, 1 =  on, 2=blink, >3 variable brightnes
{//green eye led


if(pos==0)//turn off
	{
	if(greeneyestate==1)
		{
		PORTC &= ~(1 << PORTC4); // clear the bit to drive pin low
		greeneyestate=0;
		}
	}

if(pos==1)//turn on
	{
	if(greeneyestate==0)
		{
		PORTC |= 1 << PORTC4; // set the bit to drive pin high
		greeneyestate=1;
		}
	}

if(pos==2)
	{	
	if(greeneyestate==0)//turn on led
		{
		if((greeneyetime+750)<=(get_ms()))//only if long enough time
			{
			PORTC |= 1 << PORTC4; // set the bit to drive pin high	
			greeneyetime=get_ms();
			greeneyestate=1;
			}
		}
	
	if(greeneyestate==1)//turn off led
		{
		if((blueeyetime+750)<=(get_ms()))//only if long enought time
			{
			PORTC &= ~(1 << PORTC4); // clear the bit to drive pin low
			greeneyetime=get_ms();
			greeneyestate=0;
			}
		}
	}

return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
int greenled(int pos)//0 = off, 1 =  on, 2=blink, >3 variable brightnes
{//green led
int power=0;
if(pos==0)//turn off
	{
	if(greenledstate==1)
		{
		power=0;
		greenledstate=0;
		}
	}

if(pos==1)//turn on
	{
	if(greenledstate==0)
		{
		power=512;
		greenledstate=1;
		}
	}

if(pos==2)
	{	
	if(greenledstate==0)//turn on led
		{
		if((greenledtime+750)<=(get_ms()))//only if long enough time
			{
			power=256;
			greenledtime=get_ms();
			greenledstate=1;
			}
		}
	
	if(greenledstate==1)//turn off led
		{
		if((greenledtime+750)<=(get_ms()))//only if long enought time
			{
			power=0;
			greenledtime=get_ms();
			greenledstate=0;
			}
		}
	}

if(pos>=3)
	{
	power=pos;
	}

if(power>=256)
	{
	power=255;
	}

if(power<0)
	{
	power=0;
	}

OCR2B=power;

return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
int redled(int pos)//0 = off, 1 =  on, 2 = blink, 
{//red led
int power=0;
if(pos==0)//turn off
	{
	if(redledstate==1)
		{
		power=0; 
		redledstate=0;
		}
	}

if(pos==1)//turn on
	{
	if(redledstate==0)
		{
		power=255;
		redledstate=1;
		}
	}

if(pos==2)//flash
	{
	if(redledstate==0)//turn on led
		{
		if((redledtime+1000)<=(get_ms()))//only if long enough time
			{
		 	power=255;
			redledtime=get_ms();
			redledstate=1;
			}
		}
	
	if(redledstate==1)//turn off led
		{
		if((redledtime+1000)<=(get_ms()))//only if long enought time
			{
			power=0;
			redledtime=get_ms();
			redledstate=0;
			}
		}
	}

if(pos>=3)
	{
	power=pos;
	}

if(power>=256)
	{
	power=255;
	}

if(power<0)
	{
	power=0;
	}

OCR2A=power;

return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
void rgledblink()
{
if(rgblinkstate==0)//turn on led
	{
	if((rgblinktime+1000)<=(get_ms()))//only if long enough time
		{
		greenled(0);
		redled(1);
		rgblinktime=get_ms();
		rgblinkstate=1;
		}
	}

if(rgblinkstate==1)//turn off led
	{
	if((rgblinktime+1000)<=(get_ms()))//only if long enought time
		{
		redled(0);
		greenled(1);
		rgblinktime=get_ms();
		rgblinkstate=0;
		}
	}
}

///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
void check_battery()//chack battery and turn on LED for low battery
{
int batteryvoltage=0;
int batteryvoltage2=0;
int junk=0;
int batterystate=0;//1 = low, 2 =  dead

start_analog_conversion(6);//start checking servo battery
while((analog_is_converting(6))!=0){};//wait for  conversion
junk=analog_conversion_result(6);

while((analog_is_converting(6))!=0){};//wait for  conversion
batteryvoltage=analog_conversion_result(6);

/*
for(int i=0; i<(batteryvoltage/8); i++)
{
blueeye(1);
delay_ms(500);
blueeye(0);
delay_ms(500);
}
delay_ms(3000);
*/


if ((batteryvoltage<=145)&&(batteryvoltage>=128))//servo battery is getting to low
	{
	batterystate=1;
	redled(2);
	}

if ((batteryvoltage<128)&&(batteryvoltage>=50))//if the battery is to low turn off
	{
 	batterystate=2;
	redled(1);
	}

start_analog_conversion(2);//start checking processor battery
while((analog_is_converting(2))!=0){};//wait for  conversion
junk=analog_conversion_result(2);

while((analog_is_converting(2))!=0){};//wait for  conversion
batteryvoltage2=analog_conversion_result(2);

/*
for(int i=0; i<(batteryvoltage2/8); i++)
{
redeye(1);
delay_ms(500);
redeye(0);
delay_ms(500);
}
delay_ms(3000);
*/


if ((batteryvoltage2<=184)&&(batteryvoltage2>=153))//controller battery is getting to low
	{
	if(batterystate==0)
		{
		batterystate=1;
		greenled(2);
		}
	}

if (batteryvoltage2<152)//if the battery is to low turn  off
	{
	batterystate=2;
	greenled(1);
	}
if(batterystate==0)
	{
	redled(0);
	greenled(0);
	}

if(batterystate==2)
	{
//	while(1)
		{
		rgledblink();
		}
	}
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
int set_servo(int snumber, int pos)	//snumber=servo number    pos=position
{
int hi=0;//control if using postion above 90 deg
if(pos>=256)//check to make sure in range 
	{ 
	pos=255;
	}

if (pos>=127)//check if angle is above 90 degree, if so correct
	{
	hi=1;
	pos=pos-128;
	}

char out[6]={0x80,0x01,0x03,hex[snumber],hex[hi],hex[pos]};
serial_send(out,6);//dend serial comand
delay_ms(2);//prevent serial from overloading
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
void step_forward()//walk forward one step each time function is called
{
set_servo(0,255-lift_down);	
set_servo(7,s7lift_down);
set_servo(8,255-lift_down);
delay_ms(lift_time),// all legs down
	
set_servo(3,lift_up);
set_servo(4,255-s4lift_up);
set_servo(11,lift_up);
delay_ms(lift_time);//first set of legs up
		
set_servo(1,forward);
set_servo(6,255-s6forward);
set_servo(9,forward);
set_servo(2,255-backward);
set_servo(5,backward);
set_servo(10,255-backward);
delay_ms(step_time);//all move forward

set_servo(3,lift_down);
set_servo(4,255-s4lift_down);
set_servo(11,lift_down);
delay_ms(lift_time);//all down

set_servo(0,255-lift_up);	
set_servo(7,s7lift_up);
set_servo(8,255-lift_up);
delay_ms(lift_time);// second set of legs up

set_servo(1,backward);
set_servo(6,255-backward);
set_servo(9,backward);
set_servo(2,255-forward);
set_servo(5,s5forward);
set_servo(10,255-forward);
delay_ms(step_time);//all move forward

set_servo(0,255-lift_down);	
set_servo(7,s7lift_down);
set_servo(8,255-lift_down);//end with all legs down
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
void step_backward()//walk forward one step each time function is called
{
set_servo(0,255-lift_down);	
set_servo(7,s7lift_down);
set_servo(8,255-lift_down);
delay_ms(lift_time),// all legs down
	
set_servo(3,lift_up);
set_servo(4,255-s4lift_up);
set_servo(11,lift_up);
delay_ms(lift_time);//first set of legs up
		
set_servo(1,backward);
set_servo(6,255-backward);
set_servo(9,backward);
set_servo(2,255-forward);
set_servo(5,s5forward);
set_servo(10,255-forward);
delay_ms(step_time);//all move forward

set_servo(3,lift_down);
set_servo(4,255-s4lift_down);
set_servo(11,lift_down);
delay_ms(lift_time);//all down

set_servo(0,255-lift_up);	
set_servo(7,s7lift_up);
set_servo(8,255-lift_up);
delay_ms(lift_time);// second set of legs up

set_servo(1,forward);
set_servo(6,255-s6forward);
set_servo(9,forward);
set_servo(2,255-backward);
set_servo(5,backward);
set_servo(10,255-backward);
delay_ms(step_time);//all move forward

set_servo(0,255-lift_down);	
set_servo(7,s7lift_down);
set_servo(8,255-lift_down);//end with all legs down
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
int turn_right(int amount)//amount is degrees to turn
{
int cycles=0;//number of steps to rotate
int i=0;//loop count

cycles=amount/turn_rate;//set number of rotation cycles

if(amount>=180)//dont let amount be to high
	{
	amount=180;
	}
if(amount<=0)//dont let amount be to low
	{
	amount=0;
	}

while(i<=(cycles-0))//roatate for set number of steps
	{
	i=i+1;
	set_servo(0,255-lift_up);
	set_servo(7,lift_up);
	set_servo(8,255-lift_up);//lift servo's 0,7,8
	delay_ms(lift_time);

	set_servo(1,forward);
	set_servo(5,backward);
	set_servo(9,forward);
	set_servo(2,backward);
	set_servo(6,forward);
	set_servo(10,backward);
	delay_ms(step_time);//rotate all legs to requred postition

	set_servo(0,255-lift_down);
	set_servo(7,lift_down);
	set_servo(8,255-lift_down);//lower servo's 0,7,8
	delay_ms(lift_time);

	set_servo(3,lift_up);
	set_servo(4,255-lift_up);
	set_servo(11,lift_up);//lift servo's 3,4,11
	delay_ms(lift_time);

	set_servo(1,backward);
	set_servo(5,forward);
	set_servo(9,backward);
	set_servo(2,forward);
	set_servo(6,backward);
	set_servo(10,forward);
	delay_ms(step_time);//rotate all legs to requred postition

	set_servo(3,lift_down);
	set_servo(4,255-lift_down);
	set_servo(11,lift_down);//all legs down
	delay_ms(lift_time);

	}//
return 0;
}//end turn right
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
int turn_left(int amount)//amount  is degrees 
{
int cycles=0;//number of steps to rotate
int i=0;//loop count

cycles=amount/turn_rate;//set number of rotation cycles

if(amount>=180)//dont let amount be to high
	{
	amount=180;
	}
if(amount<=0)//dont let amount be to low
	{
	amount=0;
	}

while(i<=(cycles-0))//roatate for set number of steps
	{
	i=i+1;
	set_servo(0,255-lift_up);
	set_servo(7,lift_up);
	set_servo(8,255-lift_up);//lift servo's 0,7,8
	delay_ms(lift_time);

	set_servo(1,backward);
	set_servo(5,forward);
	set_servo(9,backward);
	set_servo(2,255-forward);
	set_servo(6,255-backward);
	set_servo(10,255-forward);
	delay_ms(step_time);//rotate all legs to requred postition

	set_servo(0,255-lift_down);
	set_servo(7,lift_down);
	set_servo(8,255-lift_down);//lower servo's 0,7,8
	delay_ms(lift_time);

	set_servo(3,lift_up);
	set_servo(4,255-lift_up);
	set_servo(11,lift_up);//lift servo's 3,4,11
	delay_ms(lift_time);

	set_servo(1,forward);
	set_servo(5,backward);
	set_servo(9,forward);
	set_servo(2,255-backward);
	set_servo(6,255-forward);
	set_servo(10,255-backward);
	delay_ms(step_time);//rotate all legs to requred postition

	set_servo(3,lift_down);
	set_servo(4,255-lift_down);
	set_servo(11,lift_down);//all legs down
	delay_ms(lift_time);
	}//

return 0;
}//end turn left
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
int distance(int angle)//finds the distance to an object and returns the value if it exists. ange is 0 to 180 deg
{
double position=0;//variable for angle to servo position calculations
int positioni=0;//variable for angle to servo position calculations
int junk=0;// junk varaible
double farvoltage=0.0;
double closevoltage=0.0;
double fardistance=0.0;
double near=0.0;
int returnvalue=0;


position=((angle*255.0)/180.0)-4.0;
positioni=position;
if(positioni<=0)
	{
	positioni=1;
	}

if(positioni>=256)
	{
	positioni=255;
	}

set_servo(12,positioni);
delay_ms(scandelay);


start_analog_conversion(0);//start checking processor battery
while((analog_is_converting(0))!=0){};//wait for  conversion
junk=analog_conversion_result(0);

while((analog_is_converting(0))!=0){};//wait for  conversion
farvoltage=analog_conversion_result(0);


start_analog_conversion(0);//start checking processor battery
while((analog_is_converting(0))!=0){};//wait for  conversion
junk=analog_conversion_result(0);

while((analog_is_converting(0))!=0){};//wait for  conversion
closevoltage=analog_conversion_result(0);

closevoltage=(closevoltage*5)/256;//convert reading to voltage
farvoltage=(farvoltage*5)/256;

junkd=pow((21.3*farvoltage),-0.85);//convert voltage to distance
fardistance=1/(pow((21.3*farvoltage),0.85));//convert voltage to distance
near=pow(10.7*closevoltage,-1.31);

if((near>=5)&&(near<=24)&&((closevoltage>=1.5)||(closevoltage<=1.3)))// if in close distance range
{
returnvalue=near;
}

if((fardistance>=8)&&(fardistance<=60)&&((farvoltage<=0.4)||(farvoltage>=0.6))&&(returnvalue==0))//if in far distance range
{
returnvalue=fardistance;
}

//PC0 far IR sensor
//PC1 close IR sensor
return(returnvalue);

}


///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
int main()
{
int previousdistance[((scandegrees/180)+2)][2];
int currentdistance[((scandegrees/180)+2)];//[angle position][x/y], x= forward, y = left/right, -y is left
int currentdistancexy[((scandegrees/180)+2)][2];//[angle position][x/y], x= forward, y = left/right
int objects[60][120];//objects found during past scan
int objectsdistance[((scandegrees/180)+2)];
double angle;//angle measured in radians
double previousturn=0.0;//previous turn angle in radians
int previouswalk=0;//distance walked in prevous step
int x=0;//variable for calculations
int y=0;//variable for calculations

double changex=0.0;//change in x value, used in calculations
double changey=0.0;//change in y value, used in calculations
double slope=0.0;// used for drawing lines between points
int xpos=0;// x position for calculations
int ypos=0;//y position for calulations
int leave=0;//exit loop
int leave2=0;//second exit variable due to problems with first one
int leave3=0;//second exit variable due to problems with first one
int loopcount=0;//loop count to prevent loop from getting stuck
int calcdistance=0;//distance used in calculations
int calcdistance2=0;//distance used in calculations
int biggestchange=0;//angle that has biggest change

motors_init();
port_init();



/*
while(1)
	{
	greeneye(1);
	delay_ms(500);
	greeneye(0);
	delay_ms(500);
	}
*/


for(int x=0; x<60;x++)//fill obstical array with zero's
	{
	for(int y=0; y<120;y++)
		{
		objects[x][y]=0;
		}
	}

for(int i=0; i<=((scandegrees/180)+1);i++)//fill positioin arrays with zero's
	{
	previousdistance[i][0]=0;
	previousdistance[i][1]=0;
	currentdistance[i]=0;
	currentdistancexy[i][0]=0;
	currentdistancexy[i][1]=0;
	objectsdistance[i]=0;
	}
/*
while(1)
{
set_servo(0,128);
set_servo(1,128);
set_servo(2,128);
set_servo(3,128);
set_servo(4,128);
set_servo(5,128);
set_servo(6,128);
set_servo(7,128);
set_servo(8,128);
set_servo(9,128);
set_servo(10,128);
set_servo(11,128);
}
*/



while(1) //endless while loop
{

check_battery();

if(PIND & (1 << PORTD7))// switch is off
	{
	redeye(1);
	delay_ms(500);
	redeye(0);
	delay_ms(500);
//	blueeye(1);
//	delay_ms(500);
//	blueeye(0);
	}// end switch off

if(!(PIND & (1 << PORTD7)))//switch on
	{


//greeneye(1);
	for(int i=0; i<=(180/scandegrees);i++)//find distance to objects if objects exist
		{
//		redeye(1);
		currentdistance[i]=distance(i*scandegrees);
//		redeye(0);
		}
//		blueeye(1);
		distance(0);
//		delay_ms(1000);
//		blueeye(0);
//greeneye(0);

/*	for(int i=0; i<6; i++)
		{
		blueeye(1);
		step_forward();
		blueeye(0);
		redeye(1);
		step_forward();
		redeye(0);
		}
*/


	
	for(int i=0; i<=(180/scandegrees);i++)//calculate x and y distances to objects
		{
		angle=((i*scandegrees*2*3.14159)/180)+.0001;//angle in radians
		currentdistancexy[i][0]=currentdistance[i]*sin(angle);// x distance
		currentdistancexy[i][1]=currentdistance[i]*cos(angle);//y distance
		}

	for(int i=0; i<=(180/scandegrees);i++)//adjust previous distance array based on movements
		{
		x=previousdistance[i][0];
		y=previousdistance[i][1];
		previousdistance[i][0]=(x*(cos(previousturn)))-(y*(sin(previousturn)))-previouswalk;// x movement since previous point
		previousdistance[i][1]=(x*(sin(previousturn)))+(y*(cos(previousturn)));//y movement since previous point
		if(previousdistance[i][0]<=0)// if walker has moved past object remove it from memory;
			{
			previousdistance[1][0]=0;
			previousdistance[i][1]=0;
			}
		}

	for(int i=0; i<=(180/scandegrees);i++)//build array of locations of objects at prevous points
		{
		if((previousdistance[i][0]!=0)||(previousdistance[i][1]!=0))//set point recorded as obsticale
			{
			objects[(previousdistance[i][0])][(previousdistance[i][1])]=1;
			}

		if(((previousdistance[i][0]!=0)||(previousdistance[i][1]!=0))&&((previousdistance[(i+1)][0]!=0)||(previousdistance[(i+1)][1]!=0))&&(i<(scandegrees/180)))// if both points read as an obsticle and not at end point
			{// if both points read as an obsticle and not at end point
			changex=previousdistance[i][0]-previousdistance[(i+1)][0];
			changey=previousdistance[i][1]-previousdistance[(i+1)][1];
			if(changey!=0)//don't divide by zero
				{
				slope=changex/changey;
				}
			else
				{
				slope=100;
				}

				xpos=previousdistance[i][0];
				ypos=previousdistance[i][1];

			if((slope>0)&&(slope!=100)&&(changex>0))//if moving in posotive x, posotive y direction
				{

				while((xpos!=previousdistance[(i+1)][0])&&(ypos!=previousdistance[(i+1)][1]))//loop until positioin at x end
					{
					for(int x=0; x<slope;x++)//move in x direction
						{
						if(xpos!=previousdistance[(i+1)][0])
							{
							objects[xpos][ypos]=1;
							xpos=xpos+1;
							}
						}
					for(int y=0; y<(1/slope);y++)//move in y direction
						{
						if(ypos!=previousdistance[(i+1)][1])
							{
							objects[xpos][ypos]=1;
							ypos=ypos+1;
							}
						}
					}
				}//end +x, +y 



			if((slope>0)&&(slope!=100)&&(changex<0))//if moving in negative x, negative y direction
				{
				while((xpos!=previousdistance[(i+1)][0])&&(ypos!=previousdistance[(i+1)][1]))//loop until positioin at x end
					{
					for(int x=0; x<slope;x++)//move in x direction
						{
						if(xpos!=previousdistance[(i+1)][0])
							{
							objects[xpos][ypos]=1;
							xpos=xpos-1;
							}
						}
					for(int y=0; y<(1/slope);y++)//move in y direction
						{
						if(ypos!=previousdistance[(i+1)][1])
							{
							objects[xpos][ypos]=1;
							ypos=ypos-1;
							}
						}
					}
				}//end -x, -y 

		
			if((slope<0)&&(slope!=100)&&(changex>0))//if moving in posotive x, negative y direction
				{
				while((xpos!=previousdistance[(i+1)][0])&&(ypos!=previousdistance[(i+1)][1]))//loop until positioin at x end
					{
					for(int x=0; x<slope;x++)//move in x direction
						{
						if(xpos!=previousdistance[(i+1)][0])
							{
							objects[xpos][ypos]=1;
							xpos=xpos+1;
							}
						}
					for(int y=0; y<(1/slope);y++)//move in y direction
						{
						if(ypos!=previousdistance[(i+1)][1])
							{
							objects[xpos][ypos]=1;
							ypos=ypos-1;
							}
						}
					}
				}//end +x, -y 

			if((slope<0)&&(slope!=100)&&(changex<0))//if moving in negative x, posotive y direction
				{
				while((xpos!=previousdistance[(i+1)][0])&&(ypos!=previousdistance[(i+1)][1]))//loop until positioin at x end
					{
					for(int x=0; x<slope;x++)//move in x direction
						{
						if(xpos!=previousdistance[(i+1)][0])
							{
							objects[xpos][ypos]=1;
							xpos=xpos-1;
							}
						}
					for(int y=0; y<(1/slope);y++)//move in y direction
						{
						if(ypos!=previousdistance[(i+1)][1])
							{
							objects[xpos][ypos]=1;
							ypos=ypos+1;
							}
						}
					}
				}//end +x, -y 

		
			if((slope==0)&&(changey>0))//if not moving in x, posotive y direction
				{
				while((xpos!=previousdistance[(i+1)][0])&&(ypos!=previousdistance[(i+1)][1]))//loop until positioin at x end
					{
					objects[xpos][ypos]=1;
					ypos=ypos+1;

					}
				}//end x=0, y+ 


			if((slope==0)&&(changey<0))//if not moving in x, negative y direction
				{
				while((xpos!=previousdistance[(i+1)][0])&&(ypos!=previousdistance[(i+1)][1]))//loop until positioin at x end
					{
					objects[xpos][ypos]=1;
					ypos=ypos-1;

					}
				}//end x=0, y- 


			if((slope==100)&&(changex>0))//if posotive x direction, not moving in y, 
				{
				while((xpos!=previousdistance[(i+1)][0])&&(ypos!=previousdistance[(i+1)][1]))//loop until positioin at x end
					{
					objects[xpos][ypos]=1;
					xpos=xpos+1;

					}
				}//end x+, y=0 


			if((slope==0)&&(changey<0))//if negative x direction, not moving in y, 
				{
				while((xpos!=previousdistance[(i+1)][0])&&(ypos!=previousdistance[(i+1)][1]))//loop until positioin at x end
					{
					objects[xpos][ypos]=1;
					xpos=xpos-1;

					}
				}//end x-, y=0 

			}//end both points are obsticle




		redeye(1);
		delay_ms(100);
		redeye(0);

		if(((previousdistance[i][0]!=0)||(previousdistance[i][1]!=0))&&((previousdistance[(i+1)][0]==0)||(previousdistance[(i+1)][1]==0))&&((previousdistance[(i-1)][0]==0)||(previousdistance[(i-1)][1]==0))&&(i>0)&&(i<(scandegrees/180)))// if point reads as obstacle but both neighboring points are zero
			{// if point reads as obstacle but both neighboring points are zero

			calcdistance=sqrt((previousdistance[i][0]*previousdistance[i][0])+(previousdistance[i][1]*previousdistance[i][0]));//calculate distance to object
			calcdistance=calcdistance*sin((scandegrees*2*3.14159)/180);
			changex=previousdistance[i][0]-previousdistance[(i+1)][0];
			
			xpos=previousdistance[i][0];
			ypos=previousdistance[i][1];
			if(i<((180/scandegrees)/5))// if line is near y axis on right
				{
				for(int c=0; c<=(calcdistance/2); c++)// draw line outward vertically
					{
					objects[xpos][(ypos+c+1)]=1;
					objects[xpos][(ypos-c-1)]=1;
					}
				}
			
			if(i>((4*(180/scandegrees))/5))// if line is near y axis on left
				{
				for(int c=0; c<=(calcdistance/2); c++)// draw line outward vertically
					{
					objects[xpos][(ypos+c+1)]=1;
					objects[xpos][(ypos-c-1)]=1;
					}
				}

			if((i>((2*(180/scandegrees))/5))&&(i<((3*(180/scandegrees))/5)))// if line is near x axis in front
				{
				for(int c=0; c<=(calcdistance/2); c++)// draw line outward vertically
					{
					objects[(xpos+1+c)][ypos]=1;
					objects[(xpos-1-c)][ypos]=1;
					}
				}

			if((i>=((1*(180/scandegrees))/5))&&(i<=((2*(180/scandegrees))/5)))// if line is near 45 degrees axis on right
				{
				for(int c=0; c<=(calcdistance/2); c++)// draw line outward vertically
					{
					objects[(xpos+1+c)][(ypos-1-c)]=1;
					objects[(xpos-1-c)][(ypos+1+c)]=1;
					}
				}
			
			if((i>=((3*(180/scandegrees))/5))&&(i<=((4*(180/scandegrees))/5)))// if line is near 45 degrees axis on right
				{
				for(int c=0; c<=(calcdistance/2); c++)// draw line outward vertically
					{
					objects[(xpos+1+c)][(ypos+1+c)]=1;
					objects[(xpos-1-c)][(ypos-1-c)]=1;
					}
				}

			
			}
		}//end build array of previous locations



	for(int i=0; i<=(180/scandegrees);i++)//determine what has moved the most
		{
		if((currentdistancexy[i][0]!=0)||(currentdistancexy[i][1]!=0))// if object exists at angle
			{
			xpos=0;
			ypos=60;
			changex=sin((i*scandegrees*3.14159)/180);
			changey=cos((i*scandegrees*3.14159)/180);
			if((changey>0.01)||(changey<-0.01))
				{
				slope=changex/(changey+0.0001);
				}
			else
				{
				slope=25;
				}

	//		leave=0;
			}
		else
			{
	//		leave=1;
			}

/*		for(int e=0;e<=slope; e++)
			{
			redeye(1);
			delay_ms(1000);
			redeye(0);
			delay_ms(1000);
			}
*/

		loopcount=0;
		leave2=0;
//	while(leave2==0)
			{
			leave2=leave;
	//		leave=1;
			loopcount=loopcount+1;
			if(loopcount>=60)
				{
				leave=1;	
				}
			blueeye(1);
delay_ms(100);
blueeye(0);	
delay_ms(100);

			if(i<((180/scandegrees)/2))// if in posative y space
				{
				if(slope!=0)
					{
					for(int x=0; ((x<slope)&&(x<60));x++)//expand in x direction
						{
						if(xpos>=58)
							{
							leave=1;
							}
		//				if(leave==0)
							{
							xpos=xpos+1;
							}
						if(objects[xpos][ypos]==1)//if reach edge of previous obstical
							{
							leave=1;
							}
						}
					}

				if(slope!=25)
					{	
					if(slope==0)
						{
						slope=0.04;
						}	
					if(slope>1)
						{
						slope=1;
						}		
					for(int y=0; ((y<(1/slope))&&(y<60));y++)//expand in y direction
						{
						if(ypos<=1)
							{
							leave=1;
							}
	//					if(leave==0)
							{
							ypos=ypos-1;
							}
						if(objects[xpos][ypos]==1)//if reach edge of previous obstical
							{
							leave=1;
							}
						}
					}
				}

			if(i>=((180/scandegrees)/2))// if in negative y space
				{
				if(slope!=0)
					{
					for(int x=0; x<slope;x++)//expand in x direction
						{
						if(xpos>=60)
							{
							leave=1;
							}
			//			if(leave==0)
							{
							xpos=xpos+1;
							}
						if(objects[xpos][ypos]==1)//if reach edge of previous obstical
							{
							leave=1;
							}
						}
					}
	
				if(slope!=25)
					{	
					if(slope==0)
						{
						slope=0.04;
						}
					if(slope<-1)
						{
						slope=1;
						}
					if((slope>=-1)&&(slope<0))
						{
						slope=-slope;
						}
					for(int y=0; y<(1/(slope));y++)//expand in y direction
						{
						if(ypos>=120)
							{
							leave=1;
							}
				//		if(leave==0)
							{
							ypos=ypos+1;
							}

						if(objects[xpos][ypos]==1)//if reach edge of previous obstical
							{
							leave=1;
							}
						}
					}	
		redeye(1);
		delay_ms(100);
		redeye(0);
				}
				

			}

//		objectsdistance[i]=sqrt(((sqrt((xpos-currentdistancexy[i][0])*(xpos-currentdistancexy[i][0])))*(sqrt((xpos-currentdistancexy[i][0])*(xpos-currentdistancexy[i][0]))))+((sqrt((ypos-currentdistancexy[i][1])*(ypos-currentdistancexy[i][1])))*(sqrt((ypos-currentdistancexy[i][1])*(ypos-currentdistancexy[i][1])))));		
	greeneye(1);
	delay_ms(100);
	greeneye(0);
	delay_ms(100);
		}//end determine what has moved the most 	

/*	blueeye(1);
	delay_ms(1000);
	blueeye(0);
	delay_ms(1000);
*/


	calcdistance=0;//reset variable
	biggestchange=0;//reset variable
/*	for(int i=0; i<=(180/scandegrees);i++)//determine distance between current position and previous postion
		{
		xpos=0;
		ypos=59;

		changex=currentdistancexy[i][0];
		changey=currentdistancexy[i][1];
		if(changey!=0)//don't divide by zero
			{
			slope=changex/changey;
			}
		else
			{
			slope=100;
			}
//		leave3=0;

	

//		while((leave3==0)||((xpos<60)&&(ypos>=0)&&(ypos<=120)))//expand until edge of obstical found or border reached
			{
			if(slope>0)//expanding on right side
				{
				for(int x=0; x<slope;x++)//move in x direction
					{
//					if(leave3==0)
						{
						xpos=xpos+1;
						}
					if((objects[xpos][ypos]==1)||(xpos==59))
						{
//						leave3=1;
						}
					}
				for(int y=0; y<(1/slope);y++)//move in -y direction
					{
//					if(leave3==0)
						{
						ypos=ypos-1;
						}
					if((objects[xpos][ypos]==1)||(ypos==0))
						{
//						leave3=1;
						}
					}
				}



			if(slope<0)//expanding on left side
				{
			for(int x=0; x<slope;x++)//move in x direction
					{
//					if(leave3==0)
						{
						xpos=xpos+1;
						}
					if((objects[xpos][ypos]==1)||(xpos==59))
						{
//						leave3=1;
						}
					}
			for(int y=0; y<(1/slope);y++)//move in -y direction
					{
//					if(leave3==0)
						{
						ypos=ypos+1;
						}
					if((objects[xpos][ypos]==1)||(ypos==119))
						{
//						leave3=1;
						}
					}
				}


			if(slope==100)// no change in y
				{
				xpos=xpos+1;
				if(objects[xpos][ypos]==1)
					{
//					leave3=1;
					}
				}

			if((slope==0)&&(changey<0))//expanding left
				{
				ypos=ypos-1;
				if(objects[xpos][ypos]==1)
					{
//					leave3=1;
					}
				}

			if((slope==0)&&(changey>0))// expanding right
				{
				ypos=ypos+1;
				if(objects[xpos][ypos]==1)
					{
//					leave=1;
					}
				}
			}//end expand until edge of obstical is found

		calcdistance2=0;
		if(currentdistance[i]!=0)
			{
//			calcdistance2=sqrt((xpos*xpos)+((ypos-60)*(ypos-60)));//calculate the distance from the start to the object intersection
//			calcdistance2=sqrt((calcdistance2-objectsdistance[i])*(calcdistance2-objectsdistance[i]));//find the distance between the prevous objects and current object
			}
		if((calcdistance2!=0)&&(calcdistance2>calcdistance))//determine if current distance change is bigger then previous recorded distance change
			{
			calcdistance=calcdistance2;
			biggestchange=i;
			}

		}//end determine distance between current position and previous postion

*/



	//tell robot to move towards biggest change and head in direction
//	{
biggestchange=5;
	if(biggestchange<((180/scandegrees)/2))//turn left
		{
//		turn_left((((180/scandegrees)/2)-biggestchange)*(scandegrees));
		previousturn=1.0;
//*((180/scandegrees)/2)-biggestchange*/;
		previousturn=previousturn*(scandegrees)*(3.14159/180);
		}	

//	if(biggestchange>((180/scandegrees)/2))//turn right
//		{
//		turn_right((biggestchange-((180/scandegrees)/2))*(scandegrees));
//		previousturn=(biggestchange-((180/scandegrees)/2))*(scandegrees)*(3.14159/180);
//		}
	
//	for(int s=0; s<=4;s++)
//		{
//		step_forward();	
//		previouswalk=previouswalk+step_rate;
//		}	
//	}//end tell robot to move towards biggest change and head in direction




	for(int i=0; i<=(scandegrees/180);i++)//set prevous postition to current position and reset current postition
		{
		previousdistance[i][0]=currentdistancexy[i][0];
		previousdistance[i][1]=currentdistancexy[i][1];
		currentdistancexy[i][0]=0;
		currentdistancexy[i][1]=0;
		}



	}// end switch on

}//end of endless while loop

return 0;
}//end main



it looks like some of my comments got carried over to the line below when the code was coppied over so be aware of this.

a video can be found here

That program is way too long for me evaluate for errors. Can’t you weed out most of the irrelevant portions to get down to the core part that’s failing? It seems like this would also be very helpful in letting you find the source of the problem.

It looks like you’re doing fine on global variable memory usage, so unless you are using recursion or have some functions that use hundreds of bytes of local variables, I don’t think the stack is your issue.

If you have warnings about unused variables, you should comment out those variable declarations or remove them entirely. Otherwise, you could accidentically ignore a valid warning because you think it’s about an unused variable.

You should also consider data overflow problems or incorrectly typed values. For example, make sure that you’re never trying to store a value larger than 0xFFFF in an integer.

- Ben

I will clean up my code and post it back up this weekend. I am only getting 2 or 3 unused variable errors and they are for variables used in parts of the code that I have commented out so I am not to concerned about it.

I cleaned up my code but am still having problems. To clean up my code I removed several functions that I do not need for LED’s and removed parts of the code I had commented out. I am still having problems with it not running right. I am now having problems with this loop

for(int r=0; r<slope;r++)//move in y direction

I am thinking it is still some sort of problem with the memory. I have one large integer array that is 60x120 but this works out to 7.2 kbytes so I am wondering if this is what that is causing some of the problems. All my other arrays are about 20x2 so they don’t use much memory.

Are you storing these arrays in flash or RAM? Can you post the section of code where you declare your arrays?

- Ben

the arrays are defined in main as

int previousdistance[((scandegrees/180)+2)][2];
int currentdistance[((scandegrees/180)+2)];//[angle position][x/y], x= forward, y = left/right, -y is left
int currentdistancexy[((scandegrees/180)+2)][2];//[angle position][x/y], x= forward, y = left/right
int objects[60][120];//objects found during past scan
int objectsdistance[((scandegrees/180)+2)];

where scandegrees is a constant set to 10.

I am not sure if I am building the arrays in RAM or flash, If I am building the array in RAM how do I change it so I am building them in flash?

Well, I think we’ve found the source of your problem. Let me reiterate a few things I said earlier in this thread:

and

Your “objects” array takes up 14,400 bytes of RAM (an int is two bytes, not one), and your ATmega328P has a total of 2048 bytes of RAM. You’re working on an 8-bit microcontroller, not a PC, so you have to be much more frugal when it comes to memory usage. As it is now, your objects array is overfilling RAM and leaving no room for the stack. I’m not sure exactly how the AVR responds to something like this, but I don’t expect it to be pretty. You can store data in flash, but its mostly useful for constant values that you treat as read-only during execution. It’s not usually a good idea to write a program that repeatedly writes data to flash since the flash on the MCU is only rated for 100k erase/write cycles.

Also, I don’t think your other arrays are doing what you think they’re doing. They aren’t 20x2 arrays, they are 2x2 arrays since 10/180 = 0. Did you mean to use 180/scandegrees instead?

- Ben

another thought, if I change my 60x120 array to a boolean what size will it make it? Right now I am just filling the array with 1 and 0, so I could use boolean rather than integers

There is no boolean type; the smallest type is a byte (unsigned char), which is 8 bits (0 - 255). You could make a smaller array of bytes and then use their bits cleverly to more compactly encode your data:

unsigned char objects[60][15]; // 900-byte array (i.e. 7200 bits)

Then bit k of objects[i][j] would be equivalent to objects[i][j*8 + k] in your old program, where k is a number from 0 to 7.

Let’s say you make the function:

int getObject(int x, int y)

In your old program, this function would be:

int getObject(int x, int y)  // x < 60, y < 120
{
  return objects[x][y];
}

In your new program, this function would become:

int getObject(int x, int y)  // x < 60, y < 120
{
  return (objects[x][y / 8] & (1 << (y % 8)) != 0);  // returns 1 if bit is set, else 0
}

and you would also want a function to set the data:

void setObject(int x, int y, int value)  // x < 60, y < 120, value is 0 or 1
{
  if (value)
  {
    objects[x][y / 8] |= 1 << (y % 8);  // set the appropriate bit in objects array
  }
  else
  {
    objects[x][y / 8] &= ~(1 << (y % 8));  // clear the appropriate bit in objects array
  }
}

I haven’t actually tested this code, so there could be some bugs in it, but this is basically what you would need to do to optimally compress your boolean array. Does this make sense to you?

- Ben

Thanks for your help. Now that I know what my problem is I will go try and figure out how I want to fix it. I will change my code to use a smaller array and pay attention to my ram usage.