Atmega88 locking up

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have designed an electronic keypad lock using an Atmega88. We are testing the product at the moment and it works well. The problem is that after say 3000 operations the lock to seems to freeze, the only way to get operational is to reset.

Without going into lots of detail could anyone point me in a direction where to look. I am sure the lock works fine when used occasionally as we have had models working for months. It seems the constent operations are effecting it.

thanks

James

Last Edited: Thu. Oct 23, 2008 - 09:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Usual culprits are memory leaks, write through rogue pointer, stack corruption, other form of RAM corruption.

Lucky for you the mega88 supports debugWire so it should be possible to "look inside" a failing unit and see what's going on.

Cliff

PS Do you really think a thread title of "Help!" is a useful name for the topic? Also I see no relevance to GCC in this post.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cliff,

Sorry first thought was its done in C so ill post there but in hind sight general AVR would have been best.

I think you right about debug wire, to be fair i thought i would rack peoples brains as i am sure its something simple and there is nothing better than experience to find this out.

thanks

James

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well things that take minutes/hours to occur are, like I say, often a sign of something going slowly wrong such as a memory leak that builds up over time (though in a mega88 I doubt you'd be using malloc/free anyway?).

Another one is an inbalnaced stack where each time "something" is done the stack descends by one/two more bytes. Eventually it "bumps into" something and all hell breaks loose.

But 3,000 operations to failure suggests it cannot be, for example, one byte lost on each operation as the mega88 doesn't have 3,000 bytes to "use up".

'course it could be a hardware rather than a software issue. Maybe 3,000 operations is as long as it takes for the battery to drain to a level where the Vcc dops off and the CPU latches up because BOD was not enabled?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cliff,

Reguards the batteries, the lock after reset will work again for another few thousand operations. I am sure its something in my program as i know i aint the best programmer around. I was thinking it could be to do with poor handling of my variables.

What i am not sure of at the moment is if the lock has frozen or if it is in sleep mode and wont wake up. The lock spends all its time in sleep apart from when a button is pressed it then stores the numbers in an array of Char (4 numbers) and compares it to a stored value. If correct the lock opens if incorrect it goes back to sleep.

I have attached the scematic of the lock for reference if it helps.

[img]

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gougam,

This is where most of the members will ask to see your code if possible. It could be something simple.

A

AVR Studio 4 Ver. 4.18 684
avr-gcc Ver. 4.3.0
ISIS 7
ELECTRA

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is the code, and yes i know its messy.

#include "keypad.h"


int main(void)
{
cli(); // Turn off interupts
initialise(); // Initialise Ports

	
	while (1) //loop key check forever	

	{		
			while (pos < size) // while code is not entered loop
				{
				if (pos == 0) // If in first loop do nothing
					{
						
					}
					toc++;	// Add one to timer for time outr function
					if (timeout == 1) // if time out is set
						{
							if (toc == 41000)	//if button timed out
								{
									wrong();
									// clear Keycode 1-4 and cancel program mode
									clear();
								}
						}

				DDRD = 0xFF;
		 		PORTB = 0b01111111;	
			
				//check for rows and send key number to portD		
		
				//instead sending key number to PORTD you can use		
		
				// any function that serves pressed button	
		
				//first column	
				if (!(bit_is_set(PINB, 0))) // Is button 3 being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{
							code[pos] = 3;
							set();
							while (!(bit_is_set(PINB, 0)))
							{
								hold(0);
							}						
						}
					else if (prognew ==0)	//if inputing code
					{
						keycode[pos] = 3;
						set();
						
						while (!(bit_is_set(PINB, 0)))
							{
								hold(0);
							}			
					}
				}	
				if (!(bit_is_set(PINB, 1)))	// Is button 2 being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{		
							code[pos] = 2;
							set();
							while (!(bit_is_set(PINB, 1)))
							{
								hold(1);
							}	
						}
					else if (prognew ==0)	//if inputing code
					{		
						keycode[pos] = 2;
						set();
						while (!(bit_is_set(PINB, 1)))
							{
								hold(1);
							}	
					}
				}		
				if (!(bit_is_set(PINB, 2)))	// Is button 1 being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{	
							code[pos] = 1;
							set();
							while (!(bit_is_set(PINB, 2)))
							{
								hold(2);
							}	
						}
					else if (prognew == 0)	//if inputing code
					{	
						keycode[pos] = 1;
						set();
						while (!(bit_is_set(PINB, 2)))
							{
								hold(2);
							}	
					}
				}		
						
				//second column		
				PORTB =0b10111111;		
		
				if (!(bit_is_set(PINB, 0)))	// Is button 6 being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{	
							code[pos] = 6;
							set();
							while (!(bit_is_set(PINB, 0)))
							{
								hold(0);
							}	
						}
					else if (prognew == 0)	//if inputing code
					{	
						keycode[pos] = 6;
						set();
						while (!(bit_is_set(PINB, 0)))
							{
								hold(0);
							}	
					}
				}	
				if (!(bit_is_set(PINB, 1)))	// Is button 5 being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{	
							code[pos] = 5;
							set();
							while (!(bit_is_set(PINB, 1)))
							{
								hold(1);
							}	
						}
					else if (prognew ==0)	//if inputing code
					{	
						keycode[pos] = 5;
						set();
						while (!(bit_is_set(PINB, 1)))
							{
								hold(1);
							}	
					}
				}	
				if (!(bit_is_set(PINB, 2)))	// Is button 4 being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{	
							code[pos] = 4;
							set();
							while (!(bit_is_set(PINB, 2)))
							{
								hold(2);
							}	
						}
					else if (prognew == 0)	//if inputing code
					{	
						keycode[pos] = 4;
						set();
						while (!(bit_is_set(PINB, 2)))
							{
								hold(2);
							}	
					}
				}		
				//third column		
				PORTB =0b11011111;		
			
				if (!(bit_is_set(PINB, 0)))	// Is button 9 being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{	
							code[pos] = 9;
							set();
							while (!(bit_is_set(PINB, 0)))
							{
								hold(0);
							}	
						}
					else if (prognew ==0)	//if inputing code
					{
						keycode[pos] = 9;
						 set();
						while (!(bit_is_set(PINB, 0)))
							{
								hold(0);
							}	
					}
				}	
				if (!(bit_is_set(PINB, 1)))	// Is button 8 being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{
							code[pos] = 8;
							set();
							while (!(bit_is_set(PINB, 1)))
							{
								hold(1);
							}	
						}
					else if (prognew == 0)	//if inputing code
					{
						keycode[pos] = 8;
						set();
						while (!(bit_is_set(PINB, 1)))
							{
								hold(1);
							}	
					}
				}			
				if (!(bit_is_set(PINB, 2)))	// Is button 7 being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{	
							code[pos] = 7;
							set();
							while (!(bit_is_set(PINB, 2)))
							{
								hold(2);
							}	
						}
					else if (prognew ==0)	//if inputing code
					{
						keycode[pos] = 7;
						set();
						while (!(bit_is_set(PINB, 2)))
							{
								hold(2);
							}	
					}
				}				
		
				//fourth column		
				PORTB =0b11101111;		
		
		
				if (!(bit_is_set(PINB, 2)))	// Is button C being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{
							wrong();	
							//restore code to previouse value
							restore();
							clear();
							while (!(bit_is_set(PINB, 2)))
							{
								hold(2);
							}	
						}
					else if (prognew == 0)	//if inputing code
						{
							if (canc == 1)
								{
									wrong();
									clear();
									op = optemp;
									masttemp = 0;
									prognew = 0;
									//tempmast = 1;
									canc = 0;
								}
							else if (op == 2)
								{							
									wrong();
									tempop = 1;
									clear();
									prog = 2;					
									prognew = 0;	
									pos = 0;
								}
							else
								{
									wrong();
									prognew = 0;
								}
						
							// clear Keycode 1-6 and cancel program mode
							clear();
							while (!(bit_is_set(PINB, 2)))
							{
								hold(2);
							}	
						}		
						
				}		
				if (!(bit_is_set(PINB, 0)))	// Is button P being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{	
							wrong();
							//restore code to previouse value
							restore();
							while (!(bit_is_set(PINB, 0)))
							{
								hold(0);
							}	
						}
					else if (prognew == 0)	//if inputing code
						{
							if (pos == 0)
							{
								if (res == 0)
									{
									Reset();
									}
								else if (tempop == 2 || tempop == 3)
									{	
										wrong();
										clear();
									}
								else
									{
										progflash();
										//program mode and clear all Keycodes
										prog = 1;
										pos = 0;
										size = 6;
										toc = 0;
										timeout = 1;
									}
								while (!(bit_is_set(PINB, 0)))
									{
									hold(0);
									}	
							}
							else
							{
								wrong();	
								clear();
							}
						}
				}		
				if (!(bit_is_set(PINB, 1)))	// Is button 0 being pressed
				{
					if ((prognew == 1)||(prognew == 2)||(prognew == 3))	//if changing code
						{
							code[pos] = 0;
							set();
							while (!(bit_is_set(PINB, 1)))
							{
								hold(1);
							}	
						}
					else if (prognew ==0)	//if inputing code
					{
						keycode[pos] = 0;
						set();
						while (!(bit_is_set(PINB, 1)))
							{
								hold(1);
							}	
					}
				}
				
				res = 1;
				if (prog == 1 && op == 1) //if in single user mode and in program mode
					{
						if (pos == 4)
							{
								if ((keycode[0] == code[0])&&(keycode[1] == code[1])&&(keycode[2] == code[2])&&(keycode[3] == code[3]))
									{
										keycode[4] = 'n';
										keycode[5] = 'n';
										pos = 6;
									}
							}
					}
									
				if (pos == 0)
					{
					if (prog == 1)
						{
						}
					else
						{	// Sleep set up
							PORTB =0b00001111;
							DDRD=0xF9;
							PORTD =0b01111010;
							cli();
							//PRR =0xFF;
							//EICRA = _BV(ISC00) | _BV(ISC01);	// Rising edge of INT0 generates an interrupt
							EICRA = (0<<ISC00) | (0<<ISC01);
							EIMSK = _BV(INT0);	// External inerrupt enable
							set_sleep_mode(SLEEP_MODE_PWR_DOWN); 
							sei();	// Enable global interrupts
							sleep_mode();  // go to sleep
						}
					}
			}			
	
				if (op == 3) //if in change master code mode
					{	
								if (masttemp == 1)
									{
									if ((keycode[0] == codeM2[0])&&(keycode[1] == codeM2[1])&&(keycode[2] == codeM2[2])&&(keycode[3] == codeM2[3])&&(keycode[4] == codeM2[4])&&(keycode[5] == codeM2[5]))
										{
											codeM1[0] = keycode[0];	// if new master code is correct two times store
											codeM1[1] = keycode[1];
											codeM1[2] = keycode[2];
											codeM1[3] = keycode[3];
											codeM1[4] = keycode[4];
											codeM1[5] = keycode[5];	
											progflash();
											progflash();
											eeprom_write_block(&mast, (void*)16, 2);
											eeprom_write_block(&codeM1, (void*)18, 6);
											tempmast = 1;
											clear();
											op = optemp;
											prognew = 0;
											if (op == 1)
												{
													relaod();
												}
										}
									else
										{
											wrong();
											clear();
											prognew = 0;
											op = optemp;
											masttemp = 0;
											tempmast = 1;
											//prognew = 0;
											if (op == 1)
												{
													relaod();
												}
										}
									}
								relaod();
								if ((keycode[0] == code[0]) && (keycode[1] == code[1]) && (keycode[2] == code[2]) && (keycode[3] == code[3]))
									{
										wrong();
										clear();
										prognew = 0;
										op = optemp;
										masttemp = 0;
										tempmast = 1;
										//prognew = 0;
										if (op == 1)
											{
												relaod();
											}
									}
								else
									{
										codeM2[0] = keycode[0]; // temp store new master to check against
										codeM2[1] = keycode[1];
										codeM2[2] = keycode[2];
										codeM2[3] = keycode[3];
										codeM2[4] = keycode[4];
										codeM2[5] = keycode[5];
										clear();
										prognew = 0;
										size = 6;
										if (tempmast == 0)
											{
												masttemp = 1;
												progflash();	
											}
										tempmast = 0;		
									}
					}
		
				if (op == 2) // if in multi user mode
					{
						if (prog == 1)
							{
							}
						else
						{
							if (tempop == 1) // if new code is being entered
							{
								if (masttemp == 1)
									{
										masttemp = 0;
										size = 4;
										prognew = 0;
									}
								else
									{
										code[0] = keycode[0]; // Store new code
										code[1] = keycode[1];
										code[2] = keycode[2];
										code[3] = keycode[3];
										
										ADC_Convert();		  	// Check battery voltage
										lock();
										progflash();			// Flash LED
										progflash();
										tempop = 3;				// Set mode to check for new code to open
										prog = 2;					
										prognew = 0;	
										pos = 0;		
										clear();

										//Double enter code removed to put back in remove above and use below

										//progflash();			// Flash LED
										//tempop = 2;				// Set mode to check for new code to open
										//prog = 2;	
										//clear();				
										//prognew = 0;	
										//pos = 0;			
									}
							}
							else if (tempop == 2)
								{
									if ((code[0] == keycode[0]) && (code[1] == keycode[1]) && (code[2] == keycode[2]) && (code[3] == keycode[3]))
										{
											ADC_Convert();		  	// Check battery voltage
											lock();
											progflash();			// Flash LED
											progflash();
											tempop = 3;				// Set mode to check for new code to open
											prog = 2;					
											prognew = 0;	
											pos = 0;		
											clear();
										}
									else
										{
											wrong();
											tempop = 1;
											clear();
											prog = 2;					
											prognew = 0;	
											pos = 0;	
										}
								}
									
							else if (tempop == 3)		// If in open mode
							{
								if ((keycode[0] == code[0])&&(keycode[1] == code[1])&&(keycode[2] == code[2])&&(keycode[3] == code[3]))
									{
										ADC_Convert(); // Check battery
										op2func();		// Open lock
									}	
								else if	((keycode[0] == codeM1[0])&&(keycode[1] == codeM1[1])&&(keycode[2] == codeM1[2])&&(keycode[3] == codeM1[3])&&(keycode[4] == codeM1[4])&&(keycode[5] == codeM1[5]))
									{
										ADC_Convert(); // Check battery
										op2func();		//Open lock
									}
								else if ((keycode[0] == codeM1[0])&&(keycode[1] == codeM1[1])&&(keycode[2] == codeM1[2])&&(keycode[3] == codeM1[3])&&(keycode[4] == 'n')&&(keycode[5] == 'n'))
									{
										master(); //If it looks like master code is being entered allow two extra numbers to be added
									}	
								else if (masttemp == 1)
									{
										masttemp = 0;
										size = 4;
										prognew = 0;
									}		
								else
								{	
									prog = 3;	//If code is not good start again
									pos = 0;
									clear();
									wrong();
								}					
							}
						}
					}
				timeout = 0;
				if (prognew == 1) // Change mode 
				{
					if (user == 0)
						{
							if ((code[0] == mode1[0]))
							{
								progflash(); //Set to Single user mode
								lock();
								op = 1;
								prognew =2;
								clear();
								prog = 3;
							}
							else if ((code[0] == mode2[0]))
							{				
								unlock();
								progflash();	//Set to multi user mode
								progflash();
								op = 2;
								clear();
								prog = 3;
								prognew = 0;
							}
							else if ((code[0] == mode3[0]))
							{						
								progflash();	// To change master code
								optemp = op;
								op = 3;
								clear();
								canc = 1;
								size = 6;
								prognew = 0;	
							}
							else
							{
								wrong();	//If wrong mode entered start agin.
								clear();
								prognew = 0;
								restore();
							}
						}
					else
						{
							if ((code[0] == mode4[0]))
								{						
									progflash(); //Set Single user mode code if using user code to change
									//lock();
									op = 1;
									prognew = 3;
									clear();
									prog = 3;	
									//user = 0;
								}
							else
								{
									wrong();	//If wrong mode entered start agin.
									clear();
									prognew = 0;
									restore();
									user = 0;
								}
						}
				}
				else if (prognew == 3)
					{
						tempcode[0] = code[0];
						tempcode[1] = code[1];
						tempcode[2] = code[2];
						tempcode[3] = code[3];
						progflash();
						clear();
						prognew = 2;
						prog = 3;
					}

				else if (prognew == 2)
					{
							if (user == 1)
								{
									if ((tempcode[0] == code[0])&&(tempcode[1] == code[1])&&(tempcode[2] == code[2])&&(tempcode[3] == code[3]))
										{
											if ((code[0] == codeM1[0]) && (code[1] == codeM1[1]) && (code[2] == codeM1[2]) && (code[3] == codeM1[3]))
												{
													wrong(); //If wrong code start again
													//Clear Keycode
													clear();
													prog = 2;
													pos = 0;
													user = 0;
													prognew = 0;
													relaod();
												}
											else
												{	
													delay(1);	//When new code is entered store into eeprom
													eeprom_write_block(&code, (void*)12, 4);
													progflash();
													progflash();
													prognew = 0;
													prog = 2;
													pos = 0;
													user = 0;
												}
										}
									else
										{
											wrong(); //If wrong code start again
											//Clear Keycode
											clear();
											prog = 2;
											pos = 0;
											user = 0;
											prognew = 0;
											relaod();
										}
								}
							else
								{		
									if ((code[0] == codeM1[0]) && (code[1] == codeM1[1]) && (code[2] == codeM1[2]) && (code[3] == codeM1[3]))
										{
											wrong(); //If wrong code start again
											//Clear Keycode
											clear();
											prog = 2;
											pos = 0;
											user = 0;
											prognew = 0;
											relaod();
										}		
									else
										{
											//Replpace code
											delay(1);	//When new code is entered store into eeprom
											eeprom_write_block(&code, (void*)12, 4);
											progflash();
											progflash();
											prognew = 0;
											prog = 2;
											pos = 0;
										}
								}
					}

				if ((prog == 0)&&(op == 1))		//if not in program mode and in single user mode
					{
						if ((keycode[0] == code[0])&&(keycode[1] == code[1])&&(keycode[2] == code[2])&&(keycode[3] == code[3]))
							{
								ADC_Convert(); //Check battery
								op1func();		//Open lock
							}
						else if	((keycode[0] == codeM1[0])&&(keycode[1] == codeM1[1])&&(keycode[2] == codeM1[2])&&(keycode[3] == codeM1[3])&&(keycode[4] == codeM1[4])&&(keycode[5] == codeM1[5]))
							{
								ADC_Convert();	//Check battery
								op1func();		//Open lock
							}
						else if	((keycode[0] == codeM1[0])&&(keycode[1] == codeM1[1])&&(keycode[2] == codeM1[2])&&(keycode[3] == codeM1[3])&&(keycode[4] == 'n')&&(keycode[5] == 'n'))
							{
								master();		//If it looks like master code is being entered allow two more numbers
							}
						else if (masttemp == 1)
							{
								masttemp = 0;
								size = 4;
								prognew = 0;
							}
						else
							{
								wrong(); //If wrong code start again
								//Clear Keycode
								clear();
								prognew = 0;
							}
					}
				else if (prog == 2) //Dummy mode
					{
						prog = 0;
					}
				else if (prog == 1)
					{
					if ((keycode[0] == codeM1[0])&&(keycode[1] == codeM1[1])&&(keycode[2] == codeM1[2])&&(keycode[3] == codeM1[3])&&(keycode[4] == codeM1[4])&&(keycode[5] == codeM1[5]))
						{
							progflash(); //Enter program mode
							//Backup old code
							backup();
   							//Clear Keycode
							pos = 0;
							prognew = 1;
							size = 1;
						}
					else if ((keycode[0] == code[0])&&(keycode[1] == code[1])&&(keycode[2] == code[2])&&(keycode[3] == code[3])&&(keycode[4] == 'n')&&(keycode[5] == 'n'))
						{
							progflash(); //Enter program mode
							//Backup old code
							backup();
   							//Clear Keycode
							pos = 0;
							prognew = 1;
							size = 1;
							user = 1;
						}
					else
						{
							wrong();
							clear();
						}			
			
				}
		}
}


