[ Accueil ] [ CONTACT ] [ PLAN du Site ] [ RCNV ] [ Publications ] [ Chantiers Bateaux ] [ Technique Modélisme ] [ Electronique ] [ Radios Vintage ] [ Multi-Switch ] [ Vrac ] [ Astuces ] [ Liens ] [ Base ] [ Compteur ]
 

 ...     rgl

 

Datalogger

avec horloge RTC DS1307

 

Datalogger et son extension de mémoire en option

Application Picaxe

(c)  R.LEGAT  

 

 SOMMAIRE:

-  Introduction - Eléments constitutifs

-  Le bus i2c

-  Résumé du protocole i2c

-  Les commandes i2c du Datalogger

-  Etude de l'EEprom 24LC16B
            -  Organisation des blocs mémoire
            -  Adressage des 8 blocs
   
            -  Le buffer d'écriture de page (Ecriture de plusieurs octets en une seule opération)
           
-  Tests d'écritures dans l'EEprom 24LC16B, avec et sans dépassement de la capacité du buffer et de la limite de page
            -  Test pointeur d'adresses en mode écriture
            -  Test pointeur d'adresses en mode lecture
  

-  Extension de mémoire avec EEprom 24LC256

-  Régler l'horloge RTC DS1307

-  Afficher l'heure sur un OLED Serie 20x4

-  Affichage du jour de la semaine en clair

-  Exemple de programme de configuration du Datalogger

-  Lecture des données de l'EEprom

-  Mesure de la température avec un DS18B20

  

     Introduction - Eléments constitutifs du Datalogger

 Je n'ai pas l'habitude d'acheter des kits "tout-faits" mais je me suis laissé tenter par ce système commercialisé chez Picaxe-Store... en période de réduction.

A l'examen, il s'agit d'un Datalogger pourvu de 4 entrées et prévu pour un microcontrôleur Picaxe 18X ou 18M2. Il est cependant livré avec un Picaxe 18M2... qui n'est pas pourvu d'entrée Reset !.
Le mini switch de Reset, connecté à la pin nr.4 n'a donc aucun effet sur cette platine !

Il est doté d'une "Horloge Temps Réel" de type DS1307 pilotée par quartz horlogique de 32,768 KHz.
C'est la qualité de ce quartz qui sera le garant de la fiabilité de l'horloge.

Les données sont enregistrées dans une mémoire EEPROM. Celle livrée est de type 24LC16B permettant de stocker 2.048 octets (8 blocs de 256 octets), soit 512 enregistrements pour les  4 capteurs.
   Elle peut être remplacée par une  24LC256, permettant alors de stocker 32.768 Octets (128 blocs de 256 octets).
   Un connecteur permet encore d'ajouter une extension de mémoire pour disposer alors de 8 EEprom 24LC256, donnant un total de 1024 blocs de 256 octets = 262.144 octets !

Côté sorties optionnelles, nous pouvons raccorder un afficheur OLED / LCD Série et  un buzzer.

La carte dispose encore d'une led bicolore et d'une Led verte. Attention cette dernière était soudée à l'envers sur le kit reçu !!!
Ce défaut est récurrent et a été signalé plusieurs fois sur le Forum Picaxe !
Sur 5 modules reçus début 2017, TOUS étaient soudées à l'envers !

Nous trouvons également deux connecteurs mini-jack: un pour la programmation du Picaxe et un autre pour aller lire les datas enregistrées.

Enfin, un connecteur d'alimentation. Le module s'alimente par 3 pile AA = 4,5 V.

A noter également un logement pour y fixer une pile de sauvegarde au Lithium, type CR2032 de 3V, pour l'horloge DS1307 qui continue de compter lorsque le datalogger est hors tension.

      
                                                                                                Schéma de principe

 

     Le Bus i2c

L'horloge DS1307 et les mémoires sont gérées par un port i2c. Nous allons donc nous intéresser un tantinet à ce protocole.

Le bus Inter-Integrated-Circuit (i2c) a été initialement développé par Phillips Inc. pour le transfert de données entre les CI au niveau des BPC (Bits Per Color = Réglage de la profondeur des couleurs).

L'interface physique du bus de communication se compose de seulement deux lignes - une pour l'horloge (SCL) et une pour les données (SDA). Ces lignes sont tirées vers le haut par des résistances reliées à V+.

La valeur de ces résistances de tirage n'est pas critique. Elles peuvent varier de 2k2 à 10K. 4k7 est une valeur couramment utilisée.

Il est toutefois recommandé de choisir R=10K pour un bus cadencé à 100Khz et R=2K pour 400Khz.

Lorsque l'un des CI maître ou esclave veut «transmettre», il tire les lignes vers le bas par des transistors intégrés dans le CI.

Le CI qui contrôle le bus est appelé le maître, et est souvent un microcontrôleur. Les autres CI connectés au bus sont appelés esclaves.

 

Il peut y avoir plus d'un esclave sur le bus, à condition que chaque esclave ait été configuré pour avoir une "adresse esclave" unique afin qu'elle puisse être identifiée de manière unique sur le bus.

 

En théorie, il existe jusqu'à environ 112 adresses différentes disponibles, mais la plupart des applications pratiques n' utilisent,
au plus, qu'une dizaine d'esclaves.

      

 

 Pourquoi utiliser le bus i2c?  

 

Avantages:
- La plupart des grands fabricants de semi-conducteurs produisent de nombreux CI compatibles i2c à faible coût.
  La gamme de circuits intégrés disponibles est assez étendue: mémoires EEPROM, horloges temps réel, ADC, DAC, PWM, contrôleurs de moteur / ventilateur, pilotes de LED,  potentiomètres numériques, capteurs de température numériques, etc.
- Bon nombre de ces circuits intégrés sont livrés en petits boîtiers DIL8 broches.
Cela rend alors la conception des circuits assez simple.
- De nombreux périphériques esclaves peuvent être connectés au même bus, qui n'utilise seulement que deux pins du microcontrôleur.
   Il s'agit d'une utilisation très rationnelle et efficace des entrées/sorties du microcontrôleur.
- La conception du bus est très simple, puisqu'elle n'utilise que deux lignes et deux résistances.


Désavantages:
Le protocole de communication bus i2c est assez compliqué à gérer.
   Cependant, cette difficulté est facilement surmontée par l'utilisation de "bibliothèques" ou de fonctions intégrées et implémentées dans certains microcontrôleurs
   tels que PICAXE, qui fournissent des commandes simples de style BASIC pour tous les transferts de données i2c.
   Par conséquent l'utilisateur final n'a besoin d'aucune connaissance technique des protocoles de communication du bus i2c.
- Chaque IC esclave disposera de quelques paramètres d'installation uniques (par exemple adresse esclave), qui doivent être extraits de la fiche technique du fabricant.
   Ce n'est, en fait, pas si difficile, une fois que vous connaissez les principaux paramètres  à rechercher !

 

Paramètres de configuration de l'esclave
 Bien que tous les dispositifs esclaves i2c fonctionnent à peu près de la même manière, il y a quatre paramètres qui doivent être vérifiés à partir du Data-Sheet du fabricant,
pour chaque dispositif esclave utilisé.


