Bonjour à tous,

Un autre sujet qui m'intéresse. Je dois avant tout dire que je suis pas du tout spécialiste en C ou C++. Je ne suis qu'un modeste bidouilleur et je ne fais que du copier/coller tout en essayant quand même de comprendre le code que je recopie.

Il y a déjà plusieurs années (~ 20 ans) j'ai modifié ma radio commande en 2.4Ghz avec des modules Xbee pour la transmission et un Attiny2313 pour l'interface avec les servos.
Dernièrement j'ai voulu remettre en route ma radio et le récepteur et module d'émission Xbee à pété. Donc je dois remplacer les deux...

J'ai fouillé le net pour essayer d'en trouver. Y en a, mais à des prix exorbitants. (+ de 35€). J'ai trouvé des modules nRF24 à des prix vraiment intéressants (- de 5€). Y a pas photos...

Maintenant, je dois modifier le firmware... voici le code qui fonctionne avec le Xbee que j'aimerais adapté au nRF24.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
 
/******************************************************************************
 *   Program:           TX For O24RCP                                                                                                                                                 *
 *   Created:           2009                                                                                                                                    *
 *   Author:            C Courche et H Goncalves                                                                                                                        *
 *   Version:     V2.2                                                        *            
 ******************************************************************************/
 
 /* IMPORTANT : Cette création est mise à disposition selon le Contrat 
 *  Paternité-Pas d'Utilisation Commerciale-Partage des Conditions Initiales 
 *  à l'Identique 2.0 France disponible en ligne 
 *  http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ 
 *  ou par courrier postal à
 *  Creative Commons, 171 Second Street
 *  Suite 300, San Francisco, California 94105, USA.
 * / 
 
	/*ATTENTION: l'auteur ne pourrait assumer la responsabilité
	concernant toute modification ou utilisation inappropriée
	de ce programme */
 
#include <avr/io.h>
#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
 
// préselections de tempos de chien de garde:
#define WDTCSR_16MS (1<<WDIE)	|	(0<<WDP3)	| 	(0<<WDP2) 	| 	(0<<WDP1) 	| 	(0<<WDP0)
#define WDTCSR_32MS (1<<WDIE)	|	(0<<WDP3)	| 	(0<<WDP2) 	| 	(0<<WDP1) 	| 	(1<<WDP0)
#define WDTCSR_64MS (1<<WDIE)	|	(0<<WDP3)	| 	(0<<WDP2) 	| 	(1<<WDP1) 	| 	(0<<WDP0)
#define WDTCSR_1S  	(1<<WDIE)	|	(0<<WDP3)	|	(1<<WDP2) 	| 	(1<<WDP1) 	| 	(0<<WDP0)
#define WDTCSR_2S  	(1<<WDIE)	|	(0<<WDP3)	|	(1<<WDP2) 	| 	(1<<WDP1) 	| 	(0<<WDP0)
#define WDTCSR_4S  	(1<<WDIE) 	|	(1<<WDP3)	| 	(0<<WDP2) 	| 	(0<<WDP1) 	| 	(0<<WDP0)
 
#define EEPROM_SECTION  __attribute__ ((section (".eeprom")))
 
#define SYSCLK	8000000		//Fréquence du Quartz en Hz
 
#define BAUD_RATE 19200		//vitesse standard RS232
 
// plages des canaux 2.4GHz disponibles
#define CanalMaxiInDoor 	0x1A	// canal maxi indoor
#define CanalMaxiOutDoor 	0x17	// canal maxi outdoor
#define CanalMiniInOutDoor 	0x0C	// canal mini indoor/outdoor
 
// entrées/sorties TinY
#define CavalierInDoor 	 1		// PortB1: cavalier Indoor(absent)/outdoor(présent)
#define InterFailSafe  	 0    	// PortB0: BP Programmation failsafe
#define LedTiny 		 4		// portB4: Led rouge du TinY
#define Aux1             2     	// PortB2: voie auxiliaire PPM+1
 