void hold(char pin) //Function for hold button
	{
	char i;
		for (i = 1; i <=10; i++)
			{
				if (bit_is_set(PINB, pin))
					{
						i = 11;
					}
				delay(10); 
				if (i == 10)
					{
						wrong();	//If wrong mode entered start agin.
						clear();	
					}
			}
	}


void clear() //Function to clear all data
	{
		pos = 0;
		prog = 0;
		timeout = 0;
		size = 4;
		keycode[0] = 'n';
		keycode[1] = 'n';
		keycode[2] = 'n';
		keycode[3] = 'n';
		keycode[4] = 'n';
		keycode[5] = 'n';
	}

	
void backup() //Back up of old code function
	{
		codeback[0] = code[0];
		codeback[1] = code[1];
		codeback[2] = code[2];
		codeback[3] = code[3];
	}


void restore()	//Restore back up if failure in new code
	{
		code[0] = codeback[0];
		code[1] = codeback[1];
		code[2] = codeback[2];
		code[3] = codeback[3];
		prognew = 0;
		timeout = 0;
	}


void flash (char f, char t, char c) //Flash LED function
	{
	char i;
		if (c == R)
			{ 
				for (i = 0; i < f; i++)
					{
					 	PORTD = 0x87;
						delay(t); //delay 0.25s
						PORTD = 0x47;
						delay(t);
					}
			}
		else if (c == G)
			{
				for (i = 0; i < f; i++)
					{
					 	PORTD = 0xC5;
						delay(t); //delay 0.25s
						PORTD = 0x47;
						delay(t);
					}
			}
	}


