Bonjour,

Je programme un robot sans conducteur suiveur de ligne.
A l'aide du pic 16F877 et du CCS C compiler.
Voici les particularité du systeme:

suivit de ligne à l'aide de 8 optocoupleurs (port D)
(servo moteur avec PWM + moteur traction)

choix du trajet à l'aide d'une télécommande (HF) 3 postes (3 boutons)

Arret au poste pour prendre ou déposer une palette (moteur de levage)

La detection des postes se fait à l'aide des optocoupleurs et d'un capteur
(opto D7,D6,D0 + entrée B7)

Le circuit est ovale et les poste sont en ligne droite.

Des microrupteurs sont utilisés pour détecter un obstacle = arret du chariot , lancement d'une alarme
Interruption matérielle sur RBO

Pouvez vous vérifier mon code afin de me dire ce que vous en pensez.
Merci de votre aide


/////////////////SYTEME////////////////////////
#include <16F877.h>
#use delay(clock=1000000) // frequence du quartz 1 MHz
#fuses NOWDT,XT, PUT, NOPROTECT, BROWNOUT, NOLVP, NOCPD, NOWRT, DEBUG

/////////////////DEFINE////////////////////////
// ENTREES //
#define DETECTIONPOSTE pin_b6 // Détection de poste sur front montant
#define DETECTIONPALETTE pin_a0 // Détection présence d'une palette
#define DETECTIONTOUCHE pin_b5 // Détection touche appuyée
// SORTIES //
#define TRACTION pin_c1 // moteur de traction
#define ALIMLEVAGE1 pin_b1 // commande moteur levage
#define ALIMLEVAGE2 pin_b2 // commande moteur levage
#define FINLEVAGE pin_b4 // levage terminé (courant atteind)
#define ALARME pin_c1 // avertisseur sonore et lumineux

/////////////////VARIABLES GOLBALES////////////////////////
short TELECOMMANDE = 2;
//télécommande HF 0: bouton ARRET,1: bouton 1,2: bouton 2,3: bouton 3
short POSTE = 1;
//indique à quel poste le chariot se trouve le chariot
//1 : poste 1 ...


//////////////////external interrupt RB0////////////////////////////////
#INT_EXT
void urgence()
{
output_bit(TRACTION,0); //arret du moteur de traction
output_bit(ALARME,1); //avertisseur sonore et lumineux
delay_ms(5000); // attente 5 secondes
}


//////////////////FONCTION////////////////////////////////


void init()
{

// Validation d'une IT externe sur le bit RB0
EXT_INT_EDGE(H_TO_L); // sur front descendant
enable_interrupts(INT_EXT);
// Validation des IT
enable_interrupts(GLOBAL);


set_tris_a(0b11111111); // PORTA en entrée (info_palette, controle_courant, D6,D7,D8,D9) (0=sortie, 1=entrée)
set_tris_b(0b11111001); // PORTB : en entrées (controle_levage :, info_poste, valid_transmit, controle_courant) B1 et B2 en sorties moteur levage, B0 en entrée (interrupt)
set_tris_c(0b00000001); // PORTC : entrée (info_poste) et sorties(cmd_buzzer, LD5, LD4, pwm_mot_traction, pwm_mot_direction)
set_tris_d(0b11111111); // PORTD en entrée (8 entrées suivi de ligne)
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_16,255 ,1);
// (1/1000000) * 4 * 16 * 255 = période
// soit 61 HZ pour le servomoteur, on peut pas descendre plus bas avec Quartz 1MHz !

//initialisation des moteurs
output_bit(TRACTION,0); //traction = 0
set_pwm1_duty(64); //direction = 50% au début
output_bit(ALIMLEVAGE1,1); // alimenter moteur levage sens -
output_bit(ALIMLEVAGE2,0); // alimenter moteur levage sens -

}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------------------------------------------------------------------//

