Go Down

Topic: DS1820 et Keypad (Read 2 times) previous topic - next topic

kafifi

Bonsoir,

Je viens de finir un bout de code qui réalise dans une boucle loop :
- lecture clavier 4x4 et affichage valeur dans serial moniteur.
- lecture DS1820 et affichage sur LCD 128*4

Cela marche mais la lecture du clavier manque de réactivité  (je dois garder la touche appuyée 1sec) à cause du sleep (1000) se trouvant dans la partie lecture DS1820.

Sachant que la séquence de lecture du DS1820 ne doit pas être interrompue, comment pourrais-je améliorer la réactivité de lecture du clavier ?

Merci.

Jean-François

#1
Nov 20, 2010, 08:02 am Last Edit: Nov 20, 2010, 10:24 am by jfs Reason: 1
Met ton code pour voir...

ne peux tu pas utiliser une fonction faite avec milli() plutôt que sleep()(?) ?
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

kafifi

milli() est bien sûr la première optimisation à faire.

Néanmoins, à terme mon code devra à la fois (en tâches principales) :
- interpréter les commandes du clavier.
- lire la température de 1 ou 2 capteurs DS1820
- communiquer via CAN ou RS485 vers d'autres cartes.

Donc je m'interroge sur l'organisation de mon code, car les séquences de
lecture OneWire et lecture/écriture RS485 ne doivent pas être interrompues.
En même temps, je dois garder une réactivité du clavier.
Sur mon ancien µ Motorola, je bouclais en continue sur une lecture clavier,
et je lançais régulièrement des routines de scrutation des entrées via la RTI
(toutes les xx ms).

Avec la durée de lecture DS1820 et RS485, je suis un peu perdu...

Mon code pas optimisé du tout  :-[


Code: [Select]
void loop()
{

 //---------------------------------------------------------------------------//
 // ONEWIRE DS1820 read
 byte i, sensor;
 byte present = 0;
 byte data[12];

 for (sensor=0;sensor<MAX_DS1820_SENSORS;sensor++)
 {
   if ( OneWire::crc8( addr[sensor], 7) != addr[sensor][7])
   {
     GLCD.GotoXY(60, 40);
     GLCD.Puts("CRC is not valid");   // print a text string
     return;
   }

   if ( addr[sensor][0] != 0x10)
   {
     GLCD.GotoXY(60, 40);
     GLCD.Puts("Device is not a DS18S20 family device.");   // print a text string
     return;
   }

   ds.reset();
   ds.select(addr[sensor]);
   ds.write(0x44,1);         // start conversion, with parasite power on at the end

   delay(1000);     // maybe 750ms is enough, maybe not
   // we might do a ds.depower() here, but the reset will take care of it.

   present = ds.reset();
   ds.select(addr[sensor]);    
   ds.write(0xBE);         // Read Scratchpad

   for ( i = 0; i < 9; i++)
   {           // we need 9 bytes
     data[i] = ds.read();
   }

   LowByte = data[0];
   HighByte = data[1];
   TReading = (HighByte << 8) + LowByte;
   SignBit = TReading & 0x8000;  // test most sig bit
   if (SignBit) // negative
   {
     TReading = (TReading ^ 0xffff) + 1; // 2's comp
   }
   Tc_100 = (TReading*100/2);    

   Whole = Tc_100 / 100;  // separate off the whole and fractional portions
   Fract = Tc_100 % 100;

   //    sprintf(buf, "%d:%c%d.%d\337C",sensor,SignBit ? '-' : '+', Whole, Fract < 10 ? 0 : Fract);
   sprintf(buf, "%c%d.%d\337",SignBit ? '-' : '+', Whole, Fract/10);


   //---------------------------------------------------------------------------//
   // DISPLAY DS1820 temp
   GLCD.CursorToXY(40, 40);
   GLCD.Puts("T= ");   // print a text string
   GLCD.Puts(buf);  // print a number
   GLCD.CursorToXY(94, 40);
   GLCD.Puts("C");
 }
 
   //---------------------------------------------------------------------------//
   // KEYPAD read
   char customKey = customKeypad.getKey();
   if (customKey != NO_KEY){
     Serial.println(customKey);
   }    
}
)

Jean-François

Commence déjà par virer ce delay(1000) et remplace le par une une fonction avec millis().
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

kafifi

Help  :P

Ce que j'ai compris :
au lieu de boucler bêtement pendant 1 sec, je surveille la valeur d'un timer.

Là ou je coince :
Tant que le timer n'est pas à "1 sec", que fait mon programme principal ? Si je reboucle sur le début, il va une nouvelle fois lancer une interrogation du capteur ds1820 alors que la précédente est en cours... Que dois-je faire ?


Gozaki

tu mets une interruption toutes les secondes...

Gozaki
----------------------------
www.laboelectronique.be

Jean-François

#6
Nov 22, 2010, 06:13 pm Last Edit: Nov 22, 2010, 06:15 pm by jfs Reason: 1

Maitriser le temps

Tu remplaces SDL_GetTicks par millis()  ;)

