jeudi 21 janvier 2021

[I2C] Scanner d'adresses

 Lors de l'ajout d'un module I2C, il est nécessaire de connaitre l'adresse de ce dernier. La majeure partie du temps, cette adresse est fournie dans la datasheet constructeur. Toutefois, cela peut arriver quelle soit manquante.

L'idée est de pouvoir scanner les 128 adresses possibles sur le bus pour trouver celle de notre module.

Il existe de nombreux documents expliquant le principe. 

Principe du scanner I2C

Afin de trouver l'adresse de notre module, nous allons le connecter, seul, à l'Arduino comme suit.


Le programme sera le suivant (celui ci fonctionne plutôt bien).
Attention, il fait appel à la librairie "Wire.h".
/ ---------------------------------------------------------------- /
// Arduino I2C Scanner
// Re-writed by Arbi Abdul Jabbaar
// Using Arduino IDE 1.8.7
// Using GY-87 module for the target
// Tested on 10 September 2019
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
/ ---------------------------------------------------------------- /

#include <Wire.h> //include Wire.h library

void setup()
{
  Wire.begin(); // Wire communication begin
  Serial.begin(9600); // The baudrate of Serial monitor is set in 9600
  while (!Serial); // Waiting for Serial Monitor
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address; //variable for error and I2C 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("Unknown 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 the next I2C scan
}

Le résultat des adresses détectées sur le ou les module(s) raccordés l’Arduino seront affichées dans le moniteur série de l’IDE.

mardi 19 janvier 2021

[Electro] Protocole de communication I2C


Le bus de communication I2C est un algorithme permettant la communication d’une multitude de périphériques sur une seule ligne.

Le protocole I2C

I2C, pour Inter Integrated Circuit , est un protocole de communication crée à la base par Philips en 1982 pour standardiser l’échange de données entre différents circuits intégrés d’un même système. Elle est aujourd’hui assurée par le fabricant NXP, spin-off de l’entreprise.

Ce protocole est basé sur un bus de communication sériel, ce qui signifie qu’un seul câble est utilisé pour le transfert de données.

En pratique, le bus I2C est constitué de deux câbles, un donc pour les données, nommé SDA (Serial Data) et l’autre faisant office d’horloge pour déterminer la fréquence de la communication, nommé SCL (Serial Clock).

Tout d’abord, il n’y a qu’un maître (le microcontrôleur de votre board Arduino), et une multitude d’esclaves (vos périphériques), chacun identifiés par une adresse unique. Seul le maître peut initier une communication.

Le maître envoie tout d’abord l’adresse du périphérique dont il désire recevoir les données. L’esclave envoie un premier signal de confirmation (acknowledgement) pour signifier qu’il a bien reçu la demande.

Puis le maître envoie l’adresse d’un registre interne du périphérique. Par exemple, pour un accéléromètre, on a trois registres stockant respectivement les données de l’accélération selon X, Y et Z. Un deuxième signal de confirmation est envoyé par le périphérique.

Enfin c’est le périphérique qui émet cette fois le message, en transférant la valeur du registre qui a été sollicité. Il termine avec une dernière confirmation, après quoi le maître envoie un signal spécifique pour mettre fin à la communication.

À noter que les deux lignes SDA et SCL sont liées à une résistance de pull-up. L’état 0 est donc l’état dominant.



Utilisation d’I2C avec Arduino

La première chose à faire est d’identifier l’adresse des périphériques liés à votre carte, et l’adresse de leur divers registres internes. Vous trouverez ces informations dans la fiche technique de votre board. Ensuite, dans le cas d’une connexion de périphériques externes, indépendants ou montés sur d’autres cartes Arduino, il faut identifier les ports attribués aux lignes SDA et SCL de chaque carte ou composants et les relier entre eux.

Il s’agira ensuite principalement de coder les échanges dans votre soft. Vous trouverez ci dessous les principales commandes:

Wire.begin();    Initialisation de la communication I2C, à effectuer au début de votre programme.

Wire.beginTransmission(Adresse de votre périphérique);    Cette commande est à appeller à chaque fois pour initialiser une transmission avec le périphérique dont l’adresse est donnée en argument.

Wire.write(Adresse du registre sollicité);    Cette commande permet d’accéder à un registre du périphérique, et est à appeler avec d’écrire ou de lire des données.

Wire.write(Byte à écrire);    Écriture des données désirées dans le registre sollicité au préalable.

Wire.requestFrom(Adresse de votre périphérique, n);    Lecture de n bits du périphérique adressé, dans le registre sollicité au préalable.

Wire.endTransmission();    Fin de la transmission. Cette commande doit être appelée à chaque fois, et avant l’envoi de toute nouvelle requête par I2C.

sourcehttps://www.arduino-france.com/tutoriels/quest-ce-que-le-bus-i2c-et-comment-fonctionne-t-il-sur-arduino/

lundi 11 janvier 2021

[Electro] Pulse Width Modulations

Généralité :

Le PWM est un acronyme anglais qui signifie Pulse Width Modulation, ou Modulation de Largeur d'Impulsion (MLI) en français.

Le principe du PWM est de réduire la puissance moyenne délivrée d’une sortie digitale (0 ou 1) en modulant les impulsions du signal. L’objectif est d’avoir une pseudo sortie analogique pouvant prendre 256 valeurs (0 à 255).

Le signal est modulé avec une fréquence fixe. Le PWM est caractérisé par son rapport cyclique, qui correspond au pourcentage du temps pendant lequel le signal est à l'état haut '1' par rapport à la période du signal.

Un rapport cyclique de 100% correspond à un signal de '5 V' fixe (état haut), alors qu’un rapport cycle de 0% correspond à un signal de '0 V' fixe (état bas).


Pilotage Arduino:

La fonction permettant de fixer le rapport cyclique de la PWM est la fonction analogWrite(...).
Le premier argument de cette fonction est la broche concernée (compatible PWM) et le second argument la valeur du rapport cyclique (compris entre 0 à 255).

Pour un rapport cyclique de 50% l'opération à réaliser sera : 0,50 x 255 ~= 128.

Exemple :
analogWrite(3, 128); // PWM de 50% sur la broche 3