SHARE
TWEET

Drink-O-Matic Deluxe Firmware v1

sacio Jun 7th, 2012 75 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top