alain_haerri
Published

Kinetic little rain

100 little glass drops moving up and down

AdvancedShowcase (no instructions)2,251
Kinetic little rain

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
pololu tic T500
×1
JK35HS34-1004 Jkongmotor
×100
Microswitch, IP67
Microswitch, IP67
×100
Tic Stepper Motor Controllers
×100

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

connecting the Tic 500 poll

Code

code Kinetic rain

C/C++
//#include <Tic.h>// pas besoin de cette bibliotheque , car je gère l'écriture des bytes moi-même

#ifdef SERIAL_PORT_HARDWARE_OPEN
#define ticSerial SERIAL_PORT_HARDWARE_OPEN
#else
#include <SoftwareSerial.h>
SoftwareSerial Serial1(18, 19); //pour arduino 2560 18 tx sur arduino (transmet)  pour rx (reçois)sur le tic
#endif


#define swap(a,b){int t=a;a=b;b=t;}//utilisé pour dessiner une ligne
//TicSerial tic1000(ticSerial, 1000); pas besoin de créer un objet de ce type car je n'utilise plus la bibliotheque tic.h

// numéro des commandes utilisées
uint8_t haltandsetposition=0xEC;
uint8_t setmaxspeed=0xE6;
uint8_t settargetposition=0xE0;
uint8_t setmaxacceleration=0xEA;
uint8_t setmaxdecceleration=0xE9;
//uint8_t setstepmode=0x94;//0 =full;1=1/2, 2=1/4,  3=1/8
//*******************
float target[100];
float targetpreced[100];
float targetprochain[100];
float grandeurtrajet[100];
unsigned long tabtiming[100];
bool tabmontil[100];
float targetpossup[100];
float targetposinf[100];

float trajetleplusgrand=0;
float vitesselaplusgrande=0;
float frax=0.3; // c'est la fraction du temps pour faire le trajet pendant laquelle ça acceélere ou decellere
float ac=10000;// acceleration
int  nummoteur=0;
float vitessemax=10000000;
float d=0;
float d2=0;
float v=0;// vitesse
float tempsdutrajet=1;// est aussi defini par le bluetooth en envoyant depuis le natel t=2.5#
float alpha=0;
float alphaincr=0.3;// est aussi defini par le bluetooth en envoyant depuis le natel a=0.4#
float beta=0;
float betaincr=0.1;
float gamma=0;
float gammaincr=0.1;
bool count=true;
bool count2=true;
unsigned long t;
unsigned long tprecedent;
int laps1;
int laps2;
int incr=0;

float tinter=0;
float tinter2=0;

int endroit=4000;
float parametre=0.1;

int nbrdefois=0;
int dernieregoutte=0;
int tempspourremonter=10;
unsigned long longueuronde=20;
//*******************
// pour le bluetooth
String msg="";

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing
char messageFromPC[numChars] = {0};// variables to hold the parsed data
String messagerecu="";
float integer0FromPC = 0;

boolean newData = false;






// dans l'app pololu mettre max accelartion à 1000000(1 milion, c'est super réactif); mais c'est tres saccadé préféré 200000
// idéalement il faudrait calculé le temps exact avec l'acceleration 

// et votesse max à 100000000 ( 100 milion)
void setup()
{
  Serial.begin(115200);// pour le moniteur
  Serial1.begin(115385);// serial1 permet d'écrire les bytes dans les moteurs
  Serial2.begin(9600); //pour le bluetooth pin 16 17


  // Give the Tic some time to start up.
  delay(20);

  // Set the Tic's current position to 0, so that when we command
  // it to move later, it will move a predictable amount.
  //  // Tells the Tic that it is OK to start driving the motor.  The
//  // Tic's safe-start feature helps avoid unexpected, accidental
//  // movement of the motor: if an error happens, the Tic will not
//  // drive the motor again until it receives the Exit Safe Start
//  // command.  The safe-start feature can be disbled in the Tic


 for (int i=0;i<100;i++){
  moteurplus(i,haltandsetposition,0);//haltandsetposition avec plus de 127 moteurs
 exitsafedebut(i);//exitsafestart avec plus de 127 moteurs, si il y a une coupure de courant par exemple le moteur ne redemarre pas sauf si on utilie cette commande ou si dans
 // dans le controlleur Tic on mette Disable safe start
   }


 }


 






void loop()
{

if (count==true){
  count=false;

remonteretmettreazero(20);// attendre 23 secondes
}



courbe();
vaguepastoute();

dessincourbe(15,6,6,2999);// numéro de la courbe et temps du trajet en seconde et temps d'arret et parametre    // cercle 
dessincourbe(15,6,6,-2999);// numéro de la courbe et temps du trajet en seconde et temps d'arret et parametre    //cercle inversé
dessincourbe(15,6,6,2999);// numéro de la courbe et temps du trajet en seconde et temps d'arret et parametre    //cercle
dessincourbe(15,6,6,-2999);// numéro de la courbe et temps du trajet en seconde et temps d'arret et parametre    //cercle inversé
dessincourbe(14,6,6,0);// on remonte à zero tous en même tempsnuméro de la courbe et temps du trajet et temps d'arret et parametre  // remonte tous
remonteretmettreazero(2); // mettre à zero

chute();
vague();
sinus();


remonteretmettreazero(23);
//chenille();

//testmoteur(5000,0,0);
//testmoteur(5000,0,1);



controlbluetooth()  ; // ceci fonctionne si on veut recevoir dans une variable ce ui arrive du natel format : texte=12#



}



/////////////*******************************************************************************

void testmoteur(int targetpos, int x,int y)

{

  for (int x=0;x<1;x++){
    for (int y=0;y<10;y++){
  nummoteur=x*10+y;
   moteurplus(nummoteur,setmaxspeed,90000000);//
    moteurplus(nummoteur,setmaxacceleration,1000000);
 moteurplus(nummoteur,setmaxdecceleration,100000); 
  moteurplus(nummoteur,settargetposition,targetpos);
    }}
delay(targetpos);
  
  for (int x=1;x<2;x++){
    for (int y=0;y<10;y++){
  nummoteur=x*10+y;
   moteurplus(nummoteur,setmaxspeed,90000000);//
    moteurplus(nummoteur,setmaxacceleration,1000000);
 moteurplus(nummoteur,setmaxdecceleration,100000); 
  moteurplus(nummoteur,settargetposition,targetpos);
    }}
delay(targetpos);

for (int x=0;x<1;x++){
    for (int y=0;y<10;y++){
  nummoteur=x*10+y;
 moteurplus(nummoteur,settargetposition,0);
    }}
delay(targetpos);

 for (int x=1;x<2;x++){
    for (int y=0;y<10;y++){
  nummoteur=x*10+y;
 moteurplus(nummoteur,settargetposition,0);
    }}
delay(targetpos);

}
/////////////*******************************************************************************

