Advertisement
sacio

Drink-O-Matic Deluxe Firmware v1

Jun 7th, 2012
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.01 KB | None | 0 0
  1. /** Drink-O-Matic Deluxe **\
  2.  
  3. Firmware v1.0
  4. Odin Hoff Gardå <odinhg@gmail.com>
  5.  
  6. Spaghetti code for the spaghetti control circuit
  7. Code will be split into multiple files some day.
  8.  
  9. TODO:
  10.     Calibrate lines
  11.     Finish client side software
  12.     Some HW fixes
  13.  
  14. 07062012 - odinhg/sacio
  15.  
  16. \**                      **/
  17.  
  18. #define F_CPU           8000000
  19.  
  20. #define PUMP_PORT       PORTB
  21. #define PUMP_DDR        DDRB
  22. #define PUMP_0          PINB0
  23. #define PUMP_1          PINB1
  24. #define PUMP_2          PINB2
  25. #define PUMP_3          PINB3
  26. #define PUMP_4          PINB4
  27. #define PUMP_5          PINB5
  28.  
  29. #define VALVE_PORT      PORTC
  30. #define VALVE_DDR       DDRC
  31. #define VALVE_0         PINC0
  32. #define VALVE_1         PINC1
  33. #define VALVE_2         PINC2
  34. #define VALVE_3         PINC3
  35. #define VALVE_4         PINC4
  36. #define VALVE_5         PINC5
  37.  
  38. #define LED_PORT        PORTD
  39. #define LED_DDR         DDRD
  40. #define LED_RED         PIND6
  41. #define LED_GREEN       PIND5
  42. #define LED_BLUE        PIND7
  43.  
  44. #define IRCHANNEL       ADCH6
  45. #define IR_LOW          198
  46. #define IR_HIGH         210
  47.  
  48. #define ON              1
  49. #define OFF             0
  50.  
  51. #define ST_IDLE         0   //Idle state
  52. #define ST_DETCUP       1   //Cup detected
  53. #define ST_FILL         2   //Fill cup
  54.  
  55. #include <avr/io.h>
  56. #include <avr/interrupt.h>
  57. #include <util/delay.h>
  58.  
  59. void configureIO(void);
  60. void controlValve(uint8_t valve, uint8_t value);
  61. void controlPump(uint8_t pump, uint8_t value);
  62. uint8_t readIR(void);
  63.  
  64. volatile uint8_t pwm_red, pwm_green, pwm_blue;
  65. volatile uint8_t pwm_counter;
  66.  
  67. const uint8_t sine_wave[256] = {
  68.   0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
  69.   0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
  70.   0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
  71.   0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
  72.   0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
  73.   0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
  74.   0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
  75.   0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
  76.   0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
  77.   0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
  78.   0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
  79.   0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
  80.   0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
  81.   0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
  82.   0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
  83.   0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
  84.   0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
  85.   0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
  86.   0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
  87.   0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
  88.   0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
  89.   0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
  90.   0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
  91.   0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
  92.   0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
  93.   0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
  94.   0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
  95.   0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
  96.   0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
  97.   0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
  98.   0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
  99.   0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
  100. };
  101.  
  102. int main(){
  103.     configureIO();
  104.  
  105.     uint8_t r,g,b;          //Sine fading colors
  106.     r=0;
  107.     g=90;
  108.     b=192;
  109.  
  110.     uint8_t state = ST_IDLE;    //Holds machine state
  111.     uint8_t ratios[6];      //Hold mixing ratios
  112.     uint16_t counter;       //Counts amount of time used for filling
  113.  
  114.     while(1){
  115.         switch(state){
  116.             case ST_IDLE:
  117.                 //Just idling around           
  118.                 if(readIR()>IR_HIGH)        //Check for cup
  119.                     state = ST_DETCUP;  //If cup, go to "detected cup" state
  120.                
  121.                 //Fade leds
  122.                 pwm_red     = sine_wave[r++];
  123.                 pwm_green   = sine_wave[g++];
  124.                 pwm_blue    = sine_wave[b++];
  125.                 _delay_ms(10);
  126.                 break;
  127.  
  128.             case ST_DETCUP:
  129.                 //Cup detected, cyan light
  130.                 pwm_red     = 0;
  131.                 pwm_green   = 255;
  132.                 pwm_blue    = 255;
  133.                
  134.                 //Wait for filling ratios
  135.                 while((UCSR0A &(1<<RXC0))==0){
  136.                     if(readIR()<IR_LOW){        //Check for cup
  137.                         state = ST_IDLE;    //If no cup, go to "idle" state
  138.                         break;
  139.                     }
  140.                 state = ST_FILL;
  141.                 }
  142.                 break;
  143.             case ST_FILL:
  144.                 //Filling in progress, red light
  145.                 pwm_red     = 255;
  146.                 pwm_green   = 0;
  147.                 pwm_blue    = 0;
  148.  
  149.                 //Get mixing ratios for each tank
  150.                 for(uint8_t i=0; i<6; i++){
  151.                     while((UCSR0A &(1<<RXC0))==0);
  152.                     ratios[i] = UDR0;
  153.                 }
  154.                
  155.                 //Run each line
  156.                 for(uint8_t i=0; i<6; i++){
  157.                     //Skip if not used in recipe
  158.                     if(!ratios[0]<=0){
  159.                         //Turn on line
  160.                         controlValve(i, ON);
  161.                         controlPump(i, ON);
  162.                         //Reset counter
  163.                         counter = 0;
  164.                         //Wait until filling is done, abort if cup is removed
  165.                         while(counter++<ratios[i]){
  166.                             if(readIR()<IR_LOW){//Check for cup
  167.                                 break;
  168.                             }
  169.                             _delay_ms(100);
  170.                         }
  171.                         //Turn off line
  172.                         controlValve(i, OFF);
  173.                         controlPump(i, OFF);
  174.                     }  
  175.                 }
  176.                 //Go back to idle state
  177.                 state = ST_IDLE;
  178.                 break;
  179.             default:
  180.                 break;
  181.             }
  182.                 //UART - DEBUG CODE
  183.                 /*char itoaBuff[3];//itoa buffer               
  184.                 itoa(readIR(), itoaBuff, 10); //adc reading to ascii
  185.                 for(int i=0; i<(sizeof(itoaBuff)/sizeof(char));i++){ //loop all chars
  186.                 while (!(UCSR0A & (1 <<UDRE0)));
  187.                     UDR0 =  itoaBuff[i];//send to uart
  188.                 }
  189.                 _delay_ms(500);*/  
  190.     }
  191.  
  192.     return 0;
  193. }
  194.  
  195.  
  196. void configureIO(void){
  197.     //Set outputs
  198.     PUMP_DDR    |=  (1<<PUMP_0) | (1<<PUMP_1) | (1<<PUMP_2) |
  199.                 (1<<PUMP_3) | (1<<PUMP_4) | (1<<PUMP_5);
  200.  
  201.     VALVE_DDR   |=  (1<<VALVE_0) | (1<<VALVE_1) | (1<<VALVE_2) |
  202.                 (1<<VALVE_3) | (1<<VALVE_4) | (1<<VALVE_5);
  203.    
  204.     LED_DDR     |=  (1<<LED_RED) | (1<<LED_GREEN) | (1<<LED_BLUE);
  205.  
  206.    
  207.     //LED PWM timer setup
  208.     TCCR0A      |=  (1<<WGM01);     //Setup timer 0 in CTC mode
  209.     TCCR0B      |=  (1<<CS00) | (1<<CS01);  //Set /64 prescaler
  210.     TIMSK0      |=  (1<<OCIE0A);        //Enable timer overflow interrupt
  211.     OCR0A        =   0x04;
  212.    
  213.     //Setup IR ADC
  214.     ADMUX       |=  (1<<REFS1) | (1<<REFS0) | (1<<MUX1) |
  215.                 (1<<MUX2) | (1<<ADLAR);     //1.1V as ref, ADC channel 6, left adjust
  216.     ADCSRA      |=  (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);    //Enable
  217.    
  218.     //Setup UART   
  219.     UCSR0B      |=  (1<<RXEN0) | (1<<TXEN0);    //Enable RX/TX
  220.     UCSR0C      |=  (1<<UCSZ00) | (1<<UCSZ01);  //8bit data
  221.     UBRR0L       =   0x33;              //9600 baud @ 8Mhz
  222.  
  223.     sei();  //Enable interrupts globally
  224.  
  225. }
  226.  
  227. void controlValve(uint8_t valve, uint8_t value){
  228.     if(value == ON){
  229.         VALVE_PORT  |=   (1<<valve);
  230.     }else{
  231.         VALVE_PORT  &=  ~(1<<valve);
  232.     }
  233. }
  234.  
  235. void controlPump(uint8_t pump, uint8_t value){
  236.     if(value == ON){
  237.         PUMP_PORT   |=   (1<<pump);
  238.     }else{
  239.         PUMP_PORT   &=  ~(1<<pump);
  240.     }
  241. }
  242.  
  243. uint8_t readIR(void){
  244.     /*uint16_t buffer = 0;
  245.     uint8_t i;
  246.     for(i=0; i<10; i++){
  247.         ADCSRA |= (1<<ADSC);    //Read ADC 6
  248.         while (ADCSRA & (1<<ADSC));
  249.         buffer += ADCH;
  250.         _delay_ms(10);
  251.     }
  252.    
  253.     return buffer/10;           //Return 8bit value
  254.     */
  255.     ADCSRA |= (1<<ADSC);    //Read ADC 6
  256.     while (ADCSRA & (1<<ADSC));
  257.     return ADCH;
  258. }
  259.  
  260.  
  261. ISR(TIMER0_COMPA_vect){
  262.     pwm_counter++;
  263.  
  264.     if(pwm_counter<pwm_red){
  265.         LED_PORT |=  (1<<LED_RED);
  266.     }else{
  267.         LED_PORT &= ~(1<<LED_RED);
  268.     }
  269.  
  270.     if(pwm_counter<pwm_green){
  271.         LED_PORT |=  (1<<LED_GREEN);
  272.     }else{
  273.         LED_PORT &= ~(1<<LED_GREEN);
  274.     }
  275.  
  276.     if(pwm_counter<pwm_blue){
  277.         LED_PORT |=  (1<<LED_BLUE);
  278.     }else{
  279.         LED_PORT &= ~(1<<LED_BLUE);
  280.     }
  281. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement