#include <conio.h>
#include <dbutton.h>
#include <dsensor.h>
#include <dmotor.h>
#include <dsound.h>
#include <time.h>
#include <sys/tm.h>
#include <rom/system.h>
//quelques vitesses...
#define NORMAL_SPEED (MAX_SPEED)
#define FULL_SPEED (MAX_SPEED)
//les limites lumineuses obtenues apres de fastidieux tests....
#define BLANC_BRILLANT 110
//si on utilise que blanc et noir (et brillant !)
// mettre NOIR_GRIS proche de GRIS_BLANC
#define NOIR_GRIS 79
#define GRIS_BLANC 80
#define GRADFACT 3
int speed=0,dir=0;
int breakTime=7; //en millisecondes
int oscillTime=7; //
int karma=5;
static const note_t melody[] = {
{PITCH_A6,1},{ PITCH_END, 0 }
};
static const note_t lost[] = {
{PITCH_A4,1},{PITCH_G3,1},{PITCH_E3,1},{PITCH_D3,1},{ PITCH_END, 0 }
};
static const note_t dead[] = {
{PITCH_A4,2}, {PITCH_A4,2},{PITCH_A4,1},{PITCH_A4,2}, // ok...
{PITCH_A4,1},{PITCH_G3,1},{PITCH_E3,1},{PITCH_D3,1},
{ PITCH_END, 0 }
};
int noir(int current)
{
if (current<NOIR_GRIS)
return 1;
else
return 0;
}
int brillant(int current)
{
if (current>BLANC_BRILLANT)
return 1;
else
return 0;
}
int blanc(int current)
{
if ( (current>GRIS_BLANC)&&(current<BLANC_BRILLANT))
return 1;
else
return 0;
}
int vitesseGrad(int current, int dir){
//calcul de la vitesse, en fonction du disque colore
//et du capteur1
// "the brighter the faster"
//a priori lineaire....
//
//mais pas necessairement symetrique a l'usage...
if (dir==-1){
speed=GRADFACT * current -70;
if (speed > 120) speed=255;
}
else{
speed=(GRADFACT-1) * current -30;
if (speed > 255) speed=255;
}
return speed;
}
void tunemotor(int speed, int dir)
{//commande moteur
if (dir < 0) {
motor_a_dir(rev);
motor_b_dir(rev);
motor_c_dir(rev);
}
if (dir > 0){
motor_a_dir(fwd);
motor_b_dir(fwd);
motor_c_dir(fwd);
}
//dans tous les cas
motor_a_speed(speed);
motor_b_speed(speed);
motor_c_speed(speed);
}
//-------------------------------
int main()
{
volatile time_t time1,time2;
int speed=0;
int current1=0;
int current3=0;
int preced1=0;
int preced3=0;
int goodwork=0;
ds_active(&SENSOR_3);
ds_active(&SENSOR_1);
sleep(3);
time1=sys_time;
while (1)
{
if ((SENSOR_2<0xf000)){
cputs("oups");
motor_a_speed(0);
motor_b_speed(0);
motor_c_speed(0);
motor_a_dir(off);
motor_b_dir(off);
motor_c_dir(off);
dsound_play(lost);
wait_event(dsound_finished,0);
karma--;
sleep(3);
if (karma < 1) { //game over
cputs("argh");
dsound_play(dead);
wait_event(dsound_finished,0);
break;
}
}
current1=LIGHT_1;
current3=LIGHT_3;
if (brillant(current3))
{
time2=sys_time;
oscillTime=time2-time1;
time1=sys_time;
if ((oscillTime>20)&&(oscillTime<100)) goodwork++;
else goodwork=0;
if (goodwork > 10){
karma++;
lcd_int(karma);
}
//l'idee est ici d'analyser la periode des oscillations blanc noir pour
//declencher le freinage au moment opportun
//sur de petites oscillations, on n'attendra pas bcp
//mais sur de grandes oscill, on freinera plus tard
//car le retour est plus violent a priori
breakTime=oscillTime/10; // breakTime=F(oscillTime)
lcd_int(oscillTime);
msleep(breakTime);
motor_a_dir(off);
motor_b_dir(off);
motor_c_dir(off);
speed=0; //reset smoothly
}
else
{ //adapt speed
if (noir(current3)){
dir=1;
}
else if (blanc(current3)){
dir=-1;
}
//computes
speed=vitesseGrad(current1,dir);
//display
lcd_int(speed);
//react
tunemotor(speed, dir);
//pause
msleep(7);
//and goes for an other
preced1=current1;
preced3=current3;
}
}
return 0;
}