// paramétres encodage trame XBEE
#define TypeTrameRs      		3	// Port B3: strap  selection type de trame série (FMS/HD)
#define TesteFailSafe    		6	// Port B6: pin9/HE10 AVRISP(MISO); sert de test Failsafe(actif à 0) 
#define TempoFailSafeMax 		2	// code progfail max (0=64µs; 1=1s; 2=4s)
#define ResolutionTrameRs_FMS 	0	// mode d'encodage FMS
#define ResolutionTrameRs_HD 	1	// mode d'encodage FMS
 
// registres de l'UART 
#define USR UCSRA
#define UCR UCSRB	
#define UBRR UBRRL	
#define EICR EICRB
 
// parametres debit RS232
volatile char Id_Baud_Test; 						//contient le débit en test avec l'XBEE
const char PROGMEM ListeBaud [] = {51,25,12,8}; 	//suivant le tableau 58 doc du Tiny2313
//ou la version formule:
//const char PROGMEM ListeBaud [] = {(SYSCLK/(9600 * 16L))-1,(SYSCLK/(19200 * 16L))- 1,(SYSCLK/(38400 * 16L))-1,8};
#define ID_BAUD_RATE_MAX            3	// maxi 56K
#define ID_WORKING_BAUD_RATE    	3   // débit  de travail...
 
// table des temps de voies (utilisée aussi pour le scan des canaux)
volatile unsigned int 	TempsVoies[15]={0,0,0,0,0,0,0,0,0,0,0,0};
 
// mémoire de la séquence progammation XBEE
const char PROGMEM SequenceInit_1 [] = "ATCE1,SP0,A25,DL0000FFFF,DH0,MY0,RN0,CH"; // XBEE en coordinator
const char PROGMEM SequenceInit_2_In [] = ",PL0,WR,CN";		// émission à 10mW Indoor
const char PROGMEM SequenceInit_2_Out [] = ",PL4,WR,CN";	// émission à 100mW Outdoor
const char PROGMEM ATBD [] = "ATBD";
const char PROGMEM VAL_ATBD[] = "D904";		// H,D904=55556 bauds précisement pour 56K 
const char PROGMEM SeqProgXbee [] = "+++";
const char PROGMEM WRCN [] = ",WR,CN";
const char PROGMEM niv_dbm [] = "ATED4";	// demande au XBEE les niveaux -dBm de tous ses canaux
 
// variables de travail
volatile unsigned char 	Compteur;    				// nombre de trames répétées pour  programmation  Failsafe
volatile unsigned char 	Indoor = 1,Canal;   		// variable permettant de selectionner le canal XBEE
volatile unsigned char 	TempoFailSafe = 0;			// choix de la tempo de passage en failsafe (0; 1; 2)
volatile unsigned char	Ok_Trame = 0;				// à 1: la trame est compléte et prête à envoyer
volatile unsigned char 	VoieEnCours,VoiePrecedente;	// curseurs pour encodage de la trame
volatile unsigned char 	Vmax;						// nombre de voies maxi de la trame PPM reçue en entrée
volatile unsigned char 	Vsortie;					// nombre de voies à sortie (si ajout aux1)
volatile unsigned char 	PasSynchro = 2; 			/*  2 : synchro vu 0 fois
													    1 : synchro vu 1 fois
													    0 : synchro vu 2 fois!!  => Nb Voies déterminé*/
 