Paramètre 1 - Adresse esclave
Comme déjà mentionné, chaque IC esclave, sur le bus i2c, doit avoir une adresse unique.
Généralement cela ne pose pas de problème lors de l'utilisation de différents types d'IC sur le même bus puisque la plupart des IC ont une adresse esclave par défaut différente.


L'adresse de l'esclave est généralement de 7 bits de long, le 8ème bit étant réservé pour indiquer si le maître souhaite écrire (0) ou lire (1) l'esclave.
Une adresse esclave 10 bits est également possible, mais elle est rarement utilisée et n'est donc pas couverte dans cet article.
Cela signifie que l'adresse de l'esclave est souvent citée dans les fiches de données comme, par exemple, 1010000x ; x indiquant le bit de lecture / écriture.
Lors de l'utilisation du système PICAXE, l'état de ce 8ème bit n'est pas important, car le système PICAXE va automatiquement régler ou effacer ce bit suivant qu'on commande
une lecture ou une écriture.

Il pourrait cependant être nécessaire d'utiliser deux ou plusieurs CI i2c du même type (par exemple plusieurs mémoires EEPROM de même référence) sur le même bus.
Il est possible de configurer des adresses différentes grâce à des pins d'adressage prévues qu'il suffit simplement de connecter à V+ ou V- (par conception du circuit imprimé)
pour donner à chaque CI esclave une adresse propre et unique.

Dans le cas de la série des EEPROM populaires 24LCxx, il y a 3 broches d'adresse externes (A2, A1 et A0).
En connectant ces broches à V + ou GND sur votre circuit, vous pouvez différencier et adresser jusqu'à 8 composants pouvant alors être identifiés de façon unique sur le même bus.
Pour ces CI, l'adresse esclave du Data-Sheet peut être indiquée comme suit: 1010dddx, où les "d" prendront la valeur 1 ou 0 en fonction de votre choix de configuration de ces broches
d'adresse externe (A2-A1-A0).

Note: sur l'EEprom 24LC16B les pins A0 à A2 ne sont pas fonctionnelles. Elle conserve donc une adresse unique non configurable.



Paramètre 2 - Bus Speed (100 ou 400kHz)
La vitesse de bus maximale pour le transfert de données entre le maître et l'esclave est normalement de 400 kHz.
Toutefois, certains composants ne fonctionneront que jusqu'à 100 kHz, et la fiche technique du fabricant doit donc être vérifiée pour chaque CI esclave utilisé.
Notez que c'est la vitesse maximale - tous ces composants peuvent évidemment être cadencés à une vitesse inférieure si désiré.

Dans tous les cas, c'est le composant le plus lent qui imposera le choix de la vitesse du bus.

Paramètre 3 - Taille de l'adresse du registre (octet ou mot)
Tout transfert de données du maître vers l'esclave est une écriture, ce qui signifie qu'un octet de données est transféré du maître vers un «registre» dans le CI esclave.
Tout transfert de données de l'esclave vers le maître est une 'lecture'.
Les circuits esclaves les plus simples ont un maximum de 256 registres, et une «adresse de registre» d'une longueur d'un octet suffit donc à identifier le registre.
Cependant, des composants plus "volumineux", en particulier des mémoires EEPROM, ayant plus de 256 registres nécessiteront une adresse de registre «mot» (deux octets).


Paramètre 4 - Buffer d'écriture de page
Toutes les puces mémoire EEPROM nécessitent un «temps d'écriture» pour enregistrer les données dans la puce. Il s'agit typiquement de 5 ou 10 ms.
Lors de l'écriture de nombreuses données, cela peut entraîner un retard important.
Pour aider à surmonter ce problème, de nombreux CI ont un tampon d'écriture de page qui peut accepter plus d'un octet à la fois (généralement 8, 16, 32 ou 64 octets)
de sorte que tous ces octets peuvent être programmés à la fois.
Mais cela signifie, que dans le cas d'un envoi de 8 octets, par exemple, vous ne disposerez que d'un délai de 10 ms, plutôt que 80ms !

Note importante: Une des plus grandes erreurs commises par les débutants est qu'ils ne réalisent pas que les écritures de page ne peuvent démarrer qu'à un multiple de la taille du buffer
et ne peuvent pas déborder la taille du buffer de page.
En effet, cela signifie (pour un buffer de 8 octets) que vous pouvez écrire 8 octets à partir de l'adresse 0 (ou 8 ou 16 etc.), mais seulement 6 octets à partir de l'adresse 2 (10, 18 etc.)
sinon, vous dépasserez la limite d'écriture de page de 8 octets.

 

  

     Résumé du protocole i2C

  - Le bus est géré par le "Maître". C'est lui qui génère le Clock.

  - Bus libre: SCL =1 et  SDA =1

  - Start:        SCL =1 et  SDA =  ^ (0->1)

  - Stop:        SCL =1 et  SDA =  v (1->0)

  - La transmission commence par l'envoi de l'adresse, suivie de 1 ou plusieurs octets.
     Dans le cas des EEprom i2c, on envoie l'adresse du circuit suivie de l'adresse mémoire. Viennent ensuite les datas.

  - Il existe un protocole d'accusé de réception (ACK) fonctionnant de la manière suivante:
      Après l'envoi du 8eme bit de l'octet, le circuit émetteur libère la ligne SDA, ce qui permet au circuit récepteur de tirer cette ligne à la masse.
      Le récepteur doit ensuite libérer la ligne SDA pour que l'émetteur continue à envoyer des données.

 

     Les commandes i2C du Datalogger


Hardware - Matériel
  Toutes les pièces PICAXE X (18X, 28X, 40X) ont deux broches qui peuvent être dédiées aux deux lignes de communication i2c :  SDA et SCL.
   La configuration électrique typique est illustrée ici.

Software - Logiciel
  La communication avec le périphérique esclave ne nécessite seulement que trois commandes BASIC pour: Configurer, Ecrire
