; Programme de detection des signaux "Pulsadis" 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 ; ; Contact: pulsadis at free . fr ; ; Mars 2015 ; ; Code GCBASIC ; ; ;Chip Settings #chip 16F690, 8 #config FOSC_INTOSC, WDTE_OFF ;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 maxjrouge 22 #define maxjblanc 43 #define boutonblanc porta.0 'Bouton blanc sur A0 #define boutonrouge porta.1 'Bouton rouge sur A1 Dir PORTC.6 In Dir boutonblanc In Dir boutonrouge In InitTimer1 OSC,PS1_1 'Initialisation timer 1 dim Jour,Demain,Jour_Left,Jour_Save as string*5 dim Tarif as string*2 dim cumul1,cumul2,cumul3,cumul4 as word Dim TMR1Load alias TMR1H,TMR1L as word 'Permet de reinitialiser Timer1 dim treshold1,target as word dim vect(40) target=62700 'Variable-clé de Detect175Hz ! treshold1=30 treshold2=15 EPRead 0,Njblanc 'Lect des jours restant blanc dans EEPROM if Njblanc > Maxjblanc then Njblanc = 0 EPRead 1,Njrouge 'Lect des jours restant rouge dans EEPROM if NjRouge > MaxjRouge then NjRouge = 0 jour="BLEU " tarif="HP" demain="???? " 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 Jour_Save = Jour Check_Bouton(BoutonRouge,NjRouge,MaxjRouge) 'On vérifie état du B Rouge Check_Bouton(BoutonBlanc,NjBlanc,MaxjBlanc) 'On vérifie état du B Blanc Loop end Sub ; Check_Bouton est une macro et non une subroutine car il est impossible ; de passer le PORT en argument variable Macro Check_Bouton(bouton,nj,maxj) if Bouton = On Then wait 10 ms 'Délai de stabilisation (debounce time) ButtonCount = 0 Do While Bouton = On wait 10 ms ButtonCount += 1 Loop if ButtonCount > 40 then 'Appui long: Règlage puis affichage nj = nj + 1 if nj > maxj then nj = 0 EPWrite 0, njblanc EPWrite 1, njrouge end if 'Appui court: Affichage seulement jour="ROUGE" if maxj=maxjblanc then jour="BLANC" Affiche_Tempo 'On affiche les jours du Bouton wait 1 s Jour = Jour_save Affiche_Tempo 'On restaure l'état initial de l'écran end if end Macro 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 for index = 1 to 40 'Vect est transformé en 0 ou 1 selon seuil if (vect(index) > treshold2 ) then vect(index) = 1 else vect(index)=0 end if next Jour = "BLEU " if vect(36) then Jour = "BLANC" If vect(39) then Jour = "ROUGE" Tarif = "HC" if vect(26) or vect(35) then Tarif = "HP" Demain = "BLEU " if vect(21) then Demain = "BLANC" if vect(24) then Demain = "ROUGE" if vect(29) then Demain = "???? " ; Lorsque vect(29) passe de 0 à 1 on commence une nouvelle journée Tempo if vect(36) and vect(29) and Last29 then njblanc = njblanc + 1 if njblanc > maxjblanc then njblanc = 0 EPwrite 0,njblancj end if if vect(39) and vect(29) and Last29 then njrouge = njrouge + 1 if njrouge > maxjrouge then njrouge = 0 EPWrite 1,njrouge end if Last29=1-vect(29) Affiche_Tempo returnsub = 1 end sub sub Affiche_Tempo 'Affichage du statut Tempo sur LCD 2x16 Select case jour case "BLEU ": Jour_left = " " case "BLANC": Jour_left = Pad0(njblanc)+"/" Jour_left = Jour_left+Pad0(maxjblanc-njblanc) case "ROUGE": Jour_left = Pad0(njrouge)+"/" Jour_left = Jour_left+Pad0(maxjrouge-njrouge) end Select cls locate 0,1 print Jour locate 0,7 print Tarif locate 0,10 print Jour_Left locate 1,2 print "demain: " locate 1,10 print Demain end sub function pad0(in var) as string*2 if var < 10 then pad0=" "+str(var) else pad0=str(var) end if end Function ; Main program ; cls wait 1 s Affiche_Tempo returnsub = 1 do Select case returnsub case 1: Startbit case 2: Decode_frame case 3: Process_frame end Select loop