Bienvenue aux nouveaux arrivants sur FantasPic !
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Modérateur : Jérémy
Programme qui se bloque
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Bonsoir à tous,
Je recherche un œil neuf sur mon programme de gestion de mes stores bannes !
En effet après quelques mois d'utilisation, je me rends compte que de temps en temps le programme se bloque et m'oblige à couper le couper le courant puis à le remettre pour que ça reparte.
Comme j'utilise la watchdog que je ne connais pas trop, je sais pas trop d'ou cela peut venir
Je me demande si ce n'est pas a cause de l'uart ? Peut etre que je devrais rajouter un timeout à l’intérieur de celui-ci ?
Je vous mets le code ici , si il manque quelques choses , demandez moi.
Merci a ceux qui pourront jeter un œil !
Merci
Je recherche un œil neuf sur mon programme de gestion de mes stores bannes !
En effet après quelques mois d'utilisation, je me rends compte que de temps en temps le programme se bloque et m'oblige à couper le couper le courant puis à le remettre pour que ça reparte.
Comme j'utilise la watchdog que je ne connais pas trop, je sais pas trop d'ou cela peut venir
Je me demande si ce n'est pas a cause de l'uart ? Peut etre que je devrais rajouter un timeout à l’intérieur de celui-ci ?
Je vous mets le code ici , si il manque quelques choses , demandez moi.
Merci a ceux qui pourront jeter un œil !
Code : Tout sélectionner
/*
DS : PIC16F1825 : http://ww1.microchip.com/downloads/en/devicedoc/41440a.pdf
DS : AMB8220 : https://www.we-online.de/katalog/manual/2603011021000_Triton%202603011x2100x%20Manual_rev1.pdf
le module se reveille toutes les 2 secondes (watchdog) et reste allumé pendant 200ms ( TMR0 )
Dès la premiere donnée recue par voir radio il reste allumé tant qu'il recoit une ligne de vie
A l'allumage de l'ecran , l'ecran envoie des données toutes les 100ms pendant 3 secondes ensuite il passe une LDV / seconde
Quand il ne recoit plus de ligne de vis il attend 3 secondes et repasse en veille
Si un relais est activé il reste activer maximum 15 secondes
*/
//#############################################################################
//---------------------------- INCLUDES ---------------------------
#include "Ordre_define.h"
#define LED LATC3_bit
#define Montee_D LATC2_bit
#define Descend_D LATC1_bit
#define Descend_G LATC0_bit
#define Montee_G LATA2_bit
#define AMB_RST LATA5_bit
#define AMB_WUP LATA4_bit
//############################## VARIABLES ################################################
unsigned int i=0,CPT_100ms=0, Compteur_relais=0, CPT_10ms=0;
//-------- UART
unsigned char tmp=0, Valeur=0 ;
char Parametre_OK=0, DATA=0, RSSI=0, F_DATA_OK=0, F_Sleep_OK=0;
char F_Sleep;
//############################## PROTOTYPES ###############################################
void Sleep_mode_on();
void Sleep_mode_off();
void Conf_AMB8220();
//##############################################################################
//----------------------- INTERRUPTION -----------------------------
void interrupt(){
if (TMR0IF_bit){ // Determine le temps d'allumage du circuit : 200ms
TMR0IF_bit = 0;
TMR0 = 61;
CPT_100ms++;
F_Sleep = 0;
if (CPT_100ms>=2){
CPT_100ms=0 ;
F_Sleep = 1 ;
}
}
if (TMR1IF_bit){ // Determine la durée maximum d'allumage des relais
TMR1IF_bit = 0;
TMR1H = 0x0B;
TMR1L = 0xDC;
Compteur_relais++;
if (Compteur_relais >= 48 ){
Compteur_relais = 0 ;
TMR1IE_bit = 0; // j'éteins le TIMER
Montee_D = Montee_G = Descend_D = Descend_G = 0; // j'éteins les relais
}
}
if (TMR2IF_bit){
TMR2IF_bit = 0;
if (TMR1IE_bit == 0) CPT_10ms++;
F_Sleep = 0;
if (CPT_10ms >= 300){
CPT_10ms = 0;
TMR0IE_bit = 1;
F_Sleep = 1 ;
}
}
//----------------------- UART -----------------------------
if (RCIF_bit == 1) {
tmp = UART1_Read(); // On récupere et stock la donnée
switch (Valeur){
case 0: if (tmp == 0x02){ // Start signal
Valeur = 1;
}
else
Valeur = 0;
break;
// Numéro de la commande recue
case 1: if (tmp == 0x49) // Parametre OK
Valeur = 2;
else if (tmp == 0x81) // Validation d'un envoi
Valeur = 10;
else if (tmp == 0x68) // reponse d'une demande de sleep
Valeur = 20;
else
Valeur = 0;
break;
case 2: if (tmp == 0x01) // Nombre bytes
Valeur = 3;
else{
Valeur = 0;
}
break;
case 3: if (tmp == 0x00) //status
Valeur = 4;
else{Valeur = 0;}
break;
case 4: if (tmp == 0x4A){ // checksum 0x02 0x49 0x01 0x00 0x4A
Parametre_OK = 1; // Je léve le FLAG
}
Valeur = 0;
break;
case 10: if (tmp == 0x03) //lenght
Valeur = 11;
else Valeur = 0;
break;
case 11: if (tmp == 0x01) //adress source, 01=ecran
Valeur = 12;
else{Valeur = 0;}
break;
case 12: DATA = tmp ; // j'enregistre les données recues
Valeur = 13;
break;
case 13: RSSI = tmp ; //RSSI
Valeur = 14;
break;
case 14: if (tmp == 0x81^DATA^RSSI){
F_DATA_OK = 1; //DATA recues et valides
}
Valeur = 0;
break;
case 20: if (tmp == 0x01) //sleep
Valeur = 21;
else{Valeur = 0;}
break;
case 21: if (tmp == 0x01) //sleep
Valeur = 22;
else{Valeur = 0;}
break;
case 22: if (tmp == 0x6A){ //sleep
F_Sleep_OK = 1;
}
Valeur = 0;
break;
}
}
}
/*#################################################################################################
################################ MAIN #######################################
#################################################################################################*/
void main() {
LATA = LATC = 0x00;
ANSELA = ANSELC = 0x00;
WPUA = 0b00000011 ; // RA0 et RA1 pull-up
TRISC3_bit = 0; // LED
TRISA4_bit = TRISA5_bit = 0; // AMB_RST et AMB_WUP
TRISA2_bit = TRISC0_bit = TRISC1_bit = TRISC2_bit = 0; // Relais
//******* OSCILLATEUR ******
OSCCON = 0b00111010 ; // PLL disable ; MF 500 Khz ; internal OSC
AMB_RST = 1;
AMB_WUP = 1;
//-------------------------- INTERUPT. TIMER0 : 100ms ---------------------------------
OPTION_REG = 0x05; // Prescaler 1:64; pullup actived p.189
TMR0 = 61; // TMR0 Preload = 61
TMR0IE_bit = 0 ; // p.93
TMR0IF_bit = 0; // p.93
//-------------------------- INTERUPT. TIMER1 : 1s ---------------------------------
T1CON = 0x11; //Prescaler 1:2; timer1=ON ; p.197
TMR1H = 0x0B; // TMR1 Preload = 3036
TMR1L = 0xDC;
TMR1IF_bit = 0;
TMR1IE_bit = 0;
//-------------------------- INTERUPT. TIMER2 : 10ms ---------------------------------
T2CON = 0x24; // Prescaler 1:1; Postscaler 1:5;
PR2 = 249; // TMR2 Preload = 249;
TMR2IF_bit = 0;
TMR2IE_bit = 0;
//------------------------------ INTERUPT. UART -------------------------------------
PEIE_bit = 1; // Active les INT peripherique p.93
RCIE_bit = 1; // Active les Interruptions sur Rx UART p.94
RCIF_bit = 0; // RAZ flag p.98
//******* UART ******
UART1_Init(9600);
//******* WATCHDOG ******
WDTCON = 0b00010110 ; // timer period=2s ; SWDTEN=1 p.107
SWDTEN_bit = 0 ;
//------------------------------- INTERRUPTION ----------------------------------------
GIE_bit = 1; // Active toutes les INT p.93
CPT_100ms = CPT_10ms = Compteur_relais = 0;
F_Sleep = 1;
//Conf_AMB8220();
/*#################################################################################################
################################ BOUCLE PRINCIPALE #######################################
#################################################################################################*/
while (1){
// Mise en veille par le TIMER 0
if (F_Sleep == 1){ // C'est l'heure de dormir
F_Sleep = 0;
Sleep_mode_on(); // je met le module radio en veille avanbt d'eteindre les INT
GIE_bit = 0; // j'eteins les int
TRISA4_bit = TRISA5_bit = 1;
TRISC3_bit = 1; // LED
TRISA4_bit = TRISA5_bit = 1; // AMB_RST et AMB_WUP
WPUA = 0b00111011 ; // RA0 et RA1 pull-up
WPUC = 0b00111000 ;
LED = 0;
SWDTEN_bit = 1; // j'active le watchdog configurer sur 2s
asm CLRWDT ;
asm sleep ; // j'endors le PIC pour 2 secondes et il se reveilera grace au watchdog pour uneb durer determiner par le timer 0
asm nop ;
LED = 1;
SWDTEN_bit = 0; // J'éteins le watchdog
TRISC3_bit = 0; // LED
TRISA4_bit = TRISA5_bit = 0; // AMB_RST et AMB_WUP
WPUA = 0b00000011 ; // RA0 et RA1 pull-up
WPUC = 0b00000000 ;
Sleep_mode_off(); // Je réveil le module radio
TMR0 = 61; // TMR0 Preload = 61
CPT_100ms = Valeur = 0;
TMR0IE_bit = 1 ;
GIE_bit = 1;
}
asm CLRWDT ;
// reception d'une donnée
if (F_DATA_OK == 1){
F_DATA_OK =0; // raz flag
TMR0IE_bit = 0; // J'arrete la mise en veille
TMR0 = 61;
CPT_100ms = 0 ;
CPT_10ms = 0;
switch (DATA){
case STOP_Ban : Montee_D = Montee_G = Descend_D = Descend_G = 0; Compteur_relais = 0 ; break;// j'éteins les moteurs
case Monte_Ban_G : Descend_G = 0; delay_ms(50); Montee_G = 1; Compteur_relais = 0 ; TMR1IE_bit = 1; break;
case Descend_Ban_G : Montee_G = 0; delay_ms(50); Descend_G = 1; Compteur_relais = 0 ; TMR1IE_bit = 1; break;
case Monte_Ban_D : Descend_D = 0; delay_ms(50); Montee_D = 1; Compteur_relais = 0 ; TMR1IE_bit = 1; break;
case Descend_Ban_D : Montee_D = 0; delay_ms(50); Descend_D = 1; Compteur_relais = 0 ; TMR1IE_bit = 1; break;
case Monte_Ban_GD : Descend_D = Descend_G = 0; delay_ms(50); Montee_G = Montee_D = 1; Compteur_relais = 0 ; TMR1IE_bit = 1; break;
case Descend_Ban_GD : Montee_G = Montee_D = 0; delay_ms(50); Descend_D = Descend_G = 1; Compteur_relais = 0 ; TMR1IE_bit = 1; break;
case Reveil : TMR2IE_bit = 1; break; // je recois une ligne de vie, je raz le comtpeur
default: Montee_D = Montee_G = Descend_D = Descend_G = 0;
}
}
}
}
/*#################################################################################################
################################ PROGRAMME SECONDAIRE ####################################
#################################################################################################*/
void Sleep_mode_on(){
// rentrer en LPM ( Low Power Mode)
// envoie en hexa (02 28 01 01 2A)
// Response (02 68 01 01 6A)
do{
UART1_Write(0x02); // Start
UART1_Write(0x28); // Commande
UART1_Write(0x01); // Lenght
UART1_Write(0x01); // LPM
UART1_Write(0x2A); // CS
delay_ms(50);
}while (F_Sleep_OK == 0 );// Attente de la réponse
F_Sleep_OK = 0; // RAZ flag
}
//----- Cette fonction sort mon module de la veille
void Sleep_mode_off(){
AMB_WUP = 0;
delay_ms(10);
AMB_WUP = 1;
}
/*#############################################################################################
Cette fonction est la pour une premiere configuration lors du premier branchement. Ensuite il faut la mettre en commentaire
Sinon il faut effectuer un RESET apres effectué des modifs non-volatiles
*/
void Conf_AMB8220(){
// réglagle du RF_data_rate pour une meilleur sensibilité (02 09 02 01 03 0B)
do{
UART1_Write(0x02); // Start
UART1_Write(0x09); // Commande
UART1_Write(0x02); // Lenght
UART1_Write(0x01); // offset
UART1_Write(0x03); // parametre=3; = data rate=6kbps
UART1_Write(0x0B); // CS
delay_ms(100);
}while (Parametre_OK == 0 );// Attente de la réponse
Parametre_OK = 0; // RAZ flag
// réglagle du Tx_Power pour diminuer la conso en émission ( 02 09 02 04 00 0D )
do{
UART1_Write(0x02); // Start
UART1_Write(0x09); // Commande
UART1_Write(0x02); // Lenght
UART1_Write(0x04); // offset
UART1_Write(0x00); // parametre
UART1_Write(0x0D); // CS
delay_ms(100);
}while (Parametre_OK == 0 );// Attente de la réponse
Parametre_OK = 0; // RAZ flag
// réglagle du numero d'ID sur le réseau ( 02 09 02 03 02 08)
do{
UART1_Write(0x02); // Start
UART1_Write(0x09); // Commande
UART1_Write(0x02); // Lenght
UART1_Write(0x03); // offset
UART1_Write(ID_banette); // parametre:0x02
UART1_Write(0x0A^ID_banette); // CS
delay_ms(100);
}while (Parametre_OK == 0 );// Attente de la réponse
Parametre_OK = 0; // RAZ flag
}
Merci
Programme qui se bloque
Programme qui se bloque
Programme qui se bloque
Programme qui se bloque
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
En toute logique je n'ai qu'une boucle bloquante. C'est celle qui réveille le module radio. Le problème doit donc venir d'ici.
Après analyse les INT ne reset pas le PIC. Les INT lève seulement un drapeau. Donc si le PIC est bloqué dans une boucle, il ne verra jamais le drapeau se lever et donc jamais il sera endormi par le watchdog donc rien n'est reseter.
Après analyse les INT ne reset pas le PIC. Les INT lève seulement un drapeau. Donc si le PIC est bloqué dans une boucle, il ne verra jamais le drapeau se lever et donc jamais il sera endormi par le watchdog donc rien n'est reseter.
Programme qui se bloque
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Un truc m'échappe .
Dans cette boucle qui met en veille le module radio. En fait j'envoie l'ordre de mise en veille en permanence, tant que j'ai pas reçu de réponse positive. Ce que j'ai du mal a comprendre, c'est que OK, il arrive une erreur de réception sur l'UART. Mais le coup d’après le message devrait bien passé non ?
Sauf , vous me direz si c'est possible, Quand j’envoie l'ordre de mise en veille du module radio, celui ci le reçoit, envoie la confirmation ( que je reçois mal) puis passe en veille. C'est donc quand je reçois mal une réponse de mise en veille que le bug se produit ?
Du coup dans ce cas de figure précis, la boucle ne sert à rien car la répétition de l’ordre est inefficace vu que le module est en veille et donc par définition sourd.Il serait préférable d'augmenter un peu la temporisation mais de ne pas faire de boucle ou de limiter le nombre de boucles à 3 par exemple.
Dans cette boucle qui met en veille le module radio. En fait j'envoie l'ordre de mise en veille en permanence, tant que j'ai pas reçu de réponse positive. Ce que j'ai du mal a comprendre, c'est que OK, il arrive une erreur de réception sur l'UART. Mais le coup d’après le message devrait bien passé non ?
Sauf , vous me direz si c'est possible, Quand j’envoie l'ordre de mise en veille du module radio, celui ci le reçoit, envoie la confirmation ( que je reçois mal) puis passe en veille. C'est donc quand je reçois mal une réponse de mise en veille que le bug se produit ?
Du coup dans ce cas de figure précis, la boucle ne sert à rien car la répétition de l’ordre est inefficace vu que le module est en veille et donc par définition sourd.Il serait préférable d'augmenter un peu la temporisation mais de ne pas faire de boucle ou de limiter le nombre de boucles à 3 par exemple.
Programme qui se bloque
Programme qui se bloque
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
L'AMB8220 est censé répondre à tout les coups. Sauf dans ce cas de figure précis, car il passe en veille ! du coup il répond une fois puis s'endort. Avec les autres commandes pas de problème, tant que lui cause il répond. C'est pour ça , qu'on peut se permettre de boucle pour éviter les erreurs, si la réponse est mauvaise on lui redemande. Mais dans ce cas la , ça fonctionne pas comme ça !
Je vais essayer avec une boucle de 3 tentatives.
Je rajoute également un RAZ de ma machine d'état UART après un réveil du PIC. Car des fois un caractère bizarre se glisse dans l'UART quand on allume un équipement.
Je ne pense pas que cela devrait être nocif pour le programme de toute façon.
Le problème c'est que c'est long a tester en vrai, étant donné que le problème survenait plutôt aléatoirement et rarement! Avec les beaux jours qui arrivent, je devrais sortir mes stores plus souvent
Je vais essayer avec une boucle de 3 tentatives.
Je rajoute également un RAZ de ma machine d'état UART après un réveil du PIC. Car des fois un caractère bizarre se glisse dans l'UART quand on allume un équipement.
Je ne pense pas que cela devrait être nocif pour le programme de toute façon.
Le problème c'est que c'est long a tester en vrai, étant donné que le problème survenait plutôt aléatoirement et rarement! Avec les beaux jours qui arrivent, je devrais sortir mes stores plus souvent
Code : Tout sélectionner
void Sleep_mode_on(){
// Cette fonction fait renter le module radio en LPM. j'attends la réponse 3 fois aprés je sors pour ne pas bloquer
// rentrer en LPM ( Low Power Mode)
// envoie en hexa (02 28 01 01 2A)
// Response (02 68 01 01 6A)
char CPT_LOC=0;
do{
UART1_Write(0x02); // Start
UART1_Write(0x28); // Commande
UART1_Write(0x01); // Lenght
UART1_Write(0x01); // LPM
UART1_Write(0x2A); // CS
delay_ms(50);
CPT_LOC++;
if (CPT_LOC >= 3) break;
}while (F_Sleep_OK == 0);// Attente de la réponse
F_Sleep_OK = 0; // RAZ flag
}
Code : Tout sélectionner
Sleep_mode_off(); // Je réveil le module radio
TMR0 = 61; // TMR0 Preload = 61
CPT_100ms = Valeur = 0;
TMR0IE_bit = 1 ;
Valeur = 0; // RAZ de la machine UART
GIE_bit = 1;
Programme qui se bloque
Programme qui se bloque
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 119 invités