et 
Lire.

 

   Configurer  

 

    Commandes matérielles recommandées     Commande logicielle obsolète

 

 hi2cSetup OFF

 hi2cSetup i2cSlave, slaveaddress

 hi2cSetup i2cMaster, slaveaddress, mode, addresslen

 Le mode Master positionne le Picaxe en mode Maître pour contrôler le bus i2c.
 Le mode Slave positionne le Picaxe en mode esclave. Il est alors commandé par un autre MCU configurer en Master.

   Slaveaddress: adresse de l'esclave i2c
   Mode: permet de choisir la vitesse du bus: i2cfast = 400Khz, i2cslow = 100Khz.
                                                                Utilisez i2cfast_8 ou ic2slow_8 pour les picaxes à 8Mhz
   Adresslen: indique si la donnée est Byte (i2cbyte) ou word (i2cword)
 

  i2cslave  slave_address, bus_speed, address_size

      

      slave_address est l'adresse (par exemple,% 10100000)

      bus_speed est le mot-clé i2cfast (400kHz) ou i2cslow (100kHz)
      address_size est le mot-clé i2cbyte ou i2cword selon le cas

 

 

    Ecriture  

 

    Commandes matérielles recommandées      Commande logicielle obsolète

 hi2cOut location, (variable, ...)

 hi2cOut (variable, ...)

 hi2cOut [newslave], location, (variable, ...)

 hi2cOut [newslave], (variable, ...)

     Variable(s): contient l'octet à écrire
     Location: variable/constante spécifiant l'emplacement de départ de l'écriture
     Newslave: option pour une nouvelle adresse de commande.

  writei2c  start_address,(data,data,data,data...)

         

          start_address est l'adresse de début (octet ou mot, selon le cas)
          data, ... sont des octets de données à envoyer (soit des constantes ou des variables)
          (si plusieurs octets de données sont envoyés, il faut prendre soin de ne pas dépasser
            la taille du tampon de page !)

 

 

   Lecture  

 

    Commandes matérielles recommandées       Commande logicielle obsolète

 hi2cin (variable, ...)

 hi2cin location, (variable, ...)

 hi2cin [newslave], (variable, ...) Only Picaxe X2

 hi2cin [newslave], location, (variable, ...) Only Picaxe X2

     Variable(s): dans laquelles l'octet lu se positionne
     Location: variable/constante spécifiant l'emplacement de départ de la lecture
     Newslave: option pour une nouvelle adresse de commande.

 readi2c  start_address,(variable, variable,...)

 

          start_address est l'adresse de début (octet ou mot, selon le cas)
          Variable est l'endroit où les données retournées sont stockées dans le maître (b0, b1, b2, etc)

 

        En résumé:                 

   Commandes Logicielles

   Commandes "Matérielles"

   Fonctions
 i2cSLAVE  hi2cSETUP i2cMASTER   Configure le Picaxe comme Maître sur le bus i2c et se prépare à se connecter à un esclave.
   Pas d'application  hi2cSETUP i2cSLAVE   Configure le Picaxe comme Esclave sur le bus i2c. Picaxe X2 only !
   Pas d'application  hi2cSETUP OFF   Arrête le traitement i2c d'arrière-plan.
 WRITEi2c  hi2cOUT   Ecrit un octet ou une séquence d'octets sur le périphérique i2c.
 READi2c  hi2cIN   Lit un octet ou une séquence d'octets du périphérique i2c.

 

 Exemple
Pour écrire le texte «hello» (en fait 5 octets de données - un octet pour chaque lettre) dans une IC mémoire 24LC16B, puis le lire dans les variables, le programme serait

 

i2cSlave %10100000, i2cfast, i2cbyte         ‘ set slave parameters (Write to Block 0)Bits 4 to 7 always = "1010"

Writei2c 0,(“hello”)                         ‘ write the text at address 0

Pause 10                                     ‘ wait 10ms write time

Readi2c 0,(b0,b1,b2,b3,b4)                   ‘ read the data back again. Starting at adrress 0

Debug b0                                     ‘ display data on screen

   

     Etude de l'EEprom 24LC16B 

Une EEprom est une mémoire programmable et effaçable électriquement (Electrically Erasable Programmable Read-Only Memory).
Cette mémoire, contrairement à une RAM, est non volatile. Elle conserve donc son contenu après coupure de l'alimentation.

La 24LC16B est une EEprom de 16Kbit, organisée en 8 blocs de [256 x 8 bits] de mémoire.
 Soit: 8 blocs de 256 Bytes = 2.048 octets.

        16Kbits = 2KBytes = 1.024 x 2 Bytes  = 2.048 Bytes

Cela signifie qu'elle peut donc stocker 2.048 Octets de données.

La 24LC16B dispose d'un buffer de page de 16 octets.

La série "B" est la moins coûteuse de Microchip. Une limitation des séries B est qu'elles utilisent un adressage limité à un octet, limitant l'adresse interne à 256 registres.

Ce protocole d'adressage est suffisant pour traiter un seul bloc de registres.

Pour activer l'utilisation des 8 blocs complets, le 24LC16B emprunte 3 des 7 bits d'adresse de l'adresse esclave pour spécifier le bloc mémoire et donc les trois broches d'adressage A0, A1, A2 ne sont pas fonctionnelles.

Toutes les 24LC16B ont donc la même adresse unique en sortie d'usine !
On ne pourra donc utiliser qu'une seule de ces mémoires dans un circuit.

Mais bien que cela puisse paraître une petite mémoire, 2KB permet tout de même de stocker un peu plus de 2.000 lectures de capteurs ! (2.048 exactement = 8 blocs x 256)

 

Pins A0 à A2 : Adresse (Nc = 1)

SCL:  Serial Clock i2c

SDA:  Serial Data i2c

WP:     Protégé en écriture si =1
                  Libre si =0 ou NC.

GND/VCC: Alimentation

  Note: SCL et SDA doivent être tirées à VCC par une R de 2K2 à 10K.

 Si ce n'est alors pas suffisant, nous nous tournerons vers l'extension de mémoire prévue et dotée de mémoires EEprom 24LC256.  (voir plus bas)

Dans ce cas il sera nécessaire de retirer la 24LC16B se trouvant sur la platine du datalogger et la remplacer par une 24LC256.
Avec les 7 autres mémoires 24LC256 se trouvant sur la petite carte d'extension enfichable (optionnelle), nous disposerons alors de 8 EEprom 24LC256 permettant de réaliser 262.144 enregistrements !

 

     Organisation des blocs mémoire et des pages de l'EEprom 24LC16B

 

L'EEprom 24LC16B dispose de 128 pages de 16 octets, réparties dans 8 blocs de 256 octets.

 

Contenu d'une EEprom 24LC16B lue avec un programmateur Série.

 Adressage des 8 blocs : 

Comme nous venons de le voir, la mémoire 24LC16B possède une adresse d'identification i2c fixe, non configurable.
L'EEprom 24LC16B est structurée en
8 blocs adressables distinctement. Chaque bloc étant composé de 256 octets.

Autrement dit, si nous voulons écrire aux adresses 0 à 255, càd dans le premier bloc,  les commandes nécessaires seront celle-ci:

Low B.5        'Write Enable AXE110 EEprom

Address = 215  'Writing Position in Block 0 

 hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte 'Setup Writing Address Block 0

 hi2cout Address,(Data0): Pause 10   'Writing Data0 at address 215 in block 0

24LC16B
 

Structure de l'octet de configuration (hi2cSetup ...)

Si nous voulons écrire à des adresses supérieures à 255, nous dépassons la limite physique d'un octet d'adressage !
Le moyen d'y arriver est alors de considérer que chaque bloc distinct est composé de "cases" numérotées de 0 à 255.
Ainsi, si nous voulons placer une donnée à l'adresse 2046 (l'avant dernier octet de la mémoire) il faudra voir cet octet comme étant le n°254 du dernier Bloc n°7 !

Et on y écrira donc les commandes suivantes:

Low B.5        'Write Enable AXE110 EEprom

Address = 254  'Writing position in Block 7

 hi2csetup i2cmaster, %10101110, i2cslow, i2cbyte 'Setup Writing Address in LAST Block 7

 hi2cout Address,(Data0): Pause 10   'Writing Data0 at address 215 of LAST block 7 = Position nr.2046

    

 

 Procédure d'écriture d'un Byte

  
                  

 

 

     Buffer d'écriture de page - Ecriture de plusieurs octets en une seule opération

Lors de l'écriture sur l'une ou l'autre de ces EEPROM, un court délai d'environ 10 ms est nécessaire pour achever le cycle d'écriture.
Il est donc typique d'inclure une commande PAUSE 10 après une commande d'écriture pour accomplir ce délai.

