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 ---
Forum général sur le langage C !

Modérateur : Jérémy

Mode Sleep 12F1840 pour reduire la conso
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#1 Message par paulfjujo » jeu. 2 févr. 2017 15:31

bonjour à tous,


J'utilise un petit (mais costaud) PIC 12F1840 pour faire l'acquisition d'une sonde de temperature OWS 18B20
et envoyer cette info sur un terminal dans un premier temps
.. via bluetooth dans un second temps !
Le montage est alimenté en 3,3V et je compte utiliser une pile plate 4,5V (ou 3 piles 1,5V) + regulateur ASM117 3,3
pour alimenter le tout
et utiliser le mode sleep sur commande .. via équipement distant pour envoyer la commande SLEEP ou WAKEUP
pour recup de l'info sur demande et reduction de conso si pas besoin.
en mode sleep conso < 15µA
en mode normal conso < 1,15mA

le probleme est du coté reveil
ma commande WAKEUP ne passe qu'au bout de la 3em fois et je recupere dans les 2 premieres fois du "garbage"
l'UART est censé reveiller le PIC des le premier caractere qui devrait etre un BREAK code 00
mais dans la pratique il se reveille avec n'importe quel car reçu..
d'ou l'envoi de "WAKEUP<CR>"
sorti du mode sleep si au moins 1 car recu
delay pour laisser passer les autres car jusqu'au <CR>
si detection du CR , examen du buffer
si message WAKEUP je reveille le PIC , sinon je le rendors ..

nota: sans l'usage du SLEEP , je n'ai AUCUN probleme sur la reception des commandes SLEEP et WAKEUP


Attention!! il me semble que l'usage de asm sleep dans une condition if .. pose probleme ..
car le retour apres le sleep n'est pas dans le corps principal du programmme ,...est encore dans le if
Votre avis ?




Indice j= 1656 ; DS18B20#1 Temper.Amb.= 18,2500
Indice j= 1657 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1658 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1659 ; DS18B20#1 Temper.Amb.= 18,5625
SLEEP
Au dodo .. consommation < 15µA
å‘¥•­þ 1660 ; DS18B20#1 Temper.Amb.= 18,5625 <- 1eree tentative de reveil BAD
U-UA5

q‘¥•­þ 1661 ; DS18B20#1 Temper.Amb.= 18,5625 <- 2eme tentative de reveil BAD
U-UA5
WAKEUP <- 3eme tentative de reveil OK
Reveillé par reception de :55 Consom. remonte à ~1,15mA
Indice j= 1662 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1663 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1664 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1665 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1666 ; DS18B20#1 Temper.Amb.= 18,5625
SLEEP
Au dodo .. consommation < 15µA
å‘¥•­þ 1667 ; DS18B20#1 Temper.Amb.= 18,5625
U-UA5

q‘¥•­þ 1668 ; DS18B20#1 Temper.Amb.= 18,5625
U-UA5
WAKEUP
Reveillé par reception de :55 Consom. remonte à ~1,15mA
Indice j= 1669 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1670 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1671 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1672 ; DS18B20#1 Temper.Amb.= 18,5625
Indice j= 1673 ; DS18B20#1 Temper.Amb.= 18,5625

le hardware:
_12F1840_Sleep_DS18B20_Schem_pinout.jpg


le code :

Code : Tout sélectionner



 
// ATTENTION : deconnecté le signal OWS sonde DS18B20 de RA0 =ICSP DATA pour programmer avec Pickit2
#define Version "170202"
#define AVEC_MODE_SLEEP
/// modef : mise en mode sleep sur reception cde "SLEEP"
//#define Version "170202"
    