void positionmoteur(int targetpos)
{
// 1000 =15 cm en 1/4 de step ou 30 cm en 1/2 step
//4000=60cm
//8000=120cm
if(targetpos>8000){targetpos=8000;}

  for (int x=0;x<10;x++){
    for (int y=0;y<10;y++){
  nummoteur=x*10+y;
   moteurplus(nummoteur,setmaxspeed,10000000);//
    moteurplus(nummoteur,setmaxacceleration,100000);
 moteurplus(nummoteur,setmaxdecceleration,10000); 
 delay(1);
  moteurplus(nummoteur,settargetposition,targetpos);

}}



}

/////////////*******************************************************************************


void remonteretmettreazero(int delai)//delai en seconde
{

 for (int i=0;i<100;i++){
 moteurplus(i,setmaxspeed,8000000);//9000000 
 moteurplus(i,setmaxacceleration,100000);
 moteurplus(i,setmaxdecceleration,100000); 
 moteurplus(i,settargetposition,-23000);
   }
   
//delaiavecbluetooth(23000);
delay(delai*1000);
for (int i=0;i<100;i++){
  moteurplus(i,haltandsetposition,0);
  exitsafedebut(i);
  setstepmode(i,2);////0 =full;1=1/2, 2=1/4,  3=1/8
  targetpreced[i]=0;

}

}
/////////////*******************************************************************************