Tant la 24LC16B que la 24LC256 ont un buffer d'écriture de page qui permet d'écrire plusieurs octets en une seule opération.  (Ecriture séquentielle)
L'utilisation de ce buffer
 peut considérablement améliorer la vitesse et l'efficacité.

La 24LC16B dispose d'un tampon de page de 16 octets et la 24LC256 dispose d'un tampon de page de 64 octets.

   ATTENTION ! Cependant, cela ne signifie pas pour autant que 16 ou 64 octets pourront toujours être écrits... correctement !

En effet, les opérations d'écriture de page sont limitées à l'écriture d'octets dans une seule page. Les limites de page sont liées à l'espace d'adressage du circuit utilisé.
Elles commencent à des adresses qui sont des multiples de la taille de la page et, à la fin, à des adresses qui sont des nombres entiers multiples de la taille de la page - 1.


Par conséquent sur le 24LC16B, avec une page de 16 octets, il y a une page qui commence à l'emplacement 0 et se termine à l'emplacement 15, une autre page de 16 à 31 et une autre de 32 à 47, etc.

De même sur le 24LC256 avec une page de 64 octets, il y a  une page qui commence à l'emplacement 0 et se termine à l'emplacement 63, une autre page de 64 à 127 et une autre Page de 128 à 191, etc.

 

Si une commande hi2cOUT (ou Writei2c) tente d'écrire au delà d'une limite de page, au lieu d'être écrite à la page suivante, les données s'entasseront au début de la page en cours.
Toutes les données déjà présentes au début de la page seront donc écrasées !
Et il n'y a aucun avertissement de cette écrasement, et selon le type de données écrites, il pourrait ne pas être immédiatement évident qu'une erreur de programmation a été faite.
Le code du programme doit donc être soigneusement écrit pour empêcher les opérations d'écriture de page qui tenteraient de dépasser une limite de page.

 

 

     Test d'écriture dans l'EEprom 24LC16B

 Ecriture d'un octet à la fois, à une adresse spécifiée

Low B.5     'Write Enable AXE110 EEprom  

Address = 0

Data0 = 1

 

 for Address = 0 to 20

   hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte 'Setup Writing Address Block 0

   hi2cout Address,(Data0): Pause 10 'Writing only One Byte at a time 

   Data0 = Data0 + 1

 next Address

      

  

  Préciser distinctement l'adresse d'enregistrement de chaque octet, à chaque écriture, est la méthode idéale n'induisant aucun dépassement de page ou de buffer.
   Chaque octet reçu est ainsi directement placé à l'adresse désignée sans encombrer le buffer de page.
  

 Ecriture de plusieurs octets au début d'une page, avec dépassement de la capacité du buffer de page

Low B.5     'Write Enable AXE110 EEprom 

Address = 0 'Start Address of page 0

hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte  'Setup Writing Address Block 0

hi2cout Address,(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20):Pause 10

      

  

  En cas de dépassement de la capacité du buffer, les octets "dépassants" s'écrivent au début de la page en cours et écrasent les datas déjà présentes !
   Elles ne s'écrivent donc pas sur la page suivante !

  Ecriture de plusieurs octets dans une page, sans dépassement de la capacité du buffer de page
 mais avec dépassement de la limite de page

Low B.5     'Write Enable AXE110 EEprom

Address = 4 'Start Address in page 0

hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte  'Setup Writing Address Block 0

hi2cout Address,(1,2,3,4,5,6,7,8,9,10,11,12,13,14):Pause 10

     

 

  En cas de dépassement de la limite de page, les octets "dépassants" ne s'écrivent pas dans la page suivante.

 

 Ecriture de plusieurs octets dans une page, avec dépassement de la capacité du buffer de page
 ET avec dépassement de la limite de page

Low B.5     'Write Enable AXE110 EEprom 

Address = 4 'Start Address in page 0

hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte  'Setup Writing Address Block 0

hi2cout Address,(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20):Pause 10

     

  

En cas de dépassement de la limite de page ou de la capacité du Buffer, les octets "dépassants" s'écrivent en début de la page courante,
écrasant les datas déjà présentes. Cet écrasement ne fait l'objet d'aucun message d'avertissement !

     En conclusion    

Si on utilise une commande envoyant une série d'octets, au départ d'une seule adresse de début,
    
il faudra être très attentif à ne dépasser, ni la capacité du Buffer, ni la limite de page.

 

     Test du pointeur d'adresses en mode écriture

Un pointeur d'adresses est un registre qui enregistre la dernière zone mémoire qui a été adressée. Ce registre est censé s'incrémenter automatiquement à chaque opération dans la mémoire.
Nous allons donc envoyer une première donnée à l'adresse 4. Ensuite, nous enverrons des données, une par une, sans précision de l'adresse.

low B.5    ; write enable AXE110 EEprom

Address = 4

Data0 = 1

hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte  'Setup Writing Address Block 0

hi2cout Address,(Data0): Pause 10

' Après cette commande d'écriture, le pointeur d'adresse est maintenant censé valoir 4+1=5

 

Data0 = Data0 + 1

for i= 1 to 11 ' Ecriture de 11 datas sans précision de l'adresse

   hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte '

   hi2cout(Data0): Pause 10  'L'écriture devrait incrémenter le pointeur

   Data0 = Data0 + 1

next i

  Seule la première commande, précisant l'adresse d'écriture, a été prise en compte.
      Les commandes d'écriture de la boucle, sans adresse, n'ont pas eu d'effet !   


Le pointeur d'adresses ne fonctionne donc pas en mode écriture
.

Il est dès lors impératif de toujours préciser l'adresse du premier octet à écrire.

 

     Test du pointeur d'adresses en mode lecture

x



 

     Extension de mémoire avec EEprom 24LC256

La 24LC256 est une EEprom de 256Kbit (32KOctets) permettant ainsi de stocker 32.768 Octets (128 blocs de 256 octets).

        256kbits = 32KBytes = 1.024 x 32 Bytes = 32.768 Bytes

Outre une capacité plus importante que la 24LC16B, elle utilise un adressage de la longueur d'un Word (2 bytes).
Ici, les lignes d'adressage A0 à A2 sont fonctionnelles, permettant ainsi d'utiliser jusqu'à 8 mémoires de ce type sur un même bus.

La 24LC256 est aussi pourvue d'un buffer d'écriture de page, mais d'une capacité, de 64 octets

