Arduino & I2C

Lesquels choisir ? Comment les utiliser ?

Arduino & I2C

Postby 14 zyg 31 » Fri May 15, 2015 9:18 pm

Bonsoir,


J'ai découvert Arduino depuis peu de temps, et j'ai trouvé la solution excellente car j'arrive à programmer sans trop de difficulté !!!
En fait, j'ai un projet de commander un réseau de trains miniatures avec des "expanders" I2C.
Donc voici quelques programmes de mon cru (même si j'ai parfois pomper sur les programmes existants :oops: !!).
Lecture d'un PCF8574 [A]
Code: Select all
#include <Wire.h>
byte iInput=0;

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("Lecture d'un PCF8574");
}

void loop()
{
  Wire.requestFrom(0x38,1); // Commencement de la réception de l'état PCF8574
  if(Wire.available());  //
  {
    iInput = Wire.read(); // Lecture de l'octet
    Serial.println(iInput); // Tansfert du contenu du PCF8574A dans la liaison USB.
  }
  delay(2000);



Lectures de plusieurs PCF8574 [A] ...
Code: Select all
#include <Wire.h>
byte iInput=0;
int adresse;
int adresse2;
int car;
int check;
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("Lecture d'un PCF8574");
 }
 
void loop()
{
  adresse2 = 0x00; //reset des valeurs
  adresse = 0x00;
  car = Serial.read(); // Lecture du port série
  if ( car == 'r')  //Si on appuie sur la touche "r", envoie de l'ordre de réception
  { 
   Serial.println("Adresse ?");
   delay(2000);
   iInput=0;
   adresse = Serial.read(); // Lecture de l'adresse au foramt ASCII
   adresse = adresse - 48; // Transformation de de l'ASCII en octet
   switch (adresse) //Test de l'adresse 1 -> adresse 0x22 ; 2 -> adresse 0x38 ; 3 -> adresse 0x39
   {
    case 1 :
      adresse2 = 0x22;
      break;
    case 2 :
      adresse2 = 0x38;
      break;
    case 3 :
      adresse2 = 0x39;
      break; 
    }
   Wire.requestFrom(adresse2,1); // Commencement de la réception de l'état PCF8574
   if(Wire.available());  //
   {
     check = Wire.endTransmission();
     Serial.println(check);
     iInput = Wire.read(); // Lecture de l'octet
     Serial.println(iInput,BIN); // Tansfert du contenu du PCF8574A dans la liaison USB.
    }
    }
     else
        { Serial.println("Attente");
        }
     check = Wire.endTransmission();
     Serial.println(check);
        delay(2000);
}

14 zyg 31
 
Posts: 119
Joined: Fri Jan 17, 2014 4:36 pm

Re: Arduino & I2C

Postby 14 zyg 31 » Sat May 16, 2015 9:18 am

Bonjour,

En fait ce que j'aimerais faire ce serait de transmettre directement l'adresse du "récepteur" I2C par la liason série, il faudrait transcoder les valerus ASCII en valeur hexadécimale.

Code: Select all
#include <Wire.h>
byte iInput=0;
byte adresse;
int car;
int check;
byte unite;
byte unite2;
byte dizaine;
byte dizaine2;
byte dizaine3;
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("Lecture d'un PCF8574");
 }
 
void loop()
{
  unite =  0;//reset des valeurs
  unite2 = 0;
  dizaine = 0;
  dizaine2 = 0;
  dizaine3 = 0;
  adresse = 0x00;
  car = Serial.read(); // Lecture du port série
  if ( car == 'r')  //Si on appuie sur la touche "r", envoie de l'ordre de réception
  {
   Serial.println("Unite ?");
   delay(2000);
   unite = Serial.read(); // Lecture des unités au foramt ASCII
   delay(2000);
   Serial.println("Dizaine ?");
   delay(2000);
   dizaine = Serial.read(); // Lecture des dizaines au format ASCII
   unite2 = unite -48; //Mise au format hexadécimale des unités
   dizaine2 = dizaine -48; //Mise au format hexadecimale des dizaines
   dizaine3 = dizaine2 << 4; //décalage vers la gauche du chiffre des dizaines
   adresse = unite2 + dizaine3;
   Serial.println(adresse, HEX); //Renvoi de l'adresse dans la laison USB
   delay(2000);
   Wire.beginTransmission(adresse);
   delay(2000);
   iInput = Wire.read();
   check = Wire.endTransmission();
   Serial.println(iInput,BIN); // Tansfert du contenu du PCF8574A dans la liaison USB.
   Serial.println("Acquittement :");
   Serial.println(check);
   }
     else
        { Serial.println("Attente");
        }
     check = Wire.endTransmission();
     delay(2000);
}


Bon sur ma platine, j'ai 3 PCF dont deux PCF8574A
De gauche à droite, les adresses sont 0x38, 0x39, 0x22. Les deux de gauche sont des PCF8574A

IMG_3882.JPG


Pourtant toutes les broches sont 1 alors que quand on regarde le montage j'ai mis des broches à la masse !!
Je ne comprends ce qui se passe !
Attachments
com_arduino.JPG
Last edited by 14 zyg 31 on Sun May 31, 2015 6:35 am, edited 1 time in total.
14 zyg 31
 
Posts: 119
Joined: Fri Jan 17, 2014 4:36 pm

Re: Arduino & I2C

Postby ymasquel » Sat May 16, 2015 11:00 am

Bonjour Pierre,

Je ne pratique pas trop ces composants mais en page 13 de la doc des PCF8574A de T.I. il est indiqué des adresses entre 112 et 127 (0x70 à 0x7F). Il en est de même pour NXP.

Les PCF8574 non suffixés ont des adresses entre 64 et 79 (0x40 et 0x4F).
Amicalement,
Yves.
ymasquel
Site Admin
 
Posts: 3367
Joined: Thu Jan 02, 2014 10:44 am
Location: Oise (60)

Re: Arduino & I2C

Postby 14 zyg 31 » Sat May 16, 2015 11:39 am

En fait pour savoir les adresses des PCF, j'ai utilisé un programme scanner I2C :

Code: Select all
// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include <Wire.h>


void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknow error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }   
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}


Quand on regarde la documentation de ces composants, on s'apperçoit qu'il faut faire attention, si on tient compte ou pas du bit de Lecture/écriture ...
adressage_pcf.JPG

adressage_pcf_a.JPG

Tiré du fichier :
PCF8574_PCF8574A.pdf
(794.81 KiB) Downloaded 110 times

A mon avis la librairie d'instruction I2C ou Wire.h ne tient pas compte de ce bit.

Pourtant dans le programme du précédent message, je fais remonter l'acquitement de transmission entre l'Arduino PCF
0 : tout c'est bien déroulé
1 : données trop nombreuses
2 : absence d'acquitement pour l'envoi d'une adresse
3 : absence d'acquitement pour l'envoi d'une donnée
4 : autre problème
Cordialement
Pierre
14 zyg 31
 
Posts: 119
Joined: Fri Jan 17, 2014 4:36 pm


Return to Microcontrôleurs & microprocesseurs

Who is online

Users browsing this forum: No registered users and 1 guest