void delay(char del) //Software timer function
	{
	char n;

		for (n = 0; n <= del; n++)
			{
				_delay_loop_2(5000);
			}
	}


// External interrupt ISR
ISR(INT0_vect)
	{
		cli(); //Turn off interupts
		DDRD=0xFF;
		PORTD=0x47;
		//PRR =0xEE;
		EIMSK = !_BV(INT0); //Return to main code
	}


void wrong() //Wrong code function
	{
		flash(8,1,R);
		size = 4;
	}


void button() //Button press LED function
	{
		flash(1,3,G);
	}


void progflash() //Program LED function
	{
		flash(1,20,G);
	}


void set() //Button press setup function
	{
		toc = 0;
		timeout = 1;
		pos = pos + 1;
		button();
	}


void lock() //Lock function
	{
		PORTD = 0xD8;
		_delay_loop_2(10000);
		PORTD = 0x47; // motor control into sleep
	}


void unlock() //Unlock function
	{
		PORTD = 0xE8;
		_delay_loop_2(10000);
		PORTD = 0x47; // motor control into sleep
	}


void master() //If mode requires two more numbers for master code function
	{
		pos = 4;
		prog = 2;
		size = 6;
	}


void op1func() //Single user mode unlock function
	{
	//	flash(1,25); //Long single green flash
		unlock();							
		flash(4,25,G); //Second green flash						
		lock();		
		flash(1,25,G);		
		//Clear Keycode
		clear();
	}