La taille d'une page est donc aussi de 64 octets. Valeurs à considérer en cas d'écriture de plusieurs octets en une seule opération dite écriture séquentielle.    (V. ci-dessus le chapitre consacré au buffer d'écriture de page !)

Le datalogger est pourvu d'un connecteur d'extension de mémoire permettant de disposer de 8 EEprom 24LC256, donnant ainsi un total de 8x 32KBytes = 256KBytes  (soit 2Mbits) permettant de stocker 262.144 Octets !

 

 
 Procédure d'écriture d'un Byte

    

      La première différence, en comparaison de la 24LC16B, est que l'adresse est écrite dans un Word et non dans un Byte.
      La seconde est qu'il n'est plus nécessaire d'adresser les 128 blocs de 256 Octets.
      Ici, on adresse directement l'octet cible (de 0 à 32.768).
      On peut utiliser jusqu'à 8 circuits 24LC256 sur le bus i2c.
      Enfin, les bits 1, 2 et 3 du terme "SlaveAddress", de la commande hi2cSetup, ne représentent plus un bloc d'une mémoire
       mais l'adresse d'un des 8 circuits adressables possibles; tandis que le bit 0 signifie toujours 0 = Write, 1 = Read.
     
Les bits 4 à 7 du terme SlaveAddress restent invariablement égaux à "1010" comme pour la mémoire 24LC16B.

 Exemple:
 

   Low B.5         'Write Enable AXE110 EEprom
   Address = 2017  '0 to 32767 (WORD) 2017 = $7E1

   Data0 = 1       '0 to 255   (BYTE)
    hi2csetup i2cmaster, %10100000, i2cslow, i2cWORD 'Setup i2C slave chip. Writing to i2C chip address = 000

    hi2cout Address,(Data0): Pause 10 'Writing one Byte in 2017 Address 

 

    

 

 

     Régler l'horloge RTC - DS1307 

Pour régler le DS1307 et le mettre à l'heure, nous allons le programmer à l'aide du Picaxe 18M2 du DataLogger.
La pile Lithium de sauvegarde permettra alors au DS1307 d'assurer le comptage continu du temps réel, même en absence d'alimentation du datalogger.
Le Picaxe pourra ensuite être chargé avec le programme de gestion du DataLogger. 

DS1307 Setup

' DS1307 SETUP
'Set DS1307.bas

#picaxe 18M2

Symbol Secs    = b0
Symbol Mins    = b1
Symbol Hour    = b2
Symbol DoW     = b3 : Symbol ChkDoW   = b9
Symbol Day     = b4 : Symbol ChkDay   = b10
Symbol Month   = b5 : Symbol ChkMonth = b11
Symbol Year    = b6 : Symbol ChkYear  = b12
Symbol Century = b7
Symbol Control = b8 : Symbol ChkCtrl  = b13

High
5' Write Protect EEprom Datalogger (Security)

hi2cSetup i2cMaster
, %11010000, i2cslow, i2cbyte

'Change these settings according to the date and time of programming setup
  Century = $20
  Year    = $17
  Month   = $02
  Day     = $07
  DoW     = $02  'Day of the Week with Monday being the FIRST Day
  Hour    = $16
  Mins    = $25
  Secs    = $00
  Control = $10  '$10 = Flash 1Hz   $00 = NO Flash

hi2cOut
0, (Secs, Mins, Hour, DoW, Day, Month, Year, Control)

Pause 50

hi2cIn
3, (ChkDoW, ChkDay, ChkMonth, ChkYear)

if ChkDow   <> Dow   then Fail_Hr

if ChkDay   <> Day   then Fail_Hr

if ChkMonth <> Month then Fail_Hr

if ChkYear  <> Year  then Fail_Hr

 

Ok:

 High 3      ' Set bicolor Led Green

 Low  2

END '-----------------------------------------

 

Fail_Hr:

 High      ' Set bicolor Led Red

 Low  3

 Sertxd(" --> Time setting failed !",cr,lf)

END  '-----------------------------------------

       

                En arrière plan, une horloge radio pilotée pour choisir l'heure exacte à programmer.
                  Tenir compte du temps nécessaire à l'envoi du programme dans le picaxe.
                                   Pour ma part, j'avais un délai de 13 secondes.
                 La Led verte clignote à chaque seconde (1Hz) lorsque l'alim. externe est branchée

 

     Affichage de l'heure

 Affichage

' DS1307

' Affichage Heure, Date, nr Jour, jour en clair

 

#picaxe 18M2

 

Symbol Secs  = b0

Symbol Mins  = b1

Symbol Hour  = b2

Symbol DoW   = b3  'Day of the week with Monday being the FIRST Day

Symbol Day   = b4

Symbol Month = b5

Symbol Year  = b6

Symbol Dy1   = b7

Symbol Dy2   = b8

Symbol Dy3   = b9

 

Pause 2000     'Stabil. Serial LCD Interface

 

Serout 6,N2400,(254,1): Pause 30     'Clear Display

 

DO 

 i2cSlave %11010000, i2cslow, i2cbyte

 Readi2c 0,(Secs,Mins,Hour,DoW,Day,Month,Year)'DS1307

 

 BcdtoAscii Hour,b7,b8

 Serout 6,N2400,(254,130,b7,b8, " : ")

 BcdtoAscii Mins,b7,b8

 Serout 6,N2400,(254,135,b7,b8, " : ")

 BcdtoAscii Secs,b7,b8

 Serout 6,N2400,(254,140,b7,b8)

 

 BcdtoAscii Day,b7,b8

 Serout 6,N2400,(254,195,b7,b8)

 BcdtoAscii Month,b7,b8

 Serout 6,N2400,(254,198,b7,b8)

 BcdtoAscii Year,b7,b8

 Serout 6,N2400,(254,201,b7,b8)

 

 BcdtoAscii DoW,b7,b8

 Serout 6,N2400,(254,206,b7,b8)

 

 

Select Case DoW

 Case 1 'LUNDI

   Dy1 ="L" : Dy2 ="u" : Dy3 ="n"

 Case 2 'MARDI

   Dy1 ="M" : Dy2 ="a" : Dy3 ="r"

 Case 3 'MERCREDI

   Dy1 ="M" : Dy2 ="e" : Dy3 ="r"

 Case 4 'JEUDI

   Dy1 ="J" : Dy2 ="e" : Dy3 ="u"

 Case 5 'VENDREDI

   Dy1 ="V" : Dy2 ="e" : Dy3 ="n"

 Case 6 'SAMEDI

   Dy1 ="S" : Dy2 ="a" : Dy3 ="m"

 Case 7 'DIMANCHE

   Dy1 ="D" : Dy2 ="i" : Dy3 ="m"

EndSelect

 

 Serout 6,N2400,(254,209,Dy1,Dy2,Dy3)

 

LOOP

 

 

     Affichage du jour de la semaine en clair

Le DS1307 nous donne l'information du jour de la semaine (DoW = Day of Week) sous la forme d'une variable allant de 1 à 7.
La valeur du jour de la semaine est configurable par l'utilisateur. Pour ma part j'ai choisi Lundi étant = 1.

Nous allons donc devoir utiliser une petite routine si on désire afficher le jour de la semaine "en clair", càd Lun pour Lundi, Mar pour Mardi, ...

Nous pouvons y arriver de trois manières différentes.
La première méthode consomme le plus de place mémoire, les suivantes sont présentées de manière dégressive en terme d'occupation mémoire code.

1) Select Case 

Select Case DoW_DS  'DoW_DS issu du DS1307

 Case 1 'Lundi

   Dy1 ="L" : Dy2 ="u" : Dy3 ="n"

 Case 2 'Mardi

   Dy1 ="M" : Dy2 ="a" : Dy3 ="r"

 Case 3 'Mercredi

   Dy1 ="M" : Dy2 ="e" : Dy3 ="r"

 Case 4 'Jeudi

   Dy1 ="J" : Dy2 ="e" : Dy3 ="u"

 Case 5 'Vendredi

   Dy1 ="V" : Dy2 ="e" : Dy3 ="n"

 Case 6 'Samedi

   Dy1 ="S" : Dy2 ="a" : Dy3 ="m"

 Case 7 'Dimanche

   Dy1 ="D" : Dy2 ="i" : Dy3 ="m"

