#include <EEPROM.h>
#include "SoftwareSerial.h"
SoftwareSerial BTSerial(10, 11); // RX, TX



int sdcc=13; //DCC sur pin 13

int n=0;
byte octet;
byte octet0=0;
int vitesse=0;
int adresse=3;
int adress;
int ma=1;
int vit;
int f0=0;
int f1=0;
int f2=0;
int f3=0;
int f4=0;
int f5=0;
int f6=0;
int f7=0;
int f8=0;
int f9=0;
int f10=0;
int f11=0;
int f12=0;
int a[10];
int c[10];
int e[10];
int b[10];
int ef[10];
int d[10];
int ed[10];
int aa[10];
int ca[10];
int ea[10];
int g[10];
int eg[10];
long t0=millis();
int i;
int courant;
int courant0=0;
int cs=0;
int mode=0;
int fg1;
int fg2;
int fg;
int aca[10]; // adresse des décodeurs d'accessoires
int acc[10]; //octet de commande des décodeurs d'accessoires
int ace[10]; //octet de controle des décodeurs d'accessoires
int adresseac;
int vacc=0;
int imax=50;
int x;
int p=0;
int vm;
int vm0=0;
int ia;
long v=0;
int vref;
int adac;
String tampon;
String tampon0;
int octet1;
int octet2;
int octet3;
int commande;
int hg;
int fg10=0;
int ps;
int ps0=0;

int d1=0;
int d2=0;
int d3=0;
int d4=0;
int octetr;
int octetr0=0;
int z=0;

const byte NB_CANTONS = 8;

// Broches utilisées
const byte cantonPins[NB_CANTONS] = {
  2, 3, 4, 5, 6, 7, 8, 9
};

bool etatPrecedent[NB_CANTONS];
unsigned long dernierChangement[NB_CANTONS];

const unsigned long DELAI_FILTRAGE = 50;



void setup()
{
 pinMode(sdcc,OUTPUT);//Configuré en sorties
 pinMode(12,OUTPUT);
 digitalWrite(12,LOW);

 BTSerial.begin(9600);
 Serial.begin(9600);  //Serial monitor
 Serial.println("RETROSIGNALISATION 8 CANTONS PRETE");

  for (byte i = 0; i < NB_CANTONS; i++) {
    pinMode(cantonPins[i], INPUT);
    etatPrecedent[i] = false;
    dernierChangement[i] = 0;
  } 

  // initialisation de la mesure du courant
  for (int t=0; t<100; t++)
   {
   x=analogRead(A0);
   v=v+x;
   }
   vref=int(v/100);
   Serial.println(vref);
   v=0;
   delay(2000);
 


 
 
}