void op2func() //Multi user mode unlock function
	{
		progflash();
		unlock();
		progflash();
		code[0] = 'n';
		code[1] = 'n';
		code[2] = 'n';
		code[3] = 'n';
		tempop = 1;
		prog = 2;
		prognew = 0;
		pos = 0;
		clear();
	}



void initialise() // Initialse program
	{
		relaod();
	//	PRR = 0xEE; //remove if problem added 13/05/08 not tested
		//high for output(columns) low for input(rows);
		uint8_t check[2];
		eeprom_read_block((void*)&check, (const void*)16,2);
		if (check[0] == 1 && check[1] == 1)		// if a master code has been changed read in new code
			{
				uint8_t codeM1temp[6];
				eeprom_read_block((void*)&check, (const void*)18,6);
				codeM1[0] = codeM1temp[0];
				codeM1[1] = codeM1temp[1];
				codeM1[2] = codeM1temp[2];
				codeM1[3] = codeM1temp[3];
				codeM1[4] = codeM1temp[4];
				codeM1[5] = codeM1temp[5];
			}
		DDRB=0xF0;
		//enable internal pullups for PB0-PB3
		PORTB=0x0F;
		//Port D
		DDRD=0xFF;
		PORTD=0x47;
		lock();
		//Port C
		DDRC=0x0F;
		PORTC=0x00;
		clear();
	}