EndSelect

 

 Serout 6,N2400,(254,229,Dy1,Dy2,Dy3) 'envoi de 3 cracteres vers le serial OLED/LCD (à partir de Ligne.4, Pos.18)

 

2) Lookup 

Let Index = DoW_DS * 3     'Positionnement à la premiere lettre du jour dans la table en fonction de DoW_DS
Let Cptr  = 0 

Serout b.6,N2400,(254,220) 'Position Display to Ligne 4 , Char.18 pour le 1er caracter

                           'le pointeur du display sera ensuite automatiquement incremente.

  Do until Cptr =3

   Lookup Index, ("   LunMarMerJeuVenSamDim"), Dy123

   Serout b.6,N2400,(Dy123)   '1 caractere a la fois vers le Serial OLED/LCD

    inc Cptr                  'Loop 3x

    inc Index                 'Avance dans la "Table Lookup"

  Loop' While Cptr < 3

 

 3) Table Area 

TABLE 0, ("   LunMarMerJeuVenSamDim")

 

Let Index = DoW_DS * 3     'Positionnement à la premiere lettre du jour dans la table en fonction de DoW_DS

Let Cptr  = 0 

 

Serout b.6,N2400,(254,220)    'Position Display to Ligne 4 , Char.18 pour le 1er caractere

                              'le pointeur du display sera ensuite automatiquement incremente.

  Do 'until Cptr =3

   Readtable index,Dy123      'lecture dans la table

   Serout b.6,N2400,(Dy123)   '1 caractere a la fois vers le Serial OLED/LCD

    inc Cptr                  'Loop 3x

    inc Index                 'Avance dans la Table Area 

  Loop While Cptr < 3 

 

     Exemple de programme de saisie de données et de configuration du Datalogger

; AXE110 PICAXE - New Datalogger Mission Program

; 10 enregistrements toutes les 30 sec + affichage de l'heure, du nombre d'enregistrements effectues

; nombre d'enreg. de la mission + END a la fin.

; LED will flash green as readings are taken.

; Readings taken will be shown on serial LCD.

; Data can be retrieved after mission (LED red) by Datalink tool (F9).

; Use Datalink options: Baud rate - 4800, Sensors - 2, Send G - Enabled

 

; *******************

; ***** Options *****

; *******************

 

; Title – DS110 CONFIG

; Date  - 2017-02-09

; Time  - 15:35:12

; Options Selected

; Sensors:

; Sensor 0 - Light

; Sensor 1 - Not used

; Sensor 2 - Not used

; Sensor 7 - Temperature

; Memory:

; No of readings = 10

; 1 x 24LC256

; Outputs:

; Bi-colour LED

; Serial LCD on output pin B.6

; Logging Period:

; DS1307 RTC

; Hours: 0 Mins: 0 Secs: 20

 

; *******************

; ***** Symbols *****

; *******************

 

symbol data0           = b0                ; Light

symbol data1           = b1                ; Sensor 1

symbol data2           = b2                ; Sensor 2

symbol data7           = b3                ; Temperature

symbol top_address     = w2                ; (b4 + b5)

symbol top_address.lsb = b4

symbol top_address.msb = b5

symbol address         = w3                ; (b6 + b7)

symbol address.lsb     = b6

symbol address.msb     = b7

symbol temp_word       = w4                ; (b8 + b9)

symbol temp_byte       = b10

symbol hours           = b11

symbol mins            = b12

symbol secs            = b13

symbol day             = b14

symbol month           = b15

 

symbol hours_DS        = b16

symbol mins_DS         = b17

symbol secs_DS         = b18

symbol day_DS          = b19

symbol month_DS        = b20

Symbol DoW_DS          = b21  'Day of the week with Monday being the FIRST Day

Symbol Year_DS         = b22

Symbol Dy1             = b23

Symbol Dy2             = b24

Symbol Dy3             = b25

Symbol Char1           = b26 

Symbol Char2           = b27

symbol COM             = 44                ; comma

 

 

'Mission = 10

 

; **************************************************

; ***** Initialise Internal Eeprom On Download *****

; **************************************************

 

eeprom  0, ( 0, 0 )                        ; no eeprom data stored after download

eeprom 16, ( "Light" )                     ; Sensor 0

eeprom 32, ( "Sensor 1" )                  ; Sensor 1

eeprom 48, ( "Sensor 2" )                  ; Sensor 2

eeprom 64, ( "Temperature" )               ; Sensor 7

eeprom 80, ( "TEST for JP" )               ; Mission Name

 

; *************************

; ***** Intialisation *****

; *************************

 

initialisation:

 

        Pause 2000                         ; Stabilize Serial OLED Interface

        let dirsB = $FF                    ; set outputs

        high B.5                           ; write protect AXE110 EEprom

        read 0, address.lsb                ; get address to write to

        read 1, address.msb

         serout B.6, N2400, (254,1)        ; clear LCD

         pause 30

        gosub check_if_full                ; check if memory already full

 

; *****************************

; ***** Main Program Loop ************************************************************************************

; *****************************

 

main:

        gosub read_sensors                 ; read the sensors

        gosub save_data                    ; save sensor readings in eeprom

        gosub inc_address                  ; update address to save to

        gosub wait_time                    ; wait until ready for next reading

        goto main                          ; take next reading

 

; ****************************

; ***** Read sensor data *****

; ****************************

 

read_sensors:

        high B.3                           ; flash green LED

        readadc C.0, data0                 ; read Light

        readtemp C.7, data7                ; read Temperature

        low B.3                            ; end of green LED flash

 

; ****************************************

; ***** Display Sensor Values On LCD *****

; ****************************************

 