void loop()
{

  x=analogRead(A0);

  // détection de coupure
   if (x<vref-imax && cs==0) {
    digitalWrite(12,HIGH) ;
    BTSerial.write(201);

    cs=1;
  }

 
 // reception des commandes du PC


    if (Serial.available() > 0)
          {
                  z=z+1;
                  if (z==1) octet1=Serial.read();
                  if (z==2) octet2=Serial.read();
                  if (z==3) octet3=Serial.read();
                  if (z==4) z=0;
                  ps=octet1+octet2+octet3;
                 
            }
            
if (ps != ps0 ) {
 
 
 
if (octet2==1) {  
 commande=1; 
 
}
if (octet2==2) { 
 commande=2; 
 
} 
if (octet2==3)  {
commande=3 ;   
}
if ( octet1<100) adresse=octet1;

if (commande==1 and octet3>=0 and octet3<=28) {
  ma=0;
  vitesse=octet3;
}

if (commande==1 and octet3>=30 and octet3<=58) {
  ma=1;
  vitesse=octet3-30;
}

if (commande==2 and octet3>=0 and octet3<=60) {
  fg1=octet3;
  

   hg=fg1; 
  f0=int(hg/16);
  if (f0==1) hg=hg-16;
  f4=int(hg/8);
  if (f4==1) hg=hg-8;
  f3=int(hg/4);
  if (f3==1) hg=hg-4;
  f2=int(hg/2); 
  if (f2==1) hg=hg-2;
  f1=int(hg);
  
  
  
  
}
            
if (commande==3 and octet3>=0 and octet3<=60) {
  fg2=octet3;

  
}

ps0=ps;
delay(10);

}
  
    

// Retrosignalisation

 for (byte i = 0; i < NB_CANTONS; i++) {
    bool etatActuel = 1-digitalRead(cantonPins[i]);
    unsigned long maintenant = millis();

    if (etatActuel != etatPrecedent[i]) {
      if (maintenant - dernierChangement[i] > DELAI_FILTRAGE) {
        etatPrecedent[i] = etatActuel;
        dernierChangement[i] = maintenant;
        envoyerEtatCanton(i, etatActuel);
      }
    }
  }


    

 

   

  


  // reception des commandes du module bluetooth HC-05


    if (BTSerial.available() > 0)
          {
                  octet = BTSerial.read();
                  Serial.print(octet);
               
                 
            }
    if (octet != octet0) {            
if (octet==1) ma=1;
if (octet==0) ma=0;
if (octet>2 && octet<100) adresse=octet;
if (octet>99 && octet<121) vitesse=octet-100;
if (octet>130 && octet<147) adresseac=octet-130;
if (octet==148) vacc=1;
if (octet==149) vacc=0; 

if (octet==150) f0=1;
if (octet==151) f0=0;
if (octet==152) f1=1; 
if (octet==153) f1=0;
if (octet==154) f2=1;
if (octet==155) f2=0;
if (octet==156) f3=1;
if (octet==157) f3=0;
if (octet==158) f4=1;
if (octet==159) f4=0;
if (octet==160) f5=1;
if (octet==161) f5=0;
if (octet==162) f6=1;
if (octet==163) f6=0;
if (octet==164) f7=1;
if (octet==165) f7=0;
if (octet==166) f8=1;
if (octet==167) f8=0;
if (octet==168) f9=1;
if (octet==169) f9=0;
if (octet==170) f10=1;
if (octet==171) f10=0;
if (octet==172) f11=1;
if (octet==173) f11=0;
if (octet==174) f12=1;
if (octet==175) f12=0;
if (octet==221) {
  cs=1;
  digitalWrite(12,HIGH);
}
if (octet==220) {
  cs=0;
  digitalWrite(12,LOW);
}
if (octet>226 && octet<256) adresseac=octet-210;
octet0=octet;
}
 

  

  

        





// adresse loco
a[7]=0;
adress=adresse;
a[6]=(int)(adress/64);
if (a[6]==1) adress=adress-64;
a[5]=(int)(adress/32);
if (a[5]==1) adress=adress-32;
a[4]=(int)(adress/16);
if (a[4]==1) adress=adress-16;
a[3]=(int)(adress/8);
if (a[3]==1) adress=adress-8;
a[2]=(int)(adress/4);
if (a[2]==1) adress=adress-4;
a[1]=(int)(adress/2);
if (a[1]==1) adress=adress-2;
a[0]=(int)(adress);
  


// vitesse

c[7]=0;
c[6]=1;
c[5]=ma;

vit=vitesse;

c[4]=(int)(vit/16);
if (c[4]==1) vit=vit-16;
c[3]=(int)(vit/8);
if (c[3]==1) vit=vit-8;
c[2]=(int)(vit/4);
if (c[2]==1) vit=vit-4;  
c[1]=(int)(vit/2);
if (c[1]==1) vit=vit-2;
c[0]=(int)(vit);

// fonctions du groupe 1
b[0] = f1;
b[1] = f2;
b[2] = f3;
b[3] = f4;
b[4] = f0;
b[5]=0;
b[6]=0;
b[7]=1;

// fonctions du groupe 2
d[0] = f5;
d[1] = f6;
d[2] = f7;
d[3] = f8;
d[4] = 1;
d[5]=1;
d[6]=0;
d[7]=1;

// fonctions du groupe 3
g[0] = f9;
g[1] = f10;
g[2] = f11;
g[3] = f12;
g[4] = 0;
g[5]=1;
g[6]=0;
g[7]=1;

// premier octet accessoire
aca[7]=1;
aca[6]=0;
aca[5]=0;
aca[4]=0;



// deuxième octet accessoire
acc[7]=1;
acc[6]=1;
acc[5]=1;
acc[4]=1;
acc[3]=vacc;
acc[0]=0;

adac=adresseac+3;

aca[3]=(int)(adac/32);
if (aca[3]==1) adac=adac-32;

aca[2]=(int)(adac/16);
if (aca[2]==1) adac=adac-16;
aca[1]=(int)(adac/8);
if (aca[1]==1) adac=adac-8;
aca[0]=(int)(adac/4);
if (aca[0]==1) adac=adac-4;  
acc[2]=(int)(adac/2);
if (acc[2]==1) adac=adac-2;
acc[1]=(int)(adac);








// génération des paquets DCC

// paquet de commande de vitesse
// entete du paquet
 for ( i=0; i <= 15; i++){
  bitun();    
  } 
 bitzero(); 

// octet d'adresse 

 for (i=7; i >=0; i=i-1){
if (a[i]==1) bitun();  
if (a[i]==0) bitzero(); 
  } 
  
  

// bit à zéro
bitzero(); 

// octet de commande

 for (i=7; i >=0; i=i-1){
if (c[i]==1) bitun();  
if (c[i]==0) bitzero(); 
  } 
  


// bit à zéro
bitzero(); 

// octet de controle

for (i=0; i <=7; i=i+1){
e[i] = a[i] ^ c[i];  
}

for (i=7; i >=0; i=i-1){
if (e[i]==1) bitun();  
if (e[i]==0) bitzero(); 
  } 



// bit à un
bitun();   

// pause émission de 25 zéros
 for ( i=0; i <= 25; i++){
bitzero();  
  } 

// paquet de commande de fonctions du groupe 1
// entete du paquet
 for (int i=0; i <= 15; i++){
  bitun();    
  } 
 bitzero(); 

// octet d'adresse 
 for (i=7; i >=0; i=i-1){
if (a[i]==1) bitun();  
if (a[i]==0) bitzero(); 
  } 

// bit à zéro
bitzero();  

// octet de commande

 for (i=7; i >=0; i=i-1){
if (b[i]==1) bitun();  
if (b[i]==0) bitzero(); 
  } 


// bit à zéro
bitzero(); 

// octet de controle

for (i=0; i <=7; i=i+1){
ef[i] = a[i] ^ b[i];  
}

for (i=7; i >=0; i=i-1){
if (ef[i]==1) bitun();  
if (ef[i]==0) bitzero(); 
  } 



// bit à un
bitun();  

// pause émission de 25 zéros
 for ( i=0; i <= 25; i++){
bitzero(); 
  } 

// paquet de commande de fonctions du groupe 2
// entete du paquet
 for (int i=0; i <= 15; i++){
  bitun();    
  } 
 bitzero(); 

// octet d'adresse 
 for (i=7; i >=0; i=i-1){
if (a[i]==1) bitun();  
if (a[i]==0) bitzero(); 
  } 

// bit à zéro
bitzero();  

// octet de commande

 for (i=7; i >=0; i=i-1){
if (d[i]==1) bitun();  
if (d[i]==0) bitzero(); 
  } 


// bit à zéro
bitzero(); 

// octet de controle

for (i=0; i <=7; i=i+1){
ed[i] = a[i] ^ d[i];  
}

for (i=7; i >=0; i=i-1){
if (ed[i]==1) bitun();  
if (ed[i]==0) bitzero(); 
  } 

  // paquet de commande de fonctions du groupe 3
// entete du paquet
 for (int i=0; i <= 15; i++){
  bitun();    
  } 
 bitzero(); 

// octet d'adresse 
 for (i=7; i >=0; i=i-1){
if (a[i]==1) bitun();  
if (a[i]==0) bitzero(); 
  } 

// bit à zéro
bitzero();  

// octet de commande

 for (i=7; i >=0; i=i-1){
if (g[i]==1) bitun();  
if (g[i]==0) bitzero(); 
  } 


// bit à zéro
bitzero(); 

// octet de controle

for (i=0; i <=7; i=i+1){
eg[i] = a[i] ^ g[i];  
}

for (i=7; i >=0; i=i-1){
if (eg[i]==1) bitun();  
if (eg[i]==0) bitzero(); 
  } 



// bit à un
bitun();  

// pause émission de 25 zéros
 for ( i=0; i <= 25; i++){
bitzero(); 
  } 


  // paquet de commande d'accessoire
// entete du paquet
 for (int i=0; i <= 15; i++){
  bitun();    
  } 
 bitzero(); 

// premier octet 
 for (i=7; i >=0; i=i-1){
if (aca[i]==1) bitun();  
if (aca[i]==0) bitzero(); 
  } 

// bit à zéro
bitzero();  

// deuxième octet

 for (i=7; i >=0; i=i-1){
if (acc[i]==1) bitun();  
if (acc[i]==0) bitzero(); 
  } 


// bit à zéro
bitzero(); 

// octet de controle

for (i=0; i <=7; i=i+1){
ace[i] = aca[i] ^ acc[i];  
}

for (i=7; i >=0; i=i-1){
if (ace[i]==1) bitun();  
if (ace[i]==0) bitzero(); 
  } 



// bit à un
bitun();  

// pause émission de 25 zéros
 for ( i=0; i <= 25; i++){
bitzero(); 
  } 

}

void bitun(){    //genere un bit à 1
digitalWrite(sdcc,LOW);

delayMicroseconds(58);        // pauses for 58 microseconds      
digitalWrite(sdcc,HIGH);

delayMicroseconds(58);        // pauses for 58 microseconds  
}

void bitzero(){    //genere un bit à 0
digitalWrite(sdcc,LOW);

delayMicroseconds(116);        // pauses for 116 microseconds      
digitalWrite(sdcc,HIGH);

delayMicroseconds(116);        // pauses for 116 microsec
} 

void envoyerEtatCanton(byte numero, bool occupe) {
  Serial.print("C");
  Serial.print(numero + 1);
  Serial.print(":");
  Serial.println(occupe ? "1" : "0");

}
