Pages: [1] 2   Go Down
Author Topic: DS1820 et Keypad  (Read 2486 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Geneva
Online Online
Faraday Member
**
Karma: 30
Posts: 3230
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Met ton code pour voir...

ne peux tu pas utiliser une fonction faite avec milli() plutôt que sleep()(?) ?
« Last Edit: November 20, 2010, 04:24:13 am by jfs » Logged

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

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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);
    }    
}
)
Logged

Geneva
Online Online
Faraday Member
**
Karma: 30
Posts: 3230
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Commence déjà par virer ce delay(1000) et remplace le par une une fonction avec millis().
Logged

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

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Help  smiley-razz

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 ?

Logged

Belgium
Offline Offline
Jr. Member
**
Karma: 1
Posts: 80
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

tu mets une interruption toutes les secondes...

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

Geneva
Online Online
Faraday Member
**
Karma: 30
Posts: 3230
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Maitriser le temps

Tu remplaces SDL_GetTicks par millis()  smiley-wink

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.
« Last Edit: November 22, 2010, 12:15:54 pm by jfs » Logged

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

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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
Logged

Geneva
Online Online
Faraday Member
**
Karma: 30
Posts: 3230
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Fait un truc du genre :

Code:
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
« Last Edit: November 23, 2010, 01:17:14 am by jfs » Logged

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

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 !
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,

Pourriez-vous m'éclairer sur ceci ?
Code:
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  :-[
Logged

Ales
Online Online
Faraday Member
**
Karma: 39
Posts: 3607
Do or DIY
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

D'après ton code ça devrait être Tc_100 la variable correspondante  smiley-wink
Logged


0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oups ! Vu merci  :o
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir et bon réveillon à tous  smiley-wink

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:
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;
          }
}
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Up !
Merci.
Logged

Pages: [1] 2   Go Up
Jump to: