Go Down

Topic: [Résolu] DS1631, impossible à utiliser (Read 4481 times) previous topic - next topic

fking

Oct 06, 2013, 12:14 pm Last Edit: Oct 13, 2013, 03:57 pm by fking Reason: 1
Bonjour tout le monde

Je tente de faire marcher un DS1631 (capteur de T° en I²C de chez Maxim), et bien sûr, ça ne marche pas... ( Si ça marchait du premier coup, ça ne serait pas drôle...  :) )

Je me suis basé sur le code suivant :
http://forum.arduino.cc/index.php/topic,14156.0.html
en adaptant les nouvelles fonctions de Wire.h : Wire.write à la place de Wire.send, et Wire.read à la place de Wire.receive

Ca compile et upload sans problème (Env 1.0.5, Arduino Duemilanove avec un AT328).

Au niveau du câblage du 1631
Br1 SDA sur Analog In 4
Br2 SCL sur Analog In 5
Br3 en l'air
Br4 GND
Br 5-6-7 GND
Br8 +5V

J'ai rajouté deux résistance de 1800 ohms entre SDA et SCL et le +5.

Le moniteur série me renvoie :
Access Config (Before): -1
Access Config (After): -1
Temperature : -1.000 degC / Th register: -1 / Tl register: -1
Temperature : -1.000 degC / Th register: -1 / Tl register: -1
Temperature : -1.000 degC / Th register: -1 / Tl register: -1
Temperature : -1.000 degC / Th register: -1 / Tl register: -1
...

C'est la première fois que je mets le nez dans l'I²C.

Que se passe t-il ? Un problème d'adresse du 1631 ? Il est clair qu'on n'arrive pas à discuter avec lui au vu des deux premières lignes de retour, mais pourquoi ?

Merci d'avance.

B@tto

1800 ohms c'est peut-être trop petit, normalement il n'y a même pas besoin de résistance de pull-up sur Arduino donc tu peux les enlever pour tes essais
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

68tjs

C'est qui le fournisseur de ton DS1631. ?

Pour voir si je pouvais répondre quelque chose j'ai cherché la datasheet :
http://www.datasheetcatalog.com/datasheets_pdf/D/S/1/6/DS1631.shtml

Et là énorme surprise la recherche donne des liens vers 2 composants différents qui portent des références similaires :
Maxim/Dallas DS1631 -> c'est le bon
et National Semiconducteurs DS1631 -> c'est pas le bon.

Normalement sur le boîtier il y a le sigle du constructeur, peut-tu vérifier ?

fdufnews

#3
Oct 07, 2013, 09:42 am Last Edit: Oct 07, 2013, 09:48 am by fdufnews Reason: 1

1800 ohms c'est peut-être trop petit,

La spécification I²C préconise que les composants sur le bus doivent à minima pouvoir absorber un courant de 3mA en Standard Mode lorsqu'elles sont à l'état bas. D'ailleurs le DS1631 respecte cette exigence (voir la datasheet).


normalement il n'y a même pas besoin de résistance de pull-up sur Arduino donc tu peux les enlever pour tes essais

Je ne vois pas pourquoi !! Il n'y a aucun pullup sur l'Arduino. C'est pas parce que c'est tombé en marche qu'il faut propager ce genre de légende !!

Autrement en admettant que tu ais un DS1631 de Dallas.
Tu n'as pas fais une erreur sur l'adresse?
As-tu essayé un programme qui balaye les adresses sur le bus pour vérifier que ton composant est bien vu?http://forum.arduino.cc/index.php?topic=139103.msg1068899#msg1068899

B@tto



normalement il n'y a même pas besoin de résistance de pull-up sur Arduino donc tu peux les enlever pour tes essais

Je ne vois pas pourquoi !! Il n'y a aucun pullup sur l'Arduino. C'est pas parce que c'est tombé en marche qu'il faut propager ce genre de légende !!


??!

Tiré de la twi.c :

