/* * MotorControl.c * * Created: 11/18/2017 12:46:37 PM * Author: Gerardo */ #include #include #include #include #include #include #include "io.c" #include "keypad.h" volatile unsigned char TimerFlag = 0; // TimerISR() sets this to 1. C programmer should clear to 0. unsigned long _avr_timer_M = 1; // Start count from here, down to 0. Default 1 ms. unsigned long _avr_timer_cntcurr = 0; // Current internal count of 1ms ticks long time = 0; int exposureMaxTime = 0; long exposureMaxTimeToCompare = 0; //exposureMaxTimeToCompare = exposureMaxTime * 12000; int seekLightFlag = 0; //If set to 1 we are seeking light. If 0, seeking dark unsigned short frontLDR = 0; //Front LDR unsigned short frontLeftLDR = 0; //Front Left LDR unsigned short frontRightLDR = 0; //Front Right LDR unsigned short backLeftLDR = 0; //back Left LDR unsigned short backRightLDR = 0; //back Right LDR unsigned short topLDR = 0; //TOP LDR unsigned short obstacleFlag = 0; //Flag raised if obstacle has been detected int topLdrFlag = 0; //TOP LDR Flag char moisterVoltage = 0; //MoisterSensorInput unsigned long moister = 0; //Moister value 1 - 7 unsigned long indexM = 0; //Used to place the number of reading for saving purposes for moister unsigned long maxIndexM = 0; //Used to know the amount of moister readings taken for moister char strC[16]; char strF[16]; float temperatureVoltage = 0; //Raw Voltage from temperature sensor int temperatureC = 0; //Used to store temperature in Celsius int temperatureF = 0; //Used to store temperature in Fahrenheit unsigned long indexF = 0; //Used to place the number of reading for saving purposes for Temperature F unsigned long maxIndexF = 0; //Used to know the amount of Temperature readings taken for Temperature F unsigned char keyPadValue = 0 ; unsigned long minimumMoisterKey = 0; //Moister value 1 - 7 chosen by user unsigned char key = 0; unsigned char beginKey = 0; unsigned char historyKey = 0; int toggleStepper = 0; //Used to move exit the while loop for the stepper motor function int stepperCounter = 0; //Used the traverse the stepper motor's output int numPhases = 0; //Used to set the amount of rotation int phaseCounter = 0; //Used to compare the value of numPhase int motorOutputPortA = 0; //Used to mask PortA int darkCounter = 0; void ADC_init() { ADCSRA |= (1 << ADEN) | (1 << ADSC) | (1 << ADATE); // ADEN: setting this bit enables analog-to-digital conversion. // ADSC: setting this bit starts the first conversion. // ADATE: setting this bit enables auto-triggering. Since we are // in Free Running Mode, a new conversion will trigger whenever // the previous conversion completes. } void EEPROM_write(unsigned int uiAddress, unsigned char ucData) { /* Wait for completion of previous write */ while(EECR & (1< frontLeftLDR) && (frontLDR > frontRightLDR) && (frontLDR > backLeftLDR) && (frontLDR > backRightLDR) && (frontLDR > topLDR)) //Comparing light intensity readings { LCD_DisplayString(17,"FRONT"); delay_ms(100); LCD_ClearScreen(); moveForward(); topLdrFlag = 0; } else if((frontLeftLDR > frontLDR) && (frontLeftLDR > frontRightLDR) && (frontLeftLDR > backLeftLDR) && (frontLeftLDR > backRightLDR) && (frontLeftLDR> topLDR)) { topLdrFlag = 0; LCD_DisplayString(17,"FRONT LEFT"); delay_ms(100); LCD_ClearScreen(); moveLeft(); } else if((frontRightLDR > frontLDR) && (frontRightLDR > frontLeftLDR) && (frontRightLDR > backLeftLDR) && (frontRightLDR > backRightLDR) && (frontRightLDR > topLDR)) { topLdrFlag = 0; LCD_DisplayString(17,"FRONT RIGHT"); delay_ms(100); LCD_ClearScreen(); moveRight(); } else if((backLeftLDR > frontLDR) && (backLeftLDR > frontLeftLDR) && (backLeftLDR > frontRightLDR) && (backLeftLDR > backRightLDR) && (backLeftLDR > topLDR)) { topLdrFlag = 0; LCD_DisplayString(17,"BACK LEFT"); delay_ms(100); LCD_ClearScreen(); moveLeft(); } else if((backRightLDR > frontLDR) && (backRightLDR > frontLeftLDR) && (backRightLDR > frontRightLDR) && (backRightLDR > backLeftLDR) && (backRightLDR > topLDR)) { topLdrFlag = 0; LCD_DisplayString(17,"BACK RIGHT"); delay_ms(100); LCD_ClearScreen(); moveRight(); } else if((topLDR > frontLDR) && (topLDR > frontLeftLDR) && (topLDR > frontRightLDR) && (topLDR > backLeftLDR) && (topLDR > backRightLDR)) { topLdrFlag = 1; LCD_DisplayString(17,"TOP TOP"); delay_ms(100); LCD_ClearScreen(); stop(); } else stop(); } void moveToLowestIntensity() { obstacleFlag = PINA & 0x02; PORTB = (PORTB & 0x00); //Select Line Y0 0000 0000 frontLDR ADC_init(); ADMUX = 0x00; //Table 25.4 in Atmel in the data sheet has bit settings delay_ms(100); frontLDR = ADC; //Assigning the current analog value PORTB = (PORTB & 0x00); ADC_init(); ADMUX = 0x00; PORTB = PORTB | 0x01; //Select Line Y1 0000 0001 frontLeftLdr delay_ms(100); frontLeftLDR = ADC; PORTB = (PORTB & 0x00); ADC_init(); ADMUX = 0x00; PORTB = PORTB | 0x02; //Select Line Y2 0000 0010 frontRightLdr delay_ms(100); frontRightLDR = ADC; PORTB = (PORTB & 0x00); ADC_init(); ADMUX = 0x00; PORTB = PORTB | 0x03; //Select Line Y3 0000 0011 backLeftLdr delay_ms(100); backLeftLDR = ADC; PORTB = (PORTB & 0x00); ADC_init(); ADMUX = 0x00; PORTB = PORTB | 0x04; //Select Line Y4 0000 0011 backRightLdr delay_ms(100); backRightLDR = ADC; PORTB = (PORTB & 0x00); ADC_init(); ADMUX = 0x00; PORTB = PORTB | 0x05; //Select Line Y5 0000 0101 topLdr delay_ms(100); topLDR = ADC; PORTA = 0x00; delay_ms(250); /*if(obstacleFlag) //Adding the signal from the arduino nano { LCD_DisplayString(27,"Object"); delay_ms(100); LCD_ClearScreen(); moveAroundObject(); obstacleFlag = 0x00; }*/ if((frontLDR > frontLeftLDR) && (frontLDR > frontRightLDR) && (frontLDR > backLeftLDR) && (frontLDR > backRightLDR) && (frontLDR > topLDR)) //Comparing light intensity readings { LCD_DisplayString(17,"FRONT"); delay_ms(100); LCD_ClearScreen(); moveBackward(); topLdrFlag = 0; } else if((topLDR < frontLDR) && (topLDR < frontLeftLDR) && (topLDR < frontRightLDR) && (topLDR < backLeftLDR) && (topLDR < backRightLDR)) { topLdrFlag = 1; LCD_DisplayString(17,"TOP TOPP"); delay_ms(100); LCD_ClearScreen(); stop(); darkCounter = darkCounter + 1; } else if((frontLeftLDR > frontLDR) && (frontLeftLDR > frontRightLDR) && (frontLeftLDR > backLeftLDR) && (frontLeftLDR > backRightLDR) && (frontLeftLDR> topLDR)) { topLdrFlag = 0; LCD_DisplayString(17,"FRONT LEFT"); delay_ms(100); LCD_ClearScreen(); moveRight(); } else if((frontRightLDR > frontLDR) && (frontRightLDR > frontLeftLDR) && (frontRightLDR > backLeftLDR) && (frontRightLDR > backRightLDR) && (frontRightLDR > topLDR)) { topLdrFlag = 0; LCD_DisplayString(17,"FRONT RIGHT"); delay_ms(100); LCD_ClearScreen(); moveLeft(); } else if((backLeftLDR > frontLDR) && (backLeftLDR > frontLeftLDR) && (backLeftLDR > frontRightLDR) && (backLeftLDR > backRightLDR) && (backLeftLDR > topLDR)) { topLdrFlag = 0; LCD_DisplayString(17,"BACK LEFT"); delay_ms(100); LCD_ClearScreen(); moveRight(); } else if((backRightLDR > frontLDR) && (backRightLDR > frontLeftLDR) && (backRightLDR > frontRightLDR) && (backRightLDR > backLeftLDR) && (backRightLDR > topLDR)) { topLdrFlag = 0; LCD_DisplayString(17,"BACK RIGHT"); delay_ms(100); LCD_ClearScreen(); moveLeft(); } else if((backRightLDR + backLeftLDR) > (frontRightLDR + frontLeftLDR)) { topLdrFlag = 0; LCD_DisplayString(17,"BACK RIGHT"); delay_ms(100); LCD_ClearScreen(); moveForward(); } else stop(); } void openValve() { time = time + 31; numPhases = (90 / 5.625) * 64; toggleStepper = 0; LCD_DisplayString(1, "Dispensing water");// Starting at position 1 on the LCD screen, writes The Sun is near if(toggleStepper == 0) { while(numPhases > phaseCounter) { if(stepperCounter == 0) { motorOutputPortA = PORTA | 0x24; //Masking the varialble which will equal PORTA's output PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; //Resetting the variable which will equal PORTA'a output phaseCounter = phaseCounter + 1; } else if(stepperCounter == 1) { motorOutputPortA = PORTA | 0x20; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 2) { motorOutputPortA = PORTA | 0x30; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 3) { motorOutputPortA = PORTA | 0x10; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 4) { motorOutputPortA = PORTA | 0x18; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 5) { motorOutputPortA = PORTA | 0x08; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 6) { motorOutputPortA = PORTA | 0x0C; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 7) { motorOutputPortA = PORTA | 0x04; PINA = motorOutputPortA; stepperCounter = 0; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } if(numPhases == phaseCounter) { numPhases = 0; phaseCounter = 0; toggleStepper = 1; } while(!TimerFlag); TimerFlag = 0; } } } void closeValve() { time = time + 31; numPhases = (90 / 5.625) * 64; toggleStepper = 0; LCD_DisplayString(1, "Closing water valve");// Starting at position 1 on the LCD screen, writes The Sun is near if(toggleStepper == 0) { while(numPhases > phaseCounter) { if(stepperCounter == 0) { motorOutputPortA = PORTA | 0x04; //Masking the varialble which will equal PORTA's output PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; //Resetting the variable which will equal PORTA'a output phaseCounter = phaseCounter + 1; } else if(stepperCounter == 1) { motorOutputPortA = PORTA | 0x0C; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 2) { motorOutputPortA = PORTA | 0x08; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 3) { motorOutputPortA = PORTA | 0x18; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 4) { motorOutputPortA = PORTA | 0x10; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 5) { motorOutputPortA = PORTA | 0x30; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 6) { motorOutputPortA = PORTA | 0x20; PINA = motorOutputPortA; stepperCounter = stepperCounter + 1; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } else if(stepperCounter == 7) { motorOutputPortA = PORTA | 0x24; PINA = motorOutputPortA; stepperCounter = 0; motorOutputPortA = 0x00; phaseCounter = phaseCounter + 1; } if(numPhases == phaseCounter) { numPhases = 0; phaseCounter = 0; toggleStepper = 1; } while(!TimerFlag); TimerFlag = 0; } } PORTA = PORTA & 0x00; } //Data Collection void getMoister() { PORTB = (PORTB & 0x00); ADC_init(); ADMUX = 0x00; PORTB = PORTB | 0x06; //Selecting Moister Sensor delay_ms(100); moisterVoltage = ADC; if(ADC >= 0 && ADC <15) moister = 0; else if(ADC >= 15 && ADC <25) moister = 1; else if(ADC >= 25 && ADC <35) moister = 2; else if(ADC >= 35 && ADC <45) moister = 3; else if(ADC >= 45 && ADC <55) moister = 4; else if(ADC >= 55 && ADC <65) moister = 5; else if(ADC >= 65 && ADC <75) moister = 6; else if(ADC >= 75) moister = 7; LCD_DisplayString(17,"Moister= " ); LCD_Cursor(25); LCD_WriteData(moister + '0'); delay_ms(100); indexM = indexM + 1; maxIndexM = indexM; } void saveMoister() { EEPROM_write(indexM, moister); } void getTemperature() { PORTB = (PORTB & 0x00); ADC_init(); ADMUX = 0x00; PORTB = PORTB | 0x07; //Select Line Y7 0000 0111 temperatureSensor delay_ms(100); temperatureVoltage = ADC;//* (50000/512); temperatureF = (temperatureVoltage * 500/1024) - 16; temperatureC = (temperatureF - 32) * .55; LCD_DisplayString(1,"Temp"); delay_ms(50); LCD_DisplayString(6,itoa(temperatureC, strC, 10)); delay_ms(50); LCD_DisplayString(8,"C"); delay_ms(50); LCD_DisplayString(13,itoa(temperatureF, strF, 10)); delay_ms(50); LCD_DisplayString(15,"F"); delay_ms(50); indexM = indexM + 1; maxIndexM = indexM; } void saveTemperature() { EEPROM_write(indexM, temperatureF); } void displayMemory() { LCD_DisplayString(17,"Temperature= F"); delay_ms(100); LCD_DisplayString(29, itoa(EEPROM_read(indexM), strF, 10));//This killed me to figure out delay_ms(100); indexM = indexM + 1; LCD_DisplayString(1,"Moister= " ); LCD_Cursor(9); LCD_WriteData(EEPROM_read(indexM) + '0'); delay_ms(100); indexM = indexM + 1; } enum State {init, begin, enterMoister, enterTime, waterRelease, seekLight, avoidObstacle, recordReadings, seekDark, askForHistory, displayReadings} state; void tick() { switch(state)//Transitions ********************************************************************************************************** { case init: state = begin; break; case begin: if(beginKey == 14) { state = enterMoister; } else { state = begin; } break; case enterMoister: if(minimumMoisterKey > 7 || minimumMoisterKey == 0) { state = enterMoister; } else { state = enterTime; } break; case enterTime: if(exposureMaxTime > 9 || exposureMaxTime == 0) { state = enterTime; } else { state = seekLight; } break; case seekLight: seekLightFlag = 1; if(topLdrFlag == 0) { state = seekLight; } if(topLdrFlag == 1) { state = recordReadings; seekLightFlag = 0; } if(obstacleFlag) { moveAroundObject(); obstacleFlag = 0x00; } break; case avoidObstacle: if(seekLightFlag == 1) { state = seekLight; } if(seekLightFlag == 0) { state = seekDark; } break; case recordReadings: if(time >= exposureMaxTimeToCompare) { state = seekDark; topLdrFlag = 0; } if(time < exposureMaxTimeToCompare) { state = recordReadings; } if(minimumMoisterKey >= moister) { state = waterRelease; } break; case seekDark: seekLightFlag = 0; if(obstacleFlag) { moveAroundObject(); obstacleFlag = 0x00; } else if(topLdrFlag == 0) { state = seekDark; } else if(topLdrFlag == 1) { if(darkCounter >= 5) { state = askForHistory; } } break; case askForHistory: if(historyKey == 16) { indexM = 0; indexF = 0; state = displayReadings; } else { state = askForHistory; } break; case waterRelease: state = recordReadings; break; case displayReadings: if(indexM < maxIndexM) { state = displayReadings; } else { state = init; } break; default: state = init; break; } switch(state)//Actions ********************************************************************************************************** { case init: time = 0; exposureMaxTime = 0; exposureMaxTimeToCompare = 0; seekLightFlag = 0; obstacleFlag =0; topLdrFlag = 0; historyKey = 0; beginKey = 0; key = 0; minimumMoisterKey = 0; keyPadValue = 0; numPhases = 0; phaseCounter = 0; temperatureVoltage = 0; //Raw Voltage from temperature sensor temperatureC = 0; //Used to store temperature in Celsius temperatureF = 0; //Used to store temperature in Fahrenheit indexF = 0; //Used to place the number of reading for saving purposes for Temperature F maxIndexF = 0; //Used to know the amount of Temperature readings taken for Temperature F strF[16] = 0; //Used to store the string that came from being a temperature int strC[16] = 0; break; case begin: LCD_ClearScreen(); //LCD_DisplayString(1 ,"................................"); LCD_DisplayString(1 ," Press and hold * to begin"); delay_ms(3500); LCD_ClearScreen(); key = GetKeypadKey(); keyPadValue = 0; switch (key) { case '1': beginKey = 1; LCD_DisplayString(1,"1"); break; case '2': beginKey = 2; LCD_DisplayString(1,"2"); break; case '3': beginKey = 3; LCD_DisplayString(1,"3");break; case '4': beginKey = 4; LCD_DisplayString(1,"4");break; case '5': beginKey = 5; LCD_DisplayString(1,"5");break; case '6': beginKey = 6; LCD_DisplayString(1,"6");break; case '7': beginKey = 7; LCD_DisplayString(1,"7");break; case '8': beginKey = 8; LCD_DisplayString(1,"8");break; case '9': beginKey = 9; LCD_DisplayString(1,"9");break; case 'A': beginKey = 10; LCD_DisplayString(1,"A");break; case 'B': beginKey = 11; LCD_DisplayString(1,"B");break; case 'C': beginKey = 12; LCD_DisplayString(1,"C");break; case 'D': beginKey = 13; LCD_DisplayString(1,"D");break; case '*': beginKey = 14; LCD_DisplayString(1,"*");break; case '0': beginKey = 15; LCD_DisplayString(1,"0");break; case '#': beginKey = 16; LCD_DisplayString(1,"#");break; default: break; // Should never occur. Middle LED off. } if(beginKey == 14) { LCD_DisplayString(1," Lets Begin"); delay_ms(3500); } else { LCD_DisplayString(1," Try again"); delay_ms(3500); } break; case enterMoister: LCD_ClearScreen(); //LCD_DisplayString(1 ,"................................"); LCD_DisplayString(1 ,"Enter minimum moister level"); delay_ms(3500); LCD_DisplayString(1 ,"by pressing and holding value"); delay_ms(3500); LCD_DisplayString(1,"Choose values 1 through 7"); delay_ms(3500); LCD_DisplayString(1,"Where 1 is low moister"); delay_ms(3500); LCD_DisplayString(1,"and 7 is high moister"); delay_ms(3500); LCD_ClearScreen(); key = GetKeypadKey(); keyPadValue = 0; switch (key) { case '1': minimumMoisterKey = 1; LCD_DisplayString(1,"1"); break; case '2': minimumMoisterKey = 2; LCD_DisplayString(1,"2"); break; case '3': minimumMoisterKey = 3; LCD_DisplayString(1,"3");break; case '4': minimumMoisterKey = 4; LCD_DisplayString(1,"4");break; case '5': minimumMoisterKey = 5; LCD_DisplayString(1,"5");break; case '6': minimumMoisterKey = 6; LCD_DisplayString(1,"6");break; case '7': minimumMoisterKey = 7; LCD_DisplayString(1,"7");break; case '8': minimumMoisterKey = 8; LCD_DisplayString(1,"8");break; case '9': minimumMoisterKey = 9; LCD_DisplayString(1,"9");break; case 'A': minimumMoisterKey = 10; LCD_DisplayString(1,"A");break; case 'B': minimumMoisterKey = 11; LCD_DisplayString(1,"B");break; case 'C': minimumMoisterKey = 12; LCD_DisplayString(1,"C");break; case 'D': minimumMoisterKey = 13; LCD_DisplayString(1,"D");break; case '*': minimumMoisterKey = 14;LCD_DisplayString(1,"*");break; case '0': minimumMoisterKey = 15;LCD_DisplayString(1,"0");break; case '#': minimumMoisterKey = 16; LCD_DisplayString(1,"#");break; default: break; // Should never occur. Middle LED off. } LCD_DisplayString(1,"Min Moister="); LCD_Cursor(13); LCD_WriteData(minimumMoisterKey + '0'); delay_ms(3500); break; case enterTime: LCD_ClearScreen(); //LCD_DisplayString(1 ,"................................"); LCD_DisplayString(1 ,"Enter the number of minutes of "); delay_ms(3500); LCD_DisplayString(1,"light exposure"); delay_ms(3500); LCD_DisplayString(1 ,"by pressing and holding value"); delay_ms(3000); LCD_DisplayString(1,"Choose values 1 through 9 "); delay_ms(3500); LCD_init(); key = GetKeypadKey(); switch (key) { case '1': exposureMaxTime = 1; LCD_DisplayString(1,"1"); break; // hex equivalent case '2': exposureMaxTime = 2; LCD_DisplayString(1,"2"); break; case '3': exposureMaxTime = 3; LCD_DisplayString(1,"3");break; case '4': exposureMaxTime = 4; LCD_DisplayString(1,"4");break; case '5': exposureMaxTime = 5; LCD_DisplayString(1,"5");break; case '6': exposureMaxTime = 6; LCD_DisplayString(1,"6");break; case '7': exposureMaxTime = 7; LCD_DisplayString(1,"7");break; case '8': exposureMaxTime = 8; LCD_DisplayString(1,"8");break; case '9': exposureMaxTime = 9; LCD_DisplayString(1,"9");break; case 'A': exposureMaxTime = 10; LCD_DisplayString(1,"A");break; case 'B': exposureMaxTime = 11; LCD_DisplayString(1,"B");break; case 'C': exposureMaxTime = 12; LCD_DisplayString(1,"C");break; case 'D': exposureMaxTime = 13; LCD_DisplayString(1,"D");break; case '*': exposureMaxTime = 14;LCD_DisplayString(1,"*");break; case '0': exposureMaxTime = 15;LCD_DisplayString(1,"0");break; case '#': exposureMaxTime = 16; LCD_DisplayString(1,"#");break; default: break; // Should never occur. Middle LED off. } LCD_DisplayString(1,"Light exposure time="); LCD_Cursor(23); LCD_WriteData(exposureMaxTime + '0'); delay_ms(3500); exposureMaxTimeToCompare = exposureMaxTime * 153; break; case seekLight: moveToHighestIntensity(); break; case avoidObstacle: moveAroundObject(); break; case recordReadings: time = time + 1; getMoister(); saveMoister(); getTemperature(); saveTemperature(); break; case seekDark: seekLightFlag = 0; moveToLowestIntensity(); break; case waterRelease: openValve(); closeValve(); break; case askForHistory: LCD_ClearScreen(); //LCD_DisplayString(1 ,"................................"); LCD_DisplayString(1 ,"To see History press & hold #"); delay_ms(3500); LCD_ClearScreen(); key = GetKeypadKey(); keyPadValue = 0; switch (key) { case '1': historyKey = 1; LCD_DisplayString(1,"1"); break; case '2': historyKey = 2; LCD_DisplayString(1,"2"); break; case '3': historyKey = 3; LCD_DisplayString(1,"3");break; case '4': historyKey = 4; LCD_DisplayString(1,"4");break; case '5': historyKey = 5; LCD_DisplayString(1,"5");break; case '6': historyKey = 6; LCD_DisplayString(1,"6");break; case '7': historyKey = 7; LCD_DisplayString(1,"7");break; case '8': historyKey = 8; LCD_DisplayString(1,"8");break; case '9': historyKey = 9; LCD_DisplayString(1,"9");break; case 'A': historyKey = 10; LCD_DisplayString(1,"A");break; case 'B': historyKey = 11; LCD_DisplayString(1,"B");break; case 'C': historyKey = 12; LCD_DisplayString(1,"C");break; case 'D': historyKey = 13; LCD_DisplayString(1,"D");break; case '*': historyKey = 14;LCD_DisplayString(1,"*");break; case '0': historyKey = 15;LCD_DisplayString(1,"0");break; case '#': historyKey = 16; LCD_DisplayString(1,"#");break; default: break; // Should never occur. Middle LED off. } if(historyKey == 16) { LCD_DisplayString(1,"Retrieving History..."); delay_ms(3500); } else { LCD_DisplayString(1," Try again"); delay_ms(3500); } break; case displayReadings: displayMemory(); break; } } int main(void) { DDRA = 0xFC; PORTA = 0x00; // ADC cycles PORTA when getting analog an input. Use ADMUX to select the analog input pin. DDRB = 0x7F; PORTB = 0x00; // Motor Driver Control Lines DDRC = 0xF0; PORTC = 0x0F; // PC7..4 outputs init 0s, PC3..0 inputs init 1s DDRD = 0xFF; PORTD = 0x00; // LCD data lines TimerSet (10); TimerOn(); LCD_init(); LCD_ClearScreen(); LCD_DisplayString(1,"Self Sustaining Plant"); delay_ms(1500); LCD_ClearScreen(); while(1) { tick(); while(!TimerFlag); TimerFlag = 0; } }