Soyez le premier à donner votre avis sur cette source.
Vue 8 654 fois - Téléchargée 809 fois
/*========================================================================== DECODEUR TRAME EJP Programme en Langage C ,Compilateur Hi Tech Ansi Compiler ==========================================================================*/ #include <htc.h> #include <stdio.h> /*========================================================================== Configuration Bits: Oscillateur Interne 4Mhz WatchDog Désactivé MCLR en interne Power Time Up désactivé Brown Out Detect désactivé NB:Cette configuration est à faire dans le menu Configure-->Configure Bits ==========================================================================*/ #define _XTAL_FREQ 4000000 // Necessaire pour le calcul d'une temporisation /*========================================================================== Definition des Variables ==========================================================================*/ #define LEDROUGE RC0 #define LEDVERTE RA2 unsigned char c=0; unsigned char flag_timer=0; unsigned char flag_sync=1; unsigned int s=0; unsigned int k=0; unsigned int j=0; unsigned int l=0; unsigned int m=0; unsigned char i=1; unsigned int seuil=7168; unsigned int timer_read; unsigned int delta=0; unsigned int d=0; unsigned char calcu_vr=0; unsigned char front_montant=0; unsigned char bit_1=0; unsigned char bit_0=0; unsigned char start_trame=0; unsigned char bit_5_sup=0; unsigned char bit_5_inf=0; unsigned char bit_15_sup=0; unsigned char bit_15_inf=0; unsigned int old_delta=0; /*========================================================================== Configuration de la liaison série RS232 pour debogage ==========================================================================*/ void SetupUART(void){ SPBRG=0b00011001;BRGH=1;BRG16=0; //9600Bauds SYNC=0;SPEN=1;//Asyncrone, com allowed TXEN=1;CREN=0;//TX allowed & RX not allowed SCKP=0;//invert polarity } /*========================================================================== Fonction transmission data par la liaison série ==========================================================================*/ void SendUART(unsigned char tx){ while (TXIF==0); TXREG=tx; } /*========================================================================== Configuration du convertisseur Analogique Numérique (10 Bits) ==========================================================================*/ void SetupADC(void){ ANSEL = 0x00; // An0-7 digital ANSELH = 0x01; // AN8 en entrée analogique numerique ADCON0 = 0b10100001; // ADC on ADCON1 = 0x60; //Fosc/64 } /*========================================================================== Fonction Lecture tension analogique de la Voie 8 pour la tension Trame EJP ==========================================================================*/ unsigned int ConvertADC(){ unsigned int result=0; CHS3=1;CHS2=0;CHS1=0;CHS0=0; //Lecture voie AN8 ADON=1; GO_DONE=1;//Start conversion while (GO_DONE ); //Wait for end of conversion result=ADRESH; result<<=8; result|=ADRESL; return result; //Retourne la lecture analogique en numérique } /*========================================================================== Fonction sortie Etat leds suivant le bit 5 et 15 de la trame EJP ==========================================================================*/ void exploite_visu( unsigned char b_5_s, unsigned char b_15_s, unsigned char b_5_i, unsigned char b_15_i) { unsigned char led_5,led_15; led_5=b_5_s+b_5_i; led_15=b_15_s+b_15_i; if(led_5==1 && led_15==0){LEDROUGE=0;LEDVERTE=0;} else if (led_5==0 && led_15==1) {LEDVERTE=0;LEDROUGE=1;} else if (led_5==1 && led_15==1) {LEDROUGE=0;LEDVERTE=1;} else{ LEDROUGE=1;LEDVERTE=0;} } /*========================================================================== Routine interruption Timer appelé toutes les 700hz ==========================================================================*/ static void interrupt timer() { if (RABIF && RB4==1 && flag_sync==1)// Si synchro 50hz detecté { flag_sync=1; c++; if (c==1){ TMR1H=0; //Init timer 1 à 0 TMR1L=0; } if (c==2) // Calcul du Timer séparant une periode secteur 50hz { c=0; timer_read=0xFFFF-(TMR1H<<8 |TMR1L)/14; TMR1H=(timer_read & 0xFF00)>>8; TMR1L=timer_read & 0x00FF; flag_timer=1; // Autorisation acquisition signal Trame pour la période suivante flag_sync=0; j=0; s=0; } RABIF=0; } else{ RABIF=0; } if(TMR1IF && flag_timer==1) { flag_timer=1; TMR1H=(timer_read & 0xFF00)>>8; TMR1L=timer_read & 0x00FF; if (calcu_vr == 0) // Calcul de la moyenne du seuil sur 20 périodes secteur=20*20ms à la mise sous tension { l++; m++; s=(ConvertADC())+s; if (m<=20) { if (l==14){ if (m == 1) { if(s< 8000 && s> 6000){seuil=s;} else {m=0;} } else { if(s< 8000 && s> 6000){seuil=(s+seuil)/2;} } } if (l>=15){ k=0;s=0; j=0;d=0; l=0; } } else{ m=0; k=0;s=0; j=0;d=0; l=0; calcu_vr=1; // Depart traitement Trame EJP flag_sync=1; flag_timer=0; } } else if (calcu_vr==1 ) // Traitement trame EJP { k++; j++; calcu_vr=1; s=ConvertADC()+s; // Accumulation des échantillons de la Trame if (j==14){// Sur 20ms if (s>seuil){delta=s-seuil;} if (s<seuil){delta=seuil-s;} if (s==seuil){delta=0;} // Si trame detecte incrémente variable d if (old_delta>delta){ if (old_delta-delta>0x10){d++;} } if (old_delta<delta){ if (delta-old_delta>0x10){d++;} } old_delta=delta; } if (j>=15){ j=0; s=0; flag_sync=1; flag_timer=0; } if (k== 233 && front_montant==0)// sur 1 sec { front_montant=0; if (d>=10) {// Si niveau 175hz detecté front_montant=1; d=0; k=0; s=0; j=0; bit_1=1; } k=0; d=0; } if (bit_1==1 && !start_trame && front_montant==1) { front_montant=1; bit_1=1; if (k>=641) // Sur 2.75s à verifier { if (d<=15) { bit_0=1; front_montant=1; } else { bit_0=0; front_montant=0; bit_1=0; } k=0; j=0; s=0; d=0; } } if (bit_1== 1 && bit_0==1){ start_trame=1; front_montant=1; bit_1=1; bit_0=0; i=1; k=0; d=0; j=0; s=0; } if (start_trame==1) { start_trame=1; front_montant=1; bit_0=0; if (i==5 || i==15){ if (k==233) // sur 1 sec { if (d>=10) { d=0; s=0; j=0; if (i==5) {bit_5_sup=1;} if (i==15) {bit_15_sup=1;} } else if (d<10){ d=0; s=0; j=0; if(i==5) {bit_5_sup=0;} if (i==15){bit_15_sup=0;} } } if (k>=633) // sur 2.5sec { if (d>=10){ d=0; s=0; j=0; k=0; if (i==5) {bit_5_inf=1;} if (i==15) {bit_15_inf=1;} } else if (d<10){ d=0; s=0; j=0; k=0; if(i==5) {bit_5_inf=0;} if (i==15){bit_15_inf=0;} } i++; } } else if (i==40) // Sin fin de Trame { if (k>=633){ start_trame=0; front_montant=0; k=0; s=0; d=0; j=0; bit_1=0; bit_0=0; i=1; exploite_visu(bit_5_sup,bit_15_sup,bit_5_inf,bit_15_inf); } } else { if (k>=633){ k=0; j=0; i++; s=0; d=0; } } } } TMR1IF=0; } else{ TMR1IF=0; } } void main(void) { SetupUART(); SetupADC(); TRISC0=0; TRISA= 0b00000000; WPUB = 0; TRISB4=1; TRISB5=0; TRISB7=0; C1ON=0; C2ON=0; SSPCON=0; ADON=0; INTE=0; INTF=0; SSPEN=0; SSPSTAT=0; TRISC0=0; TRISA2=0; LEDVERTE=0; LEDROUGE=1; SetupADC(); SetupUART(); __delay_ms(100); __delay_ms(100); __delay_ms(100); __delay_ms(100); __delay_ms(100); __delay_ms(100); __delay_ms(100); __delay_ms(100); __delay_ms(100); TRISC0=0; TRISB6=0; ADIE=0; SSPIE=0; CCP1IE=0; T0IE = 0 ; GIE = PEIE = 1 ;//autorise interruption TRISB4=1; IOCB4=1; // Activation changement interrupt sur RB4 IOCB5=1; RABIE=1;// Autorise interrupt changement etat sur RB4 T0IE = 0 ; // inValid TMR0 (OPTION = 0x04) // 1Mhz --> 1 µs TMR1ON = 1 ; // Validation du TIMER1 TMR1IE=1; while (1) { // Traitement en tache infini } }
Ce montage m'intéresse par contre j'ai une interrogation : Le potentiel du secteur est mis à la masse du montage. A ma connaissance le max 232 ne fait pas isolation galvanique donc par le GND on transmet ce potentiel. De plus le max232 semble difficile a se procurer aujourd'hui.
Serait -il possible de rajouter une isolation galvanique sur le Rx Tx avec GND différent.
Je n'ai plus trop la fibre électronicien et est-ce que quelqu'un pourrais réaliser ce montage même sans cette amélioration?
Quel en serait le tarif?
http://bleuciel.edf.com/abonnement-et-contrat/les-prix/les-prix-de-l-electricite/option-ejp/l-observatoire-52417.html
avec l'historique de la saison en cours.
Pour ma part j'ai installé un simple système à relais qui me coupe les trois phases du chauffage au niveau des fusibles sur le tableau électrique, leurs voyants EJP (à EDF) ne fonctionne qu'en mode "plein tarif" le préavis ne marche pas malgré plusieurs interventions EDF et changement du boitier EJP.
Je vais testé ce montage...en utilisant des capas X2 en 630V.
La boucle infini en fin de programme sert justement à garder le programme actif en attendant l'interruption provoquer par le signal EJP.
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.