void courbe()
{

//
dessincourbe(1,4.3,4.2,0);// numéro de la courbe et temps du trajet en seconde et temps d'arret et parametre    // x2-y2
dessincourbe(2,4,3.8,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre              //-(x2-y2)

dessincourbe(5,5,4.9,0);//numéro de la courbe et temps du trajet et temps d'arret et parametre           // sin(x/3)*sin(y/3)
dessincourbe(6,5,4.9,0);//numéro de la courbe et temps du trajet et temps d'arret et parametre            // // sin(x/3)*cos(y/3)
dessincourbe(7,5,4.9,0);//numéro de la courbe et temps du trajet et temps d'arret et parametre           // cos(x/3)*cos(y/3)

dessincourbe(10,2.5,2.4,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre         // x*y // vol oiseau
dessincourbe(11,2.5,2.4,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre        //-(x*y)
dessincourbe(10,2.5,2.4,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre         // x*y
dessincourbe(11,2.5,2.4,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre        //-(x*y)
dessincourbe(12,3,2.8,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre         // -(x2+y2-2xy)
dessincourbe(13,3,2.8,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre        //x2+y2-2xy
dessincourbe(12,3,2.8,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre         // -(x2+y2-2xy)
dessincourbe(13,3,2.8,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre        //x2+y2-2xy// fin vol oiseau

dessincourbe(3,5,4,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre            // x2+y2//  bond et rebond
dessincourbe(4,3,2.8,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre          // -(x2+y2)
dessincourbe(3,3,2.8,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre         // x2+y2
dessincourbe(4,3,2.8,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre          // -(x2+y2)
dessincourbe(3,3,3,0);// numéro de la courbe et temps du trajet et temps d'arret et parametre         // x2+y2   /fin de bon et rebond

///////*************************** courbe 8
  parametre=0.1;
dessincourbe(8,5,5,parametre); // numéro de la courbe et temps du trajet et temps d'arret et parametre // sin(x+y+parametre/3)
for (int i=0;i<50;i++){
  parametre=parametre+0.5;
dessincourbe(8,0.8,0.3,parametre);//numéro de la courbe et temps du trajet et temps d'arret et parametre
//ici de délai d'attente est 0 car le temps de calcul est suffisant entre chaque intrscution donnée toutes les 0.05 sec
}

///////***************************courbe 9

  parametre=0.1;
dessincourbe(9,5,8,parametre);// numéro de la courbe et temps du trajet et temps d'arret et parametre // sin(x+parametre/)+sin(y+parametre/)+
for (int i=0;i<50;i++){
  parametre=parametre+0.5;
dessincourbe(9,0.8,0.3,parametre);//numéro de la courbe et temps du trajet et temps d'arret et parametre

//ici de délai d'attente est 0 car le temps de calcul est suffisant entre chaque intrscution donnée toutes les 0.01 sec
//positionmoteur(5000);// 1000 =15 cm en 1/4 de step // 1000 =15 cm en 1/4 de step ou 30 cm en 1/2 step//4000=60cm//8000=120cm
}

///////*************************** courbe 14 on remonte tout
dessincourbe(14,6,6,0);// on remonte à zero tous en même tempsnuméro de la courbe et temps du trajet et temps d'arret et parametre 

remonteretmettreazero(2);

}// fin de courbe


/////////////*******************************************************************************
void dessincourbe(int numerodessin,  float temps, float tempsdelai,float parametre)
{

//calcul de la prochaine position
float kapa=0;//pour le dessin no 15
  
 for (int x=0;x<10;x++){
    for ( int y=0;y<10;y++){
      nummoteur=x*10+y;

if(numerodessin==1){
    target[nummoteur]=3000-60*((x-5)*(x-5)-(y-5)*(y-5));// donc un trajet au max de 1000=15cm; 2000=30cm
}

if(numerodessin==2){
    target[nummoteur]=5000+60*((x-5)*(x-5)-(y-5)*(y-5));// donc un trajet au max de 1000=15cm; 2000=30cm
   }
if(numerodessin==3){
    target[nummoteur]=3500-70*((x-5)*(x-5)+(y-5)*(y-5));// donc un trajet au max de 1000=15cm; 2000=30cm
}

if(numerodessin==4){
    target[nummoteur]=4500+70*((x-5)*(x-5)+(y-5)*(y-5));// donc un trajet au max de 1000=15cm; 2000=30cm
   }
   
if(numerodessin==5){
  float t=x-5;
  float u=y-5;
    target[nummoteur]=4000+2000*sin(t/3)*sin(u/3);// donc un trajet au max de 1000=15cm; 2000=30cm
   }
   
if(numerodessin==6){
  float t=x-5;
  float u=y-5;
    target[nummoteur]=4000+2000*cos(t/3)*sin(u/3);// donc un trajet au max de 1000=15cm; 2000=30cm
   }
   
   if(numerodessin==7){
  float t=x-5;
  float u=y-5;
    target[nummoteur]=4000+2000*cos(t/3)*cos(u/3);// donc un trajet au max de 1000=15cm; 2000=30cm
   }

   if(numerodessin==8){
  float t=x-5;
  float u=y-5;
    target[nummoteur]=4000+2000*sin((t+u+parametre)/3);// donc un trajet au max de 1000=15cm; 2000=30cm
   }

   if(numerodessin==9){
  float t=x-5;
  float u=y-5;
    target[nummoteur]=4000+1500*(sin((t+parametre)/2)+sin((u+parametre)/2));// donc un trajet au max de 1000=15cm; 2000=30cm
   }

  if(numerodessin==10){
  float t=x-5;
  float u=y-5;
    target[nummoteur]=4000+100*t*u;// donc un trajet au max de 1000=15cm; 2000=30cm
   }
  if(numerodessin==11){
  float t=x-5;
  float u=y-5;
    target[nummoteur]=5000-100*t*u;// donc un trajet au max de 1000=15cm; 2000=30cm
   }
  if(numerodessin==12){
  float t=x-5;
  float u=y-5;
    target[nummoteur]=5000-40*(t*t+u*u-2*t*u);// donc un trajet au max de 1000=15cm; 2000=30cm
   }
  if(numerodessin==13){
  float t=x-5;
  float u=y-5;
    target[nummoteur]=4000+40*(t*t+u*u-2*t*u);// donc un trajet au max de 1000=15cm; 2000=30cm
   }

 if(numerodessin==14){// on remonte à 0 en même temps
  target[nummoteur]=0;
   }


if(numerodessin==15){
    target[nummoteur]=3000+parametre*sin(kapa);// donc un trajet au max de 1000=15cm; 2000=30cm// cercle
    kapa=kapa+0.31415;
   
}



   

if(target[nummoteur]>8000){target[nummoteur]=8000;}//pour ne pas aller trop bas

grandeurtrajet[nummoteur]=abs(target[nummoteur]-targetpreced[nummoteur]);
}}



//calcul de la vitesse pour y arriver tous en même temps
for (int i=0;i<100;i++){
calculvitesseetacc (temps,grandeurtrajet[i], 0.15);

moteurplus(i,setmaxspeed,v); 
moteurplus(i,setmaxacceleration,ac);
moteurplus(i,setmaxdecceleration,ac); 
 delayMicroseconds(10);
//nepas mettre ici  moteurplus(i,settargetposition,target[i]); car le delay de 10ms fait qu'il y a un petit decalage dans les gouttes
}


for (int i=0;i<100;i++){
moteurplus(i,settargetposition,target[i]);
targetpreced[i]=target[i];
//delay(2);// voir si vrament utile
}

delay(tempsdelai*1000);
//delaiavecbluetooth(tempsdelai*1000); ne fonctionne pas bien les gouttes desscendent trop bas




}





/////////////*******************************************************************************
void sinus()

{
//1 pulse/seconde= vitesse 10000
// pour faire un tour il faut 200 pulse en full, 800 en 1/4
// 1 tour de poulie environ 12 cm donc 800 pulse , 24 cm =1600 pulse
 unsigned long dureeprogrammedepart=0;
 
 tempsdutrajet=0.5;  // est donné par le bluetooth t=1.5#    pas descendre en dessous de 0.5 secondes sinon accout pour de long trajet
 alpha=0;
 beta=0;
 alphaincr=0.1;//des increment plus grand que 0.3 font des décalages entre les moteurs
 betaincr=0.1;
 gammaincr=0.2;
 frax=0.40;// c'est à dire 40% dutrajet en acceleration; 20% en vitesse constante et40% en deceleration, maximum c'est 0.5
// en fait pour de court trajet genre sinus (alpha =alpha+01, il faut mettre frax au minimum=0.001
//ça marche bien avec 0.2 et un délai plus court entre chaque salve de commande
// a= Path/(t au carré *frax*(1-frax))
// a*t*frax=v



if (count2==true){
  count2=false;
//pour amener les gouttes au bon endroit avant de lancer sinus
    for (int x=0;x<10;x++){
    for (int y=0;y<10;y++){
  nummoteur=x*10+y;
   moteurplus(nummoteur,setmaxspeed,9000000);//
    moteurplus(nummoteur,setmaxacceleration,100000);
 moteurplus(nummoteur,setmaxdecceleration,100000); 
  
target[nummoteur]=4000+3000*sin(alpha+x*betaincr+y*0.2);// donc un trajet au max de 1600+1550=3150/800=3.9X12cm=47cm

if(target[nummoteur]>8000){target[nummoteur]=8000;}//pour ne pas aller trop bas
  
  moteurplus(nummoteur,settargetposition,target[nummoteur]);
targetpreced[nummoteur]=target[nummoteur];
}}
delay(10000);
}


dureeprogrammedepart=millis();

while(millis()<dureeprogrammedepart+120000){// durée de 3 minutes
 Serial.println(millis()/1000);
//calcul de la prochaine position
  for (int x=0;x<10;x++){
    for (int y=0;y<10;y++){
  nummoteur=x*10+y;
  target[nummoteur]=4000+3000*sin(alpha+x*betaincr+y*0.2);// donc un trajet au max de 1000=15cm; 2000=30cm
  //Serial.print("x  :");Serial.print(x);Serial.print("  y  :");Serial.print(y);Serial.print("  target  :");Serial.println( target[nummoteur]);
  if(target[nummoteur]>8000){target[nummoteur]=8000;}//pour ne pas aller trop bas

  grandeurtrajet[nummoteur]=abs(target[nummoteur]-targetpreced[nummoteur]);
  }
}

betaincr=betaincr+0.003;
alpha=alpha+alphaincr;

//calcul de la vitesse pour y arriver tous en même temps
for (int i=0;i<100;i++){

calculvitesseetacc (tempsdutrajet,grandeurtrajet[i], frax);// calcul de la vitesse et de l'accelerationn en fonction du temps du rajet de la longueure du trajet et du % d'acceleration 

moteurplus(i,setmaxspeed,v); 
moteurplus(i,setmaxacceleration,ac);
moteurplus(i,setmaxdecceleration,ac); 
moteurplus(i,settargetposition,target[i]);
targetpreced[i]=target[i];
delayMicroseconds(1000);
 
}


d2=(tempsdutrajet)*1000;
incr=incr+1;
t=millis();
laps1=t-tprecedent;// temps entre deux série d'envoi de commande (pour les 100 moteurs)sur les tics
tprecedent=t;
// idélalement laps1 devrait être égale au tempsdutrajet , mais ça ne l'est pas car le fait de mettre un délai=au tempsdutrajet s'ajoute encore le temps ppur executer toutes les instrcution
// donc il faut diminuer le délai
if(incr==2){// avant j'avais mis 3 mais ça fait buger les moteurs ????????
  laps2=laps1;
 laps2=laps2-(tempsdutrajet)*600; // 700 au lieu de 1000 pour prndre le 70% de la durée du trajet
 
 if(laps2>d2){laps2=d2;}
}
delay(d2-laps2);

}
 remonteretmettreazero(20);
}

/////////////*******************************************************************************


void vague()
{ 
  
float targetinf=4000;
float targetsup=1000;

 unsigned long tempsdepart=0;// timing de l'arduino au début, il faut un unsigned long sinon millis ne fonctionne pas correctement
    
 unsigned long temps=0;//  en ms la première salve de gouttes partent au bout de 0 secondes
 unsigned long tempsentregoutte=200; //en ms , pas moins de 100ms 200 pose des problèmes
 unsigned long longueuronde=15; // demi longueure d'onde en goutte d'eau du prochain minimum
// tempsdutrajet=longueuronde*tempsentregoutte/1000;//tempsdutrajet en seconde
int aa=1;
int bb=0; //utiliser avec modulo
int cc=1;
int dd=0;
alpha=0;
alphaincr=0.04;
beta=0;
betaincr=0.01;
int nummoteur2=0;

   // assignation de départ des gouttes
  for (int x=0;x<10;x++){
    for (int y=0;y<10;y++){
        assignationdepart(x,y,temps,4000,1000,true);// x,y,temps, targetinf, targetsup, on commence par monter? true ou false
   }
  temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms
  }
  // fin d'assignation de départ des gouttes
nbrdefois=4;


positionmoteur(targetinf);
delay(7000);


tempsdepart=millis();// on prend le temps du départ

while(aa<8){

  for (int i=0;i<100;i++){// on boucle pour chaque goutte, mais au moment de la première goutte on change au bout d'un moment certain parametre


if(millis()-tempsdepart>tabtiming[i]){ // faire comme ça plutôte que :if (millis()>tempsdepart+tabtiming[i] )   pour que l'équation soit moins longue à traiter 

// si on veut changer la longueure d'onde en cours de route il faut recalculer le temps du trajet , la vitesse et l'acceleration
// le passage à une autre longueure d'onde ne se fait que lorsque on recommence avec la première gouttequi avait démarer ici c'est la 0
    
if(i==0){ dd=dd+1;

 if((dd==nbrdefois)&&(aa==1)){longueuronde=20;aa=2;dd=0;nbrdefois=2;}// 
    
 if((dd==nbrdefois)&&(aa==2)){longueuronde=15;aa=3;dd=0;nbrdefois=4;// croisement de la moitié
     for (int yy=0;yy<5;yy++){
      for (int xx=0;xx<10;xx++){
      nummoteur2=xx*10+yy;
     
 if(tabmontil[nummoteur2]==true){
     tabmontil[nummoteur2]=false;}
     else{
     tabmontil[nummoteur2]=true;}}}}

 if((dd==nbrdefois)&&(aa==3)){longueuronde=15;aa=4;dd=0;nbrdefois=3;// fin de croisement 
 for (int yy=0;yy<5;yy++){
      for (int xx=0;xx<10;xx++){
      nummoteur2=xx*10+yy;
 if(tabmontil[nummoteur2]==true){
     tabmontil[nummoteur2]=false;}
     else{
     tabmontil[nummoteur2]=true;}}}}
 

 if((dd==nbrdefois)&&(aa==4)){longueuronde=13;aa=5;dd=0;nbrdefois=2;// plus bas
     for (int jj=0;jj<100;jj++){
    targetposinf[jj]=6000;}}
   
if((dd==nbrdefois)&&(aa==5)){longueuronde=16;aa=6;dd=0;nbrdefois=5;// croisememt
     for (int jj=0;jj<100;jj++){
     if(jj%2==0){
     if(tabmontil[jj]==true){
     tabmontil[jj]=false;}
     else{
     tabmontil[jj]=true; }
      }}}
     
if((dd==nbrdefois)&&(aa==6)){longueuronde=16;aa=7;dd=0;nbrdefois=4;// arret croisement     et changer la longueure d'onde la faire plus grande pour que ce soit un peu plus lent 
      for (int jj=0;jj<100;jj++){
      if(jj%2==0){
      if(tabmontil[jj]==true){
      tabmontil[jj]=false;}
      else{
      tabmontil[jj]=true;}} } }

if((dd==nbrdefois)&&(aa==7)){longueuronde=13;aa=8;dd=0;nbrdefois=2; }
//     for (int jj=0;jj<100;jj++){
//    targetposinf[jj]=6000;}}
      
 //if((dd==nbrdefois)&&(aa==7)){longueuronde=16;aa=8;dd=0;nbrdefois=4; 
//        //Serial.println(cc); 
//     if(cc==5){aa=8;}// on fait ce bout 5x  ( ce qui fait qu'on passe 5x4=20x)
//      if(bb%4==0){// on refait ce bout tous les 4x
//        
//      for (int yy=0;yy<10;yy++){
//      for (int xx=0;xx<10;xx++){
//      nummoteur2=xx*10+yy;
//      targetpossup[nummoteur2]=1500+1000*sin(alpha+beta);
//      
//      targetposinf[nummoteur2]=5000;
//      beta=beta+betaincr;
//      }
//      alpha=alpha+alphaincr;}
//    cc=cc+1;
//   
//      }
//      bb=bb+1;
//      }
     
       
}

tempsdutrajet=longueuronde*tempsentregoutte/1000;//tempsdutrajet en seconde
calculvitesseetacc (tempsdutrajet,targetposinf[i]-targetpossup[i], 0.15);// calcul de la vitesse et de l'accelerationn en fonction du temps du rajet de la longueure du trajet et du % d'acceleration 
 tabtiming[i]=tabtiming[i]+tempsdutrajet*1000;// on repart ilfaut mettre cette instruction ici et non pas après l'envoi des commandes de moteurs qui prennent un certain temps du coup certaines gouttes ont du retard


 moteurplus(i,setmaxspeed,v);//
 moteurplus(i,setmaxacceleration,ac);
 moteurplus(i,setmaxdecceleration,ac); 
//delayMicroseconds(1);// pas  variment necessaire
 
if(tabmontil[i]==true){
  moteurplus(i,settargetposition,targetpossup[i]);
  tabmontil[i]=false;
  }

 else{
  moteurplus(i,settargetposition,targetposinf[i]);
  tabmontil[i]=true;}
  
 


}

}


}


remonteretmettreazero(3);
}




/////////////*******************************************************************************


void vaguepastoute()
{ 
float targetinf=4000;
float targetsup=1000;

 unsigned long tempsdepart=0;// timing de l'arduino au début, il faut un unsigned long sinon millis ne fonctionne pas correctement
    
 unsigned long temps=0;//  en ms la première salve de gouttes partent au bout de 0 secondes
 unsigned long tempsentregoutte=200; //en ms , pas moins de 100ms
 //unsigned long longueuronde=20; // demi longueure d'onde en goutte d'eau du prochain minimum 
// tempsdutrajet=longueuronde*tempsentregoutte/1000;//tempsdutrajet en seconde
int aa=1;
int bb=1; 
int cc=1;

int nummoteur2=0;



while(bb<5){

   // assignation de départ des gouttes      // dans les scénaris il faut encore mettre le nbr de fois et la goutte qui est dernière et temps pour remonter à la fin
if(bb==1){scenario1departgoutte();}// nbrdefois=11; dernieregoutte=55; la longieurd'onde peut être modifiée dans le scénario
if(bb==2){scenario2departgoutte();} 
if(bb==3){scenario3departgoutte();}
if(bb==4){scenario4departgoutte(); } 
  // fin d'assignation de départ des gouttes




tempsdepart=millis();// on prend le temps du départ

while(aa<nbrdefois){
  for (int i=0;i<100;i++){// on boucle pour chaque goutte, mais au moment de la première goutte on change au bout d'un moment certain parametre
delayMicroseconds(1);// ça ne fonctionne pas sinon

if(millis()>tempsdepart+tabtiming[i]){

// si on veut changer la longueure d'onde en cours de route il faut recalculer le temps du trajet , la vitesse et l'acceleration
// le passage à une autre longueure d'onde ne se fait que lorsque on recommence avec la première gouttequi avait démarer ici c'est la 0

    
if(i==dernieregoutte){aa=aa+1;//nbrdefois+1

//if(bb==4){//scénario 4 on change le target inf à chaque fois
// for (int y=0;y<10;y++){
//    for (int x=0;x<10;x++){
//     nummoteur=x*10+y;
//  targetpossup[nummoteur]=targetpossup[nummoteur]+y*50;
//   //targetposinf[nummoteur]=targetposinf[nummoteur]-y*50;
//  }}
//}

}// fin de on compte nbr de fois



tempsdutrajet=longueuronde*tempsentregoutte/1000;//tempsdutrajet en seconde
calculvitesseetacc (tempsdutrajet,targetposinf[i]-targetpossup[i], 0.15);// calcul de la vitesse et de l'accelerationn en fonction du temps du rajet de la longueure du trajet et du % d'acceleration 

 moteurplus(i,setmaxspeed,v);//
 moteurplus(i,setmaxacceleration,ac);
 moteurplus(i,setmaxdecceleration,ac); 
delayMicroseconds(10);
 
if(tabmontil[i]==true){
  moteurplus(i,settargetposition,targetpossup[i]);
  tabmontil[i]=false;
  }

 else{
  moteurplus(i,settargetposition,targetposinf[i]);
  tabmontil[i]=true;}
  
  tabtiming[i]=tabtiming[i]+tempsdutrajet*1000;// on repart


}

}

}
bb=bb+1;//scenario suivant
aa=1;

remonteretmettreazero(tempspourremonter);



}

}



 
//*******************************************************************
void chute()
{
 
float targetinf=7000;
float targetsup=0;

 unsigned long tempsdepart=0;// timing de l'arduino au début, il faut un unsigned long sinon millis ne fonctionne pas correctement
    
 unsigned long temps=1000;//  en ms la première salve de gouttes partent au bout de 0 secondes
 unsigned long tempsentregoutte=200; //en ms , pas moins de 100ms
 //unsigned long longueuronde=20; // demi longueure d'onde en goutte d'eau du prochain minimum 
// tempsdutrajet=longueuronde*tempsentregoutte/1000;//tempsdutrajet en seconde
int nbrdefois=1;
int a=0;
int nummoteur=0;
int tabordre[100];
int x1=0;
int x2=0;
int c=0;
//scenario de chute


 for(int ii=0;ii<100; ii++) {
tabordre[ii]=ii;// initilaistation du tableau de l'odre de depart
targetposinf[ii]=targetinf;
targetpossup[ii]=targetsup;
tabmontil[ii]=false;

}


for(long j=0;j<2560;j++){// on mélange le tableau
 x1=random(0,100);
 x2=random(0,100);
c=tabordre[x1];
tabordre[x1]=tabordre[x2];
tabordre[x2]=c;
}



for(int l=0;l<5; l++) {
nummoteur=tabordre[l];
temps=temps+1000;
tabtiming[nummoteur]=temps;}

for(int l=5;l<20; l++) {
nummoteur=tabordre[l];
temps=temps+500;
tabtiming[nummoteur]=temps;}

for(int l=20;l<30; l++) {
nummoteur=tabordre[l];
temps=temps+400;
tabtiming[nummoteur]=temps;}

for(int l=30;l<100; l++) {
nummoteur=tabordre[l];
temps=temps+200;
tabtiming[nummoteur]=temps;}




tempsdepart=millis();// on prend le temps du départ

while(a<1){
  for (int i=0;i<100;i++){// on boucle pour chaque goutte, mais au moment de la première goutte on change au bout d'un moment certain parametre
delayMicroseconds(1);// ça ne fonctionne pas sinon

if(millis()-tempsdepart>tabtiming[i]){   

tempsdutrajet=2;//tempsdutrajet en seconde
calculvitesseetacc (tempsdutrajet,targetposinf[i]-targetpossup[i], 0.15);// calcul de la vitesse et de l'accelerationn en fonction du temps du rajet de la longueure du trajet et du % d'acceleration 

 moteurplus(i,setmaxspeed,v);//
 moteurplus(i,setmaxacceleration,ac);
 moteurplus(i,setmaxdecceleration,ac); 
delayMicroseconds(10);
 
//if(tabmontil[i]==true){
//  moteurplus(i,settargetposition,targetpossup[i]);
//  tabmontil[i]=false;
//  }
//
// else{
  moteurplus(i,settargetposition,targetposinf[i]);
 // tabmontil[i]=true;
 // }
  
//  tabtiming[i]=tabtiming[i]+tempsdutrajet*1000;// on repart

if(i==tabordre[99]){a=1;}// c'est fini au monent ou la dernière goutte est tombée
}

}

}

delay(3000);
//remonteretmettreazero(tempspourremonter);



}









//*************************** commande avec plus que 127 moteurs*******************************
// dans le protocle pour communiquer avec les tic, le premier byte est toujurs complets puis ceux qui viennent après le bi 7 est toujours à 0
// la communciation avec les tics , si on veut utiliser plus que 127 moteurs , il faut d'abord envoyer le premier byte=0xAA, puis tous les autres seront avec le bit 7 à 0
// donc 2 bytes pour le numéro du device (bi7 à0), 1 byte pour le numéro de la commande (avec le bit7=0), puis 5 bytes pour les positions ou vitesse ou acceleration

void moteurplus(int deviceNumber,uint8_t command,int32_t target)
{
//deviceNumber = 1000; //Can be anywhere from 0 to 16383

      
uint8_t deviceNumberLower = deviceNumber & 0x7F;
uint8_t deviceNumberUpper = (deviceNumber >> 7) & 0x7F;

//int32_t target = 200;



uint8_t msb = ((target >> 7) & 1) | ((target >> 14) & 2) | ((target >> 21) & 4) | ((target >> 28) & 8);
uint8_t data1 = (target >> 0) & 0x7F;
uint8_t data2 = (target >> 8) & 0x7F;
uint8_t data3 = (target >> 16) & 0x7F;
uint8_t data4 = (target >> 24) & 0x7F;

//start byte
Serial1.write(0xAA);

//14-bit device number
Serial1.write(deviceNumberLower); 
Serial1.write(deviceNumberUpper);

//0xE0 command byte with MSB cleared // set target position = 0xE0
uint8_t commandmsbclear = command & 0x7F;
Serial1.write(commandmsbclear); 

//data bytes for target position
Serial1.write(msb); 
Serial1.write(data1); 
Serial1.write(data2);
Serial1.write(data3);
Serial1.write(data4);





}
// **********exit safe start**********
void exitsafedebut(int deviceNumber){
uint8_t deviceNumberLower = deviceNumber & 0x7F;
uint8_t deviceNumberUpper = (deviceNumber >> 7) & 0x7F;

//start byte
Serial1.write(0xAA);
//14-bit device number
Serial1.write(deviceNumberLower); 
Serial1.write(deviceNumberUpper);

// command
Serial1.write(0x03);
}

// **********set step mode**********//0 =full;1=1/2, 2=1/4,  3=1/8
void setstepmode(int deviceNumber, int stepmode){
uint8_t deviceNumberLower = deviceNumber & 0x7F;
uint8_t deviceNumberUpper = (deviceNumber >> 7) & 0x7F;

//start byte
Serial1.write(0xAA);
//14-bit device number
Serial1.write(deviceNumberLower); 
Serial1.write(deviceNumberUpper);

// command
Serial1.write(0x94);

// data

Serial1.write(stepmode);

}

//**********************************************************************
void delaiavecbluetooth(unsigned long delai)
{
unsigned long tempsdepart;
tempsdepart=millis();
while(millis()<tempsdepart+delai)
{

controlbluetooth()  ; // ceci fonctionne si on veut recevoir dans une variable ce ui arrive du natel format : texte=12#
}
}




//**********************************************************************
// envoi d'une chaine du natel vers le bluetooth de l'arduino

// pour le module HC-08BLE bluetooth BT05
// VCC sur 5volt de l'arduino
// GND sur GND de l'arduino
// RX du module blutooth va sur le TX2 pin 16 de l'arduino, mais il passe par un pont de ressitance de220 ohms pour transformer le 5v de l'arduino en 3v
// TX du module bluetooth var sur le RX2  pin 17 de l'aeduino
// ne pas oublier d'activer le bluetoth sur le telephone

//le natel envoie une chaine de caractère terminée par #, puis lorsque le # est atteint, il rajoute un '\0' pour terminer la string
// puis il extrait le premier bout de chaine séparé de l'aure par un =
// exemple: "a=101#" s=1# etc  IMPORTANT le bluetoth s'appelle ALAIN si il n'apparait pas sur le natel desactiver le bluetooth et le réactiver

void controlbluetooth(){
 
  byte ndx = 0;
 char rc;
char messageFromPC[numChars] = {0};
 
 while (Serial2.available() > 0 && newData == false)  {

        rc = Serial2.read();
        if (rc != '#') {
        receivedChars[ndx] = rc;
        ndx=ndx+1;
   delay(100);  // si on ne met pas cette attente le while voit qu'il n'y a plus de  Serial2.available() et sort du while   
                
                  if (ndx >= numChars) {
                    ndx = numChars - 1;
                }}
else {
 
                receivedChars[ndx] = '\0'; // terminate the string
       ndx = 0;
       
 newData=true;

 
 }
}


// reçoit "numero=101" et séparation de receivedChars en 2 chaines distinctes messageFromPC et  integer1FromPC: numéro     puis 101

if (newData == true) {
 
char * chaine; // this is used by strtok() dont on ne sait pas à priori la longieur de chaine donc on met un * qui fait que chaine devient un pointeur vers le début de chaine
 strcpy(tempChars, receivedChars);// copie la string receivedChars dans tempChars
 chaine = strtok(tempChars,"=");   //    // obtient la première partie de la string
 strcpy(messageFromPC, chaine); // copy it to messageFromPC
 chaine = strtok(NULL, "");// le Null veut dire qu'on prend toujours tempschars ez qu'on continue a chercher des delimitateurs ici ""
    integer0FromPC = atof(chaine);// trabsforne une chaine de caractere en float



messagerecu=String(messageFromPC);// transforme la chaine de caratcetre reçu en string
Serial.println(messageFromPC);
Serial.println( integer0FromPC);

if(messagerecu=="t"){
tempsdutrajet=integer0FromPC;
tprecedent=0; 
t=0;
laps1=0;
laps2=0; 
incr=0;}

if(messagerecu=="a"){
alphaincr=integer0FromPC;
tprecedent=0; 
t=0;
laps1=0;
laps2=0; 
incr=0;}

if(messagerecu=="s"){
remonteretmettreazero(23);
}



//Serial.println(  tempsdutrajet);
//Serial.println(  alphaincr);

}
newData=false;

}


//***********************************************************************************
//***********************************************************************************
//****  Chenille  ******************
//***********************************************************************************

void chenille(){

int longueurchenille=2;
int xchenille[longueurchenille];
int ychenille[longueurchenille];
int xincrement=1;
int yincrement=1;
int x=0;
int y=0;
float tempstrajetavant=0.5;

for(int k=0;k<longueurchenille;k++){
xchenille[k]=x-k;
ychenille[k]=y-k;}
float target=5000;
  

for(int i=0;i<100;i++){
targetprochain[i]=target;
targetpreced[i]=target;
}

positionmoteur(target);
delay(12000);

xincrement=1;
yincrement=0;
for(int ii=0;ii<1000;ii++){

if(ii%5==0){
xincrement=(random(0,199)%3)-1;
yincrement=(random(0,300)%3)-1;
}


if(((xchenille[0]+xincrement)!=xchenille[0])|((ychenille[0]+yincrement)!=ychenille[0])){
if(((xchenille[0]+xincrement)!=xchenille[1])|((ychenille[0]+yincrement)!=ychenille[1])){




targetprochain[xchenille[0]]=target-1000;

unmoteuracetteposition(xchenille[0], ychenille[0], tempstrajetavant,targetprochain[xchenille[0]], target);// on monte l'avant     unmoteuracetteposition( int x, int y, float tempstrajet, float newtarget, float targetprecedent)

unmoteuracetteposition(xchenille[longueurchenille-1], ychenille[longueurchenille-1], tempstrajetavant+0.5,target,targetpreced[xchenille[longueurchenille-1]]);// on descend l'arrière

targetpreced[xchenille[0]]=targetprochain[xchenille[0]];


for(int i=longueurchenille-1;i>0;i--){// décalage de tous les élements de la chenille
xchenille[i]=xchenille[i-1];
ychenille[i]=ychenille[i-1];
targetpreced[i]=targetpreced[i-1];
}

xchenille[0]=xchenille[0]+xincrement;
ychenille[0]=ychenille[0]+yincrement;

//if(xchenille[0]<0){xchenille[0]=9;}
//if(xchenille[0]>9){xchenille[0]=0;}
//if(ychenille[0]<0){ychenille[0]=9;}
//if(ychenille[0]>9){ychenille[0]=0;}

if(xchenille[0]<0){xchenille[0]=0;}
if(xchenille[0]>9){xchenille[0]=9;}
if(ychenille[0]<0){ychenille[0]=0;}
if(ychenille[0]>9){ychenille[0]=9;}

//if(xchenille[0]>8){xincrement=0;yincrement=1;}
//if(xchenille[0]>9){xchenille[0]=0;}
//if(ychenille[0]<0){ychenille[0]=9;}
//if(ychenille[0]>9){ychenille[0]=0;}

alpha=alpha+alphaincr;
delay(tempstrajetavant*1000/longueurchenille);

}}

}
positionmoteur(target);
delay(12000);

}







//******************************* calcul de la vitesse et de l'acceleration en fonction du temps du trajet de la longieure du trajet et du % d'acceleration


void calculvitesseetacc (float tempstrajet, float longueuretrajet, float fraxacc)
{
  frax=0.15;// c'est à dire 20% dutrajet en acceleration; 60% en vitesse constante et 20% en deceleration, maximum c'est 0.5
// en fait pour de court trajet genre sinus (alpha =alpha+01, il faut mettre frax au minimum=0.001
//ça marche bien avec 0.2 et un délai plus court entre chaque salve de commande
// a= Path/(t au carré *frax*(1-frax))
// a*t*frax=v
float tinter=tempstrajet*tempstrajet;
tinter=tinter*fraxacc; 
tinter=tinter*(1-fraxacc);
float tinter2=tempstrajet*fraxacc;

ac=longueuretrajet/tinter;
v=ac*tinter2;
ac=ac*100;
v=v*10000;

}

//*********************************** 1moteuracette position en un temps donné en fonction de la nouvelle positioon et de l'ancienne

void unmoteuracetteposition( int x, int y, float tempstrajet, float newtarget, float targetprecedent)
{

 if((x>-1)&&(x<10)){
  if ((y>-1)&&(y<10)){


calculvitesseetacc(tempstrajet,abs(newtarget-targetprecedent),0.15);
 int nummoteur=x*10+y;
 moteurplus(nummoteur,setmaxspeed,v);//
 moteurplus(nummoteur,setmaxacceleration,ac);
 moteurplus(nummoteur,setmaxdecceleration,ac); 
delayMicroseconds(10);
 moteurplus(nummoteur,settargetposition,newtarget);
}
 }
 }
// ********************************************* assignation départ des timing gouttes
void assignationdepart(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
{
    if((x>=0)&&(x<10)){
      if((y>=0)&&(y<10)){
    nummoteur=x*10+y;
  tabtiming[nummoteur]=temps;
  tabmontil[nummoteur]=monte;// les gouttes vont monter
  targetpossup[nummoteur]=targetsup;
  targetposinf[nummoteur]=targetinf; 
    }}
}
// ***********************************************************************************************
void scenario1departgoutte()

{// assignation de départ des gouttes
 unsigned long temps=0;//  en ms la première salve de gouttes partent au bout de 0 secondes
 unsigned long tempsentregoutte=200; //en ms , pas moins de 100ms
 nbrdefois=7;
 dernieregoutte=55;
 tempspourremonter=8;
 longueuronde=16;
  
 for (int y=0;y<10;y++){
    for (int x=0;x<2;x++){assignationdepart(x,y,temps,4000,1000,false) ;}  //(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
    temps=temps+tempsentregoutte;}// la prochaine salve partira apres tant de ms

 for (int x=2;x<10;x++){
    for (int y=8;y<10;y++){assignationdepart(x,y,temps,4000,1000,false) ;}  //(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
    temps=temps+tempsentregoutte;}// la prochaine salve partira apres tant de ms

 for (int y=7;y>-1;y--){
    for (int x=8;x<10;x++){assignationdepart(x,y,temps,4000,1000,false) ;}  //(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
    temps=temps+tempsentregoutte;}// la prochaine salve partira apres tant de ms

 for (int x=7;x>1;x--){
    for (int y=0;y<2;y++){assignationdepart(x,y,temps,4000,1000,false) ;}  //(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
    temps=temps+tempsentregoutte;}// la prochaine salve partira apres tant de ms


 temps=temps+tempsentregoutte;
  temps=temps+tempsentregoutte;
  temps=temps+tempsentregoutte;// un délai plus long avant que celles du milieu descencent
 for (int y=3;y<7;y++){
    for (int x=3;x<7;x++){assignationdepart(x,y,temps,6000,500,false) ;}  //(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
  }// la prochaine salve partira apres tant de ms
    
  // fin d'assignation de départ des gouttes
}

// ***********************************************************************************************
void scenario2departgoutte()

{// assignation de départ des gouttes
 unsigned long temps=0;//  en ms la première salve de gouttes partent au bout de 0 secondes
 unsigned long tempsentregoutte=800; //en ms , pas moins de 100ms
 nbrdefois=5;
 dernieregoutte=55;
 tempspourremonter=11;
  longueuronde=20;
  
 for (int y=0;y<10;y++){
    assignationdepart(0,y,temps,4000,1000,false) ;//(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
     assignationdepart(9,y,temps,4000,1000,false) ;}  
 for (int x=1;x<9;x++){
    assignationdepart(x,0,temps,4000,1000,false) ;//(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
     assignationdepart(x,9,temps,4000,1000,false) ;}
 temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

 for (int y=1;y<9;y++){
    assignationdepart(1,y,temps,5000,1000,false) ;//(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
     assignationdepart(8,y,temps,5000,1000,false) ;}  
 for (int x=2;x<8;x++){
    assignationdepart(x,1,temps,5000,1000,false) ;//(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
     assignationdepart(x,8,temps,5000,1000,false) ;}
 temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

  for (int y=2;y<8;y++){
    assignationdepart(2,y,temps,6000,1000,false) ;//(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
     assignationdepart(7,y,temps,6000,1000,false) ;}  
 for (int x=3;x<7;x++){
    assignationdepart(x,2,temps,6000,1000,false) ;//(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
     assignationdepart(x,7,temps,6000,1000,false) ;}
 temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

  for (int y=3;y<7;y++){
    assignationdepart(3,y,temps,7000,1000,false) ;//(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
     assignationdepart(6,y,temps,7000,1000,false) ;}  
 for (int x=4;x<6;x++){
    assignationdepart(x,3,temps,7000,1000,false) ;//(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
     assignationdepart(x,6,temps,7000,1000,false) ;}
 temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms
   
   for (int y=4;y<6;y++){
    assignationdepart(4,y,temps,7500,1000,false) ;//(int x, int y, unsigned long temps, float targetinf, float targetsup, bool monte)
     assignationdepart(5,y,temps,7500,1000,false) ;}  
assignationdepart(5,4,temps,7500,1000,false) ;
assignationdepart(5,5,temps,7500,1000,false) ;
 //temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms
    
}

// ***********************************************************************************************
void scenario3departgoutte()

{// assignation de départ des gouttes
 unsigned long temps=0;//  en ms la première salve de gouttes partent au bout de 0 secondes
 unsigned long tempsentregoutte=1000; //en ms , pas moins de 100ms
 
 nbrdefois=5;
 dernieregoutte=45;
 tempspourremonter=8;
 longueuronde=20;
 // drawCircle(int x0, int y0, int r,  unsigned long temps, float targetinf, float targetsup, bool monte)

 drawCircle(5, 5, 4, temps, 4000, 1000, false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms
 drawCircle(5, 5, 3, temps, 4500, 1000, false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms
 drawCircle(5, 5, 2, temps, 5000, 1000, false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms
 drawCircle(5, 5, 1, temps, 5500, 1000, false);




// drawCircle(0, 0, 4, temps, 4000, 1000, false);
//  drawCircle(9, 9, 4, temps, 4000, 1000, false);
//drawCircle(0, 9, 4, temps, 4000, 1000, false);
//  drawCircle(9, 0, 4, temps, 4000, 1000, false);
//temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms
//
// drawCircle(0, 0, 3, temps, 4000, 1000, false);
//  drawCircle(9, 9, 3, temps, 4000, 1000, false);
//drawCircle(0, 9, 3, temps, 4000, 1000, false);
//  drawCircle(9, 0, 3, temps, 4000, 1000, false);
//temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms
//
// drawCircle(0, 0, 2, temps, 4000, 1000, false);
//  drawCircle(9, 9, 2, temps, 4000, 1000, false);
//drawCircle(0, 9, 2, temps, 4000, 1000, false);
//  drawCircle(9, 0, 2, temps, 4000, 1000, false);
//temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms




    
  // fin d'assignation de départ des gouttes
}

// ***********************************************************************************************
void scenario4departgoutte()
//
{// assignation de départ des gouttes
 unsigned long temps=0;//  en ms la première salve de gouttes partent au bout de 0 secondes
 unsigned long tempsentregoutte=200; //en ms , pas moins de 100ms
 nbrdefois=11;
 dernieregoutte=0;
 tempspourremonter=12.5;
  longueuronde=20;
//writeLine(byte x0, byte y0, byte x1, byte y1, unsigned long temps, float targetinf, float targetsup, bool monte)

writeLine (0,0,9,0,temps,4000,2000,false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

writeLine(0,1,9,1,temps,4500,2000,false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

writeLine(0,2,9,2,temps,5000,2000,false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

writeLine(0,3,9,3,temps,5500,2000,false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

writeLine(0,4,9,4,temps,6000,2000,false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

writeLine(0,5,9,5,temps,6500,2000,false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

writeLine(0,6,9,6,temps,7000,2000,false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

writeLine(0,7,9,7,temps,7500,2000,false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

writeLine(0,8,9,8,temps,8000,2000,false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms

writeLine(0,9,9,9,temps,8500,2000,false);
temps=temps+tempsentregoutte;// la prochaine salve partira apres tant de ms



}






// cercle
//*************************************************************************************

// assignation des temps de départ en cercle

void drawCircle(int x0, int y0, int r,  unsigned long temps, float targetinf, float targetsup, bool monte) {
  if(r>0){
    int f = 1 - r;
    int ddF_x = 1;
    int ddF_y = -2 * r;
    int x = 0;
    int y = r;


assignationdepart(x0, y0 + r,temps,targetinf,targetsup,monte);
assignationdepart(x0, y0 - r,temps,targetinf,targetsup,monte);
assignationdepart(x0+r, y0,temps,targetinf,targetsup,monte);
assignationdepart(x0-r, y0,temps,targetinf,targetsup,monte);



    while (x<y) {
        if (f >= 0) {
            y--;
            ddF_y += 2;
            f += ddF_y;
        }
        x++;
        ddF_x += 2;
        f += ddF_x;
assignationdepart(x0, y0 + r,temps,targetinf,targetsup,monte);
        
assignationdepart(x0+x, y0 + y,temps,targetinf,targetsup,monte);
assignationdepart(x0-x, y0 + y,temps,targetinf,targetsup,monte);
assignationdepart(x0+x, y0 - y,temps,targetinf,targetsup,monte);
assignationdepart(x0-x, y0 - y,temps,targetinf,targetsup,monte);
assignationdepart(x0+y, y0 + x,temps,targetinf,targetsup,monte);
assignationdepart(x0-y, y0 + x,temps,targetinf,targetsup,monte);
assignationdepart(x0+y, y0 - x,temps,targetinf,targetsup,monte);
assignationdepart(x0-y, y0 - x,temps,targetinf,targetsup,monte);

    }
  }
}


//**************************************************************************/
/*!
   @brief    Write a line.  Bresenham's algorithm - thx wikpedia
    @param    x0  Start point x coordinate
    @param    y0  Start point y coordinate
    @param    x1  End point x coordinate
    @param    y1  End point y coordinate
    @param    color 16-bit 5-6-5 Color to draw with
*/
//**************************************************************************

void writeLine(int x0, int y0, int x1, int y1, unsigned long temps, float targetinf, float targetsup, bool monte) {


if((x0==x1)or(y0==y1)){

if(y0==y1){// on dessine une ligne horizontale
byte longeur=abs(x1-x0)+1;
for(byte x=0;x<longeur;x++){
   assignationdepart(x+x0, y0,temps,targetinf,targetsup,monte);  }}


else{// on dessine une ligne verticale
    byte longueur=abs(y1-y0)+1;
for(byte y=0; y<longueur; y++){
 
  assignationdepart(x0, y+y0,temps,targetinf,targetsup,monte);}

}

 
}
else{// c'est ni une horizontale ni une verticale
    int steep = abs(y1 - y0) > abs(x1 - x0);
  
    if (steep) {
        swap(x0, y0);
        swap(x1, y1);
    }

    if (x0 > x1) {
        swap(x0, x1);
        swap(y0, y1);
    }

    int dx, dy;
    dx = x1 - x0;
    dy = abs(y1 - y0);

    int err = dx / 2;
    int ystep;

    if (y0 < y1) {
        ystep = 1;
    } else {
        ystep = -1;
    }

    for (; x0<=x1; x0++) {
        if (steep) {
     
         assignationdepart(y0, x0,temps,targetinf,targetsup,monte);

    
        } else {
            
          assignationdepart(x0, y0,temps,targetinf,targetsup,monte);
        
        }
        err -= dy;
        if (err < 0) {
            y0 += ystep;
            err += dx;
        }
    }
}
}

Credits

alain_haerri
2 projects • 18 followers
Contact

Comments

Please log in or sign up to comment.