void commande()
{
BYTE lectureB = 0b00000000;
if(input(DETECTIONTOUCHE)) // si une touche a été appuyée
{
lectureB = input_b();
lectureB = lectureB & 0b00111100; //on garde B2 B3 B4 et B5
switch (lectureB)
{
case 0b00011100 : TELECOMMANDE = 1; //1 bouton 1
case 0b00111000 : TELECOMMANDE = 2; //2 bouton 2
case 0b00110000 : TELECOMMANDE = 3; //3 bouton 3
default : TELECOMMANDE = 2;
}
}
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------------------------------------------------------------------//


void determinationPoste()
{
BYTE lectureD = 0b00000000;
if(input(DETECTIONPOSTE)) // si un poste est détecter on determine son numéro
{
lectureD = input_d();
lectureD = lectureD & 0b11000001; //on garde D7 D6 et D0 pour déterminer le poste
switch (lectureD)
{
case 0b11000001 : POSTE = 1; // le chariot est au poste 1 chargement
case 0b11000000 : POSTE = 2; // le chariot est au poste 2
case 0b10000001 : POSTE = 3; // le chariot est au poste 3
default : POSTE = 1; // le chariot est au poste 1
}
}

}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------------------------------------------------------------------//


void suiviLigne() // suivi de ligne + TRACTION
{

// gestion du suivi de ligne : PWM direction
BYTE lectureD = 0b00000000;
lectureD = input_d();
output_bit(TRACTION,1); // démarrage moteur traction
// rapport cyclique du PWM varie de 0 (0%) à 255(100%)
switch (lectureD)
{
case 0b11000000 : set_pwm1_duty(0); // IL FAUT TOURNER A GAUCHE à 100 %
case 0b01100000 : set_pwm1_duty(21); //
case 0b00110000 : set_pwm1_duty(43); //
case 0b00011000 : set_pwm1_duty(64); //position INITIAL (milieu)
case 0b00001100 : set_pwm1_duty(85); //
case 0b00000110 : set_pwm1_duty(107); //
case 0b00000011 : set_pwm1_duty(128); // IL FAUT TOURNER A DROITE à 100 %
default : set_pwm1_duty(64);
}
}


void mission1() // on prend la palette poste 1 et on la pose poste 1
{

//prendre palette
do
{
output_bit(ALIMLEVAGE1,0); // alimenter moteur levage sens +
output_bit(ALIMLEVAGE2,1); // alimenter moteur levage sens +
}
while(input(FINLEVAGE));


do
{
suiviLigne(); // avancer le chariot en suivant la ligne
}
while((POSTE == 1) && (input(DETECTIONPOSTE)) ); // chariot arrivé au poste 1 Terminus

// poser palette
output_bit(ALIMLEVAGE1,1); // alimenter moteur levage sens -
output_bit(ALIMLEVAGE2,0); // alimenter moteur levage sens -


}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------------------------------------------------------------------//

void mission3() // on prend la palette poste 1 et on la pose poste 3
{

//prendre palette
do
{
output_bit(ALIMLEVAGE1,0); // alimenter moteur levage sens +
output_bit(ALIMLEVAGE2,1); // alimenter moteur levage sens +
}
while(input(FINLEVAGE));


do
{
suiviLigne(); // avancer le chariot en suivant la ligne
}
while((POSTE == 3) && (input(DETECTIONPOSTE)) ); // chariot arrivé au poste 3 Déchargement

// poser palette
output_bit(ALIMLEVAGE1,1); // alimenter moteur levage sens -
output_bit(ALIMLEVAGE2,0); // alimenter moteur levage sens -
delay_ms(5000); // prévoir un temps pour déposer la palette, ne pas repartir directement

do
{
suiviLigne(); // avancer le chariot en suivant la ligne
}
while((POSTE == 1) && (input(DETECTIONPOSTE)) ); // chariot arrivé au poste 1 Terminus
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------------------------------------------------------------------//



//-------------------------------------------------------------------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------------------------------------------------------------------//

void main()
{
init();
while(1)
{

commande();
determinationPoste();

if ( (POSTE == 1) && (input(DETECTIONPOSTE)) && (input(DETECTIONPALETTE)) )
{
switch (TELECOMMANDE)
{
case 1 : mission1() ; // on prend la palette poste 1 et on la pose poste 1
case 3 : mission3() ; // on prend la palette poste 1 et on la pose poste 3
default :mission3() ; // mission 3 par défaut
}


}
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------------------------------------------------------------------//





}


Merci