Code: [Select]
void twi_init(void)
{
 // initialize state
 twi_state = TWI_READY;
 twi_sendStop = true; // default value
 twi_inRepStart = false;
 
 // activate internal pullups for twi.
 digitalWrite(SDA, 1);
 digitalWrite(SCL, 1);

 // initialize twi prescaler and bit rate
 cbi(TWSR, TWPS0);
 cbi(TWSR, TWPS1);
 TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;

 /* twi bit rate formula from atmega128 manual pg 204
 SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
 note: TWBR should be 10 or higher for master mode
 It is 72 for a 16mhz Wiring board with 100kHz TWI */

 // enable twi module, acks, and twi interrupt
 TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
}


De plus je n'utilise aucune résistance en i2c et je m'en sers dans beaucoup de montage, jamais eu un problème !
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

fdufnews

#5
Oct 07, 2013, 11:25 am Last Edit: Oct 07, 2013, 12:16 pm by fdufnews Reason: 1
Les pullups ce n'est pas la panacée.
Les pullups sont donnés entre 20k et 60k c'est OK pour des liaisons de proximités dès que l'on déporte un peu le capteur ou que l'ambiance est bruitée c'est galère potentielle.
L'utilisation des pullups c'est bien pour faire des montages sur la table vite fait bien fait ou pour des gadgets chinois à 2 balles ou on gratte le moindre centime mais franchement pour un fonctionnement fiable c'est vraiment pas une bonne idée.
Surtout dans le cas de l'I²C ce n'est pas du tout adapté si on dépasse le Normal mode donc méfiance. Le tirage n'est pas assez fort pour faire remonter la ligne dans le temps nécessaire pour fonctionner en Fast.

68tjs


Les pullups ce n'est pas la panacée.

+1
Avec les pull up ce qui peut fonctionner avec les micros issus d'un lot de fabrication peut ne pas fonctionner avec un autre lot.

Un peu d'eau au moulin en PJ avec un document que je viens d'écrire.

fking

Déjà merci pour vos réponses !

Mon DS1631 vient de chez maxim, c'est des échantillons gratuits que j'ai demandé.

http://www.maximintegrated.com/datasheet/index.mvp/id/3241

Je vais essayer avec des 4.7k et sans résistances, et je vais tester le programme de scan I²C. Je vous tiens au courant.

68tjs


Je vais essayer avec des 4.7k et sans résistances,

Sans résistance ce n'est pas une bonne idée.
Par contre ce qui serait une bonne idée ce serait de vérifier avec un multimètre qu'au repos toutes les tensions sont conformes et que toutes les masses sont bien reliées.

fking

Bon, j'ai uploadé le programme de scan du bus I²C, il y a bien un slave en 0x84 :



Mais toujours pas possible de dialoguer avec. J'ai mis des 4k7, même chose. Il faut que je teste les tensions, mais bien sûr, plus de pile dans le metrix...  :smiley-yell:

Je collectionne...

B@tto

Oué enfin y'a pas de magie, si le code détecte quelque chose sur le bus, c'est qu'il n'y a pas de problème de connexion. Il ne fait qu'utiliser la méthode brute qui consiste à tester toute les combinaisons possibles.

Donc l'erreur vient de ton code
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

fdufnews


Bon, j'ai uploadé le programme de scan du bus I²C, il y a bien un slave en 0x84 :

Mais toujours pas possible de dialoguer avec. J'ai mis des 4k7, même chose. Il faut que je teste les tensions, mais bien sûr, plus de pile dans le metrix...  :smiley-yell:

Le programme de test interroge une adresse et attend de recevoir un acquittement. Donc si le périphérique est vu à une l'adresse donnée c'est qu'il y a un minimum de dialogue.

Maintenant concernant l'adresse c'est 0x48 et non pas 0x84.
Et 0x48 c'est bien l'adresse attendue lorsque les 3 bits de sélection de l'adresse sont à 0 comme tu l'as dit dans un post précédent.

fking

:* ok pour 0x48... Mais pas de changement... Voilà le code, c'est un exemple trouvé ici. J'essaie de comprendre mon erreur, mais sans succès... J'ai essayé d'autres exemples de code, même problème. Par contre, je suis bien d'accord que si le scanner trouve le slave, c'est qu'il y a bien un minimum de dialogue.

Code: [Select]
#include <Wire.h>

// PIN adresses are set to GND
#define DS1631_ADDR 0x48 >> 1

