; Programme de detection des signaux "Pulsadis" EJP ou Tempo ; Ne nécessite qu'une entrée secteur (ici AN8) sur un PIC16F690 ; L'affichage du signal se fait sur un ecran LCD 2x16 ; Choisir l'une des deux options: tempo=1 (Mode Tempo, defaut) ou ; tempo=0 (Mode EJP) ; ; Si debug=1 alors on génère un log sur terminal ; ; Contact: pulsadis at free . fr ; ; Janvier 2015 ; ; Code GCBASIC ; ; ;Chip Settings #chip 16F690, 8 #config FOSC_INTOSC, WDTE_OFF debug=1 'Si =1 alors log généré sur terminal tempo=0 'Tempo=1 EJP=0 'Config UART #define USART_BLOCKING true #define USART_BAUD_RATE 19200 ' Define serial port addresses #define SerInPort PORTB.5 ' RX #define SerOutPort PORTB.7 ' TX 'Set pin directions Dir SerInPort In Dir SerOutPort Out ;Defines (Constants) 'parametrage ecran LCD affichage #define LCD_IO 4 #define LCD_RS PORTC.5 #define LCD_NO_RW #define LCD_Enable PORTC.4 #define LCD_DB4 PORTC.0 #define LCD_DB5 PORTC.1 #define LCD_DB6 PORTC.2 #define LCD_DB7 PORTC.3 #define ADSpeed InternalClock InitTimer1 OSC,PS1_1 'Initialisation timer 1 dim jour,demain,tarif,tagEJP as string dim cumul1,cumul2,cumul3,cumul4 as word Dim TMR1Load alias TMR1H,TMR1L as word 'Permet de reinitialiser Timer1 dim treshold1,target as word dim cumul_signal as long dim vect(40) target=62700 'Variable-clé de Detect175Hz ! treshold1=30 treshold2=15 ; les 3 variables suivantes sont à initialiser en fonction du jour ; de démarrage de l'application: 1 si EJP - 0 sinon ; en tout état de cause elles seront correctes au bout de 24h max if !tempo then ejpstart=0 vs5=1 vs15=0 end if Dir PORTC.6 In Function Detect175Hz 'Détection du signal 175Hz ; on initialise la variable timer1 à la valeur de target et on attend l'overflow ; du timer lorsqu'il atteind sa valeur max soit 65535 ; Si target=62700 il s'écoulera 65535-62700=2835 soit à 8Mhz 2835/2=1417,5 msec ; La valeur 62700 a été déterminée par optimisation (voir blog) ; Elle devra impérativement être revue si le code de la fonction ou si la ; fréquence du processeur sont modifiés cumul1=0 cumul2=0 cumul3=0 cumul4=0 index4=0 for index = 1 to 28 '28 relevés sur 40 ms index4=index4+1 TMR1ON = 0 'Arrêt timer1 TMR1Load = target 'Initialisation de timer1 TMR1IF = 0 'Flag d'interruption timer1 initialisé TMR1ON = 1 'Démarrage timer1 readAN8=ReadAD(an8) 'Lecture signal analogique sur AN8 select case index4 case 1: cumul1=cumul1+ReadAN8 case 2: cumul2=cumul2+ReadAN8 case 3: cumul3=cumul3+ReadAN8 case 4: cumul4=cumul4+ReadAN8 end select if index4 > 3 then index4=0 end if wait until TMR1IF 'on attend l'overflow du timer1 next if (cumul1 > cumul3) then cumul1 = cumul1 - cumul3 else cumul1 = cumul3 - cumul1 end if if (cumul2 > cumul4) then cumul2 = cumul2 - cumul4 else cumul2 = cumul4 - cumul2 end if cumul1=cumul1+cumul2 if (cumul1 > treshold1) then Detect175Hz = 1 else Detect175Hz = 0 end if end function Sub Startbit 'On attend la trame de démarrage Do if Detect175Hz = 1 then 'Si signal 175Hz sur 40 ms détecté ... nbtrame = 1+testbit(24) '... on decode les 24 x 40ms suivantes returnsub = 1 if (nbtrame > treshold2 ) then savetrame=nbtrame returnsub = 2 'signal OK :-) exit sub end if end if Loop end Sub Sub Decode_frame wait 1248 ms 'On attend 1248 ms (1250ms en théorie) for i1=1 to 40 'On décode les 40 signaux Pulsadis... wait 1500 ms '... espacés de 1,5 sec vect(i1)=testbit(25) 'on stocke le nombre de trames détectées next returnsub = 3 end sub Function testbit(ntime) 'appel ntime fois fonction Detect175Hz nbtrame=0 repeat ntime nbtrame = nbtrame + Detect175Hz end repeat testbit = nbtrame '...et retourne le nbre trames détectées End function Sub Process_frame 'Traitement du signal pour affichage if debug then HSerPrint target HSerPrint " " HSerPrint savetrame HSerPrint "..." cumul_signal = 0 nbtrame = 0 for index = 1 to 40 if (vect(index) > treshold2) then nbtrame = nbtrame + 1 cumul_signal = cumul_signal + vect(index) end if if (vect(index) < 10) then HSerPrint "0" end if HSerPrint vect(index) index1 = index%5 if (index1 = 0) then HSerPrint " " else HSerPrint "-" end if next cumul_signal = 1000*cumul_signal cumul_signal = cumul_signal / nbtrame 'cumul1 doit être le + proche de 2500... HSerPrint " avg: " HSerPrint cumul_signal HSerPrint " " HSerPrint nbtrame HSerPrintCRLF end if for index = 1 to 40 'Après debug vect est transformé en 0 ou 1 if (vect(index) > treshold2 ) then vect(index) = 1 else vect(index)=0 end if if debug then HSerPrint vect(index) index1 = index%5 if (index1 = 0) then HSerPrint " " end if end if next if tempo then Code_Tempo 'Initialisation des variables Tempo else Code_EJP 'Initialisation des variables EJP end if if debug then if tempo then HSerPrint "Coherent: " HSerPrint Coherent HSerPrint " - Today: " HSerPrint jour HSerPrint " - Demain: " HSerPrint demain HSerPrint " - Tarif: " HSerPrint tarif HSerPrint " " else HSerPrint tagEJP end if HSerPrintCRLF end if if tempo then Affiche_Tempo 'Affichage Tempo else Affiche_EJP 'Affichage EJP end if returnsub = 1 end sub sub Affiche_Tempo 'Affichage du statut Tempo sur LCD 2x16 cls wait 100 ms locate 0,0 print "Now : " locate 0,8 print jour locate 0,14 print tarif locate 1,0 print "Demain: " locate 1,8 print demain end sub sub Affiche_EJP 'Affichage du statut EJP sur LCD 2x16 cls wait 100 ms locate 0,0 print "Now : " locate 1,0 print "Demain: " locate 1,8 print demain if flash_ejp then repeat 1620 'flash pendant 27 mn ... (27 x 60sec) locate 0,8 print jour wait 500 ms locate 0,8 print " " wait 500 ms end repeat else locate 0,8 print jour end if end sub function Coherent 'Test coherence des signaux test1=vect(18)+vect(21)+vect(24)+vect(29) 'Lendemain Bleu, Blanc, Rouge test2=vect(33)+vect(36)+vect(39) 'Jour Bleu, Blanc, Rouge test3=vect(23)+vect(26) 'HC Rouge, HP Rouge test4=vect(32)+vect(35) 'HC Blanc & Bleu, HP Blanc & Bleu Coherent=0 if test2 then if vect(39) then Coherent = (test1 and test3) else Coherent = (test1 and test4) end if end if end function sub Code_Tempo 'Initialisation var Tempo jour="Bleu " if (vect(36 )= 1) then jour = "Blanc " end if tarif = "HC" if (vect(35) = 1) then tarif = "HP" end if if (vect(39 )= 1) then jour = "Rouge " tarif = "HC" if (vect(26) = 1) then tarif="HP" end if end if demain = "Bleu " if (vect(21) = 1) then demain = "Blanc " end if if (vect(24) = 1) then demain = "Rouge " end if if (vect(29) = 1) then demain = "???? " end if end sub sub Code_EJP if debug then TagEJP="NON EJP" if (vect(5) and !vect(15)) then TagEJP="Alerte EJP" end if if (!vect(5) and vect(15)) then TagEJP="Fin EJP" end if if (vect(5) and vect(15)) then TagEJP="Preavis EJP" end if end if ; démarrage effctif de la journée EJP après 30' de préavis ; ce flag restera actif jusqu'à l'apparition du flag fin de journée EJP if vs5 & vs15 & !vect(5) & !vect(15) then ejpstart = 1 end if ; fin de la journée EJP if !vect(5) & vect(15) then ejpstart = 0 end if jour = "---" if ejpstart then jour = "EJP" end if ; signal de préavis 30' avant début journée EJP flash_ejp = 0 if vs5 & !vs15 & vect(5) & vect(15) then jour = "EJP" flash_ejp = 1 end if demain = "---" if vect(5) & !vect(15) then demain = "EJP" end if if vs5 & !vs15 & !vect(5) & vect(15) then demain = " EJP" end if ; Save bits 5 & 15 pour traitement suivant vs5=vect(5) vs15=vect(15) end sub ; ; Main program ; cls wait 1 s if debug=1 then HSerPrint "Entering Tempo..." HSerPrintCRLF end if returnsub = 1 do Select case returnsub case 1: Startbit case 2: Decode_frame case 3: Process_frame end Select loop