当红外对管下面是黑色时由于黑色反光很弱,因此通过Q1的电流非常小,因此LM358的2脚的电压会接近
电源电压,并且大于3脚的参考电压,此时LM358输出低电平,反之亦然。因此可以用单片机捕获这个电平变化。
1. 参考程序
We have used twolibrary, they are Servo and LiquidCrystal, we will upload Servo or you cansearch it on google, because we downloadit from internet.
#include
#include
#include
#define BIT(x)(1<<(x))
Servomyservo; // create servoobject to control a servo
int key =4; // key's pin
int motor =5; // motor's pin
intsliding_block = 2;
int servo =9;
int degree =100; // servo degree
float game_
time= 0; // game's time
volatileunsigned int delay_counter = 0; // tomydelay()
booleangame_over = true;
boolean reset =true;
LiquidCrystallcd(0);
void int0_init() // get sliding_block's data
{
DDRD &=~BIT(2);
PORTD |= BIT(2);
EICRA &=~BIT(1);
EICRA |= BIT(0);
EIFR |= BIT(0); // clear flag
EIMSK &=~BIT(0);
}
voidtimer0_init() // controlmotor
{
OCR0A = 100;
OCR0B = 10;
TCCR0A |= BIT(COM0A0) | BIT(COM0B1) | BIT(WGM01)| BIT(WGM00);
TCCR0B |= BIT(WGM02) | BIT(CS00);
}
voidtimer2_init() // tomydelay(), because it seems like delay() can't be interrupted by otherinterrupt such as INT0
{
TCCR2A = 0;
TCCR2B = BIT(CS22) + BIT(CS21) +BIT(CS20); // 1024 divide
TCNT2 = 99; //10ms
TIMSK2 &= ~BIT(TOIE2);
}
void lcd_init()
{
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print(" press key! ");
lcd.setBacklight(HIGH);
}
void setup()
{
myservo.attach(servo); // attaches the servo on pin 9 to theservo object
pinMode(motor, OUTPUT);
timer0_init(); //motor
pinMode(key, INPUT);
pinMode(13, OUTPUT); //LED
digitalWrite(13, LOW);
timer2_init(); //mydelay
pinMode(sliding_block, INPUT);
int0_init(); //sliding_block
lcd_init();
sei();
}
voidmydelay(unsigned int x, void (*fun)(void)) //min=10ms
{
unsigned int time_count = x/10;
volatile unsigned int comp_count =delay_counter + time_count; //comp_count and delay_counter must is a volatilevariable
TIMSK2 |= (1<
while(delay_counter < comp_count){ //in order to notwaste CPU, you can execute your function in this loop
if(0 != fun)
fun();
}
TIMSK2 &=~(1<
}
voidlcd_display(void)
{
lcd.setCursor(6, 1);
lcd.print(game_time);
}
void loop()
{
static int key_time = 0;
if(!game_over){
if(!digitalRead(key)){
if(key_time < 2)
degree = 140;
else
degree = 100;
key_time++;
}
else{
degree = 100;
key_time = 0;
}
myservo.write(degree); // sets the servo positionaccording to the scaled value g
if(degree > 120){
mydelay(80, lcd_display);
game_time += 0.1;
mydelay(80, lcd_display);
game_time += 0.1;
}
else{
game_time += 0.1;
mydelay(80, lcd_display); // waits for theservo to get there
}
}else{
if(!reset){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Game Over ");
lcd.setCursor(5, 1);
lcd.print(game_time);
mydelay(3000, 0);
}
reset = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" press key! ");
while(digitalRead(key)){
myservo.write(degree); // sets the servo positionaccording to the scaled value
mydelay(32, 0); // waits for theservo to get there
OCR0B = 10;
}
mydelay(64, 0);
while(!digitalRead(key));
lcd.clear();
lcd.setCursor(8, 0);
lcd.print("2");
mydelay(1000, 0);
lcd.clear();
lcd.setCursor(8, 0);
lcd.print("1");
mydelay(1000, 0);
lcd.clear();
lcd.setCursor(7, 0);
lcd.print("go");
game_over = false;
game_time = 0;
OCR0B = 60;
EIFR|= BIT(0);
EIMSK |= BIT(0); //enable extern interrupt 0
}
}
ISR(INT0_vect)
{
EIMSK &=~BIT(0);
OCR0B = 10;
game_over = true;
TIMSK1 &=~BIT(TOIE1);
}
ISR(TIMER2_OVF_vect)
{
TCNT2 = 99; //10ms
delay_counter++;
}