// SETUP
void setup(){
   
  // Setup Serial connection
  Serial.begin(9600);
  Serial.println("");
  Serial.println("-----------------------------------");
  Serial.println("DS1631 test: Temp. sensor");
  Serial.println("-----------------------------------");
  Serial.println("");
 
  Wire.begin();             // join I2C bus

  // Stop conversion to be able to modify "Access Config" Register
  Wire.beginTransmission(DS1631_ADDR);
  Wire.write((int)(0x22)); // Stop conversion
  Wire.endTransmission(); 
   
  // Read "Access Config" regsiter
  Wire.beginTransmission(DS1631_ADDR);
  Wire.write((int)(0xAC)); // @AC : Acces Config
  Wire.endTransmission();
  Wire.requestFrom(DS1631_ADDR,1); //Reade 1 byte
  Wire.available();
  int AC = Wire.read(); // receive a byte

  Serial.print("Acces Config (Before): "); Serial.print(AC);  Serial.println("");
   
  // WRITE into "Access Config" Register
  Wire.beginTransmission(DS1631_ADDR);
  Wire.write(0xAC); // @AC : Acces Config
  Wire.write(0x0C); // Continuous conversion & 12 bits resolution
  Wire.endTransmission();
   
  // READ "Access Config" register
  Wire.beginTransmission(DS1631_ADDR);
  Wire.write((int)(0xAC)); // @AC : Acces Config
  Wire.endTransmission();
  Wire.requestFrom(DS1631_ADDR,1);
  Wire.available();
  AC = Wire.read();

  Serial.print("Acces Config (AFTER): "); Serial.print(AC);  Serial.println("");
 
  // START conversion to get T°
  Wire.beginTransmission(DS1631_ADDR);
  Wire.write((int)(0x51)); // Start Conversion
  Wire.endTransmission();
}

// Main Loop
void loop(){
 
  //READ T°
  Wire.beginTransmission(DS1631_ADDR);
  Wire.write((int)(0xAA)); // @AA : Temperature
  Wire.endTransmission();
  Wire.requestFrom(DS1631_ADDR,2); // READ 2 bytes
  Wire.available(); // 1st byte
  int Th = Wire.read(); // receive a byte
  Wire.available(); // 2nd byte
  int Tl = Wire.read(); // receive a byte


  // T° processing
  if(Th>=0x80) //if sign bit is set, then temp is negative
  Th = Th - 256;
  int T_dec=(10*(100*(Tl/16)))/16; // decimal part of the T°

  // Display T° on "Serial Monitor"
  Serial.print("Temperature : ");
  Serial.print(Th);   Serial.print(".");
  if (T_dec<10)   Serial.print("0");
  if (T_dec<100)   Serial.print("0");
  Serial.print(T_dec);   Serial.print(" degC / ");
  Serial.print("Th register: "); Serial.print(Th);  Serial.print(" / ");
  Serial.print("Tl register: "); Serial.print(Tl);  Serial.println("");
 
  // Wait 1s before restart
  delay(1000);
}

68tjs

Je ne vais pas entrer dans le détail ton code mais j'en ai vu assez pour voir que tu ne fais jamais de test intermédiaire.
Quand cela ne marche pas :
- on coupe en petit morceaux indépendants que l'on teste UN par UN.
- on fait des controles avec le serial moniteur : quand tu lis un octet avant de le traiter  commence par l'afficher dans le serial moniteur pour controler que ce tu reçois est conforme avec ce que tu attends. Tant que cette opération très simple n'est pas bonne ce n'est pas la peine d'écrire des dizaines de ligne de code.

B@tto

#14
Oct 08, 2013, 09:34 pm Last Edit: Oct 08, 2013, 09:36 pm by B@tto Reason: 1
Le problème vient de l'adresse à mon avis :

#define DS1631_ADDR 0x48 >> 1

0x48 ==> 1001000 ==> on a déjà une adresse à 7 bits, si tu shift de 1 tu perds un bit ...

D'ailleurs je ne comprend pas la logique tu codes de l'autre topic :

#define DS1631_ADDR 0x90 >> 1 ==> 0x90 = 10010000 ou comment se compliquer la vie ...
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

Go Up