void ADC_Convert() //Check battery funtion
	{ 
		ADMUX   = 0x4E;  // set Vcc as ref and internal ref 1.2V as input
	   	ADCSRA  =   (1 << ADEN)|(1 << ADPS2)|(0 << ADPS1)|(1 << ADPS0); // turn on ADC and set speed
	   	ADCSRA |= (1 << ADSC); //start dummy conversion

	   	while(!(ADCSRA & 0x10)) ; //Dummy step
		ADCSRA |= (1 << ADSC);	

		while(!(ADCSRA & 0x10)) ;	
	    vcc = ADC;				// take reading
		ADCSRA = (0 << ADEN);
	
	    vcc = vcc >> 3;
	
		if (vcc >= 56)
			{
				flash(8,1,R);
			}
		else if (vcc >= 52)
			{
				flash(4,1,R);
			}
 	} 

void relaod()
	{
		uint8_t code1[4];
		eeprom_read_block((void*)&code1, (const void*)12, 4);
		code[0] = code1[0];
		code[1] = code1[1];
		code[2] = code1[2];
		code[3] = code1[3];
	}

void Reset()
	{
		char g;
		for (g = 1; g <=10; g++)
			{
				if (bit_is_set(PINB, 0))
					{
						g = 11;
					}
				delay(50); 
				if (g == 10)
					{
						codeM1[0] = 6;	// if new master code is correct two times store
						codeM1[1] = 5;
						codeM1[2] = 4;
						codeM1[3] = 3;
						codeM1[4] = 2;
						codeM1[5] = 1;	
						progflash();
						progflash();
						eeprom_write_block(&codeM1, (void*)18, 6);
						clear();
					}
			}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is the header file


#define F_CPU 4000000UL  // 4 MHz
    

#include 
#include 
#include 
#include  
#include 
#include 
#include 
#include 



//#define eeprom_is_ready  ()  
void hold(char);
void clear(void);
void backup(void);
void restore(void);
void flash (char, char, char);
void delay (char);
void timer0_init(void);
void wrong(void);
void set(void);
void progflash(void);
void initialise(void);
void lock(void);
void unlock(void);
void master(void);
void op1func(void);
void op2func(void);
void ADC_Convert(void);
void relaod(void);
void Reset(void);


// Delcare globals
int pos = 0;
char prog = 0;
char prognew = 0;
int size = 4;
char keycode[6] = {'n','n','n','n','n','n'};
char code[4] = {'n','n','n','n'};
char codeM1[6] = {6,5,4,3,2,1};
char codeM2[6];
char mode1[1] = {1};
char mode2[1] = {2};
char mode3[1] = {0};
char mode4[1] = {3};
char op = 1;
char tempop =1;
char codeback[4] ;
char timeout = 0;
unsigned toc;
unsigned vcc;
char optemp;
char masttemp = 0;
char tempmast = 0;
char canc = 0;
char mast[2] = {1,1};
char user = 0;
char tempcode[4];
char res = 0;
char G ='G';
char R ='R';
//char mode;
//char vcc2[]= {'0','0','0','\0'};





  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First step is to get readable code that gives you a fair chance to spot the error/problem...

            if (pos == 0) // If in first loop do nothing
               {
                  
               }
               toc++;   // Add one to timer for time outr function
               if (timeout == 1) // if time out is set
               .
               .
               .

That first if-statement (the "do-nothing" one) is totally meaningless. Delete it. Or are you actually missing an "else"? The indentation suggests the latter.

After that you have all those nearly-identical if-blocks. Break the code in them out to a function to reduce your code size with maybe 50%.

And then...

if   ((keycode[0] == codeM1[0])&&(keycode[1] == codeM1[1])&&(keycode[2] == codeM1[2])&&(keycode[3] == codeM1[3])&&(keycode[4] == codeM1[4])&&(keycode[5] == codeM1[5])) 

You have a lot of these comparisons. Break them out to a testing function, eg

bool MatchCode( char code1[], char code2[]) { ... }

so that you can

if ( MatchCode( keycode, codeM1 ) ) ...

Keep on doing such refactorings and you will find that the code might shink considerably, and that doesn't just save FLASH but actually gives you a fair chance to spot a problem/error.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

goujam,

You may want to use want to use the delay routines included in . It makes timing more controllable and at least the delay settings can be related to real time.

I also notice you are comparing arrays byte by byte. This is easier to do with strcmp(). You can also use strcpy() for copying data. Although I have not seen it in the library reference, it should be easy to produce your own memcpy()and memcmp().

A

AVR Studio 4 Ver. 4.18 684
avr-gcc Ver. 4.3.0
ISIS 7
ELECTRA

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Johan and Andrew ill spend today cleaning the program up. Over the weekend i have been having a think about this problem too. I am now wondering if there is a problem with the PRR Register command i put in.

Anyway ill work at my code again and get back with my results.

Thanks

James