//déclaration des nouvelles fonctions
void EnvoieTempsVoieRs (unsigned char NVoie, unsigned char TypeTrameSerie);
void EnvoieFinTrame (unsigned char OrdreTrame, unsigned char TypeTrameSerie);
void Rs232_Init (unsigned char IndexBaud);
char uart_putchar (char c);
void uart_putstr (char * str);
void uart_putstr_P (const prog_char * str);
unsigned char Wait_Ok( void );
unsigned char Retourne_Char( void );
void config_TX_XBEE(void);
 
 
/****************************************************************************************************************
 
                          DEBUT DU PROGRAMME PRINCIPAL
 
*****************************************************************************************************************/
int main(void)
{
	volatile unsigned char i;				
	volatile unsigned char ResolutionTrameRs;
 
    DDRB  = 0b10110000;                     // bit 0..3 et 6 (test fail) en entree
    PORTB = 0b01001111;                     // on tire les entrées au  1
 
    PORTB |= (1<<LedTiny);  				// Allume la LED 
 
	config_TX_XBEE();	
 
// configurations du Timer 1:
	TIMSK |=  (1<<ICIE1);     			// Interruption Tmer1  sur Input Capture
 
	TCCR1B |= (1<<ICES1);    							//Input capture sur front  montant
    TCCR1B |= (0<<CS12) | (1<<CS11) | (0<<CS10) ;    	// Clk/8 -> 1 tic = 1 µsec
 
    PORTB &= ~(1<<LedTiny);    		// on éteint la LED
 
	sei();				// le module est OPERATIONNEL !	
 
 
 
//***************************************** BOUCLE PRINCIPALE du MAIN *****************************************
 
    while(1)
	{
		if ( (!PasSynchro) && (Ok_Trame) )	// trame voies prête
		{
			ResolutionTrameRs = ResolutionTrameRs_FMS;
			// on peut revenir en FMS en strappant à 0 le PortB,3; pas de strap -> mode HD (12bits)
 
			if ( (PINB &(1<<TypeTrameRs)) ) ResolutionTrameRs = ResolutionTrameRs_HD;//par défaut HD!
 
	// TESTE BP PROG FAILSAFE..................................
			if (PINB &(1<<InterFailSafe))           
			{						//BP PROG FAILSAFE relaché
				Compteur = 0;   	
				TempoFailSafe = 0;
			}
 
			else									
			{						//BP PROG FAILSAFE appuyé
				Compteur++;        
			}
 
	// ENVOI DE LA TRAME......................................	
			for (i = 1;i < Vsortie+1;i++)
			{
				EnvoieTempsVoieRs (i, ResolutionTrameRs);
			}
 
	// ENVOI FIN TRAME........................................
			if (Compteur == 100) // Maintenir le BP enfoncé durant 100 trame (soit environ 100x20ms=2sec)
			{
				EnvoieFinTrame (TempoFailSafe,ResolutionTrameRs); // alors seulement on ajoute l'octet de CMDE
				Compteur = 0;
 
				if (TempoFailSafe != TempoFailSafeMax) TempoFailSafe++; // si BP maintenu on passe la cmde à 01, puis 02
			}
			else 
 
			{
				EnvoieFinTrame (0xFF,ResolutionTrameRs ); // si pas de CMDE, on met "FF" à la place
			}
 
		Ok_Trame = 0; //la trame est partie, on raz pour attendre la suivante		  
		} 
 
	};   //boucle sans fin
 
};
//______________________________________________ fin PROGRAMME PRINCIPAL _________________________________________________
 
 
 
//________________________________________________ DEBUT DES ROUTINES ____________________________________________________
 
