Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /** Drink-O-Matic Deluxe **\
- Firmware v1.0
- Odin Hoff Gardå <odinhg@gmail.com>
- Spaghetti code for the spaghetti control circuit
- Code will be split into multiple files some day.
- TODO:
- Calibrate lines
- Finish client side software
- Some HW fixes
- 07062012 - odinhg/sacio
- \** **/
- #define F_CPU 8000000
- #define PUMP_PORT PORTB
- #define PUMP_DDR DDRB
- #define PUMP_0 PINB0
- #define PUMP_1 PINB1
- #define PUMP_2 PINB2
- #define PUMP_3 PINB3
- #define PUMP_4 PINB4
- #define PUMP_5 PINB5
- #define VALVE_PORT PORTC
- #define VALVE_DDR DDRC
- #define VALVE_0 PINC0
- #define VALVE_1 PINC1
- #define VALVE_2 PINC2
- #define VALVE_3 PINC3
- #define VALVE_4 PINC4
- #define VALVE_5 PINC5
- #define LED_PORT PORTD
- #define LED_DDR DDRD
- #define LED_RED PIND6
- #define LED_GREEN PIND5
- #define LED_BLUE PIND7
- #define IRCHANNEL ADCH6
- #define IR_LOW 198
- #define IR_HIGH 210
- #define ON 1
- #define OFF 0
- #define ST_IDLE 0 //Idle state
- #define ST_DETCUP 1 //Cup detected
- #define ST_FILL 2 //Fill cup
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <util/delay.h>
- void configureIO(void);
- void controlValve(uint8_t valve, uint8_t value);
- void controlPump(uint8_t pump, uint8_t value);
- uint8_t readIR(void);
- volatile uint8_t pwm_red, pwm_green, pwm_blue;
- volatile uint8_t pwm_counter;
- const uint8_t sine_wave[256] = {
- 0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
- 0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
- 0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
- 0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
- 0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
- 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
- 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
- 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
- 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
- 0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
- 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
- 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
- 0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
- 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
- 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
- 0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
- 0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
- 0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
- 0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
- 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
- 0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
- 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
- 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
- 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
- 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
- 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
- 0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
- 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
- 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
- 0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
- };
- int main(){
- configureIO();
- uint8_t r,g,b; //Sine fading colors
- r=0;
- g=90;
- b=192;
- uint8_t state = ST_IDLE; //Holds machine state
- uint8_t ratios[6]; //Hold mixing ratios
- uint16_t counter; //Counts amount of time used for filling
- while(1){
- switch(state){
- case ST_IDLE:
- //Just idling around
- if(readIR()>IR_HIGH) //Check for cup
- state = ST_DETCUP; //If cup, go to "detected cup" state
- //Fade leds
- pwm_red = sine_wave[r++];
- pwm_green = sine_wave[g++];
- pwm_blue = sine_wave[b++];
- _delay_ms(10);
- break;
- case ST_DETCUP:
- //Cup detected, cyan light
- pwm_red = 0;
- pwm_green = 255;
- pwm_blue = 255;
- //Wait for filling ratios
- while((UCSR0A &(1<<RXC0))==0){
- if(readIR()<IR_LOW){ //Check for cup
- state = ST_IDLE; //If no cup, go to "idle" state
- break;
- }
- state = ST_FILL;
- }
- break;
- case ST_FILL:
- //Filling in progress, red light
- pwm_red = 255;
- pwm_green = 0;
- pwm_blue = 0;
- //Get mixing ratios for each tank
- for(uint8_t i=0; i<6; i++){
- while((UCSR0A &(1<<RXC0))==0);
- ratios[i] = UDR0;
- }
- //Run each line
- for(uint8_t i=0; i<6; i++){
- //Skip if not used in recipe
- if(!ratios[0]<=0){
- //Turn on line
- controlValve(i, ON);
- controlPump(i, ON);
- //Reset counter
- counter = 0;
- //Wait until filling is done, abort if cup is removed
- while(counter++<ratios[i]){
- if(readIR()<IR_LOW){//Check for cup
- break;
- }
- _delay_ms(100);
- }
- //Turn off line
- controlValve(i, OFF);
- controlPump(i, OFF);
- }
- }
- //Go back to idle state
- state = ST_IDLE;
- break;
- default:
- break;
- }
- //UART - DEBUG CODE
- /*char itoaBuff[3];//itoa buffer
- itoa(readIR(), itoaBuff, 10); //adc reading to ascii
- for(int i=0; i<(sizeof(itoaBuff)/sizeof(char));i++){ //loop all chars
- while (!(UCSR0A & (1 <<UDRE0)));
- UDR0 = itoaBuff[i];//send to uart
- }
- _delay_ms(500);*/
- }
- return 0;
- }
- void configureIO(void){
- //Set outputs
- PUMP_DDR |= (1<<PUMP_0) | (1<<PUMP_1) | (1<<PUMP_2) |
- (1<<PUMP_3) | (1<<PUMP_4) | (1<<PUMP_5);
- VALVE_DDR |= (1<<VALVE_0) | (1<<VALVE_1) | (1<<VALVE_2) |
- (1<<VALVE_3) | (1<<VALVE_4) | (1<<VALVE_5);
- LED_DDR |= (1<<LED_RED) | (1<<LED_GREEN) | (1<<LED_BLUE);
- //LED PWM timer setup
- TCCR0A |= (1<<WGM01); //Setup timer 0 in CTC mode
- TCCR0B |= (1<<CS00) | (1<<CS01); //Set /64 prescaler
- TIMSK0 |= (1<<OCIE0A); //Enable timer overflow interrupt
- OCR0A = 0x04;
- //Setup IR ADC
- ADMUX |= (1<<REFS1) | (1<<REFS0) | (1<<MUX1) |
- (1<<MUX2) | (1<<ADLAR); //1.1V as ref, ADC channel 6, left adjust
- ADCSRA |= (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0); //Enable
- //Setup UART
- UCSR0B |= (1<<RXEN0) | (1<<TXEN0); //Enable RX/TX
- UCSR0C |= (1<<UCSZ00) | (1<<UCSZ01); //8bit data
- UBRR0L = 0x33; //9600 baud @ 8Mhz
- sei(); //Enable interrupts globally
- }
- void controlValve(uint8_t valve, uint8_t value){
- if(value == ON){
- VALVE_PORT |= (1<<valve);
- }else{
- VALVE_PORT &= ~(1<<valve);
- }
- }
- void controlPump(uint8_t pump, uint8_t value){
- if(value == ON){
- PUMP_PORT |= (1<<pump);
- }else{
- PUMP_PORT &= ~(1<<pump);
- }
- }
- uint8_t readIR(void){
- /*uint16_t buffer = 0;
- uint8_t i;
- for(i=0; i<10; i++){
- ADCSRA |= (1<<ADSC); //Read ADC 6
- while (ADCSRA & (1<<ADSC));
- buffer += ADCH;
- _delay_ms(10);
- }
- return buffer/10; //Return 8bit value
- */
- ADCSRA |= (1<<ADSC); //Read ADC 6
- while (ADCSRA & (1<<ADSC));
- return ADCH;
- }
- ISR(TIMER0_COMPA_vect){
- pwm_counter++;
- if(pwm_counter<pwm_red){
- LED_PORT |= (1<<LED_RED);
- }else{
- LED_PORT &= ~(1<<LED_RED);
- }
- if(pwm_counter<pwm_green){
- LED_PORT |= (1<<LED_GREEN);
- }else{
- LED_PORT &= ~(1<<LED_GREEN);
- }
- if(pwm_counter<pwm_blue){
- LED_PORT |= (1<<LED_BLUE);
- }else{
- LED_PORT &= ~(1<<LED_BLUE);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement