#include #include #define begin { #define end } #define t0 100 #define t1 100 #define t2 50 #define t3 100 #define numJugs 3 #define lightLimit 30 #define numDrinks 5 #define photoPin 0b01100001; // A1 #define forcePin 0b01100000; // A0 #define pin 0x55 #define but0 0x22 #define but1 0x33 #define but2 0x44 // prototypes void gets_int(void); //starts getting a string from serial line void puts_int(void); //starts a send to serial line // eeprom to store reciepes to memory eeprom int dataBase[numDrinks][numJugs]; char received[5]; int time0, time1, time2, time3; int initWeight, initLight; char selectedDrink; char state, programState; int mask; char currentJug; int currentDrinks, temp1, temp2, temp3; int photoADC, forceADC, toggle; char wireless, wirelessState; int currCupVal, targetForce; //RXC ISR variables unsigned char r_index; //current string index unsigned char r_buffer[32]; //input string unsigned char r_ready; //flag for receive done unsigned char r_char; //current character //TX empth ISR variables unsigned char t_index; //current string index unsigned char t_buffer[50]; //output string unsigned char t_ready; //flag for transmit done unsigned char t_char; //current character //timer 0 compare ISR; 1 ms interrupt [TIM0_COMP] void timer0_compare(void) begin if (time0>0)--time0; if (time1>0)--time1; if (time2>0)--time2; if (time3>0)--time3; end // initialize the rs232 stuff void initRS232(void) begin //serial setop for debugging using printf, etc. UCSRB = 0x18 ; // UBRRL = 103 ; // 9600 baud UBRRL = 207 ; // 4800 baud putsf("\f\r\n Juicer!\r\n"); r_ready=0; t_ready=1; gets_int(); end void init(void) begin //set up timer 0 TIMSK=2; //turn on timer 0 cmp match ISR OCR0 = 249; //set the compare re to 249 time ticks TCCR0=0b00001011; //prescalar to 64 and turn on clear-on-match #asm ("sei"); time0= t0; time1= t1; time2= t2; time3= t3; DDRA = 0x00; // a will be input DDRB = 0xff; // b will be output PORTB = 0x00; // init b DDRD = 0x00; // d will be input PORTD.0 = 1; // iniit selectedDrink=-1; state =0; currentDrinks=0; currentJug =0; toggle =1; // light up the led DDRD=DDRD^0xa0; PORTD.7=0; // setup the ADC ADCSR = 0b11000111; wirelessState=0; currCupVal = 0; targetForce = 0; end // toggle between gettin the two sensor values // and check for the wirelss jumper void task0 (void) begin time0=t0; if (toggle) begin forceADC = ADCH; ADMUX = photoPin; end else begin photoADC = ADCH; ADMUX = forcePin; end ADCSR.6 =1; toggle = toggle ^1; if (PINA.2 ==0) wireless =0; else wireless =1; end // the linear interpolation of the non liner force sensor void CalcTargetForce (void) begin currCupVal += dataBase[selectedDrink][currentJug]; if (currCupVal < 25) targetForce = initWeight + (currCupVal*60)/100; else if (currCupVal < 50) targetForce = initWeight + 60 + ((currCupVal-25)*50)/100; else if (currCupVal < 75) targetForce = initWeight + 60 + 50 + ((currCupVal-50)*40)/100; else targetForce = initWeight + 60 + 50 + 40 + ((currCupVal-75)*30)/100; end // the pour state.. start at the first jug and cycle through each jug when enough has been dispensed. void Pour(void) begin time1=t1; if (currentJug < numJugs) begin if (targetForce > forceADC) begin mask = 0x00 | (1 << currentJug); // turn on sprintf(t_buffer, "Pouring drink=%d jug=%d weight%d target%d\n\r", selectedDrink, currentJug, forceADC, targetForce); puts_int(); while (0==t_ready); end else begin CalcTargetForce(); mask = 0x00; currentJug++; end end else begin state=0; currentJug=0; sprintf(t_buffer, "Done with %d\n\r", selectedDrink); puts_int(); currCupVal=0; while (0==t_ready); end end // gets the selection of the user choices void GetInput(void) begin time2=t2; if (r_ready) begin sscanf(r_buffer,"%c",&selectedDrink); gets_int(); switch (selectedDrink) begin case '0': case '1': case '2': case '3': case '4': selectedDrink = selectedDrink-48; initWeight = forceADC; // get the initial weight of cup initLight = photoADC; // get the initial light of cup // do this for wireless also CalcTargetForce(); state =2; break; case 'p': case 'P': sprintf(t_buffer, "Program Mode\n\r"); puts_int(); while (0==t_ready); programState=0; state = 3; break; case 's': sprintf(t_buffer, "Show All\n\r"); puts_int(); while (0==t_ready); sprintf(t_buffer, "\f"); puts_int(); while (0==t_ready); for (temp1 =0; temp1< numDrinks; temp1++) begin sprintf(t_buffer, "Drink #%d = %d, %d, %d\n\r",temp1, dataBase[temp1][0], dataBase[temp1][1], dataBase[temp1][2]); puts_int(); while (0==t_ready); end while (0==t_ready); state = 0; break; end end end // program the ee prom with new recipes void ProgramDB(void) begin time3=t3; switch (programState) begin case 0: sprintf(t_buffer, "input format = index bin1 bin2 bin3\n\r"); puts_int(); programState = 1; sprintf(r_buffer, ""); break; case 1: if (r_ready) begin sscanf(r_buffer,"%d %d %d %d", ¤tDrinks, &temp1, &temp2, &temp3); dataBase[currentDrinks][0]=temp1; dataBase[currentDrinks][1]=temp2; dataBase[currentDrinks][2]=temp3; sprintf(r_buffer, ""); state = 0; end break; end end // the main state machine void main(void) begin init(); initRS232(); while(1) begin if (time0==0) task0(); switch (state) begin case 0: sprintf(t_buffer, "#0-4, s, p\n\r"); puts_int(); while (0==t_ready); selectedDrink=-1; state =1; case 1: // get serial input if (!wireless){ if (time2==0) GetInput(); } break; case 2: // pour state if(time1==0) Pour(); // stop checks. the photo resistor and the for sensor if (photoADC < (initLight -lightLimit)) begin sprintf(t_buffer, "Stopped by Photo=%d initi=%d\n\r", photoADC, initLight); puts_int(); while (0==t_ready); state = 0; mask = 0x00; end if (forceADC >=198) begin sprintf(t_buffer, "Stopped by over force limit=%d\n\r", forceADC); puts_int(); while (0==t_ready); state = 0; mask = 0x00; end break; case 3: // programming if(time3==0) ProgramDB(); break; end PORTB = mask; if (wireless==1) PORTD.7 =0; else PORTD.7 =1; end end //********************************************************** // -- non-blocking keyboard check initializes ISR-driven // receive. This routine merely sets up the ISR, which then //does all the work of getting a command. void gets_int(void) begin r_ready=0; r_index=0; UCSRB.7=1; end //********************************************************** // -- nonblocking print: initializes ISR-driven // transmit. This routine merely sets up the ISR, then //send one character, The ISR does all the work. void puts_int(void) begin t_ready=0; t_index=0; if (t_buffer[0]>0) begin putchar(t_buffer[0]); UCSRB.5=1; end end //********************************************************** //UART character-ready ISR // all of the wireless logic for filtering the noise // it will receive all of the wireless data and only // process the information that has been key coded // kepts the last 5 received symbols. and if the a command is inbetween // a head and end key. then it will process it and tell the // main statemachine to start pouring the drink interrupt [USART_RXC] void uart_rec(void) begin r_char=UDR; //get a char if (wireless ==0){ UDR=r_char; //then print itsssss //build the input string if (r_char != '\r') r_buffer[r_index++]=r_char; else begin putchar('\n'); //use putchar to avoid overwrite r_buffer[r_index]=0x00; //zero terminate //r_myBuffer r_ready=1; //signal cmd processor UCSRB.7=0; //stop rec ISR end } else if(state!=2){ { // UDR=r_char; received[0]=received[1]; received[1]=received[2]; received[2]=received[3]; received[3]=received[4]; received[4]=r_char; if ((received[0]== 0xaa) && (received[1]== 0xaa) && (received[2]== pin) && (received[4]== pin)) { if (received[3] == but0) selectedDrink = 0; if (received[3] == but1) selectedDrink = 1; if (received[3] == but2) selectedDrink = 2; initWeight = forceADC; // get the initial weight of cup initLight = photoADC; // get the initial light of cup // do this for wireless also CalcTargetForce(); state =2; //UDR=received[3]; debug } } } end /**********************************************************/ //UART xmit-empty ISR interrupt [USART_DRE] void uart_send(void) begin t_char = t_buffer[++t_index]; if (t_char == 0) { UCSRB.5=0; //kill isr t_ready=1; //transmit done } else { UDR = t_char ; //send the char } end