/*************************************************************************************************************************/
//                                                Initialisation en émission du XBEE
/*************************************************************************************************************************/
void config_TX_XBEE(void)
{
	volatile unsigned char i,HFmaxi;		// ATTENTION: HFmaxi est la valeur absolue du niveau en -dBm!
	volatile unsigned char Caractere,Chrono;
 
	//------------------------------------- DETERMINATION  DU  CANAL (INDOOR/OUTDOOR) -----------------------------------   
    Indoor = 1;   	// force en Indoor par  défaut
 
	if (  !( PINB & (1<<CavalierInDoor)) ) // si presence cavalier => OutDoor
	{
	    Indoor = 0;   
	}
 
    Id_Baud_Test = ID_WORKING_BAUD_RATE; 	// teste à vitesse de travail
	Rs232_Init (ID_WORKING_BAUD_RATE);		// initialisation UART
 
	for(Chrono = 0;Chrono < 50;Chrono++) _delay_ms(10); //0.5sec pour init UART
 
	cli();
		wdt_reset();						// pas d'IT pendant cette action
		WDTCSR = (1<<WDCE) | (1<<WDE);		// On démarre le Watchdog
		WDTCSR = WDTCSR_2S;					// tempo WD à 2 sec
	sei();
 
	uart_putstr_P (SeqProgXbee); 			// 1er appel du XBEE
 
	while (!Wait_Ok()); // il faut attendre le OK, sinon le WDTimer rebootera
 
	// c'est bon on a le OK XBEE, on continue...
	MCUSR &= ~(1<<WDRF);
	WDTCSR |= (1<<WDCE) | (1<<WDE);	// Désactication du Watchdog
    WDTCSR = 0x00;
 
 	if (Id_Baud_Test != ID_WORKING_BAUD_RATE) 	// si vitesse XBEE pas la bonne...
 	{
     	uart_putstr_P (ATBD);		// ...envoi la vitesse de travail...
        uart_putstr_P (VAL_ATBD);
	   	uart_putstr_P (WRCN);
	   	uart_putchar (0x0D);		//CR 
 
     	while (!Wait_Ok());			// attend le OK
 
     	wdt_reset();
		WDTCSR = (1<<WDCE) | (1<<WDE); 
	    WDTCSR = (1<<WDE);		// provoque un Reset
 
		while(1){}; 			// attend le reset pour tourner à la bonne vitesse
    }
 
	// RECHERCHE  DU  CANAL LIBRE:
    uart_putstr_P (niv_dbm); 	//demande au XBEE ses niveaux -dBm pour chaque canal (en valeur absolue!)
	uart_putchar (0x0D);  		//CR    
 
	// RECEPTION DES 12 VALEURS DE PUISSANCE:
	for (Caractere = 0;Caractere < 12; Caractere++)
	{	
		TempsVoies[Caractere] = Retourne_Char();	// la table tempsvoies sert a stocker les 12 niveaux -dBm
	}
 
	Caractere = 0;					//  index de scrutation des canaux, jusqu'à canal (limite Indoor/outdoor)
 
    Canal = 9;						// 	9 canaux possibles en Outdoor  (100mW)
 
    if (Indoor) 	Canal = 12;		// 	12 canaux possibles en Indoor  (10mW)
 
	HFmaxi = 0;	                	//	maximum en valeur absolue: à ce niveau le canal n'est pas disponiblr
 
	for (i = 0;i < Canal; i++)
	{
		if (TempsVoies[i] > HFmaxi)		// scrute toutes les valeurs de la table...
		{
			HFmaxi = TempsVoies[i];		//...pour garder la plus élevée
			Caractere = i;				// garde la position dans la table du meilleur canal retenu
		}
	}
 
	if (Caractere == Canal)			// -0db partout, canaux saturés!
	{
 
		while (1) 					// clignote le led en boucle: y a pas de place pour cette fois!
		{
		    for(Caractere = 0;Caractere < 100;Caractere++) _delay_ms(10);
		    PORTB &= ~(1<<LedTiny);                                     // Eteint la LED		    
		   	for(Caractere = 0;Caractere < 100;Caractere++) _delay_ms(10);
		   	PORTB |= (1<<LedTiny);                                      // Allume la LED
		}
 
	}
 
	// on a notre canal! on continue...	
    Canal = CanalMiniInOutDoor + Caractere;   		// recalcule le N°CANAL choisi parmis les 9 ou 12
 
	// ENVOI  DE LA SEQUENCE AU  XBEE:	
	uart_putstr_P(SequenceInit_1);					// 1er tronçon...
 
	Caractere = (Canal>>4); 						// ...puis le Canal  utilisé: 1er caractère (poids fort):	
		if (Caractere > 9)	Caractere += 7; 		// 								passage en Hexa...
		uart_putchar (Caractere + 48);    			// ...puis le caractère en ASCII!
 
	Caractere = (Canal & 0b00001111); 				// ensuite 2nd caractère (poids faible):
		if (Caractere > 9)	Caractere += 7; 		// 								passage en Hexa...
		uart_putchar (Caractere + 48);    			// ...puis le caractére en ASCII!	
 
	if (Indoor) uart_putstr_P(SequenceInit_2_In);	// et  enfin 2ème troncon...
	else 	uart_putstr_P(SequenceInit_2_Out);		// ...en fonction du strap Indoor/Outdoor
 
	uart_putchar (0x0D);   // important:le RETOUR  CHARIOT!!!!	
 
};
 
 
/*************************************************************************************************************************/
//                                                Initialisation RS232
/*************************************************************************************************************************/
void Rs232_Init (unsigned char IndexBaud)
{	
	UCSRB = (1 << TXEN) | (1 << RXEN);  		// autorisation  Tx et Rx mais sans interruption
	UBRRL = (pgm_read_byte(&ListeBaud[IndexBaud]));
};
 
 
/*************************************************************************************************************************/
//                                       Envoi d'un caractere de SRAM vers UART
/*************************************************************************************************************************/
char uart_putchar (char c)
{
	loop_until_bit_is_set(USR, UDRE);	//attente buffer UART vide pour envoyer le caractère
	UDR = c;
	return (0);
};
 
 
/*************************************************************************************************************************/
//                                        Envoi d'un string de SRAM vers UART
/*************************************************************************************************************************/
void uart_putstr (char * str)
{
	while (str[0] != 0)					// tant qu'il reste un caractère de la chaine...
	{
	    uart_putchar (str[0]);			// ...on l'envoie!
	    str++;
	}
};
 
 
/*************************************************************************************************************************/
//                                      Envoi d'un string de Mémoire (FLASH) vers UART
/*************************************************************************************************************************/
void uart_putstr_P (const prog_char * str)
{
	while (pgm_read_byte(str) != 0)				// tant qu'il reste un caractère de la chaine stockée en mémoire...
	{
	    uart_putchar (pgm_read_byte(str));		// ...on l'envoie!
        str++;
	}
};
 
 
/*************************************************************************************************************************/
//                                                Attente OK + CR du XBBE
/*************************************************************************************************************************/
unsigned char Wait_Ok( void )
{
	unsigned char  Recu;
 
	while ( !(UCSRA & (1<<RXC)) );		
	Recu = UDR;
	if (Recu != 'O') return 0;			// attente "O"
 
	while ( !(UCSRA & (1<<RXC)) );		
	Recu = UDR;
	if (Recu != 'K') return 0;			// attente "K"
 
	while ( !(UCSRA & (1<<RXC)) );		// attente CR
	Recu = UDR;							
	if (Recu != 0x0D) return 0;			// vérification
 
	return 1; //Ok  on revient
};
 
 
/**************************************************************************************************************************/
// 									Attente 2 caractéres + CR (réponses du XBEE)
/**************************************************************************************************************************/
unsigned char Retourne_Char( void )
{
	// on reçoit une valeur Hexadécimale, codée sur 2 car. ASCII, on la retourne en Hexa sur 1 octet
	unsigned char  Recu,Blanc;
 
	while ( !(UCSRA & (1<<RXC)) );		// attente caractère arrivé dans l'UART
	Blanc = UDR;
	if (Blanc > 64) Blanc -= 7;			// premier caractère ASCII...
	Recu = (Blanc - 48)<<4;				// pour le poids fort....
 
	while ( !(UCSRA & (1<<RXC)) );		
	Blanc = UDR;						
	if (Blanc > 64) Blanc -= 7;			// second caractère ASCII...
	Recu = Recu + (Blanc - 48);			// .... pour finir en Hexa (poids fort + poids faible)
 
    while ( !(UCSRA & (1<<RXC)) ); 	// ON attend CR
	Blanc = UDR;  						// il suffit de le lire pour continuer
 
	return Recu; 	//Ok  on raméne la valeur reçue en ASCII
};
 
 
/**************************************************************************************************************************/
//                                              envoie  des temps de voie
/**************************************************************************************************************************/
void EnvoieTempsVoieRs (unsigned char NVoie, unsigned char TypeTrameSerie)
{
	if  ( ! (PINB & (1<<TesteFailSafe))) return;
 
	switch (TypeTrameSerie)
	{
		case ResolutionTrameRs_FMS:						// cas FMS
 
 
        	if ( TempsVoies[NVoie]< 760) {uart_putchar(0); break;}			
			if ( TempsVoies[NVoie]> 2290){ uart_putchar(0xFE); break;}			
 
		    uart_putchar ( (char) (((TempsVoies[NVoie])-760)/6) );		// encodage norme FMS
		break;
 
 
		case ResolutionTrameRs_HD :						// cas HD
 
			// poids faible  d'abord
			if ((char) (TempsVoies[NVoie]) == 0xFF)uart_putchar(0xFE);		
 
			else 	uart_putchar ( (char) (TempsVoies[NVoie]) );			// encodage 12 bits...
 
			// Poids Forts ensuite
            uart_putchar ( (char)( (TempsVoies[NVoie]) /256) );			// ...sur 2 octets
		break;
 
	}
 
};
 
 
/**************************************************************************************************************************/
//                                                envoie  fin de trame
/**************************************************************************************************************************/
void EnvoieFinTrame (unsigned char OrdreTrame, unsigned char TypeTrameSerie)
{
    if  ( ! (PINB & (1<<TesteFailSafe))) return;
	switch (TypeTrameSerie)
	{
		case ResolutionTrameRs_FMS:		// cas FMS
 
            uart_putchar(0xFF);			
			if ( OrdreTrame != 0xFF)
			{
            	uart_putchar(0xFF);		// 2 FF suivi de l'octet de cmde
            	uart_putchar(OrdreTrame);
			}
		break;
 
		case ResolutionTrameRs_HD:		// cas HD
 
        	uart_putchar(0xFF);
        	uart_putchar(OrdreTrame);	// 1 FF suivi de l'octet de cmde (00, 01, 02, FF)
		break;
	} 
 
};
 