Ainsi si ta boucle est faite plus rapidement que la fréquence désirée pour tes mesures sur le DS1820, une boucle est refaite sans lecture de ton capteur.
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

kafifi

@Gozaki,
A tester aussi autour de cela je suppose :

Code: [Select]
void InterruptTimer()
Reste à clarifier ce que je mets dans la boucle principale et dans l'interruption.

@Jean-François,
Très instructif cette page du siteduzero !
Encore un point que je n'arrive pas à saisir, la première partie du code avant la pause d'1 sec :

- J'adresse le DS1820
- Je compare la valeur du temps avec millis().
- Si je n'ai pas encore 1000, je continue.
- Je passe par la lecture clavier (parfait, je n'ai plus la latence de 1sec).
- Mais je reviens au début du code. Il faut donc un flag qui m'empêche de redérouler le début du code.
Sinon je relance encore un adressage ds1820. Est-ce bien cela ?

PS : j'espère avoir été clair  :o

Jean-François

#8
Nov 23, 2010, 07:14 am Last Edit: Nov 23, 2010, 07:17 am by jfs Reason: 1
Fait un truc du genre :

Code: [Select]
boolean lecture = true;

void looop(){

if (lecture=true){
lit le DS1820;
lecture = false;
}

if (si la boucle est supérieur à 1000){
fait la fonction keypad;
lecture = true ;
}
}



Ou un truc approchant...  ;D
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

kafifi

Ah, ça y est, c'est monté au cerveau  :o
Je suis en déplacement prof., je m'y remets ce week-end.

Merci beaucoup pour les explications !

kafifi

Bonsoir,

Pourriez-vous m'éclairer sur ceci ?
Code: [Select]
sprintf(buf, "%c%d.%d\337",SignBit ? '-' : '+', Whole, Fract/10);

L'affichage indique 21.5 °. J'aimerais sauvegarder la valeur numérique en
mémoire car je dois ensuite comparer avec une température de consigne.

Pourriez-vous m'expliquer comment faire ? Je suis un peu perdu avec le
chiffre après la virgule...

Désolé si cela parait trivial  :-[

B@tto

D'après ton code ça devrait être Tc_100 la variable correspondante  ;)
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

kafifi


kafifi

Bonsoir et bon réveillon à tous  ;)

Je me suis repenché sur ce bout de code, mais dès que j'applique ma
première modif, le DS1820 n'affiche plus la température.

Explications de ce que je fais :
Le sous programme est appelé régulièrement dans ma boucle loop.  
Au démarrage du code, je mets le flag "lecture_en_cours" à false.

La modification de la première partie du code (activation des 3 lignes
précédées de // pose pb : plus de lecture du DS1820. Pourtant je n'ai
pas encore modifié la second partie du code (remplacement de delay
par les deux ligne du dessous.

Pourriez-vous m'aider à comprendre ce qui coince ?
Merci.

Code: [Select]
void Ds1820Capture(void)
{
 unsigned long currentMillis = millis();
 int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
 char buf[20];
 byte i, sensor; byte present = 0; byte data[12];

////////// 1/2 : Adressage / demande de mesure

     //  if (lecture_en_cours == false)
     //  {
      for (sensor=0;sensor<MAX_DS1820_SENSORS;sensor++)
       {
       if ( OneWire::crc8( addr[sensor], 7) != addr[sensor][7])
         { GLCD.GotoXY(60, 40); GLCD.Puts("CRC is not valid"); return; }
       if ( addr[sensor][0] != 0x10)
         { GLCD.GotoXY(60, 40); GLCD.Puts("Device is not a DS18S20 family device."); return; }
       ds.reset(); ds.select(addr[sensor]); ds.write(0x44,1); // start conversion, with parasite power on at the end
       lecture_en_cours = true;
     //  }

////////// 2/2 : Après 1 seconde d'attente, lecture scratchpad
     
        delay(1000);          
        //if(currentMillis - previousMillis > interval){
        // previousMillis = currentMillis;  
         present = ds.reset(); ds.select(addr[sensor]); ds.write(0xBE); // Read Scratchpad
         for ( i = 0; i < 9; i++)
           {           // we need 9 bytes
           data[i] = ds.read();
           }
         LowByte = data[0]; HighByte = data[1];
         TReading = (HighByte << 8) + LowByte;
         SignBit = TReading & 0x8000;  // test most sig bit
         if (SignBit) // negative
           {
           TReading = (TReading ^ 0xffff) + 1; // 2's comp
           }
         Tc_100 = (TReading*100/2);    
         Whole = Tc_100 / 100;  // separate off the whole and fractional portions
         Fract = Tc_100 % 100;
         //    sprintf(buf, "%d:%c%d.%d\337C",sensor,SignBit ? '-' : '+', Whole, Fract < 10 ? 0 : Fract);
         sprintf(buf, "%c%d.%d\337",SignBit ? '-' : '+', Whole, Fract/10);
         TempNow = Tc_100;
         lecture_en_cours = false;
         }
}

kafifi


Go Up