L’objectif de ce projet est de proposer un montage permettant de détecter les signaux Pulsadis envoyé par ERDF. Ces signaux permettent à EdF de gérer ses tarifications spécifiques comme le contrat EJP (qui n’est plus commercialisé) ou le contrat Tempo (qui l’est encore). Ces signaux sont codés sur 40 impulsions à partir d’un signal à 175Hz qui se superpose au 50Hz secteur avec une amplitude de l’ordre de 2% du courant secteur.
Si vous disposez d’un compteur électronique, les informations peuvent être lues via le signal Teleinfo en sortie du compteur et le montage proposé ici ne présentera pas d’intérêt. Par contre, si votre compteur n’a pas une telle sortie, est éloigné ou si vous souhaitez vous affranchir de ce dernier vous pourrez trouver ce dispositif utile.
On trouvera sur le site de Matthieu Benoit une explication détaillée du fonctionnement du signal Pulsadis et son application au décodage des signaux EJP. Une variante « Tempo » est également disponible ici. On peut également trouver sur le net un montage à base de PIC16F690 avec le programme C associé mais ce dernier est d’une lecture complexe. Enfin un autre montage est proposé par Thierry Eggen à partir d’un processeur Parralax. Le code fourni pour ce dernier a inspiré le code utilisé ici.
La signification des signaux Pulsadis est donnée quant à elle à la page 125 du document de référence EdF HN 96-S-65 et disponible ici.
Bonjour,
Je vous ai laissé un message sur la page « Me contacter », n’ayant pas eu de réponse je me permets de vous écrire sur cette page.
J’ai réaliser le montage de l’ensemble PIC avec afficheur pour la version EJP.
N’ayant pas le PIC approprié, je me heurte au problème de la modification de votre programme en GCBSIC. Si je ne me trompe, certaines déclaration dans ce programme sont réaliser hors affichage principal, peut être dans l’onglet « Project » !
Que puis je faire pour arriver à mes fins ?
Merci d’avance pour votre aide.
Arsène.
Désolé ne n’avoir pas trouvé votre message plus tôt 🙁
Quel PIC souhaitez vous utiliser ?
En général la seule instruction à modifier est la déclaration en première ligne, soit en GCBASIC:
#chip 16F690, 8
Bonjour,
Dans le même cas, en consultant votre site je viens de vous lire.
Merci pour la réponse.
J’ai finalement fait des tests et réalisations avec le Pic 16F690 le faisant fonctionner sur un afficheur 1 ligne 8 caractères et en cours sur un afficheur 2 lignes 8 caractères avec rétroéclairage.
Vos trouverez des photos de cette première réalisation sur le site de Matthieu Benoit.
Cordialement.
Bonjour,
Dans le but de faire fonctionner le détecteur EJP sur un affichage LCD 2 x 8, je dois jongler avec l’affichage pour si retrouver. Pour plus de moyen d’affichage, celui ci se fait en lecture verticale.
Par exp: Trif. NB (Trif. pour Tarif et Nb pour le nombre de journée EJP).
??? 1
J’ai donc modifier le PRG mais le résultat n’est pas du tout ce que j’attendais du coté affichage.
J’ai bien 2 lignes mais au lieu de retrouver mon texte l’affichage donne des chiffres !
Derrière des ; vous verrez une autre façon de réaliser le mode d’affichage mais celui surement trop encombrant pour le bon déroulement du PRG, ne fonctionnait pas correctement non plus.
Pourriez-vous me guider vers mes erreurs sachant que j’ai fait un certain nombre d’essais avec votre PRG modifier pour une affichage sur 1 ligne fonctionne bien (voir le site de Matthieu Benoit).
Merci d’avance pour votre aide.
Ci dessous le code du PRG modifié.
; 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 ADSpeed InternalClock ‘Le convertisseur A/D utilise la fréquence du PIC
#define MaxjEjp 22 ‘Nombre Maxi de jour d’EJP par année
#define BoutonEjp porta.0 ‘Bouton ajustement nbre jours EJP sur A0
#define LedRouge portb.5 ‘Led Rouge
#define LedVerte portb.4 ‘Led Verte
Dir PORTC.6 In
Dir BoutonEjp In
Dir PORTB.4 Out
Dir PORTB.5 Out
InitTimer1 OSC,PS1_1 ‘Initialisation timer 1
dim cumul1,cumul2,cumul3,cumul4,cumul5,Tempo,TempoVerte as word
Dim TMR1Load alias TMR1H,TMR1L as word ‘Permet de reinitialiser plus facilement Timer1
dim treshold1,target as word
dim vect(40)
vs5=0
vs15=0
dim Ligne_1 as Word
dim Ligne_2 as Word
dim Aff_L1a as Word
dim Aff_L1b as Word
dim Aff_L1c as Word
dim Aff_L2a as Word
dim Aff_L2b as Word
dim Aff_L2c as Word
target=62700 ‘Variable-clé de Detect175Hz !
treshold1=30
treshold2=15
flash_ejp = 1
Tempo = 0
TempoVerte = 0
LedClignote = 0
LedVerteClignote = 1
EPRead 0,NjEJP ‘Lect des jours restant EJP dans EEPROM
wait 10 ms ‘On fait toujours une petite pause après une requette sur EEPROM
if NjEjp > MaxjEjp then NjEjp = 0 ‘Gestion du débordement du nombre de jour EJP écoulé
; Composition des Aff_L1a etc…..
Aff_L1a = « Trif. Nb » ‘ Les 3 cas d’affichage de la ligne 1
Aff_L1b = « Dmain Nb »
Aff_L1c = « Pavis Nb »
Aff_L2a = » ??? « Pad0(NjEjp) ‘ Les 3 cas d’affichage de la ligne 2
Aff_L2b = » EJP « Pad0(NjEjp)
Aff_L2c = « Norm. »Pad0(NjEjp)
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 ‘Gestion du débordement du compteur
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 ‘Si le calcul des prises de mesure est suppérieur au seuil le 175Hz est detecté
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é …
LedVerteClignote = Off ‘On arrête le clignotement de la LED Verte
if ejpstart = 1 Then ‘Si l’on devait être en situation EJP
LedVerte = Off ‘Alors on laisse la led verte OFF
Else LedVerte = On ‘Sinon on laisse la led verte ON
end if
nbtrame = 1+testbit(24) ‘… on decode les 24 x 40ms suivantes
returnsub = 1
if (nbtrame > treshold2 ) then ‘Si on a détecté 15 x le 175hz
savetrame=nbtrame
returnsub = 2 ‘signal OK 🙂
exit sub
end if
end if
If LedClignote Then ‘Clignotement des leds pour avis EJP
wait 1 ms
Tempo = Tempo + 1
If (tempo 13) Then ’26 avant
Tempo = 0
end if
End if
If LedVerteClignote Then ‘Au démarrage on fait clignoter la led verte jusqu’à la première detection 175Hz
Wait 1 ms
TempoVerte = TempoVerte + 1
If (TempoVerte 26) Then
TempoVerte = 0
End if
End if
Check_Bouton ‘On vérifie état du bouton
Loop
end Sub
Sub Check_Bouton
if BoutonEjp = On Then
wait 10 ms ‘Délai de stabilisation (debounce time)
ButtonCount = 0
Do While BoutonEjp = On
wait 10 ms
ButtonCount += 1
Loop
if ButtonCount > 40 then ‘Appui long: Règlage puis affichage
NjEjp = NjEjp + 1
if NjEjp > MaxjEjp then NjEjp = 0
EPWrite 0, NjEjp
wait 10 ms
end if ‘Appui court: Affichage seulement
Affiche_EJP ‘On affiche les jours du Bouton
end if
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
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
; démarrage effctif de la journée EJP après préavis
; ce flag restera actif jusqu’à l’apparition du flag fin de journée EJP
if vs5 & vs15 & (1-vect(5)) & (1-vect(15)) then ‘EJP démarrage on ne clignote plus les leds
ejpstart = 1
Ligne_1 = Aff_L1a ;Locate 0,0 ‘Affichage sur LCD du tarif EJP
;Print « Trif. Nb » ‘
Ligne_2 = Aff_L2b ;Locate 1,0
;print » EJP »
;Locate 1,6
;Print Pad0(NjEjp) ‘Et la valeur du compteur
LedRouge = On ‘On passe les LEDs en tarif EJP
LedVerte = Off
LedClignote = Off
end if
; fin de la journée EJP
if (1-vect(5)) & vect(15) then ‘Fin d’EJP (pas 5 et 15)
ejpstart = 0
FlagEjp = 0 ‘Utilisé pour le compteur NjEJP
Ligne_1 = Aff_L1a ;Locate 0,0 ‘Affichage sur LCD du tarif Normal
;Print « Trif. Nb »
Ligne_2 = Aff_L2c ;Locate 1,0
;Print « Norm. »
;Locate 1,6
;Print Pad0(NjEjp)
If (1-LedClignote) Then ‘On passe les LEDs en tarif Normal
LedRouge = Off
LedVerte = On
end if
end if
If (ejpstart & (1-FlagEjp)) then ‘Si la journée d’EJP démarre et FlagEjp = 0
NjEjp = NjEjp + 1 ‘On incrémente le nbre de jour d’EJP
if NjEjp > maxjEjp then NjEjp = 0 ‘On gère le débordement du nombre de jours EJP
EPWrite 0, NjEjp ‘On ecrit dans EEPROM le nombre de jour d’EJP déjà passé
wait 10 ms ‘Pause après écriture EEPROM
FlagEjp = 1 ‘On met le FlagEjp à 1 pour la suite éviter la rotation d’incrémentation du compteur NjEjp
end if
; signal de préavis avant début journée EJP
if vs5 & (1-vs15) & vect(5) & vect(15) then ‘Confirmation EJP après le préavis de la veille (mémoire : 5 et pas 15 // trame actuel : 5 et 15)
LedClignote = On ‘On fait clignoter les LEDs en cas de préavis
end if
if vect(5) & (1-vect(15)) then ‘Préavis d’EJP le lendemain (5 et pas 15)
LedClignote = On ‘On fait clignoter les LEDs en cas de préavis
Ligne_1 = Aff_L1b ;Locate 0,0 ‘Affichage sur LCD du tarif Préavis
;Print « Dema. Nb »
Ligne_2 = Aff_L2b ;Locate 1,0
;Print » EJP »
;Locate 1,6
;Print Pad0(NjEjp)
end if
if vs5 & (1-vs15) & (1-vect(5)) & vect(15) then ‘Si On eu un préavis et que la trame de stop arrive il faut continuer à informer du préavis
LedClignote = On ‘On fait clignoter les LEDs en cas de préavis
Ligne_1 = Aff_L1c ;Locate 0,0 ‘Affichage sur LCD du tarif Préavis
Ligne_2 = Aff_L2b ;Print « Preav. »
end if
; Save bits 5 & 15 pour traitement suivant
vs5=vect(5)
vs15=vect(15)
returnsub = 1
end sub
sub Affiche_EJP ‘Affichage du statut EJP sur LCD 2×8
if flash_ejp then ‘A la mise en service on affiche le texte « START »
locate 0,2 ‘Position de l’affichage, ligne 0, 2ème caractère
print « Start » ‘On affiche « Start »
wait 2000 ms ‘Tempo de 2s
cls
flash_ejp = off
Locate 0,0 ‘A La mise ne service on ne connait pas le mode en cours, à la aposition ligne 0, position 1 caractère
Print Aff_L1a ‘On affiche « Trif. » pour Tarif et Nb pour nombre
Locate 1,0
Print Aff_L2a
end if
‘On affiche la valeur nb jours EJP en mémoire
Locate 1,0
Print Ligne_2 ‘ » ??? »
‘Locate 1,6
‘Print Pad0(NjEjp)
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 500 ms
Affiche_EJP
returnsub = 1
cumul5 = 0
Tempo = 0
FlagEjp = 0
do
Select case returnsub
case 1: Startbit
case 2: Decode_frame
case 3: Process_frame
end Select
loop
J’ai regardé rapidement votre code.
Je pense qu’il faut que vous déclariez vos variables Aff_* comme des strings et non comme des words.