//Andrew Lee //Susan Lin //Akosua Kyereme-Tuah #include #include #include #include #include #define begin { #define end } #define Aref 2.33 //Aref #define offset1 1.83 //offsets used to find tilt angles #define offset2 1.83 //256 X 128 sed1330f lcd //LCD Control (PORTC) #define LCDreset 0x00 // Reset the Display #define LCDnop 0x47 // No operation #define CmdSetup 0x47 // Set A0 high #define CmdWrite 0x43 // Set WR low #define DataSetup 0x07 // Set A0 low #define DataWrite 0x03 // Set WR low #define StatusRead 0x05 // Set RD low, A0 low #define DataRead 0x45 // Set RD low, A0 high // LCD DATA (PORTB) #define SystemSet 0x40 // Initialize system #define SleePIn 0x53 // Enter standby mode #define DispOFF 0x58 // Display Off #define DispON 0x59 // Display On #define Scroll 0x44 // Initialize Address & Regions #define CSRForm 0x5D // Set cursor type #define CharAddr 0x5C // Set address of character RAM #define CSRRight 0x4C // Cursor direction = right #define CSRLeft 0x4D // Cursor direction = left #define CSRUp 0x4E // Cursor direction = up #define CSRDown 0x4F // Cursor direction = down #define HorzScroll 0x5A // Set horz scroll position #define Overlay 0x5B // Set Display Format #define CSRW 0x46 // Set cursor address #define CSRR 0x47 // Read cursor address #define MWRITE 0x42 // Write to display memory // Global Constants #define TextAddress 0x0000 // Character layer base address #define GraphicsAddress 0x03E8 // Graphics layer base address = 1000 #define NUM_TEXT_LINES 16 // 128 / 8 = 16 character lines #define NUM_GRAPHICS_LINES 128 // 128 / 1 = 128 graphics lines #define BYTES_PER_LINE 32 // 256 / 8 = 32 bytes per line //Global variables unsigned char start_form, end_form; unsigned char slant,replace; unsigned char temp_posX, temp_posY; unsigned char neg, flag; unsigned int byte, prevbytenum, bytenum; float m, b; unsigned int x1; unsigned int y1; unsigned int x2; unsigned int y2; unsigned int x3; unsigned int y3; unsigned int x4; unsigned int y4; unsigned int lastX; unsigned int firstX; float sand_amount1; float sand_amount2; float tilt_angle; float old_tilt_angle; //A/D conversion int Ain; float voltage1; float voltage2; //Subroutines void initLCD(void); void WriteCMD(unsigned char CommandCode); void WriteDATA(unsigned char CommandCode); void clearLCD(void); void FillQuad(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int x3, unsigned int y3, unsigned int x4, unsigned int y4); void drawGlass(void); void FillRect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int x3, unsigned int y3, unsigned int x4, unsigned int y4); void c_cal(float tilt_angle, float sand_amount, unsigned int which_box); /**********************************************************/ /*finds tilt_angle of hourglass */ /**********************************************************/ void get_tilt_angle(void) begin voltage1 = (voltage1/256)*Aref; voltage1 = voltage1 - offset1; voltage2 = (voltage2/256)*Aref; voltage2 = voltage2 - offset2; if ((voltage2/0.5) < 0.6) tilt_angle = (voltage1/0.5)*180; else if ((voltage2/0.5) >= 0.6) tilt_angle = 360 - (voltage1/0.5)*180; if ((tilt_angle/30) < (floor(tilt_angle/30) + 0.5)) tilt_angle = floor(tilt_angle/30)*30; else tilt_angle = ceil(tilt_angle/30)*30; end /**********************************************************/ /*timer 1 compare-match A ISR */ /**********************************************************/ interrupt [TIM1_COMPA] void cmpA_overflow(void) begin if (PORTD.7) PORTD.7 = 0; //toggle the port to sound the alarm else PORTD.7 = 1; end /**********************************************************/ /* A/D Conversion Interrupt */ /**********************************************************/ interrupt [ADC_INT] void adc_done(void) begin Ain = ADCH; end /*********************************************************************/ /* initLCD() : Initializes the LCD controller */ /*********************************************************************/ void initLCD(void) begin // set I/O port directions DDRC = 0xFF; DDRB = 0xFF; PORTC = LCDnop; delay_us(500); delay_us(500); delay_us(500); delay_us(500); PORTC = LCDreset; delay_us(500); delay_us(500); delay_us(500); PORTC = LCDnop; delay_us(500); delay_us(500); delay_us(500); delay_us(500); WriteCMD(SystemSet); WriteDATA(0x30); WriteDATA(0x87); // WriteDATA(0x87); WriteDATA(0x07); // 2nd hex sets the width WriteDATA(0x07); WriteDATA(0x27); // 2nd hex sets the height WriteDATA(0x27); WriteDATA(0x2F); WriteDATA(0xC7); WriteDATA(0x28); WriteDATA(0x00); WriteCMD(Overlay); WriteDATA(0x00); WriteCMD(Scroll); WriteDATA(0x00); WriteDATA(0x00); WriteDATA(0xC8); WriteDATA(0xE8); WriteDATA(0x03); WriteDATA(0xC8); WriteCMD(CSRForm); WriteDATA(0x04); WriteDATA(0x86); WriteCMD(CSRRight); WriteCMD(HorzScroll); WriteDATA(0x00); WriteCMD(DispON); //WriteDATA(0x14); //n0 cursor WriteDATA(0x16); //cursor return; end /*********************************************************************/ /* WriteCMD() : Sends Command to LCD controller */ /*********************************************************************/ void WriteCMD(unsigned char CommandCode) begin PORTB = CommandCode; PORTC = CmdSetup; PORTC = CmdWrite; PORTC = CmdSetup; return; end /*********************************************************************/ /* WriteDATA() : Sends parameters or data to LCD controller */ /*********************************************************************/ void WriteDATA(unsigned char CommandCode) begin PORTB = CommandCode; PORTC = DataSetup; PORTC = DataWrite; PORTC = DataSetup; return; end /*********************************************************************/ /* clearLCD() : Clears the LCD display memory */ /*********************************************************************/ void clearLCD(void) begin unsigned short i; WriteCMD(CSRRight); WriteCMD(CSRW); WriteDATA(0x00); WriteDATA(0x00); WriteCMD(MWRITE); for (i=0; i<1000; i++) begin WriteDATA(0x20); // write " " to character memory end WriteCMD(CSRW); WriteDATA(0xE8); WriteDATA(0x03); WriteCMD(MWRITE); for (i=0; i<8000; i++) begin WriteDATA(0x00); // erase graphics memory end return; end /*********************************************************************/ /* Find_startform() : finds form of beginning byte of rectangle /*********************************************************************/ void Find_startform(unsigned char start_bit) begin unsigned char temp_form; switch(start_bit) //find form depending on starting bit begin case 0: temp_form = 0b11111111; break; case 1: temp_form = 0b01111111; break; case 2: temp_form = 0b00111111; break; case 3: temp_form = 0b00011111; break; case 4: temp_form = 0b00001111; break; case 5: temp_form = 0b00000111; break; case 6: temp_form = 0b00000011; break; case 7: temp_form = 0b00000001; break; end start_form = temp_form; end /*********************************************************************/ /* Find_endform() : finds form of ending byte of rectangle /*********************************************************************/ void Find_endform(unsigned char end_bit) begin unsigned char temp_form; switch(end_bit) //find form depening on ending bit begin case 0: temp_form = 0b10000000; break; case 1: temp_form = 0b11000000; break; case 2: temp_form = 0b11100000; break; case 3: temp_form = 0b11110000; break; case 4: temp_form = 0b11111000; break; case 5: temp_form = 0b11111100; break; case 6: temp_form = 0b11111110; break; case 7: temp_form = 0b11111111; break; end end_form = temp_form; end /*********************************************************************/ /* UnFillPoint() : unfill a point /*********************************************************************/ void UnFillPoint(unsigned int x1, unsigned int line) begin unsigned char and_form, last_form, first_form; unsigned char start_bit; unsigned short zero_address; unsigned short address; unsigned short start_address; unsigned char addrl, addrh; // low and high bytes of address zero_address = 0x03E8; // 1111101000 if(x1 == 0) start_bit = 0; else start_bit = x1%8; bytenum = x1/8; if((flag == 1) || (prevbytenum != bytenum)) byte = 0xff; switch(start_bit) begin case 0: and_form = 0b01111111; break; case 1: and_form = 0b10111111; break; case 2: and_form = 0b11011111; break; case 3: and_form = 0b11101111; break; case 4: and_form = 0b11110111; break; case 5: and_form = 0b11111011; break; case 6: and_form = 0b11111101; break; case 7: and_form = 0b11111110; break; end prevbytenum = bytenum; byte = byte & and_form; if (x1 == lastX) begin switch(start_bit) begin case 0: last_form = 0b10000000; break; case 1: last_form = 0b11000000; break; case 2: last_form = 0b11100000; break; case 3: last_form = 0b11110000; break; case 4: last_form = 0b11111000; break; case 5: last_form = 0b11111100; break; case 6: last_form = 0b11111110; break; case 7: last_form = 0b11111111; break; end byte = byte & last_form; end else if (x1 == firstX) begin switch(start_bit) begin case 0: first_form = 0b01111111; break; case 1: first_form = 0b00111111; break; case 2: first_form = 0b00011111; break; case 3: first_form = 0b00001111; break; case 4: first_form = 0b00000111; break; case 5: first_form = 0b00000011; break; case 6: first_form = 0b00000001; break; case 7: first_form = 0b00000000; break; end byte = byte & first_form; end start_address = zero_address + bytenum; address = start_address + (40*line); //position to start from addrl = address; addrh = address >> 8; WriteCMD(CSRW); WriteDATA(addrl); WriteDATA(addrh); WriteCMD(MWRITE); WriteDATA(byte); end /*********************************************************************/ /* slope() : calculates m and b of straight line /*********************************************************************/ void slope(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) begin float castx1, castx2, casty1, casty2; castx1 = (float)x1; castx2 = (float)x2; casty1 = (float)y1; casty2 = (float)y2; m = (casty2-casty1) / (castx2-castx1); b = casty1 - (m*castx1); end /*********************************************************************/ /* UnfillRest() : unfills rest of points so that can have trapezoid /*********************************************************************/ void UnfillRest(unsigned int x, unsigned int y) begin unsigned char bitpos; unsigned short zero_address; unsigned short address; unsigned short start_address; unsigned char addrl, addrh; // low and high bytes of address zero_address = 0x03E8; bitpos = x%8; prevbytenum = x/8; if(x == firstX) begin switch(bitpos) begin case 0: byte = 0b11111111; break; case 1: byte = 0b01111111; break; case 2: byte = 0b00111111; break; case 3: byte = 0b00011111; break; case 4: byte = 0b00001111; break; case 5: byte = 0b00000111; break; case 6: byte = 0b00000011; break; case 7: byte = 0b00000001; break; end end else if (x == lastX) begin switch(bitpos) begin case 0: byte = 0b10000000; break; case 1: byte = 0b11000000; break; case 2: byte = 0b11100000; break; case 3: byte = 0b11110000; break; case 4: byte = 0b11111000; break; case 5: byte = 0b11111100; break; case 6: byte = 0b11111110; break; case 7: byte = 0b11111111; break; end end start_address = zero_address + prevbytenum; address = start_address + (40*y); //position to start from addrl = address; addrh = address >> 8; WriteCMD(CSRW); WriteDATA(addrl); WriteDATA(addrh); WriteCMD(MWRITE); WriteDATA(byte); end /*********************************************************************/ /* CheckandUnfill() : checks where to unfill and unfills it /*********************************************************************/ void CheckandUnfill(unsigned int px1, unsigned int py1, unsigned int px2, unsigned int py4) begin float tempy; float castrow; unsigned char row, col; prevbytenum = 0; for (row=py1; row<=py4; row++) begin flag = 1; for (col=px1; col<=px2; col++) begin tempy = (m*col) + b; if ((slant==34) || (neg && (slant==23)) || ((!neg) && (slant==14))) begin castrow = (float)row; if (tempy < castrow) UnFillPoint(col, row); else if ((tempy == castrow) && ((col==firstX) || (col==lastX))) UnfillRest(col, row); end //works for 12, works for 23+, 14- else if ((slant==12) || (neg && (slant==14)) || ((!neg) && (slant==23))) begin castrow = (float)row; if (tempy > castrow) UnFillPoint(col, row); else if ((tempy == castrow) && ((col==firstX) || (col==lastX))) UnfillRest(col, row); end flag = 0; end end end /*********************************************************************/ /* Slant() : finds slanted edge /*********************************************************************/ void Slant(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int x3, unsigned int y3, unsigned int x4, unsigned int y4) begin //Determine which line is slanted if (y1==y2) begin if (x2==x3) begin if (y3==y4) begin if (x1==x4) begin slant = 0; end else begin slant=14; if(x1 > x4) //first case begin replace = 1; neg = 1; temp_posX = x4; if(y1 < y4) temp_posY = y1; else temp_posY = y4; end else //second case begin neg = 0; replace = 4; temp_posX = x1; if(y1 < y4) temp_posY = y4; else temp_posY = y1; end end //end else for x1==x4 end //end if y3==y4 else begin slant= 34; if(y3 > y4) //first case begin neg = 0; replace = 4; temp_posY = y3; if(x3 < x4) temp_posX = x3; else temp_posX = x4; end else //second case begin neg = 1; replace = 3; temp_posY = y4; if(x3 < x4) temp_posX = x4; else temp_posX = x3; end end //end else for y3==y4 end //end if x2 == x3 else begin slant=23; if(x2 > x3) //first case begin neg = 1; replace = 3; temp_posX = x2; if(y2 < y3) temp_posY = y3; else temp_posY = y2; end else //second case begin neg = 0; replace = 2; temp_posX = x3; if(y2 < y3) temp_posY = y2; else temp_posY = y3; end end //end else for x2 == x3 end //end if y1 == y2 else begin slant = 12; if(y1 > y2) //first case begin neg = 1; replace = 1; temp_posY = y2; if(x1 < x2) temp_posX = x1; else temp_posX = x2; end else //second case begin neg = 0; replace = 2; temp_posY = y1; if(x1 < x2) temp_posX = x2; else temp_posX = x1; end end //end else for y1==y2 end /*********************************************************************/ /* FillQuad() : fills a quad (one side slanted) /*********************************************************************/ void FillQuad(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int x3, unsigned int y3, unsigned int x4, unsigned int y4) begin Slant(x1, y1, x2, y2, x3, y3, x4, y4); if(slant == 0) FillRect(x1,y1,x2,y2,x3,y3,x4,y4); else if(slant == 12) begin slope(x1, y1, x2, y2); if(replace == 1) begin FillRect(temp_posX, temp_posY,x2,y2,x3,y3,x4,y4); firstX = temp_posX; lastX = x2; CheckandUnfill(temp_posX, temp_posY,x2,y4); end else begin FillRect(x1,y1,temp_posX,temp_posY,x3,y3,x4,y4); firstX = x1; lastX = temp_posX; CheckandUnfill(x1,y1,temp_posX,y4); end end else if(slant == 14) begin slope(x1, y1, x4, y4); if(replace == 1) begin FillRect(temp_posX, temp_posY,x2,y2,x3,y3,x4,y4); firstX = temp_posX; lastX = x2; CheckandUnfill(temp_posX, temp_posY,x2,y4); end else begin FillRect(x1,y1,x2,y2, x3,y3,temp_posX,temp_posY); firstX = x1; lastX = x2; CheckandUnfill(x1,y1,x2,temp_posY); end end else if(slant == 23) begin slope(x2, y2, x3, y3); if(replace == 2) begin FillRect(x1,y1,temp_posX,temp_posY, x3,y3,x4,y4); firstX = x1; lastX = temp_posX; CheckandUnfill(x1,y1,temp_posX,y4); end else begin FillRect(x1,y1,x2,y2, temp_posX,temp_posY, x4, y4); firstX = x1; lastX = x2; CheckandUnfill(x1,y1,x2, y4); end end else if(slant == 34) begin slope(x3, y3, x4, y4); if(replace == 3) begin FillRect(x1,y1,x2,y2, temp_posX,temp_posY, x4, y4); firstX = x1; lastX = x2; CheckandUnfill(x1,y1,x2, y4); end else begin FillRect(x1,y1,x2,y2, x3,y3,temp_posX,temp_posY); firstX = x1; lastX = x2; CheckandUnfill(x1,y1,x2,temp_posY); end end return; end /*********************************************************************/ /* FillRect() : fills a rectangle/square /*********************************************************************/ void FillRect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int x3, unsigned int y3, unsigned int x4, unsigned int y4) begin unsigned short zero_address; unsigned short address; unsigned short start_address; unsigned short end_address; unsigned char start_byte, end_byte; unsigned char start_bit, end_bit; unsigned char addrl, addrh; // low and high bytes of address unsigned char lines_down; unsigned char bytes_across; unsigned int i,j; y2 = y2; x3 = x3; y3 = y3; x4 = x4; zero_address = 0x03E8; // 1111101000 start_byte = x1/8; end_byte = x2/8; start_address = zero_address + start_byte; end_address = zero_address + end_byte; if(x1 == 0) start_bit = 0; else start_bit = x1%8; if(x2 == 0) end_bit = 0; else end_bit = x2%8; Find_startform(start_bit); Find_endform(end_bit); lines_down = (y4 - y1) + 1; if (start_byte == end_byte) start_form = start_form & end_form; //draw the starting byte form eg 10001100 address = start_address + (40*y1); //position to start from for(i=0; i> 8; WriteCMD(CSRW); WriteDATA(addrl); WriteDATA(addrh); WriteCMD(MWRITE); WriteDATA(start_form); address = address + 40; end if(start_byte != end_byte) begin //draw the ending byte form eg 10001100 address = end_address + (40*y1); //position to end for(i=0; i> 8; WriteCMD(CSRW); WriteDATA(addrl); WriteDATA(addrh); WriteCMD(MWRITE); WriteDATA(end_form); address = address + 40; end if((end_byte - start_byte) > 1) //more than a byte so fill in between begin //every byte in between bytes_across = end_byte - (start_byte + 1); address = (start_address + 1) + (40*y1); for(i=0; i> 8; WriteCMD(CSRW); WriteDATA(addrl); WriteDATA(addrh); WriteCMD(MWRITE); for(j=0; j 0) && (tilt_angle < 90)) begin b = (unsigned int) floor(sqrt(2*sand_amount/tan(tilt_angle/180*PI))); h = (unsigned int) floor(2*sand_amount/sqrt(2*sand_amount/tan(tilt_angle/180*PI))); if ((b <= (box_ymax-box_ymin)) && (h <= (box_xmax-box_xmin))) //triangle begin x1 = box_xmin; y1 = box_ymax-b; x2 = box_xmin+1; y2 = box_ymax-b; x3 = h+box_xmin; y3 = box_ymax; x4 = box_xmin; y4 = box_ymax; end if ((b > (box_ymax-box_ymin)) && (h < (box_xmax-box_xmin))) begin b = box_ymax-box_ymin; h1 = (unsigned int) floor(y_size*tan(tilt_angle/180*PI)); h2 = (unsigned int) floor((sand_amount - 0.5*y_size*y_size*tan(tilt_angle/180*PI))/y_size); x1 = box_xmin; y1 = box_ymin; x2 = h2+box_xmin; y2 = box_ymin; x3 = h1+h2+box_xmin; y3 = box_ymax; x4 = box_xmin; y4 = box_ymax; end if ((b < (box_ymax-box_ymin)) && (h > (box_xmax-box_xmin))) begin h = box_xmax-box_xmin; b1 = (unsigned int) floor(x_size/tan(tilt_angle/180*PI)); b2 = (unsigned int) floor((sand_amount - 0.5*x_size*x_size/tan(tilt_angle/180*PI))/x_size); x1 = box_xmin; y1 = box_ymax-(b1+b2); x2 = box_xmax; y2 = box_ymax-b2; x3 = box_xmax; y3 = box_ymax; x4 = box_xmin; y4 = box_ymax; end end if ((tilt_angle > 90) && (tilt_angle < 180)) begin b = (unsigned int) floor(sqrt(2*sand_amount/tan((tilt_angle-90)/180*PI))); h = (unsigned int) floor(2*sand_amount/sqrt(2*sand_amount/tan((tilt_angle-90)/180*PI))); if ((b <= (box_xmax-box_xmin)) && (h <= (box_ymax-box_ymin))) //triangle begin x1 = box_xmax-1; y1 = box_ymax-h; x2 = box_xmax; y2 = box_ymax-h; x3 = box_xmax; y3 = box_ymax; x4 = box_xmax-b; y4 = box_ymax; end if ((b > (box_xmax-box_xmin)) && (h < (box_ymax-box_ymin))) begin b = box_xmax-box_xmin; h1 = (unsigned int) floor(x_size*tan((tilt_angle-90)/180*PI)); h2 = (unsigned int) floor((sand_amount - 0.5*x_size*x_size*tan((tilt_angle-90)/180*PI))/x_size); x1 = box_xmin; y1 = box_ymax-h2; x2 = box_xmax; y2 = box_ymax-(h1+h2); x3 = box_xmax; y3 = box_ymax; x4 = box_xmin; y4 = box_ymax; end if ((b < (box_xmax-box_xmin)) && (h > (box_ymax-box_ymin))) begin h = box_ymax-box_ymin; b1 = (unsigned int) floor(y_size/tan((tilt_angle-90)/180*PI)); b2 = (unsigned int) floor((sand_amount - 0.5*y_size*y_size/tan((tilt_angle-90)/180*PI))/y_size); x1 = box_xmax-b2; y1 = box_ymin; x2 = box_xmax; y2 = box_ymin; x3 = box_xmax; y3 = box_ymax; x4 = box_xmax-(b1+b2); y4 = box_ymax; end end if ((tilt_angle > 180) && (tilt_angle < 270)) begin b = (unsigned int) floor(sqrt(2*sand_amount/tan((tilt_angle-180)/180*PI))); h = (unsigned int) floor(2*sand_amount/sqrt(2*sand_amount/tan((tilt_angle-180)/180*PI))); if ((b <= (box_ymax-box_ymin)) && (h <= (box_xmax-box_xmin))) //triangle begin x1 = box_xmax-h; y1 = box_ymin; x2 = box_xmax; y2 = box_ymin; x3 = box_xmax; y3 = b+box_ymin; x4 = box_xmax-h; y4 = box_ymin+1; end if ((b > (box_ymax-box_ymin)) && (h < (box_xmax-box_xmin))) begin b = box_ymax-box_ymin; h1 = (unsigned int) floor(y_size*tan((tilt_angle-180)/180*PI)); h2 = (unsigned int) floor((sand_amount - 0.5*y_size*y_size*tan((tilt_angle-180)/180*PI))/y_size); x1 = box_xmax-(h1+h2); y1 = box_ymin; x2 = box_xmax; y2 = box_ymin; x3 = box_xmax; y3 = box_ymax; x4 = box_xmax-h2; y4 = box_ymax; end if ((b < (box_ymax-box_ymin)) && (h > (box_xmax-box_xmin))) begin h = box_xmax-box_xmin; b1 = (unsigned int) floor(x_size/tan((tilt_angle-180)/180*PI)); b2 = (unsigned int) floor((sand_amount - 0.5*x_size*x_size/tan((tilt_angle-180)/180*PI))/x_size); x1 = box_xmin; y1 = box_ymin; x2 = box_xmax; y2 = box_ymin; x3 = box_xmax; y3 = b1+b2+box_ymin; x4 = box_xmin; y4 = b2+box_ymin; end end if (tilt_angle > 270) begin b = (unsigned int) floor(sqrt(2*sand_amount/tan((tilt_angle-270)/180*PI))); h = (unsigned int) floor(2*sand_amount/sqrt(2*sand_amount/tan((tilt_angle-270)/180*PI))); if ((b <= (box_xmax-box_xmin)) && (h <= (box_ymax-box_ymin))) begin x1 = box_xmin; y1 = box_ymin; x2 = b+box_xmin; y2 = box_ymin; x3 = b+box_xmin; y3 = box_ymin+1; x4 = box_xmin; y4 = h+box_ymin; end if ((b > (box_xmax-box_xmin)) && (h < (box_ymax-box_ymin))) begin b = box_xmax-box_xmin; h1 = (unsigned int) floor(x_size*tan((tilt_angle-270)/180*PI)); h2 = (unsigned int) floor((sand_amount - 0.5*x_size*x_size*tan((tilt_angle-270)/180*PI))/x_size); x1 = box_xmin; y1 = box_ymin; x2 = box_xmax; y2 = box_ymin; x3 = box_xmax; y3 = h2+box_ymin; x4 = box_xmin; y4 = h1+h2+box_ymin; end if ((b < (box_xmax-box_xmin)) && (h > (box_ymax-box_ymin))) begin h = box_xmax-box_xmin; b1 = (unsigned int) floor(y_size/tan((tilt_angle-270)/180*PI)); b2 = (unsigned int) floor((sand_amount - 0.5*y_size*y_size/tan((tilt_angle-270)/180*PI))/y_size); x1 = box_xmin; y1 = box_ymin; x2 = b1+b2+box_xmin; y2 = box_ymin; x3 = b2+box_xmin; y3 = box_ymax; x4 = box_xmin; y4 = box_ymax; end end end /*********************************************************************/ /* MAIN /*********************************************************************/ void main(void) begin float index; /* PORT C */ DDRC.0=1; //PortC bit 0 is output, Reset DDRC.1=1; //PortC bit 1 is output, Read Strobe DDRC.2=1; //PortC bit 2 is output, Write Strobe DDRC.5=1; //PortC bit 5 is output, Chip Select DDRC.6=1; //PortC bit 6 is output, A0 /* PORT B */ DDRB.0=1; //PortB bit 0 is output, Data 0 DDRB.1=1; //PortB bit 1 is output, Data 1 DDRB.2=1; //PortB bit 2 is output, Data 2 DDRB.3=1; //PortB bit 3 is output, Data 3 DDRB.4=1; //PortB bit 4 is output, Data 4 DDRB.5=1; //PortB bit 5 is output, Data 5 DDRB.6=1; //PortB bit 6 is output, Data 6 DDRB.7=1; //PortB bit 7 is output, Data 7 initLCD(); // initialize the LCD clearLCD(); // clear screen DDRD = 0xF0; //high bits (alarm) are output, low bits (buttons) are input PORTD = 0xFF; //timer 1 setup TIMSK = 0x10; //turn on timer 1 overflow ISR, to include timer0, change to 0x11 TCCR1B = 0; //disable until alarm sounds //init the A to D converter //channel zero/ left adj /int Aref //!!!DISCONNECT Aref jumper!!!! //enable ADC and set prescaler to 1/64*8MHz=125,000 //and set int enable ADCSR = 0x80 + 0x06 + 0x08; MCUCR = 0b01010000; //enable sleep and choose ADC mode alarm = 0; sand_amount1 = 3000; sand_amount2 = 0; old_tilt_angle = 0; tilt_angle = 0; #asm sei #endasm while (1) begin while (alarm==0) begin //INCREASE/DECREASE SAND AMOUNT if (PIND.1 == 0) //increase begin if (((sand_amount1+300) + sand_amount2) < 3000) sand_amount1 = sand_amount1 + 300; clearLCD(); drawGlass(); c_cal(tilt_angle,sand_amount1,1); FillQuad(x1,y1,x2,y2,x3,y3,x4,y4); c_cal(tilt_angle,sand_amount2,2); FillQuad(x1,y1,x2,y2,x3,y3,x4,y4); end else if (PIND.2 == 0) //decrease begin if ((sand_amount1-300) > 0) sand_amount1 = sand_amount1 - 300; else if ((sand_amount2-300) > 0) sand_amount2 = sand_amount2 - 300; clearLCD(); drawGlass(); c_cal(tilt_angle,sand_amount1,1); FillQuad(x1,y1,x2,y2,x3,y3,x4,y4); c_cal(tilt_angle,sand_amount2,2); FillQuad(x1,y1,x2,y2,x3,y3,x4,y4); end ADMUX = 0b11100000; #asm sleep #endasm voltage1 = (float) Ain; ADMUX = 0b11100001; #asm sleep #endasm voltage2 = (float) Ain; get_tilt_angle(); if (tilt_angle == 180) begin fall = 1; if (sand_amount1 > 0) begin sand_amount1 = sand_amount1 - 100; sand_amount2 = sand_amount2 + 100; clearLCD(); drawGlass(); c_cal(tilt_angle, sand_amount1, 1); FillQuad(x1,y1,x2,y2,x3,y3,x4,y4); c_cal(tilt_angle, sand_amount2, 2); FillQuad(x1,y1,x2,y2,x3,y3,x4,y4); end else begin sand_amount1 = 0; alarm = 1; OCR1A=15267/2; TCCR1B = 9; end delay_ms(300); end else if ((tilt_angle == 0) || (tilt_angle == 360)) begin fall = 1; if (sand_amount2 > 0) begin sand_amount1 = sand_amount1 + 100; sand_amount2 = sand_amount2 - 100; clearLCD(); drawGlass(); c_cal(tilt_angle,sand_amount1,1); FillQuad(x1,y1,x2,y2,x3,y3,x4,y4); c_cal(tilt_angle,sand_amount2,2); FillQuad(x1,y1,x2,y2,x3,y3,x4,y4); end else begin sand_amount2 = 0; alarm = 1; OCR1A=15267/2; TCCR1B = 9; end delay_ms(300); end else if (old_tilt_angle != tilt_angle) begin fall = 0; clearLCD(); drawGlass(); if (sand_amount1 > 0) begin c_cal(tilt_angle,sand_amount1,1); FillQuad(x1,y1,x2,y2,x3,y3,x4,y4); end if (sand_amount2 > 0) begin c_cal(tilt_angle,sand_amount2,2); FillQuad(x1,y1,x2,y2,x3,y3,x4,y4); end end //makes sand fall if ((fall==1) && ((sand_amount2!=0) && ((tilt_angle==0) || (tilt_angle==360)))) FillQuad(21, 62, 159, 62, 159, 63, 21, 63); else if ((fall==1) && ((sand_amount1!=0) && (tilt_angle==180))) FillQuad(96, 62, 231, 62, 231, 63, 96, 63); old_tilt_angle = tilt_angle; delay_ms(100); end//ends the alarm==0 if (PIND.0 == 0) begin TCCR1B = 0; //turn off alarm alarm = 0; end end //ends the while(1) end //ends main