//__________________________________________________ fin DES ROUTINES ______________________________________________________
 
 
 
 
//_________________________________________ DEBUT TRAITEMENT DES INTERRUPTIONS ___________________________________________
 
 
//******************************************* INTERRUPTION SUR FRONT DE PULSE ********************************************
//				ici voieEnCours représente le numéro  de la voie qui vient de finir à l'interruption
 
SIGNAL(SIG_INPUT_CAPTURE1) 
{	
	volatile unsigned int TempsMesure;
 
	TCNT1H = 0;        // reset TCNT1
	TCNT1L = 4;        // reset TCNT1 :4! pourquoi pas 0 ??? ... +4µs (<0,1°) c'est pas bien grave...
 
	TempsMesure = ICR1L;
	TempsMesure += (ICR1H*256);		// On récupère le temps de la voie qui vient de finir
 
 
	//------------------------------ COMPTAGE DU NOMBRE DE VOIES ENTRE 2 SYNCHROS --------------------------------------
 
	if (PasSynchro)	// cherche le temps de synchro (2 fois) pour scruter ce qui vient entre les deux
	{
		if (TempsMesure > 6000)  // plus de 6ms ==> c'est le temps de synchro
		{
			switch (PasSynchro)
			{			
				case 2	: 				// à 2: ==> première fois passage du temps de synchro
				VoieEnCours = 1;		// initialise le compteur de voies à 1
				break;
 
				case 1 : 				// à 1: ==> deuxième passage du synchro (on a compté les pulses entre les 2)
				Vmax = VoieEnCours - 1;	// on calcule le nombre maxi de voies trouvées en entrée PPM
				VoieEnCours = 1;		// On se recale au début de table
				break;				
			}	
			PasSynchro--; 		// décrémente le nombre de passage synchro
			return;		
		} 		
		VoieEnCours++; 		// incrémente le compteur de voies à chaque pulses (vue entre les 2)
		return;	
	}
 
	//--------------------------- ENREGISTREMENT DES TEMPS DE VOIES POUR CONSTRUIRE LA TRAME XBEE ---------------------
 
	TempsVoies[VoieEnCours] = TempsMesure;	// enregistre le temps de voie dans la table
	VoiePrecedente = VoieEnCours;	
	VoieEnCours++;							// passe à la voie suivante
 
	if ( VoieEnCours == (Vmax+1))	//on est à la fin de la dernière voie PPM entrée
	{
		Vsortie = Vmax;			// nombre de voies à sortir
		VoieEnCours = 0;  		// réinitialise la table à la première voie
        Ok_Trame = 1; 			// on autorise l'envoi de la trame
 
		// ajoute voie AUX1: facultatif ------		
		if (Vmax < 9)   // fait seulement si on n'a que 8 voies maxi en entrée
		{
        	Vsortie = Vsortie + 1;	// ajoute 1 voie dans la trame de sortie
 
			if (PINB &(1<<Aux1))    // teste la Touche auxiliaire
			{
				TempsVoies[Vmax+1] = 1000;  // 1ms si strap ouvert
	        }
 
	        else
	        {
				TempsVoies[Vmax+1] = 2000;	// 2ms si strap fermé
	        }
	    }
		//------------------------------------			
	}
 
	// ---------------------------------- CAS d'INCOHERENCES DU TEMPS MESURE -------------------------------------------
	/*                 ici VoieEnCours représente la voie que l'on est en train de parcourir	
                    par contre TempsMesure est le temps de la voie précédente
			        si ce TempsMesure est hors norme, on va refaire une passe de Passynchro
			        ...çà sert à se resynchronise au moment d'une commutation de l'inter MAITRE/ELEVE en écolage      */
 
   if (VoiePrecedente == 0) // seulement si on n'a pas commencer à encoder la trame: sinon =1 au mini
   {
		if ( (TempsMesure < 4000) || (TempsMesure > 20000)) 	// entre 4ms et 20ms c'est un temps de synchro PPM
        {
          	PasSynchro = 2; 									//on a perdu le fil on refait une passe de synchro
          	return;
        }
   }
 
   else    // n'importe qu'elle autre numéro de voie autre que synchro (0)
   {
         // si le temps de voie n'est pas aux normes on se mets en condition de synchro
        if (  (TempsMesure < 700) || (TempsMesure > 3000)) 	// si une voie est faussée...
        {
          	PasSynchro = 2;	 									// ...on refait une passe de synchro
          	return;
        }
 
   }
 
	PORTB &= ~(1<<LedTiny); //LED éteint
};
 
//_________________________________________________ fin IT FRONT DE PULSE _________________________________________________
 
 
 
/*************************************************************************************************************************/
//                                                 interruption sur watchdog
/*************************************************************************************************************************/
SIGNAL(WDT_OVERFLOW_vect)
{
 
    WDTCSR = WDTCSR_2S;			// relance le WDT à 2 sec
    if (Id_Baud_Test >= ID_BAUD_RATE_MAX )Id_Baud_Test = 0; // passe à la vitesse suivante
		else Id_Baud_Test++;
	Rs232_Init (Id_Baud_Test);
	uart_putstr("+++");    
};
 
//_______________________________________________ FIN DES INTERRUPTIONS __________________________________________________