#define Langage "MikroC 7.0.0"
#define Directory "C:\\_MikroC\\_MesProjets_MikroC\\_12F1840_Sleep"
#define Projet "12F1840_Sleep_Temper_DS18B20_WakeUpbyUart_2017.mcppi"
#define Source "_12F1840_Sleep_WakeUpOnUartBreak_DS18B20_Test"      // sans extension !
#define MCU "12F1840 DIP8"
#define POWER_SUPPLY "3,3V"    // (3,3 to 4,2V battery)
#define OSCILLATEUR_INTERNE
#define FOSC 8MHZ
#define EEPROM_FILE "xxx_Eeprom.ihex"


 // deconnecter l'ICSP pour reduire la conso.
 // nota : necessite de rajouter des delais sur les UART Write ??
 // probalement à cause de la remise en route oscillateur ??
 /*
 pour utiliser l'I2C, 
 il faut reaffecter L'UART RA0 RA1 par defaut,   et L'ADC sur d'autres PIN  Hardware
  12F1840
  pin 1     VDD Alim +5.0
  pin 2     RA5   UART RX <---    UART
  pin 3     RA4   UART --> TX
  pin 4     RA3/MCLR/VPP -- ICSP Reset   R=5.6K  de rappel au +3,3V
  pin 5     RA2 --------------- I2C SDA  * option -- LCD      avec R rappel 4,7K
  pin 6     RA1  ICSP Clock  ---I2C SCL  * option -- LCD      avec R rappel 4,7K
  pin 7     RAO  ICSPDAT  ------ OWS sonde temperature  DS18B20  avec R pull up =4,7K
  pin 8    VSS alim 0V

 Mesures de courant consommé
 Vzersion avec Entree NALOGIQUE :
 Vcc=3,3V   (alim avec 3 afficheur 7seg  inp=9V DC  out reglée à  = 3,3V)
 avec Potar 4,7K entre +alim et Gnd pour consigne EA0
 consom en sleep   640µA     (mais 12 µA sans le POTAR 4,7K connecté)
  consom reveillé  1,71mA     (mais 1,09mA sans le potar connecté)
  normal car 3,3V / 4,7k = 702µA consommé rien que par le potar
  
  Alim 4 piles 1,5V -> Regulateur ACS117-3,3V
 Version avec capteur OWS 18B20
 consom en sleep   <15µA
  consom reveillé  1,15mA
*/

 //ac:Schema_sleep_12F1840


#define TAB 9
#define CLS 12
#define CR 13
#define LF 10
#define STX 2
#define ETX 3


#include "built_in.h"     // for  Hi  Lo ..etc


const code char mesg0[]="                    "; // 20 blancs pour effacer la ligne LCD
const code char mesg1[]=" Compilateur : "Langage"\n\r";
const code char mesg2[]=" Directory :"Directory"\r\n";
const code char mesg3[]=" Projet    :"Projet"\r\n";
const code char mesg4[]=" Source    :"Source"_"Version"\r\n";
const code char mesg5[]=" MCU  :"MCU"\r\n";
const code char mesg6[]=" POWER_SUPPLY: "POWER_SUPPLY"\r\n";
const code char * Messages[]={mesg0,mesg1,mesg2,mesg3,mesg4,mesg5,mesg6};


//  Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
//  18S20: 9  (default setting; can be 9,10,11,or 12)
//  18B20: 12
const unsigned short TEMP_RESOLUTION = 12;
unsigned int temp;

#define MAXLEN1 60
volatile unsigned char buffer1[MAXLEN1];
volatile unsigned  char * p1;
char TEXTE[60];
char CRam1[20];
char *txt;
char *p;

unsigned short error;
volatile unsigned int CptErr;
volatile int Index1;
volatile  unsigned char c1;
volatile unsigned int i1;
volatile int Flag_Buffer1;
unsigned int i,j,k;
unsigned int Mode_Sleep;


void strConstRamCpy(unsigned char *dest, const code char *source);
void CRLF1(void);
void interrupt(void) ;
void RAZ_Buffer1(void);


void Read_Msg_Eeprom(unsigned char depuis);
void Init_Timer0(void);
void Init_Timer1 (void);    //125mS
void Init_Timer2 (void);    //125mS
//void Float2Ascii (float x, unsigned char *str,char precision);



void interrupt(void)  org 0x04
{
 if ( (RCIE_bit) && ( RCIF_bit))
   {
   // traitement separe des erreurs de COM
      if (RCSTA.OERR==1)    // voir parag 16.1.26 p273
      {
       RCSTA.CREN = 0 ;
       c1 = RCREG;
       RCSTA.CREN = 1 ;
        CptErr++;

       }
      if(RCSTA.FERR==)
      {
      RCSTA.SPEN = 0 ;
      RCSTA.SPEN= 1 ;
      CptErr++;
       c1 = RCREG;
      }
      c1 = RCREG;
     if (c1==CR)
      {
      Flag_Buffer1=1;
      RCIE_bit=; //interdit IT Reception UART
      buffer1[i1]=0;
      Index1=i1;
      i1=0;
      c1=0;
     }
     else
     
{
        buffer1[i1]=c1;
        Index1=i1;
        i1++;

      }
     PIR1.RCIF=0   ;
   }
 }





// --- Copie le texte depuis ROM vers RAM
void strConstRamCpy(unsigned char *dest, const code char *source)
 {
  while (*source)*dest++ = *source++ ;
  *dest = 0 ;    // terminateur
}

void CRLF1()
{
 UART1_Write(CR);
 UART1_Write(LF);
}

void UART1_Write_CText(const char *txt) {
   while (*txt)
      UART1_Write(*txt++);
      asm nop
      asm nop
}

void Raz_Buffer1()
{
  
      buffer1
[0]=0;
      Index1=0;
      Flag_Buffer1 =0;
      // nettoye le buffer
      for(Index1=0;Index1<MAXLEN1;Index1++)buffer1[Index1]=0;
      c1=RCREG;
      i1=0;
      Index1=0;
      c1=0;
      RCIE_bit = 1;
      p=0;

}

