/** * * Breathe Light * MikroC PIC 16F88 Source Code * * Copyright (C) 2005 Matsuda Shota * http://sgssweb.com/ * sgss@mac.com * * ------------------------------------------------------------------------ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ------------------------------------------------------------------------ * */ #define STARTUP 0 #define INCREASE 1 #define DECREASE 2 #define LIGHT_MINIMUM 20 #define LIGHT_MAXIMUM 255 unsigned int senser_cache; signed int light; unsigned short threshold; unsigned short state; unsigned long timer; /** * main function */ void main() { unsigned int i; signed int speed; unsigned short check_count; /** * initialization */ // set internal clock // 8MHz OSCCON.IRCF2=1; OSCCON.IRCF1=1; OSCCON.IRCF0=1; // set analog input port // A0(AN0) B6(AN5) B7(AN6) ANSEL = 0b01100001; // set input port // A0, B6, B7 TRISA = 0b00000001; TRISB = 0b11000000; // set pwm clock // 5MHz PWM_Init(5000); // set Timer0 interrupt // disable PORTB pull-up // prescaler is Timer0 module clock // prescaler rate is 1/4 OPTION_REG = 0b10000001; // set port // all low PORTA = 0b00000000; PORTB = 0b00000000; /** * start */ // enable Timer0 interruption //INTCON.TMR0IE = 1; //INTCON.GIE = 1; // start pwm PWM_Start(); // initialize senser cache as 0 so that we can recognize it is not cached senser_cache = 0; // light value is minimum by default light = LIGHT_MINIMUM; // read parameters threshold = Adc_Read(5) / 20; timer = Adc_Read(6); // set state startup state = STARTUP; // indicate startup PORTB.F0 = 1; check_count = 0; while(1) { // senser is from 0v to 3.7v, that is 0 to 768 in value. // so, we have to adjust value from 0 to 255. // do processes if senser input below around 3.0v if(senser_cache == 0) { senser_cache = Adc_Read(0); } speed = Adc_Read(0) - senser_cache; senser_cache = Adc_Read(0); switch(state) { case STARTUP: if(speed < -threshold) { check_count = 0; } else { check_count ++; } break; case INCREASE: // if any change in senser if(speed < -threshold) { if(light + 10 > 255) { light = LIGHT_MAXIMUM; } else { if(light < 50) { light += 5; } else if(light < 100) { light += 6; } else if(light < 200) { light += 8; } else { light += 10; } // reset timer for decline mode timer = Adc_Read(6); } } break; case DECREASE: // if any change in senser if(speed < -threshold) { if(light - 20 < LIGHT_MINIMUM) { light = LIGHT_MINIMUM; } else { light -= 20; } } break; } // apply to photo coupler PWM_Change_Duty(light); // state changing switch(state) { case STARTUP: if(check_count > 30) { // change state state = INCREASE; // indicate startup ends PORTB.F0 = 0; } break; case INCREASE: // step timer if light value is set (light is above 10) if(light > 50) { timer --; } if(timer == 0 || light == LIGHT_MAXIMUM) { // change state state = DECREASE; // indicate state change for(i = 0; i < 3; i++) { PORTB.F0 = 1; Delay_ms(125); PORTB.F0 = 0; Delay_ms(125); } // reset cache senser_cache = 0; } break; case DECREASE: if(light == LIGHT_MINIMUM) { // reset timer timer = Adc_Read(6); // change state state = INCREASE; // delay for 2sec so that senser becomes stable Delay_ms(2000); // indicate state change for(i = 0; i < 3; i++) { PORTB.F0 = 1; Delay_ms(125); PORTB.F0 = 0; Delay_ms(125); } // reset cache senser_cache = 0; } break; } Delay_ms(100); } }