display_on_lcd:

        serout B.6, N2400, (254,128,"In0=",#data0,"   ")

        serout B.6, N2400, (254,136,"In2=",#data2,"   ")

        serout B.6, N2400, (254,192,"Ext=",#data1,$D2)

        serout B.6, N2400, (254,200,"Int=",#data7,$D2)

        return

 

; *******************************

; ***** Save Data to Eeprom *****

; *******************************

 

save_data:

        low B.5                            ; write enable AXE110 EEprom

        ; Single 24LC256. Input0 from address 0, input1 from address 4096

        ; Single 24LC256. Input2 from address 8192, input7 from address 12288

 

        i2cslave %10100000, i2cslow, i2cword

        ; save Light

        hi2cout address, (data0)

        pause 10

        hi2cin address, (temp_byte)

        if temp_byte <> data0 then ee_error

        ; save Temperature

        let temp_word = address + 12288

        hi2cout temp_word, (data7)

        pause 10

        hi2cin temp_word, (temp_byte)

        if temp_byte <> data7 then ee_error

        high B.5                           ; write protect AXE110 EEprom

        return

 

 

; ***********************

; ***** Write Error *****

; ***********************

; flash the red and green LED alternatively

 

ee_error:

        high B.2                           ; turn on red LED

        low B.3

        pause 500

        high B.3                           ; turn on green LED

        low B.2

        pause 500

        goto ee_error

 

; **********************

; ***** Time Delay *****

; **********************

 

wait_time:

        hi2csetup i2cmaster, %11010000, i2cslow, i2cbyte

        hi2cin 0, (secs,mins,hours)

 

        ; Convert to decimal then add offset

        gosub bcd_decimal

        let data0 = secs

        let data1 = mins

        let data2 = hours

 

Add_Secs:

        let data0 = data0 + 20

        if data0 < 60 then Add_Mins

        ; Secs is now greater than 60 so add 1 to minute instead

        let data0 = data0 - 60

        let data1 = data1 + 1

 

Add_Mins:

        let data1 = data1 + 0

        if data1 < 60 then Add_Hours

 

        ; Mins is now greater than 60 so add 1 to hour instead

 

        let data1 = data1 - 60

        let data2 = data2 + 1

 

Add_Hours:

 

        let data2 = data2 + 0

        if data2 < 24 then read_rtc

        ; Hours is now greater than 24 so correct

        let data2 = data2 - 24

        ; Read rtc to test alarm

 

read_rtc:

        gosub read_DS1307

        hi2csetup i2cmaster, %11010000, i2cslow, i2cbyte

        hi2cin 0, (secs,mins,hours)

 

        gosub bcd_decimal

 

        if secs <> data0 then read_rtc

        if mins <> data1 then read_rtc

        if hours <> data2 then read_rtc

 

        return

 

; **********************************

; ***** Convert BCD to decimal *****

; **********************************

 

bcd_decimal:

        let temp_byte = secs & %11110000 / 16 * 10

        let secs = secs & %00001111 + temp_byte

        let temp_byte = mins & %11110000 / 16 * 10

        let mins = mins & %00001111 + temp_byte

        let temp_byte = hours & %11110000 / 16 * 10

        let hours = hours & %00001111 + temp_byte

        return

 

; *****************************

; ***** Increment Address *****

; *****************************

 

inc_address:

 

        if address < 10 then

         let address = address + 1          ; increment address

        endif

          serout B.6, N2400, (254,145,">",#ADDRESS)

          serout B.6, N2400, (254,209,"/10")

        write 0, address.lsb               ; remember address in internal eeprom

        write 1, address.msb

 

; ***********************************

; ***** Check If Memory Is Full *****

; ***********************************

 

check_if_full:

        if address >= 10 then memory_is_full

        return

 

; **************************

; ***** Memory Is Full *****

; **************************

 

memory_is_full:

        high B.2                           ; turn on red LED

        serout B.6, N2400, (254,209,"END")

 

 

 

; *****************************

; ***** Datalink Transfer *****************************************************************************************

; *****************************

 

read_init:

        Gosub Read_DS1307                  ; display time after mission ended        

        read 0, top_address.lsb            ; determine top address of memory used

        read 1, top_address.msb

      

        serin[850,read_init], C.6, N4800, ("G")            ; Wait for GO signal

        ; send sensor information

        serout B.7, N4800, ( "Address",COM,"Light",COM,"Temperature",CR,LF )

        let address = 0                    ; start with first sensor data

 

send_data: ' to Console PC !

        gosub read_data                    ; retrieve the data and send it

        serout B.7,N4800, (#address,COM,#data0,COM,#data7,CR,LF)

 

        if address < 10 then

             

         let address = address + 1          ; point to next data to send to PC

        endif

 

         if address < top_address then send_data

 

all_done:

        ; after all data sent then send a null character

        pause 10

        serout B.7, N4800, (0)

        ; ready for another datalink download

        goto read_init '***** Bouclage !

 

; *********************************

; ***** Read Data From Eeprom *****

; *********************************

 

read_data:

 

        ; Single 24LC256. Input0 from address 0, input1 from address 4096

        ; Single 24LC256. Input2 from address 8192, input7 from address 12288

 

        i2cslave %10100000, i2cslow, i2cword

        ; read Light

        hi2cin address, (data0)

       ; read Temperature

        let temp_word = address + 12288

        hi2cin temp_word, (data7)

        return

 

Read_DS1307:

 

 i2cSlave %11010000, i2cslow, i2cbyte

 Readi2c 0,(Secs_DS,Mins_DS,Hours_DS,DoW_DS,Day_DS,Month_DS,Year_DS)'DS1307

 BcdtoAscii Hours_DS,Char1,Char2

 Serout 6,N2400,(254,150,Char1,Char2, " : ")

 BcdtoAscii Mins_DS,Char1,Char2

 Serout 6,N2400,(254,155,Char1,Char2, " : ")

 BcdtoAscii Secs_DS,Char1,Char2

 Serout 6,N2400,(254,160,Char1,Char2)

 BcdtoAscii Day_DS,Char1,Char2

 Serout 6,N2400,(254,215,Char1,Char2)

 BcdtoAscii Month_DS,Char1,Char2

 Serout 6,N2400,(254,218,Char1,Char2)

 BcdtoAscii Year_DS,Char1,Char2

 Serout 6,N2400,(254,221,Char1,Char2)

 BcdtoAscii DoW_DS,Char1,Char2

 Serout 6,N2400,(254,226,Char1,Char2)

 

 Select Case DoW_DS

 Case 1 'LUNDI

   Dy1 ="L" : Dy2 ="u" : Dy3 ="n"

 Case 2

   Dy1 ="M" : Dy2 ="a" : Dy3 ="r"

 Case 3

   Dy1 ="M" : Dy2 ="e" : Dy3 ="r"

 Case 4

   Dy1 ="J" : Dy2 ="e" : Dy3 ="u"

 Case 5

   Dy1 ="V" : Dy2 ="e" : Dy3 ="n"

 Case 6

   Dy1 ="S" : Dy2 ="a" : Dy3 ="m"

 Case 7

   Dy1 ="D" : Dy2 ="i" : Dy3 ="m"

EndSelect 

 

Serout 6,N2400,(254,229,Dy1,Dy2,Dy3) 'Send 3 characters to OLED/LCD Serial (Line.4, Pos.18)

Return

 

; **************************

; ***** End of Program *****
; **************************   

 

 

   

     Lecture des données de l'EEprom

Pour aller lire les données stockées dans l'EEprom au terme de l'échéance de la "Mission", il suffit de raccorder le câble de programmtion Picaxe au deuxième connecteur mini-jack et lancer l'assitant de récupération "Liaison de données" de l'Editeur Picaxe.

A ce moment, un signal "Go" sera transmis au Picaxe du Datalogger et la lecture s'effectuera automatiquement vers le PC.

Ces données seront retranscrites sous forme d'un tableau de données et de courbes.

Il y a enfin possibilité d'exporter ces données vers divers autres formats : Excel, Pdf, Word, CSV.

Routine de lecture d'une EEprom 24LC16B générée par l'Assistant "Liaison de Données"

; *****************************

; ***** Datalink Transfer *****

; *****************************

symbol top_address     = w2   ; (b4 + b5)

symbol top_address.lsb = b4

symbol top_address.msb = b5

symbol COM = 44               ; Comma

 

< ... > 

  ''' let address = address + 1         ; increment address in Write Part of programm

  ''' write 0, address.lsb             ; remember address in INTERNAL EEprom

  ''' write 1, address.msb

< ... >
; -------------------------------------------------------------------------- 

 

Read_Init:

 

        read 0, top_address.lsb        ; determine top address of memory used

        read 1, top_address.msb

 

           Serin C.6, N4800, ("G")            ; Wait for GO signal    

 

        ; send sensor information

        serout B.7, N4800, ( "Address",COM,"Light",CR,LF )

 

        let address = 0                    ; start with first sensor data

 

Send_Data:

        gosub read_data                    ; retrieve the data and send it

        serout B.7,N4800, (#address,COM,#data0,CR,LF)

        let address = address + 1          ; point to next data

        if address < top_address then send_data

 

All_Done:

 

        ; after all data sent then send a null character

        pause 10

        serout B.7, N4800, (0)

 

        ; ready for another datalink download

        goto read_init

 

; *********************************

; ***** Read Data From Eeprom *****

; *********************************

 

Read_Data:

 

        ; Single 24LC16B. Input0 in block 0,4, input1 in block 1,5

        ; Single 24LC16B. Input2 in block 2,6, input7 in block 3,7

 

        if address > 255 then read_high_address

 

        ; read Light

        hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte 'Block 0

        hi2cin address, (data0)

        return

 

Read_High_Address:

        let temp_word = address - 256

        ; read Light

        hi2csetup i2cmaster, %10101000, i2cslow, i2cbyte 'Block 4 (Middle Point/ Half of the Memory)

        hi2cin temp_word, (data0)

        return

 

; **************************

; ***** End of Program *****

; **************************

 

     Le DS18B20    Mesure et affichage de la température

Le capteur DS est un capteur de température mesurant une plage variant de -55°C à +125°C.

Il se présente sous la forme d'un petit transistor à 3 pattes mais il existe aussi en modèle étanche protégé dans une capsule métallique d'où émane un câble à trois conducteurs.
il nécessite juste une résistance pull-up de polarisation de 4K7.

Le Picaxe a deux commandes dédiées permettant de mesurer la température, l'une avec avec une résolution du degré, l'autre affichant deux décimales après le degré !

La précision dépendra de la qualité du composant. Un facteur de correction est cependant prévu dans le programme.

Vous trouverez, ci-dessous, un exemple de code utilisant les deux commandes et affichant les résultats sur deux LCD Display distincts.
Le thermomètre en arrière plan sur la photo sert juste à contrôler les résultats du programme. 

 

' RGL Fevrier 2017

' Test sur Module Axe401/Picaxe 28X2

' Serial OLED 16x2

' Serial OLED 20x4

 

#picaxe 28x2

 

Init:

     symbol LCD1 = C.6          'Assign LCD to port C.6  4Lignes

     symbol LCD2 = C.7          'Assign LCD to port C.7   2Lignes

     symbol Sonde1 = A.0        'Assign Sonde to port A.0

 

     Symbol Temp = b20          'Calculation variable

     Symbol Temperature12 = w11 'Temperature word using b22 and b23

     Symbol temperature = w14

     Symbol TempinC_100 = w12   'Temperature value in C * 100 (uses b24, b25)

 

     Symbol TempSign = bit0     'The sign of the temperature reading

     Symbol Whole = b2          'The Whole Temperature reading

     Symbol Fract = b3          'The Fraction Temperature reading

     Symbol Correction = w13    'If needed, for precision !

            Correction = 0

     pause 1000                 'Init.LCDs

 

    

iniLCD1: 

     serout LCD1,N2400, (254, 1)               'Clear Display1 (4 lignes)

     pause 500                      'Wait 500ms for display

     serout LCD1,N2400, (254,128)              'Move to line 1 position 1

     serout LCD1,N2400, ("TEMPERATURE INT1:")  'Output Texte

 

 

iniLCD2: 

     serout LCD2,N2400, (254, 1)               'Clear Display2 (2 lignes)

     pause 500                      'Wait 500ms for display

     serout LCD2,N2400, (254,128)              'Move to line 1 position 1

     serout LCD2,N2400, ("TEMPERATURE INT2:")  'Output Texte

 

main: 

DO     

     serout LCD1,N2400, (254,197)              'Move to line 2 position 6

     call ReadTemp12Sensor

 

     serout LCD2,N2400, (254,197)              'Move to line 2 position 6

     call ReadTempSensor

 

LOOP               'loop to beginning

     end

    

' ******************************************************

' ******  SUB-ROUTINES *********************************

'*******************************************************

 

ReadTemp12Sensor:

     '*******************************************************************************

     '** Read DS18B20 and Display Temperature in 12bit Resolution                  **

     '**                                                                           **

     '** The sub use the following:                                                **

     '** Symbol Temperature12 = w11 'Temperature word using b22 and b23            **

     '** Symbol TempSign = bit0     'The sign of the temperature reading           **

     '** Symbol TempinC_100 = w12   'Temperature value in C * 100 (uses b24, b25)  **

     '** Symbol Whole = b2          'The Whole Temperature reading                 **

     '** Symbol Fract = b3          'The Fraction Temperature reading              **

     '** Symbol Temp = b20          'Calculation variable                          **

     '*******************************************************************************

     ReadTemp12 Sonde1, Temperature12     'Read the DS18B20 temp sensor in 12 bit

      Temperature12 = Temperature12 - Correction

     TempSign = Temperature12 / 256 / 128 'Isolate the MSB bit

     If TempSign = 0 Then Positive        'Test the Temperature's sign

     'Temperature is negative

      Temperature12 = Temperature12 ^ $ffff + 1 'Take two's complement 65535 +1

 

Positive:

     TempInC_100 =  Temperature12 * 6          'TC = value * 0.0625, TC*100 = 6.25

      Temperature12 = Temperature12 * 25 / 100      'The rest of the value

            TempInC_100 = TempInC_100 + Temperature12    'The temperature value * 100 in C       

     Whole = TempInC_100 / 100           'Separate the whole degrees

     Fract = TempInC_100 % 100            'Separate the fractional degrees

     If TempSign > 0 then                 'Temp is negative

     serout LCD1,N2400, ("-")             'Send negative sign to LCD

     end if

     serout LCD1,N2400, (#Whole)               'Send Temperature to LCD

     serout LCD1,N2400, (".")             'Send point to LCD

     'To ensure the Fraction is double digits if the fract is 0

 

     temp = Fract / 10                    'Calc the first digit of Fract

     serout LCD1,N2400, (#temp)                'Send First Fraction Digit to LCD

     temp = Fract % 10                    'Calc the second digit of Fract

      

     serout LCD1,N2400, (#temp)                'Send Second Fraction Digit to LCD

     serout LCD1,N2400, (%11010010)            'Send Degree "°" Char $D2

     serout LCD1,N2400, ("C")             'Send Char C to LCD

     return

 

ReadTempSensor:

     '*****************************************************************

     '** Read DS18B20 and Display Temperature in 1 Deg Resolution    **

     '**                                                             **

     '** The sub use the following:                                  **

     '** Symbol Temperature =b21   'Temperature variable for DS18B20 **

     '*****************************************************************

     ReadTemp Sonde1, Temperature              'Read the DS18B20 temp sensor

     Temperature = Temperature - Correction

     If Temperature > 127 then                 'Temperature is Negative

        Temperature = Temperature - 128        'Remove bit 7, the sigh bit

        serout LCD2,N2400, ("-")               'Send negative sign to LCD

     end if

    

     serout LCD2,N2400, (#Temperature)         'Send Temperature to LCD as a number

     serout LCD2,N2400, (%11010010)            'Send Degree "°" Char  $D2

     serout LCD2,N2400, ("C")             'Send Char C to LCD

     return

 

 

 

 

   Trafic Visiteurs:  

 
[ Electronique ]
Copyright © Roger LEGAT - 2008 - Tous Droits réservés - (Thds V2)