void Write_Msg_Eeprom(unsigned char Adr,const char * d1)
{
 int i1 ,i;
  char c1;
  i1=Adr;
  do
  
{
  c1=*d1;
  EEPROM_Write(Adr,c1);
  if ( c1==0) break;
  if ( i1>254) break;
  Delay_ms(5);
  i1++;
  }
  while (i!=0) ;
 }
 

void Display_Temperature
(unsigned int temp2write)
{
  const unsigned int RES_SHIFT = TEMP_RESOLUTION - 8;
  char temp_whole;
  unsigned int temp_fraction;
  // Check if temperature is negative
  if (temp2write & 0x8000) {
     CRam1[0] = '-';
     temp2write = ~temp2write + 1;  // complement à 2
     }
  // Extract temp_whole
  temp_whole = temp2write >> RES_SHIFT ;

  // Convert temp_whole to characters
  if ((temp_whole/100)>0)
     CRam1[0] = temp_whole/100  + 48;
  else
     CRam1
[0] = ' ';
  if( (temp_whole/10)%10==0)
   CRam1[1]=' ';
   else
    CRam1
[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
  CRam1[2] =  temp_whole%10     + 48;             // Extract ones digit
  // Extract temp_fraction and convert it to unsigned int
  temp_fraction  = temp2write << (4-RES_SHIFT);
  temp_fraction &= 0x000F;
  temp_fraction *= 625;
   CRam1[3]=',';
  // Convert temp_fraction to characters
  CRam1[4] =  temp_fraction/1000    + 48;         // Extract thousands digit
  CRam1[5] = (temp_fraction/100)%10 + 48;         // Extract hundreds digit
  CRam1[6] = (temp_fraction/10)%10  + 48;         // Extract tens digit
  CRam1[7] =  temp_fraction%10      + 48;         // Extract ones digit
  CRam1[8]=0;
  // Print temperature
  UART1_Write_Text(CRam1);
}

 

void main
() 
{
  // FOSC INTERNE
  // voir page 61
  // 0=4xPLL OFF, 1111=IOFS=16Mhz  0=0  00=SCS=config via Conf1 word FOSC<2:0>
  // 0=4xPLL OFF, 1110=IOFS=8Mhz  0=0  00=SCS=config via Conf1 word FOSC<2:0>
  // OSCCON=0b01111000;    // choix 16Mhz  internal osc
  OSCCON=0b01110000;    // choix 8Mhz  internal osc

          // RA5 as input for RX , RA4 as output for TX RA2 as input
  TRISA=0b00101111;      // RA4 en sorties
  ANSELA=0;          // no analog
  WPUA=0b00110000;      // weak pull up on RX & TX

  CM1CON0=0;       // disable comparators
  CM1CON1=0;
   // RA4=TX RA5=RX   (voir page 111 )
  APFCON=0;
  APFCON.P1BSEL=1;    // pour deconnecter de RA0 mais connecte sur RA4 ???!!
  APFCON.RXDTSEL=1;   // RX sur RA5
  APFCON.TXCKSEL=1;   // TX sur RA4
    // RA5 as input for RX , RA4 as output for TX RA2 as input

  i=j=k=0;

  txt=&TEXTE[0];
  UART1_Init(9600);
   // re-init AGAIN , because Uart init disturbing
   //TRISA=0b00101111;      // RA0 et RA1 en sorties
   // 2 times to get empty fifo !
   if (PIR1.RCIF==1) c1 = RCREG;     // vide Fifo
   if (PIR1.RCIF==1) c1 = RCREG;     // vide fifo

   UART1_Write(CLS);
   Delay_ms(500);
   CRLF1();
   txt=&TEXTE[0];
   // presentation
   for (i=1;i<6;i++)
   {
   UART1_Write_CText(Messages[i]);
   Delay_ms(100);
   }
  // strConstRamCpy(txt,mesg1);   UART1_Write_Text(txt);
  // UART1_Write_CText(mesg2);
   CRLF1();

   txt=&TEXTE[0];
    #ifdef AVEC_MODE_SLEEP
     UART1_Write_CText("Send <SLEEP> to put PIC en mode sommeil\r\n") ;
     UART1_Write_CText("Send a BREAK character pour reveiller  le PIC\r\n");
     #else
    UART1_Write_CText("Test envoi coammndes SLEEP et WAKEUP\r\n");
   #endif
     Delay_ms(100);
     Raz_Buffer1();
     PEIE_bit = 1;
     GIE_bit = 1;
     WUE_bit = 1;
     ADC_Init();


     Mode_Sleep=0;
     j=0;
     while(1)
      { 
      
        
#ifdef AVEC_MODE_SLEEP
      
        if
((Flag_Buffer1==1) && (Mode_Sleep==0))
        {
        p=strstr(buffer1,"SLEEP");
        }
        if(p>0)
        {
          Mode_Sleep=1;
         UART1_Write_Text(buffer1);CRLF1();
          Delay_ms(100);
          UART1_Write_CText("Au dodo .. consommation < 15µA \r\n") ;
          Delay_ms(100);
          Raz_Buffer1();

         }
         if(((Flag_Buffer1==1) || (i1>0)) && (Mode_Sleep==1))
         //if(Index1>0) // if (UART_Data_Ready()==1)  au moins 1 car est arrivé
           {  
              Delay_ms
(500);  //laisse passer les autres
              UART1_Write_Text(buffer1);CRLF1();
               p=strstr(buffer1,"WAKEUP");
                  if(p>0)
                  {
                    ByteToHex(buffer1[0],CRam1);
                    Delay_ms(100);
                    UART1_Write_CText("Reveillé par reception de :");
                    Delay_ms(100);
                    UART1_Write_Text(CRam1);
                    Delay_ms(100);
                    UART1_Write_CText("  Consom. remonte à ~1,15mA");
                    CRLF1();
                    Delay_ms(100);
                    Raz_Buffer1();
                    Mode_Sleep=0;
                    Raz_Buffer1();
                  }
                  else    // reste en mode sleep
                  {
                    Mode_Sleep=1;
                  }
           }
            if( Mode_Sleep==1)
             {
                   Raz_Buffer1();
                   WUE_bit=1;  // voir page 265..etc
                    asm NOP  ;
                    asm NOP  ;
                    asm NOP  ;
                    asm NOP  ;
                    asm sleep

              
}
              #else
                if (Flag_Buffer1==1)
                {
                  p=strstr(buffer1,"SLEEP");
                  if(p>0)
                  {
                    UART1_Write_Text(buffer1);CRLF1();
                    Delay_ms(100);
                    UART1_Write_CText("Sleep.. consommation < 15µA \r\n") ;
                    Delay_ms(100);
                   }
                   p=strstr(buffer1,"WAKEUP");
                  if(p>0)
                  {
                    UART1_Write_Text(buffer1);CRLF1();
                    Delay_ms(100);
                    UART1_Write_CText("Normal. consommation ~1,15mA \r\n") ;
                    Delay_ms(100);
                   }
                     Raz_Buffer1();
                }

         #endif
         Raz_Buffer1();
         UART1_Write_CText("Indice j=");
         WordToStr(j,CRam1);
         Delay_ms(100);
         UART1_Write_Text (CRam1);
         Delay_ms(100);
         UART1_Write(TAB);
         j++;
         Ow_Reset(&PORTA, 0);                         // Onewire reset signal
         Ow_Write(&PORTA, 0, 0xCC);                   // Issue command SKIP_ROM
         Ow_Write(&PORTA, 0, 0x44);                   // Issue command CONVERT_T
         Delay_us(200);
         Ow_Reset(&PORTA, 0);
         Ow_Write(&PORTA, 0, 0xCC);                   // Issue command SKIP_ROM
         Ow_Write(&PORTA, 0, 0xBE);                   // Issue command READ_SCRATCHPAD
         temp =  Ow_Read(&PORTA, 0);
         temp = (Ow_Read(&PORTA, 0) << 8) + temp;
           //--- Format and display result
            UART1_Write_CText(" ; DS18B20#1 Temper.Amb.=");
            Delay_ms(100);
            Display_Temperature(temp);
            CRLF1();

            Delay_ms(3000);  // le temps de lire la consommation
        } //while1
}
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

Mode Sleep 12F1840 pour reduire la conso
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#2 Message par paulfjujo » jeu. 2 févr. 2017 16:01

il semblerait bien que le premier car pour reveiller le PIC
ait un codage < 0x3F ..
test avec >WAKEUP ..OK pas de garbage !
test avec .WAKEUP .. OK pas de garbage !

:mur: je vais essayer de trouver un explicage ...

page 266 Datasheet
26.4.3 AUTO WAKE P BREAK
.. the initial character in the transmission must be all '0'S.
This must be 13 times for LIN bus ,or any number of bit times for RS232
il semblerait donc que les 2 premiers bits de
">" = 0011 1110
ou
"." = 0010 1110
suffisent à sortir du mode sleep et reactiver l''UART
Aide toi, le ciel ou FantasPic t'aidera

Mode Sleep 12F1840 pour reduire la conso
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » dim. 5 févr. 2017 09:57

Bonjour Paul et tout le monde,

désolé ne pas pouvoir t'aider plus que ca sur ce coup !
C'est en faisant des erreurs, que l'on apprend le mieux !!!


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 31 invités