dimanche 25 novembre 2018

Afficheur MAX7219 et RTC DS3231 sur STM32








Afficheur MAX7219 et RTC DS3231

sur STM32


J'aborde une phase cruciale de mon existence : le dernier trimestre de ma vie professionnelle.

Il m'est venu à l'idée d'afficher sur mon bureau le décompte de secondes qui va s'écouler jusqu'à ce moment tant attendu.

Une espèce de QUILLE électronique.

1. Le matériel

Qu'allons-nous utiliser comme matériel ?
Un ARDUINO avec un MAX7219 + afficheur 8x7 segments ?
Oui mais c'est trop facile. Il fallait que je fasse un petit effort supplémentaire.

J'ai donc choisi cette carte : la "petite" BLUE PILL que l'on peut trouver ICI à un prix plus qu'intéressant.

Pour le même prix qu'une NANO :
  • cœur 32bits 72MHz
  • large gamme de tension d'utilisation de 2V à 3.6V
  • 128Ko de mémoire flash
  • 20Ko de SRAM
  • RTC interne
  • unité de calcul CRC, ID unique 96 bits
  • deux convertisseurs A/N 1µs 12 bits (jusqu'à 10 voies)
  • dontrôleur DMA 7 voies, 3 timers à usage général et 1 timer de contrôle avancé
  • 37 ports E/S rapides
  • interfaces de débogage fil série (SWD) et JTAG
  • interfaces : deux SPI, deux I2C, trois USART, une USB et une CAN
  • 50% des entrées sont tolérantes au 5V

Le module MAX7219 se présente sous cette forme :
Il est câblé comme suit :
  • GND : GND
  • VCC : 3.3V
  • DIN : PA1
  • CLK : PA2
  • CS : PA3
Afin de conserver l'heure et la date en cas de coupure, un module RTC DS3231 est utilisé :
 
Il est câblé ainsi :
  • GND : GND
  • VCC : 3.3V
  • SDA : PB7
  • SCL : PB6
Le STM32 a deux I2C et l'I2C1 peut utiliser soit PB9+PB8 ou PB7+PB6 en fonction de la configuration des GPIOs.
Le problème est qu'il faudrait lire le code de la librairie core pour savoir comment tout cela est configuré.

Remarque : le STM32F103C8 possède un RTC interne et un oscillateur 32.768KHz est implanté sur la carte BLUE PILL.
Mais j'avais envie de jouer avec l'I2C. :)

2. Le logiciel

Mon intention est de faire tourner ce petit sketch :

#include <TimeLib.h>
#include <LedControl.h>
#include <Wire.h>

#define TIME_HEADER  "T"   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 

#define LED     PC13
#define DS3231_I2C_ADDRESS  0x68

LedControl lc = LedControl(PA1, PA2, PA3, 1);

const unsigned long DEFAULT_TIME = 1543138573; // Nov 25 2018

byte decToBcd(byte val)
{
  return ((val / 10 * 16) + (val % 10));
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ((val / 16 * 10) + (val % 16));
}

void setDS3231time(int second, int minute, int hour, int wday, int day, int month, int year)
{
  Serial.println("Writing DS3231: ");
  Serial.print(day);
  Serial.print("/");
  Serial.print(month);
  Serial.print("/");
  Serial.print(year);
  Serial.print(" ");
  Serial.print(hour);
  Serial.print(":");
  Serial.print(minute);
  Serial.print(":");
  Serial.println(second);
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(wday)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(day)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year-2000)); // set year (0 to 99)
  Wire.endTransmission();
}

void readDS3231time(int *second, int *minute, int *hour, int *wday, int *day, int *month, int *year)
{
  Serial.print("Reading DS3231: ");
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *wday = bcdToDec(Wire.read());
  *day = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read()) + 2000;
  Serial.print(*day);
  Serial.print("/");
  Serial.print(*month);
  Serial.print("/");
  Serial.print(*year);
  Serial.print(" ");
  Serial.print(*hour);
  Serial.print(":");
  Serial.print(*minute);
  Serial.print(":");
  Serial.println(*second);
}

void processSyncMessage() {
  time_t pctime;

  if (Serial.find(TIME_HEADER)) {
    pctime = Serial.parseInt();
    Serial.print("PC TIME: ");
    Serial.println(pctime);
    if ( pctime >= DEFAULT_TIME) { // check the integer is a valid time
      setTime(pctime); // Sync Arduino clock to the time received on the serial port
      setDS3231time(second(), minute(), hour(), weekday(), day(), month(), year());
    }
  }
}

time_t requestSync()
{
  Serial.write(TIME_REQUEST);
  return 0; // the time will be sent later in response to serial mesg
}

void setup()
{
  Serial.begin(115200);
  Wire.begin();
  pinMode(LED, OUTPUT);
  lc.shutdown(0, false);
  lc.setIntensity(0, 4);
  lc.clearDisplay(0);
  setTime(DEFAULT_TIME);
  setSyncProvider(requestSync);
}

tmElements_t t = {0, 0, 0, 6, 1, 2, 2019 - 1970};

void loop()
{
  int second = 0, minute = 0, hour = 0, wday = 0, day = 0, month = 0, year = 0;

  readDS3231time(&second, &minute, &hour, &wday, &day, &month, &year);
  if (second > 59 || minute > 59 || hour > 23 | day > 31 || year > 2030) {
    Serial.println("Invalid Time");
    setDS3231time(0, 0, 0, 1, 25, 11, 2018);
  }
  setTime(hour, minute, second, day, month, year);

  time_t retirement = makeTime(t);  // convert time elements into time_t
  if (Serial.available()) {
    processSyncMessage();
  }
  lc.clearDisplay(0);
  printNumber(0, retirement - now());
  if (timeStatus() == timeSet) {
    digitalWrite(LED, LOW); // LED on if synced
  } else {
    digitalWrite(LED, HIGH);  // LED off if needs refresh
  }
  delay(1000);
}

void printNumber(int addr, long num) {
  byte c;
  int j;
  int d;
  num = abs(num);
  Serial.print(":");
  Serial.println(num);
  d = countDigits(num);
  for (j = 0; j < d; j++) {
    c = num % 10;                      // Modulo division = remainder
    num /= 10;                         // Divide by 10 = next digit
    boolean dp = (j == 3);              // Add decimal point at 3rd digit.
    lc.setDigit(addr, j, c, dp);
  }
}

int countDigits(long num) {
  int c = 0;
  if (num == 0) {
    return 1;
  }
  while (num) {
    c++;
    num /= 10;
  }
  return c;
}

Comme vous pouvez le remarquer, la différence par rapport à un sketch ARDUINO ne saute pas aux yeux.
Ceci est normal, car je l'ai développé d'abord sur une NANO.

Seules ces deux lignes diffèrent :

// version NANO
#define LED     13
LedControl lc = LedControl(12, 11, 10, 1);

// version STM32
#define LED     PC13
LedControl lc = LedControl(PA1, PA2, PA3, 1);

3. Le chargement

Comment faire pour exécuter du code ARDUINO sur un STM32 ?
Toutes les explications sont ICI.
Un petit tuto personnel pour aider pas à pas les néophytes ICI.

Le sketch utilise Wire, TimeLib et LedControl, des librairies classiques qui ne devraient à priori pas poser de problème particulier.
De plus, le Board Package "Arduino SAM Boards" utilisé pour l'installation dans l'IDE ARDUINO - qui inclut l'ARDUINO DUE - nous laisse penser que nous avons toutes les chances que cela fonctionne.

Et cela fonctionne !


1er février 00H00 :

Maintenant :

4. Mise en route

La date par défaut dans le code est la date d'aujourd'hui.
Pour mettre à l'heure le montage, il faut utiliser le moniteur série de l'IDE ARDUINO ou n'importe quel autre terminal série.
Il faut envoyer la commande suivante :

TXXXXXXXXXX 

La commande se compose de la lettre T suivie du timestamp (nombre de secondes écoulées depuis le 1/1/1970) correspondant à l'heure courante.
Si vous possédez une machine sous LINUX entrez la commande shell suivante :

expr `date +%s` + 3600

La commande affiche un nombre correspondant à l'heure GMT + 1H:

1543157582

Vous pouvez utiliser aussi ce site :

http://www.timestamp.fr/

Il vous faudra également ajouter 3600.

Copiez / collez le timestamp dans votre moniteur série :

T1543157582

Le sketch mettra alors votre RTC à l'heure ainsi que votre horloge système.

5. Conclusion

Ce petit exemple démontre que l'utilisation de librairies prévues pour les cartes ARDUINO est possible sur d'autres cartes.
L'apport des librairies ARDUINO en matière de simplification est indéniable  et permet de gagner un temps fou sur le développement logiciel.
Les développeurs ayant déjà travaillé avec les librairies STM32 de chez ST MicroElectronics savent de quoi je parle.

Cordialement
Henri

mercredi 21 novembre 2018

Les régulateurs LDO




Les régulateurs LDO


Si certains montages classiques se contentent d'un régulateur courant LM7805 ou LF33CV, la majeure partie des circuits alimentés par batterie réclament un peu plus, et même beaucoup plus.

Dans cette petite page nous allons étudier les caractéristiques essentielles des régulateurs de tension destinés à alimenter des montages peu gourmands en énergie, ceci afin de faire un choix correspondant à nos attentes. Il comporte une liste de modèles susceptibles d'être utilisés dans cette optique.

1. Présentation

Tous les montages basse-consommation à l'heure actuelle sont axés autour d'un processeur Low Power fonctionnant de manière générale en 3.3V ou moins. Nous allons nous intéresser à la catégorie des microcontrôleurs accessibles au grand public :
  • ATMEGA328P
  • STM32
  • ESP8266
  • etc.
Il arrive souvent que l'on réussisse au prix de peu d'efforts à obtenir d'un montage utilisant ces processeurs une consommation qui s'exprime en µA ou en dizaines de µA. Malheureusement, ces processeurs ou leurs périphériques ne supportent en général pas que l'on se permette de les alimenter avec une tension supérieure à 3.6V ou 4V.

Que faire lorsque l'on ne dispose pour ce faire que d'une batterie LITHIUM-ION, LIFEPRO ou NI-MH ?
La courbe de décharge d'une batterie LITHIUM-ION part de 4.2V à pleine charge et se termine aux environs de 3V, tension en dessous de laquelle il est déconseillé de descendre, sous peine de réduire la durée de vie de celle-ci.

Un ATMEGA328P cadencé à 8MHz supportera jusqu'à 6V et pourra espérer fonctionner jusqu'aux environs de 2.7V. On pourra donc l'alimenter directement avec une batterie LITHIUM-ION, sans régulateur.
Mais ce n'est pas le cas d'autres processeurs, ou de certains modules ou circuits périphériques destinés à les servir.

Un exemple typique est le NRF24L01, un module radio qui doit être alimenté au maximum sous 3.6V.

C'est aussi le cas des STM32 et ESP8266, limités eux aussi à 3.6V.

Il faut impérativement limiter la tension d'alimentation fournie par la batterie. Et pour ce faire, nous aurons besoin d'un régulateur.

Quelles qualités doit-on attendre d'un régulateur destiné à alimenter un montage basse consommation ?
 

2. Courant de sortie

Bien entendu notre régulateur devra fournir le courant de sortie nécessaire à notre montage.

Un ATMEGA328P et un NRF24L01 pourront se contenter de 50mA.
Un ESP8266 devra être alimenté avec un régulateur capable de fournir les 430mA nécessaires au démarrage de sa connexion WIFI.

3. Quiescent current

Bien entendu la deuxième caractéristique essentielle semble être le courant consommé par le régulateur lui-même, sans qu'il soit chargé, dit "quiescent current". A quoi servirait-il d'alimenter un montage consommant 5µA avec un régulateur LM7833 consommant 4.5mA au repos ?

Il ne faut pas focaliser son choix sur les modèles ayant un quiescent current extrêmement bas, car souvent la batterie que vous allez choisir aura un courant de fuite supérieur à celui-ci. Un jeu de piles aura plus de chances d'avoir un courant de fuite suffisamment bas pour justifier l'emploi d'un tel régulateur.

4. Drop Out Voltage

La dernière caractéristique essentielle est la valeur de la chute de tension provoquée par le régulateur.
Pour en revenir au LM7833, celui-ci a une tension de drop-out de 2V. Alimenter notre montage à partir d'une batterie 3.7V à travers un tel régulateur réduirait à néant nos efforts, car il nous resterait une petite tension de 1.7V à sa sortie.

Un régulateur ayant une tension de drop-out de 200mV sera capable  d'alimenter votre montage jusqu'à ce que la tension de la batterie descende au plus bas. Une batterie LITHIUM-ION dont la tension la plus basse est de 3V pourra dans de bonnes conditions alimenter un ATMEGA328P car il restera dans le pire des cas 2.8V.

Comment va se comporter un régulateur lorsque sa tension d'entrée chute en dessous de sa tension de sortie nominale ?
Sa tension de sortie va chuter elle aussi. Sa valeur sera égale à celle de la tension d'entrée diminuée de la tension de drop-out. Mais il y a une limite basse. La datasheet vous renseignera de toutes façons sur la tension minimale en dessous de laquelle il ne faut pas descendre.

Remarque concernant le 7133-1: lorsque sa tension d'entrée descend en dessous de sa tension nominale, la chute de tension provoquée par le régulateur est ridicule : 1mV pour 60µA !
Ce régulateur est particulièrement intéressant lorsque l'on travaille avec une batterie LITHIUM-ION 3.7V ou NI-MH 3.6V avec de faibles courants.
Il équipe les fameux détecteurs de passage HC-SR501.

Attention : la tension de drop-out est toujours indiquée pour un courant donné.
Par exemple un ME6211 3.3V :
  • 120mV pour 100mA
  • 260mV pour 200mA
La datasheet vous fournira généralement une courbe :



Autre exemple, le RT9013 3.3V :
  • 160mV pour 400mA
  • 250mV pour 500mA
On voit donc que la tension de drop-out augmente avec le courant. Certains modules, même s'ils sont capables de fonctionner en mode veille avec quelques µA ou dizaines de µA, nécessitent un courant élevé pour pouvoir démarrer.
C'est le cas de l'ESP8266, qui a besoin de 300mA avec des pics à 430mA pour démarrer sa connexion WIFI :
https://www.ondrovo.com/a/20170207-esp-consumption/
Avec une batterie chargée à 3.7V, la tension de sortie d'un régulateur ME6211 chutera à 3.7V - 550mV = 3.15V.
Avec un RT9013 elle sera de 3.7V - 250mV = 3.55V. Le régulateur limitera à 3.3V

Autre remarque : il semblerait que l'ESP8266 soit capable de démarrer à partir de 2.5V.
Avec un régulateur RT9013, la tension de la batterie pourra chuter au maximum à 2.75V (ce n'est cependant pas recommandé).
Avec un régulateur ME6211, celle-ci pourra chuter au maximum à 3.05V.

Il est possible d'associer un gros condensateur de 1000µF ou plus, en parallèle sur la sortie du régulateur, pour fournir les pics de courant nécessaires, si le régulateur n'est pas capable de les fournir. Mais il semble illusoire qu'un régulateur fournissant 250mA puisse être utilisé.

5. La liste 

La liste qui suit n'est pas exhaustive, loin de là, mais elle est régulièrement enrichie.
 

Les régulateurs sont classés par tension de drop-out croissante.
La tension mini en entrée est celle qu'il vous faudra appliquer pour obtenir 3.3V en sortie.
 

Nous nous intéresserons ici uniquement aux modèles exploitables par les amateurs que nous sommes, en excluant ceux dont les boîtiers sont trop exotiques, tels les DFN par exemple.
 

Comme vous pouvez le remarquer, rares sont les modèles qui pourront vous offrir une tension de drop-out très basse et également un courant de repos très bas. Il faut souvent choisir un compromis.



A titre indicatif, le deuxième onglet donne une courte liste de régulateurs 5V.

Les fameux AMS1117 et LM7833 ne sont présents qu'à titre d'exemple de ce qu'il ne faut pas employer bien entendu. Avec de tels régulateurs votre batterie de 1000mAH serait vide au bout de 200 heures.

Les régulateurs ayant une tension de dropout de 600mV vous obligeront à adopter une tension d'alimentation supérieure, au delà de 3.9V, 4 batteries AA par exemple.
Pour un régulateur ayant une tension de dropout de 2V, une alimentation d'au moins 5.3V sera nécessaire. 5 batteries AA ou 2 batteries 18650 par exemple.

5. Mesurer la tension batterie

Ceci est un peu hors sujet mais il vous faudra prévoir une mesure périodique de la tension batterie en amont du régulateur afin d'éviter que celle-ci ne chute en dessous de 3V (pour une LITHIUM-ION).
Tous les processeurs cités ici possèdent un ADC. Il est intéressant de l'utiliser afin de réaliser cette opération.
Cet article montre comment mesurer une tension batterie à l'aide d'un pont diviseur :
Le sketch du projet permet de calculer la capacité restante et de la remonter par liaison radio à un serveur domotique (DOMOTICZ dans mon cas).

On peut facilement développer la même solution sur un ESP8266 ou un ESP32.

L'essentiel est de pouvoir visualiser à distance le résultat pour pouvoir le consulter.

Il est possible également de faire clignoter une LED rouge avec des flashs de très courte durée espacés de quelques dizaines de secondes. La tension de seuil sera par exemple de 3.35V, ce qui correspond à environ 20% de capacité restante.
Le courant dans la LED devra être suffisamment faible pour ne pas décharger la batterie à l'excès et suffisamment fort pour que les flashs se remarquent

6. Trier ses régulateurs

Dans un lot de régulateurs les dispersions de caractéristiques peuvent être importantes. Il peut même arriver que le composant acheté ne soit pas du tout le modèle annoncé, malgré une sérigraphie correcte.

Sur un lot de 20 régulateurs HT7533-1 achetés sur AliExpress j'ai pu remarquer que le courant sans charge (quiescent current) était dans la fourchette de la datasheet pour la majorité d'entre eux : 2.5µA - 5µA.
Un seul régulateur était très au dessus : 30µA
Quelques-uns étaient en dessous : 1.2µA.

Lorsque l'on recherche un régulateur très performant, un petit tri s'impose.

7. Conclusion

J'espère que ce document vous aura aidé à éclairer votre choix en matière de régulateur pour votre future réalisation basse consommation.


Cordialement
Henri

8. Mises à jour

25/06/2019 : 6. Trier ses régulateurs
12/07/2019 : liste de régulateurs 5V

mardi 13 novembre 2018

ARDUINO : les performances de l'ADC




ARDUINO : les performances de l'ADC

Nous allons essayer dans cet article d'approfondir nos connaissances de l'ADC (convertisseur analogique / numérique) de l'ATMEGA328P.
Nous allons explorer les possibilités de ce périphérique et essayer d'en augmenter les performances.

1. L'ADC de l'ATMEGA328P

1.1. Description

Les entrées analogiques de l'ATMEGA328P sont constituées d'un seul convertisseur analogique / numérique 10 bits, précédé d'un multiplexeur à 8 canaux.
Les valeurs mesurées par l'ADC varieront donc entre 0 et 1023.

Les pins de l'ARDUINO UNO réduisent ce nombre à 6 canaux.
Les pins de l'ARDUINO NANO mettent à disposition les 8 canaux, ainsi que la plupart des MINI et PRO MINI.

1.2. Circuit

Cette figure est tirée de la datasheet :

Le texte suivant accompagne la figure:
The ADC is optimized for analog signals with an output impedance of approximately 10k or less. If such a source is used, the sampling time will be negligible. If a source with higher impedance is used, the sampling time will depend on how long time the source needs to charge the S/H capacitor, with can vary widely. The user is recommended to only use low impedance sources with slowly varying signals, since this minimizes the required charge transfer to the S/H capacitor.

Il est donc recommandé de ne mesurer que des sources de tension à basse impédance.

Une légende circule qui tendrait à faire croire qu'il faut systématiquement faire deux lectures dont une pour rien quand on effectue des mesures sur plusieurs entrées différentes. Est-ce vrai dans tous les cas ?

A la lecture du schéma, on peut émettre quelques hypothèses :

Si l'impédance de la source est basse, la mesure ne sera pas influencée, y compris si la tension varie rapidement. La constante de temps induite par la résistance de 100KΩ et la capacité de 14pF est de l'ordre de la µs, largement inférieure à la période de l'horloge de l'ADC. Une impédance de source basse (10KΩ) n'aura qu'une faible influence.

Si l'impédance de la source est élevée par contre, la mesure sera influencée, car la capacité CS/H mettra plus de temps à se charger.

1.3. La référence de tension

Lorsqu'on utilise un ADC, le code que l'on va écrire ressemblera forcément à ceci :

int value = analogRead(0);     // lecture ADC sur A0
float voltage = value * 5.0 / 1023;

Ici, on remarque plusieurs choses :

  • la lecture se fait sur A0
  • la référence de tension est supposée valoir 5V
  • analogRead() retourne une valeur entre 0 et 1023. Il y a 1024 valeurs possibles, et 1023 intervalles

On remarque également que la référence choisie dans le code (5.0V) a peu de chances de refléter la réalité. Pour être plus précis, il faudrait mesurer la tension d'alimentation et utiliser cette valeur dans le code :

#define VREF                  5.07

int value = analogRead(0);     // lecture ADC sur A0
float voltage = value * VREF / 1023;

1.3.1. Référence par défaut

La référence par défaut est la tension d'alimentation du processeur. Sa précision dépend du mode d'alimentation de la carte :

  • si on alimente par la broche VIN, la qualité de la référence sera directement dépendante de celle du régulateur de tension 5V ou 3.3V de la carte
  • si on alimente par la broche VCC, la qualité de la référence sera directement dépendante de celle de l'alimentation
  • si on alimente par l'USB, la qualité de la référence sera directement dépendante de celle de la tension USB du PC

On en déduit assez facilement qu'utiliser la référence de tension par défaut n'est probablement pas la meilleure solution, étant donné que la précision de la mesure dépendra principalement de la précision de la source d'alimentation. Or, toutes les alimentations ne se valent pas, spécialement s'il s'agit de blocs secteurs 5V, souvent de piètre qualité. Le 5V USB d'un PC n'est pas non plus une source d'alimentation  stable, elle peut varier elle aussi.

De plus, la valeur de la mesure sera différente si l'on change de mode d'alimentation, en passant par exemple d'une alimentation par USB à une alimentation par bloc secteur.

Pour corriger ce problème, en fonction du processeur utilisé, on peut soit utiliser la référence interne ou une référence externe.

On peut se référer à cette page :

https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/

1.3.2. Référence interne

La référence interne est de 1.1V pour un ATMEGA328. La précision de cette tension est de l'ordre de 10%. De plus elle varie légèrement en fonction de la tension et de la température :

Pour utiliser la référence interne, il faut bien entendu la sélectionner :

analogReference(INTERNAL);

Lorsqu'on utilise cette référence, on peut la mesurer sur la pin AREF pour en tenir compte dans le code :

#define VREF                  1.095

int value = analogRead(0);     // lecture ADC sur A0
float voltage = value * VREF / 1023;

On peut également découpler cette référence par un petit condensateur entre la pin AREF et la masse, pour une meilleure immunité au bruit.

1.3.3. Référence externe

Pour utiliser une référence externe, il faut la sélectionner comme ceci :

analogReference(EXTERNAL);

On peut utiliser la sortie 3.3V présente sur certaines cartes, en la branchant sur la broche AREF. Cela peut être suffisant dans la majeure partie des cas.

La référence externe peut être fournie aussi par être n'importe quel composant appelé "référence de tension" :

  • TL431 : 2.5V 0.5% à 2%
  • LM4040 : 2.048V, 2.5V, 3 V, 4.096V, 5 V 0.1%
  • LT1009 : 2.5V 0.2%
  • MCP1501 : 1.024V, 1.25V, 1.8V, 2.048V, 2.5V, 3V, 3.3V, 4.096V 0.1%

Sur ce schéma, j'utilise un TL431 (U1, en haut à gauche) :

Notre code devient :

#define VREF                  2.5        // TL431 reference

int value = analogRead(0);     // lecture ADC sur A0
float voltage = value * VREF / 1023;

Il existe des références très précises. Je vous les donne juste pour information. Bien évidemment, n'utilisez pas une référence à 0.02% avec un ADC 10bits, ce serait du gâchis.

  • MAX6225 : 2.5V 0.02%
  • MAX6241 : 4.096V 0.02%
  • MAX6250 : 5V 0.02%

En fonction de l'application, le besoin sera différent. Par exemple, si on mesure la tension d'une batterie afin de déterminer sa capacité on aura besoin d'une précision importante et surtout d'une bonne stabilité en température.

1.4. Tension maximale mesurée

La tension maximale que l'on pourra mesurer sera égale à la tension de référence. Si l'on applique une tension supérieure sur une entrée analogique, l'ADC va saturer, et le résultat sera faux.

Si la tension à mesurer est supérieure à la tension de référence, il faut l'abaisser :

Dans ce projet, la référence interne de 1.1V est choisie. La tension à mesurer est celle d'une batterie LITHIUM-ION : 4.2V maximum.

Les deux résistances R2 et R3 forment un pont diviseur. Voici la formule de calcul classique :

Vo = VBATT * R3 / (R2 + R3)

Ici la valeur maximale sur A0 pour VBATT = 4.2V sera :

Vo = 4.2V * 330000 / (1000000 + 330000) = 1.04V

Cette valeur est bien en dessous de la référence choisie : 1.1V

Quelles valeurs de résistances choisir ? Cela va dépendre de l'application. Ici, les valeurs sont élevées, car l'alimentation se fait par batterie, et il est hors de question de consommer un courant trop important dans le pont diviseur.

On peut commencer par fixer deux valeurs :

  • la valeur maximale à mesurer : 1V (elle doit être inférieure à la référence 1.1V)
  • la résistance R3 : 330KΩ

Ensuite on en déduit R2 :

R2 = R3 * (VBATT / Vo) - R3 = 330000 * (4.2V / 1V) - 330000 = 1056KΩ

Comme on ne trouvera pas cette valeur dans le commerce, on adoptera la valeur standard la plus approchante : 1MΩ.

Si l'on adoptait une valeur de 910KΩ :

Vo = 4.2V * 330000 / (910000 + 330000) = 1,117V

Cette valeur est au dessus de 1.1V, elle ne convient donc pas.

Que faire dans le code ?

Ici, nous ajustons la valeur de la référence 1.1V à celle qui a été mesurée : 1.095V

Ensuite nous appliquons un coefficient correspondant la la valeur du pont diviseur :

Coeff = R3 / (R2 + R3) = 330000 ÷ (1000000+330000) = 0.248

Cela donne ceci au final :

#define VREF                  1.095
#define COEFF                
0.248

  unsigned int adc = analogRead(0);
  float voltage = adc * VREF / 1023 / COEFF;

2. Augmenter la précision dynamique

Comme vu au paragraphe 1.2, l'entrée de l'ADC comporte une capacité.

Cette capacité d'entrée de l'ADC  risque de nous poser un problème si nous cherchons à effectuer une mesure sur deux entrées ayant des potentiels très différents.

Mais cela nous posera également un problème si nous effectuons une mesure sur une seule entrée avec de fortes et rapides variations de tension.

Pour mettre en évidence le problème, appliquons sur deux entrées A0 et A1 deux tensions différentes :


Sur l'entrée A0 nous mesurerons idéalement :
3.3V / (10000+4700) / 10000 = 2.25V
Sur l'entrée A1 nous mesurerons idéalement :
3.3V / (10000+4700) / 4700 = 1.05V

2.1. La théorie

La fréquence d'horloge de l'ADC pour la librairie ARDUINO est de 125KHz, cela nous donne donc un temps de cycle de 8µs.Entre le moment où la conversion démarre et le moment où l'échantillon est prélevé (sample & hold), il se passe 1.5 temps de cycle soit 12µs :


2.1.1. Impédance élevée
Imaginons que nous ayons à l'entrée de l'ADC une source de tension à mesurer ayant une impédance forte, 1MΩ par exemple.

La constante RC de temps de charge du condensateur de l'ADC sera de :

RC = 1MΩ * 14pf soit 14µs.

On considère que le condensateur sera chargé à 99% au bout de :

t = 5 * RC soit 70µs.

L'idéal serait d'attendre un temps équivalent entre la sélection de l'entrée et le démarrage de la conversion.Or la librairie ARDUINO n'attend pas !

Et comme il faut 12µs entre le démarrage de la conversion et la prise d'échantillon, on voit bien que cela va provoquer une erreur de lecture assez importante. En fait cette erreur dépendra de la différence de tension entre les deux canaux. Si les tensions sont presque identiques, l'erreur sera minime. Si la différence est importante, l'erreur le sera aussi.

2.1.2. Impédance faible
Avec une source de tension ayant une impédance faible, 10KΩ par exemple, il nous faudra tenir compte de la résistance série interne de l'ADC (une valeur de 1 à 100KΩ comme le montre la figure plus haut). Elle est estimée par certains expérimentateurs à une vingtaine de KΩ, ce qui nous donne 30KΩ en tout. Il nous faudra donc attendre 33 fois moins longtemps, donc 2µs. Dans ce cas nous sommes très en dessous des 12µs requises.
Mais n'oublions pas que ces 2µs permettent de charger le condensateur à seulement 99%. Pour garantir une résolution maximale (théoriquement 0.5 LSB), il est possible que l'on ait effectivement besoin des 12µs.

2.1.3. Impédance moyenne
Avec une source de tension ayant une impédance moyenne, 100KΩ par exemple, il nous faudra attendre 8.3 fois moins longtemps, donc 8.4µs. Dans ce cas nous sommes aussi en dessous des 12µs requises, mais n'oublions pas ici aussi que nous nous sommes contentés de charger le condensateur à 99%, ce qui donne quand même 1% d'erreur.

2.1.4. La théorie de la double lecture
Sur le WEB on voit couramment des conclusions hâtives du genre "pour éviter les problèmes faire systématiquement une double lecture et ne conserver que la deuxième.

Prenons un exemple simple :
- une LDR en série avec une résistance, point milieu sur une entrée
- un potentiomètre sur une autre entrée

En fonction du sens de branchement et de la différence de tension entre les deux entrées, le condensateur a une chance sur quatre de se charger ou décharger à travers la LDR. S'il fait nuit noire, certaines LDR ont une résistance de 10MΩ.
Il s'en suit un temps de charge ou de décharge du condensateur de l'ADC de :

RC = 10MΩ * 14pf  * 5 soit 700µs.

Dans ce cas, ce n'est pas avec une double lecture que l'on s'en sortira, ni avec une triple.
Avec une fréquence d'horloge de 125KHz, le nombre de mesures par seconde et de 8900, donc 110µs par mesure. Il faudra donc 7 mesures et non pas 2 !
On voit bien que la théorie fumeuse de la double mesure systématique ne tient pas.
Dans certains cas, elle est totalement inutile, dans d'autres cas, elle est totalement insuffisante.

2.1.5. Expérimentation
Nous allons vérifier ceci par expérimentation dans les paragraphes suivants.

2.2. Les sketches

Nous mesurons alternativement les deux entrées A0 et A1 à l'aide des deux sketches suivants :

Le premier sketch lit alternativement les deux entrées A0 et A1 en prenant un seul échantillon à chaque fois.

// SKETCH N°1 (une lecture)

#define VREF 4.72

void setup() {
  Serial.begin(115200);
}

void loop() {
  uint16_t valA0 = analogRead(A0);
  Serial.print("Voltage A0: ");
  Serial.println((float)valA0 * VREF / 1023);
  uint16_t valA1 = analogRead(A1);
  Serial.print("Voltage A1: ");
  Serial.println((float)valA1 * VREF / 1023);
  delay(1000);
}


Le deuxième sketch lit alternativement les deux entrées A0 et A1 en prenant deux échantillons à chaque fois.
 
// SKETCH N°2 (deux lectures)

#define VREF 4.72

void setup() {
  Serial.begin(115200);
}

void loop() {
 
  analogRead(A0); 
  uint16_t valA0 = analogRead(A0);
  Serial.print("Voltage A0: ");
  Serial.println((float)valA0 * VREF / 1023);
 
  analogRead(A1); 
  uint16_t valA1 = analogRead(A1);
  Serial.print("Voltage A1: ");
  Serial.println((float)valA1 * VREF / 1023);
  delay(1000);
}


2.3. Impédance source faible

Notre premier essai est effectué avec deux ponts diviseurs 10KΩ/4.7KΩ et 4.7KΩ/10KΩ comme sur le schéma ci-dessus.

La mesure avec le sketch N°1 donne les résultats suivants :

Voltage A0: 2.26
Voltage A1: 1.04
Voltage A0: 2.26
Voltage A1: 1.05
Voltage A0: 2.26
Voltage A1: 1.04 


La mesure avec le sketch N°2 donne les résultats suivants :

Voltage A0: 2.26
Voltage A1: 1.04
Voltage A0: 2.26
Voltage A1: 1.05
Voltage A0: 2.26
Voltage A1: 1.04


On obtient le même résultat. On s'y attendait un peu non ?

L'impédance de 4.7KΩ est très faible devant les 100KΩ de l'entrée de l'ADC, donc la capacité d'entrée de l'ADC se charge en un temps très court.

2.3. Impédance source forte

Augmentons les valeurs. Remplaçons ces résistances de 10KΩ et 4.7KΩ par des résistances de 1MΩ et 470KΩ.

Les résistances utilisées sont des modèles film métallique 1%. Les différences de mesure par rapport au test précédent seront minimes mais pas inexistantes.

La mesure avec le sketch N°1 donne les résultats suivants :

Voltage A0: 2.27
Voltage A1: 1.19
Voltage A0: 2.16
Voltage A1: 1.17
Voltage A0: 2.09
Voltage A1: 1.19


La mesure de A0 est systématiquement tirée vers le bas, sauf la première, celle de A1 est tirée vers le haut.
La tension a du mal à se stabiliser après une baisse ou une hausse rapide.

La mesure avec le sketch N°2 donne les résultats suivants :

Voltage A0: 2.27
Voltage A1: 1.03
Voltage A0: 2.27
Voltage A1: 1.03
Voltage A0: 2.26
Voltage A1: 1.03


Ce résultat est nettement meilleur non ?

Le fait de lire deux fois améliore grandement les choses. L'opération peut se décomposer ainsi :
  • sélection de l'entrée
  • démarrage de la conversion
  • attente de la fin de la conversion
  • récupération du résultat (pour rien)
  • sélection de l'entrée
  • démarrage de la conversion
  • attente de la fin de la conversion
  • récupération du résultat
Il y a fort à parier que l'on obtienne le même résultat comme ceci :
  • sélection de l'entrée 
  • delay(x)
  • démarrage de la conversion
  • attente de la fin de la conversion
  • récupération du résultat
L'important n'est pas de lire deux fois, mais de laisser un peu de temps entre la sélection de l'entrée est le démarrage de la conversion.

2.4. Impédance source moyenne

Remplaçons les résistances par des résistances de 100KΩ et 47KΩ.

La mesure avec le sketch N°1 donne les résultats suivants :

Voltage A0: 2.23
Voltage A1: 1.07
Voltage A0: 2.23
Voltage A1: 1.07
Voltage A0: 2.23
Voltage A1: 1.07


La mesure de A0 est légèrement tirée vers le bas, celle de A1 est légèrement tirée vers le haut.

Nous pouvons en tirer la conclusion suivante :

Si l'impédance de la source de tension est très inférieure à 100KΩ, nous pouvons lire plusieurs entrées alternativement, ou lire une entrée dont la tension varie rapidement, ceci sans précaution particulière.

2.5. La solution électronique

Quand l'impédance de la source est élevée, comment faire pour ne pas dégrader les performances de la conversion alors que cela impose de lire deux fois ou d'introduire un délai entre la sélection de l'entrée est le démarrage de la conversion ?

Il est possible d'intercaler un amplificateur opérationnel suiveur entre la source et l'ADC afin d'abaisser l'impédance :


Reprenons le montage avec cette fois-ci :
  • R3 = 4.7KΩ
  • R4 = 10KΩ
  • R1 = 2MΩ
  • R2 = 1MΩ
La mesure avec le sketch N°1 donne les résultats suivants :

Voltage A0: 2.26
Voltage A1: 1.26
Voltage A0:
2.26
Voltage A1: 1.24
Voltage A0:
2.26
Voltage A1: 1.24

La mesure de A0 est normale, celle de A1 est tirée vers le haut.
 
La mesure avec le sketch N°2 donne les résultats suivants :

Voltage A0: 2.26
Voltage A1:
1.05
Voltage A0:
2.26
Voltage A1: 1.04
Voltage A0:
2.26
Voltage A1:
1.05

Ajoutons maintenant un amplificateur opérationnel comme ceci :

L'amplificateur opérationnel est un LT1077, que l'on peut alimenter avec une simple ligne 5V.

La mesure avec le sketch N°1 donne les résultats suivants :

Voltage A0: 2.26
Voltage A1: 1.04
Voltage A0:
2.26
Voltage A1: 1.05
Voltage A0:
2.26
Voltage A1: 1.05


La mesure avec le sketch N°2 donne les résultats suivants :

Voltage A0: 2.26
Voltage A1: 1.05
Voltage A0:
2.26
Voltage A1: 1.04
Voltage A0:
2.26
Voltage A1: 1.05

 
La situation "normale" est rétablie. Il n'y a plus de différence entre une simple mesure et une double mesure.

L'amplificateur opérationnel abaisse l'impédance à l'entrée de A1.

Qu'y avons-nous gagné ?
Nous pouvons nous contenter d'une mesure unique en toutes circonstances. Donc nous avons gagné du temps et une prise d'échantillon plus rapide.


3. Augmenter la vitesse

La librairie standard fixe l'horloge de l'ADC à 125KHz. Or celui-ci peut facilement faire le même travail à 500KHz.
Il est possible également de le configurer en free-running. Dans ce cas, le convertisseur tourne librement et nous venons récupérer le résultat de la conversion quand nous en avons besoin.

Essayons le sketch suivant (tiré de ce site) :

#include "wiring_private.h"

#define TEST  10000L

uint32_t sensorValue;

void testDefaultADC(int pin)
{
  uint32_t start = millis();
  for (int x = 0 ; x < TEST ; x++) {
    sensorValue += analogRead(pin);
  }
  uint32_t elapsed = millis() - start;
  Serial.print("ADC value ");
  Serial.println(sensorValue / TEST);
  Serial.print("elapsed time ");
  Serial.print(elapsed);
  Serial.println(" ms");
  Serial.print("samples ");
  Serial.println(TEST);
  Serial.print("ADC speed: ");
  Serial.print(TEST * 1000L / elapsed);
  Serial.println(" SPS");
}

void startFreeRunningADC(uint8_t pin)
{
  ADMUX = (1 << REFS0) | ((pin - 14) & 0x07); //select AVCC as reference and set MUX to pin
  ADCSRB = 0; //set free running mode
  ADCSRA = (1 << ADEN) | (1 << ADATE) | (1 << ADPS2) | (1 << ADPS0); //set adc clock to 500Khz, enable, free running mode
  //ADCSRA=(1<<ADEN)|(1<< ADATE)|(1<<ADPS2)|(1<<ADPS1); //set adc clock to 250Khz, enable, free running mode
  sbi(ADCSRA, ADSC); //start the ADC
}

inline uint8_t sampleDone()
{
  // ADIF is set when the conversion finishes
  return bit_is_set(ADCSRA, ADIF);
}

inline uint16_t getSampleResult()
{
  uint8_t low, high;
  low = ADCL; //make sure to read L value first
  high = ADCH;
  sbi(ADCSRA, ADIF); //clear conversion complete flag
  return (high << 8) | low;
}

#define ADCport A0

void setup()
{
  Serial.begin(115200);
  testDefaultADC(ADCport);
  startFreeRunningADC(ADCport); //free running mode, only needs to start once.
}

#define ELAPSE    1000L

uint32_t start;
uint32_t count;

void loop()
{
  if (start == 0) {
    start = millis();
    sensorValue = 0;
  }
  while (!sampleDone());
  sensorValue += getSampleResult();
  count++;
  if (millis() - start >= ELAPSE) {
    Serial.print("ADC value ");
    Serial.println(sensorValue / count);
    Serial.print("elapsed time ");
    Serial.print(ELAPSE);
    Serial.println(" ms");
    Serial.print("samples ");
    Serial.println(count);
    Serial.print("ADC speed: ");
    Serial.print(count * 1000L / ELAPSE);
    Serial.println(" SPS");
    while(1);
  }
}


Dans un premier temps, dans le setup, nous mesurons à l'aide de la fonction testDefaultADC le temps d'exécution pour 10000 mesures.
Ensuite, l'ADC est boosté à 500KHz et tourne en free-running, de manière asynchrone.

Les résultats sont éloquents :

ADC value 510
elapsed time 1119 ms
samples 10000
ADC speed: 8936 SPS
ADC value 510
elapsed time 1000 ms
samples 38470
ADC speed: 38470 SPS


La valeur de la mesure (nous mesurons ici VCC/2) ne change pas, par contre nous avons multiplié le nombre de SPS (échantillons / seconde) par 4.

Remarque : pour les besoins du test, la fin de la conversion est attendue :

  while (!sampleDone());

Mais nous pouvons nous dispenser de cette attente de manière à ne pas rester bloqué et pouvoir faire autre chose pendant ce temps :

  if (!sampleDone()) {
    sensorValue = getSampleResult();

  } else {
    // faire autre chose
  }

4. Augmenter la résolution

4.1. ADC externe

Afin d'augmenter la résolution il est possible d'utiliser un ADC 16bits du type ADS1115, fonctionnant en I2C :

Malheureusement, il vous en coûtera une nette dégradation des performances en vitesse. Cet ADC a des performances excellentes en matière de résolution mais il est peu rapide : 860 SPS.

Un ADS1256 SPI 24bits sera beaucoup plus rapide (30000 SPS) :

ADS1256 : ADC Hautes Performances

Sinon, changer de processeur pour un ARDUINO DUE ou un STM32.

L'ADC d'un STM32F401 a une résolution de 12bits, une fréquence d'horloge de 30MHz et peut offrir 2000000 SPS.

4.2. Mesure moyenne

Afin d'obtenir une meilleure immunité au bruit et une meilleure précision, il est possible de lire plusieurs fois la valeur et faire une moyenne :

float readAdc(int pin)
{
  uint32_t val = 0;

  analogRead(pin);
  for (int i = 0 ; i < 4 ; i++) {
    val += analogRead(pin);
  }
  return (float)val * VREF / 1023;
}

Il vous en coûtera une dégradation certaine des performances en vitesse d'acquisition, proportionnelle au nombre de lectures.

5. La totale

Ci dessous le schéma précédent complété a l'aide d'un LM4040 :

Le LM4040 est alimenté par une résistance de 1K, ce qui produit un courant de 5V - 2.5V / 1000 =  2.5mA.

Le sketch utilise la référence externe et effectue une moyenne sur quatre lectures consécutives.

#define VREF 2.5  // LM4040

void setup() {
  Serial.begin(115200);
  analogReference(EXTERNAL);
}

float readAdc(int pin)
{
  uint32_t val = 0;

  analogRead(pin);
  for (int i = 0 ; i < 4 ; i++) {
    val += analogRead(pin);
  }
  return (float)val * VREF / 1023;
}

void loop() {
  Serial.print("Voltage A0: ");
  Serial.println(readAdc(A0));
  Serial.print("Voltage A1: ");
  Serial.println(readAdc(A1));
  delay(1000);
}

La mesure est exceptionnellement stable :

Voltage A0: 2.25
Voltage A1: 1.11
Voltage A0: 2.25
Voltage A1: 1.11
Voltage A0: 2.25
Voltage A1: 1.11
Voltage A0: 2.25
Voltage A1: 1.11

6. Conclusion

L'ADC de l'ATMEGA328P peut offrir des performances acceptables pour peu que l'on se donne la peine de le configurer correctement.


Cordialement
Henri

7. Mises à jour

01/06/2019 : 2.1. La théorie

dimanche 4 novembre 2018

Concevoir un PCB






Concevoir un PCB

Nous allons expliquer dans cet article, sans trop entrer dans les détails, comment se conçoit un PCB maison.

Je ne m'adresse pas aux personnes ayant une grosse expérience de la chose, mais plutôt aux amateurs qui aimeraient pouvoir se lancer dans l'aventure mais que la chose effraie.

D'abord pourquoi un PCB quand on peut relier un ARDUINO a des modules du commerce avec des fils DUPONT ?
Tout d'abord pour obtenir un produit fini, facilement intégrable dans un boîtier. Ensuite il faut reconnaître que les fils volants ne sont pas une méthode de raccordement très fiable. Les faux contacts sont vos ennemis, et la soudure votre amie.

Alors, pourquoi ne pas souder les composants sur un PCB d'expérimentation ?
Outre les possibilités d'accueil de composants ultra limitées (2.54mm) , le câblage de ce genre de carte est un vrai casse-tête.
Quand il s'agit de câbler un transistor, un relais, deux condensateurs et quelques résistances cela peut être une solution rapide, mais au delà, clairement non.

1. Les outils de conception

Bien entendu nous allons éviter de parler des logiciels professionnels aux tarifs dissuasifs.
Il existe dans le monde du logiciel libre des outils très performants permettant de réaliser le schéma et le routage d'un montage très facilement et confortablement.
Je vais vous présenter KICAD, que j'utilise avec beaucoup de satisfaction depuis plusieurs années.

Installez le à partir de ce lien : http://kicad-pcb.org/download/

Les utilisateurs de LINUX n'auront pas à télécharger le logiciel. Il pourront l'installer directement depuis l'outil d'installation de leur distribution.
Sous UBUNTU :

sudo apt-get install kicad

Je n'ai pas l'intention de vous noyer dans 40 pages avec une centaine de copies d'écran. Je ne vais pas vous montrer pas à pas comment cliquer sur chaque bouton de chaque boîte de dialogue. Le but est plutôt de réunir en un seul article d'une quinzaine de pages l'essentiel de ce qu'il faut connaître sur le sujet.

Vous submerger sous des tonnes d'informations n'est pas le but. Explorez les menu, les icônes, le clic droit contextuel, et voyez l'effet qu'ils produisent. La curiosité est la plus grande des qualités.

J'aborderai par contre certaines fonctionnalités que vous verrez dans peu de tutoriels. L'essentiel est de savoir qu'elles existent. Vous pourrez vous entraîner à les utiliser en les expérimentant vous-même.
Vous aurez droit également à un gros chapitre de conseils.

Les questions et commentaires sont bien entendu les bienvenus. Ils peuvent contribuer à enrichir ce document.

2. Principes généraux

KICAD est un logiciel qui fonctionne assez différemment des logiciels Windows ou LINUX habituels.

Dans un schéma ou une implantation, on ne clique pas sur un composant ou une empreinte, sauf en utilisant le bouton droit pour accéder au menu contextuel. On place le curseur de la souris sur l'élément voulu, sans cliquer, et on agit sur le clavier pour réaliser une action.

Pour supprimer un composant, placez le curseur dessus sans cliquer et appuyez sur la touche "SUPPR".
Il est aussi possible de aussi de faire un clic droit et de choisir "Supprimer".

Pour tirer un fil entre deux composants, placez le curseur dessus sans cliquer et appuyez sur la touche "w".
Il est aussi possible de aussi de cliquer sur l'icône "Place Component" et cliquer sur la feuille.

La méthode utilisant les touches clavier est nettement plus efficace.

Comme la majeure partie des logiciels, "CTRL-Z" annule le dernier changement, "CTRL-Y" le rétablit.

3. Le projet

Lorsque vous lancez KICAD, cette fenêtre apparaît :


Vous allez cliquer sur "File/New Project", donner un nom explicite à votre projet et un emplacement pour vos fichiers.

Nous allons nommer ce projet : test

Vous allez voir apparaître dans la fenêtre de gauche deux fichiers :
  • test.sch : votre schéma
  • test.kicad_pcb : votre routage
Le schéma est la représentation théorique de votre projet.
Le routage est la représentation physique des composants et des pistes sur votre carte.
Double-cliquez sur test.sch. Une belle fenêtre pleine de vide apparaît.

4. Le schéma (Eeschema)

La première mission lorsque l'on développe un carte électronique est de dessiner le schéma de celle-ci.
La barre d'icône sur la droite vous permet :
  • d'ajouter des composants
  • d'ajouter des points d'alimentation
  • de les raccorder entre eux
  • d'ajouter des libellés
  • etc.
Noua allons placer sur une feuille blanche des composants et relier ces composants à l'aide de fils. Partons d'un exemple, un détecteur de mouvement :
Vous pouvez télécharger et l'ouvrir dans KICAD. Double-cliquez simplement sur le fichier mysensors-motion-sensor.pro

4.1. Les librairies

KICAD est installé dès le départ avec une librairie de composants assez impressionnante. Vous allez vite vous apercevoir que cette librairie ne contiennent que des éléments standards et courants : des composants passifs, des circuits intégrés, des transistors, des diodes, des relais, etc.

Malheureusement, les éléments essentiels de ce schéma sont manquants :
  • ARDUINO MINI
  • NRF24L01
  • TP4056 (chargeur de batterie)
Vous avez plusieurs solutions :
  • les dessiner vous même à l'aide du "Library Editor"
  • les trouver sur le WEB
On peut en trouver beaucoup ici :
https://github.com/KiCad/kicad-symbols
Vous pouvez également me demander de vous les envoyer en me contactant. Un petit commentaire en bas de n'importe quelle page de ce blog suffira.

Il s'agit de fichiers portant l'extension .lib que vous copierez dans le sous-répertoire library de votre répertoire KICAD.

Ensuite il vous faudra les intégrer à votre projet. il suffira d'utiliser le menu "Preferences/components libraries". Cette fenêtre apparaît :



Cliquez sur le bouton "Add" pour ajouter votre nouvelle librairie.
Maintenant celle-ci est disponible dans votre éditeur de schéma et vous allez pouvoir placer les composants qu'elle contient.

4.2. L'éditeur de composants

Cet outil se lance en cliquant sur l'icône "Library Editor".

Il y a deux méthodes de travail.
  • vous créez une librairie, puis vous dessinez votre composant et vous le sauvegardez dedans.
  • vous dessinez votre composant et vous l'exportez dans une nouvelle librairie.
Vous pouvez importer un composant ressemblant à celui que vous voulez créer ou démarrer de zéro.

A droite vous disposez d'un certain nombre d'icônes. Vous pouvez :
  • ajouter une pin
  • tracer le contour du composant
  • etc. 
Voici ce que vous devez obtenir :

Chaque pin doit avoir un nom et un numéro. C'est plus facile ensuite sur le schéma de savoir quelle est la fonction de chaque pin. Utilisez simplement les noms et les numéros que vous trouverez dans la datasheet du composant.



Vous pourriez bien entendu créer un composant générique à 16 pattes, mais ensuite sur le schéma vous auriez beaucoup de mal à associer chaque patte à sa fonction, à moins d'avoir la datasheet sous les yeux, ou de la connaître par cœur.

Lorsque votre tracé est terminé, sauvegardez ou exportez votre composant dans votre répertoire libraries.

Je vous conseille vivement de développer des librairies thématiques. Afin d'éviter les confusions, nommez vos librairies afin qu'il n'y ait pas de confusion possible avec celles de KICAD :
  • my_resistors.lib
  • my_connectors.lib
  • my_transistors.lib
  • my_microcontrollers.lib
  • etc.
Dans l'onglet description de votre composant, ajoutez une ligne de commentaire indiquant la fonction du composant.

4.3. Placer les composants

Utilisez l'icône "Place Component" ou appuyez sur "a".


Choisissez le composant et placez-le sur votre page blanche d'un simple clic.

Je vous conseille vivement d'explorer les librairies mises à votre disposition. C'est le meilleur moyen de les connaître. Contentez-vous de les survoler, cela suffira.

Chaque composant est accompagné de deux textes :
  • le libellé
  • la référence (terminée par ?)
Changez les libellés de vos composants :
  • valeur des résistances, des condensateurs
  • type d'amplificateur opérationnel
  • etc.
Pour éditer un composant, pointez-le avec la souris puis appuyez sur "e".

Ne touchez pas à la référence. KICAD le fera pour vous.

Placez d'autres composants au hasard sur le schéma. Nous allons maintenant les relier.

4.4. Tirer les fils

Utilisez l'icône "Place Wire" ou pointez une patte de composant et appuyez sur "w". Tirez le fil jusqu'à atteindre la patte de l'autre composant auquel vous voulez le relier.

KICAD ne tire que des fils horizontaux ou verticaux. A chaque fois que vous voulez prendre un virage, cliquez. Lorsque vous avez atteint le second composant, cliquez simplement sur la pin sur laquelle vous voulez que se termine le fil.

Votre schéma prend forme.

4.5. Les points d'alimentation

Vous pouvez placer des points d'alimentation avec l'icône "Place Power Port" ou en appuyant sur "p". Choisissez le point (5V, 12V, GND, etc.), placez le sur le schéma d'un simple clic.
Reliez ces points d'alimentations aux fils existants ou aux pins d'alimentation des composants. Bien entendu, deux points d'alimentation portant le même nom seront considérés par KICAD comme un seul point d'alimentation.

Pour certains circuits comme la série CMOS 4000 ou la série 74XX, les points d'alimentation n'apparaissent pas sur les composants. Il vous suffit de placer deux points d'alimentation nommés VDD et VSS (CMOS 4000) ou VCC et GND (74XX) sur deux fils ou un connecteur d'alimentation pour que KICAD comprenne qu'il aura à relier toutes les pins d'alimentation des portes CMOS à ces points.

Placez obligatoirement un point "GND" car tous les schémas ont une masse.

4.6. Quelques trucs

  • déplacer un composant : "m".
  • draguer un composant (le déplacer avec ses fils) : "g". La même touche peut aussi déplacer un fil
  • faire tourner un composant : "r" 
  • copier un composant : "c"
  • changer le libellé d'un composant : "v"
  • orienter un composant :  clic droit puis "Orient Component"
  • ajouter un texte : "t"
  • rafraîchissement schéma :  F3
  • zoom : utilisez la molette de la souris
  • défilement vers la droite ou la gauche : CTRL + molette
  • défilement vers le bas ou le haut : SHIFT + molette
N'hésitez pas à utiliser le clic droit sur un composant, explorez le menu contextuel. Soyez curieux.

4.7. Fonctionnalités spéciales et astuces

Les fonctionnalités suivantes n'apparaissent en général pas dans les tutoriels habituels.

4.8.1. Les sous-schémas

Lorsque votre schéma est de dimensions importantes, vous pouvez le découper en plusieurs parties.

Utilisez le menu "Place / Hierachical Sheet". Cliquez dans un coin du schéma. Un petit rectangle se dessine. Agrandissez-le en déplaçant la souris. Cliquez une deuxième fois. Une popup apparaît. Validez.

Votre rectangle "Hierachical Sheet" devra être suffisamment grand pour pouvoir y placer toutes les entrées et sorties.

Appuyez sur ESC. Double-cliquez dans le rectangle. Une page blanche s'ouvre.
Procédez de la même manière que pour un schéma principal. Ajoutez des composants, reliez-les, ajoutez des points d'alimentation.

Pour créer des entrées et sortie dans votre sous-schéma vous allez créer des "Hierarchical labels", en leur donnant un petit nom parlant. Vous allez relier ces labels à des pins de composants ou des fils existants.

Ces labels sont les entrées et sorties de votre sous-schéma.

Inutile d'ajouter des labels pour vos points d'alimentation. Ils suffit de placer des points d'alimentation normaux. S'il portent les même noms que ceux du schéma principal, ils sont considérés comme reliés.

Pour revenir au schéma principal, avec un clic droit, choisissez "Leave Sheet".

Maintenant vous allez importer chaque label à l'aide de l'icône "Place a hierarchical pin imported from ...". Cliquez à chaque fois sur le rectangle représentant le sous schéma et placez votre pin à l'endroit désiré.

Ces pins pourront être reliées à des fils ou des pattes de composant du schéma principal de la même manière qu'un composant normal.

4.7.2. Le copier / coller dans un schéma

Copier et coller une partie de schéma sur un nouveau schéma est faisable.

Utilisez le menu "Place / Hierachical Sheet". Cliquez dans un coin du schéma. Un petit rectangle se dessine. Agrandissez-le en déplaçant la souris. Cliquez une deuxième fois. Une popup apparaît. Validez.

Appuyez sur ESC. Double-cliquez dans le rectangle. Une page blanche s'ouvre.
Utilisez le menu "File / Append Schematic Sheet". Choisissez le fichier à importer. Placez-le sur la page.

Sélectionnez la partie qui vous intéresse. Appuyez sur CRTL-C.
Avec un clic droit, choisissez "Leave Sheet". Utilisez l'icône "Paste" et placez votre bloc sur la page.

Quand vous n'avez plus besoin du schéma secondaire, pointez-le avec la souris, appuyez sur DEL, sinon il sera considéré comme un sous-schéma

4.8.3. Les composants à plusieurs unités

Certains composants de la librairie contiennent plusieurs unités :
  • CMOS 4000
  • 74XX
  • etc.
Lorsque vous placez une porte NAND d'un CD4011 par exemple, vous pouvez placer l'unité A,B, C ou D. Si vous dépassez le nombre de 4 unités, 2 composants seront utilisés.

Mais sur aucune de ces unités vous ne voyez apparaître de pin d'alimentation. Ne vous inquiétez pas, elles sont implicites. Cela permet d'alléger le schéma.

Pour la série CMOS 4000 il vous suffit de placer deux points d'alimentation nommés VDD et VSS sur deux fils ou un connecteur d'alimentation pour que KICAD comprenne qu'il aura à relier toutes les pins d'alimentation des portes CMOS à ces points.

Pour la série 74XX, ces pins se nomment VCC et GND.

Bien sûr si vous utilisez des composants  74XX et CMOS 4000 sur la même carte, VSS et GND peuvent être au même potentiel si tout est alimenté en 5V, VCC et VDD également.

4.8.4. Choix des composants

Le choix des composants est guidé par leur fonction :
  • résistance
  • condensateur
  • transistor
  • circuit intégré
  • etc.
Pour un composant passif ou un circuit intégré le problème est relativement simple.
En ce qui concerne les composants passifs il y a peu de choix dans la librairie :
  • une résistance
  • un condensateur non polarisé
  • un condensateur polarisé
  • un potentiomètre
  • une diode
  • une zener
  • etc. 
En effet, d'un point de vue strictement schématique, une résistance de 1/4W est équivalente à une résistance de 3W.
Seule l'empreinte sera différente.

En ce qui concerne les circuits intégrés il suffit de choisir le composant adéquat :
  • un ARDUINO NANO
  • un CD4511
  • un LM741
  • etc.
L'empreinte sera choisie par vous parmi les boîtiers proposés :
  • ARDUINO NANO : DIP30
  • CD4511 : DIP16
  • LM741 : DIP8
Qu'en est-il des transistors ?
Vous allez vite vous apercevoir d'une chose :

Si le composant existe dans la librairie, vous le choisissez, naturellement.
Remarquez : le brochage n'est pas toujours dans le même ordre :
  • PN2222 : EBC
  • BC237 : CBE
Comment allons-nous nous en sortir s'il n'existe pas ?

La méthode de luxe : vous  recherchez un composant schématique correspondant exactement à votre matériel, ou vous le créez à partir d'un composant existant, ayant le même brochage, par copier / coller en respectant la datasheet.

C'est la méthode professionnelle. A chaque composant son empreinte spécifique, quitte à multiplier à l'infini le nombre de composants identiques.

La méthode bricoleur : vous utilisez un composant générique de la librairie qui se trouve dans la libraire devices.
  • 2N3906 : Q_NPN_EBC
  • BC239 : Q_NPN_BCE
Ensuite lors du choix de l'empreinte, celle-ci sera de toutes façons un boîtier TO92 de votre choix, ou éventuellement un TO18.

Les boîtiers sont toujours numérotés 1 2 3 de la gauche vers la droite.
Donc pour un 2N3906 ou un BC239 le brochage sera respecté.

Le raisonnement est identique pour un MOSFET.

5. Choix des empreintes (CvPCB)

Quand tous vos fils sont en place, il va falloir attribuer une empreinte (footprint) à chaque composant. L'empreinte est la représentation physique de votre composant, la disposition de ses pattes, son encombrement, etc.

Vous devez utiliser le menu "Tools/Assign Component footprint" ou l'icône "Run CvPCB to Associate Componants and Footprints".

Le logiciel va d'abord vous demander d'annoter les composants. Cliquez sur  "Annotate" et laissez-le faire tout seul. Vos composants porteront tous une référence : R1, R2, C1, U1, etc.

La fenêtre suivante va vous permettre de choisir les empreintes de vos composants :


A gauche, vous trouvez les librairies d'empreinte, au centre vos composants, à droite les composants disponibles de la librairie sélectionnée.

Cliquez sur l'icône "View selected footprint" pour ouvrir une fenêtre permettant de visualiser l'empreinte que vous choisissez.

Je vous conseille vivement de parcourir les librairies disponibles afin de les retrouver plus facilement et aussi ne pas avoir à recréer les empreintes qui existent déjà.

Par exemple, pour le composant L293D que nous avons créé au paragraphe 3.2, vous allez choisir l'empreinte "Housings-DIP / DIP-16_W7.62mm". Pas besoin de la créer :


5.1. Les librairies d'empreintes

Car bien sûr vous pouvez créer vos propres librairies d'empreintes. Comme précédemment avec les librairies de composants, vous aurez le choix :

  • les dessiner vous même à l'aide du "Footprint Editor"
  • les trouver sur le WEB

On en trouve beaucoup ici :

https://github.com/KiCad/kicad-footprints

Vous pouvez également me demander de vous les envoyer en me contactant sur ce blog.

Il s'agit de fichiers portant l'extension .kicad_mod que vous placerez dans le sous-répertoire library.pretty de votre répertoire kicad.

Je vous conseille vivement de classer vos empreintes dans des sous répertoires :

  • library.pretty
    • resistors.pretty
    • connectors.pretty
    • cases.pretty
    • microcontrollers.pretty
    • etc.

Il faut ensuite lancer PcbNew ou CvPCB et ajouter chaque répertoire à l'aide du menu "Preferences / Footprint Libraries Manager". Ensuite, quitter et relancer KICAD. Oui c'est un petit défaut. Mais si je n'étais pas là pour vous le dire vous pourriez chercher longtemps.

Ensuite vous verrez apparaître votre librairie dans la liste de gauche de la fenêtre CvPCB, tout en bas.

Pour sélectionner une empreinte, choisissez la librairie dans la fenêtre de gauche, cliquez sur le composant dans la fenêtre du milieu et double-cliquez sur l'empreinte choisie dans la fenêtre de droite.

KICAD passe tout seul à la ligne suivante.

Quand toutes vos empreintes sont choisies, sauvegardez et fermez la fenêtre.

5.2. L'éditeur d'empreintes

Cet outil se lance en cliquant sur l'icône "Footprint Editor".

Vous pouvez importer une empreinte ressemblant à celle que vous voulez créer ou démarrer de zéro.

A droite vous disposez d'un certain nombre d'icônes. Vous pouvez :

  • ajouter une pin, la nommer, la numéroter
  • tracer le contour de l'empreinte
  • etc.

Il est bien entendu que votre empreinte doit correspondre à votre composant, même nombre de pins, même numérotation.

Vous pouvez aussi créer une empreinte pour un composant existant dans la librairie standard. Un transistor NPN ou MOSFET existe dans une multitude de boîtiers différents. Toutes les empreintes ne sont pas forcément présentes dans la librairie.

Lorsque votre dessin est terminé, exportez votre empreinte dans votre répertoire libraries.pretty, dans un sous répertoire si vous le jugez nécessaire (c'est conseillé).

5.3. La netlist

Nous allons maintenant générer la netlist, un fichier qui va décrire les associations entre composants, empreintes et fils.

Dans l'éditeur de schéma, cliquez sur "Tools / Generate Netlist File" ou l'icône "NET". Cliquez sur le bouton "Generate", "Enregistrer". C'est fini pour cette partie.

Il est bien entendu que :

  • à chaque fois que vous modifiez le schéma, vous devez générer la netlist
  • à chaque fois que vous ajoutez un composant au schéma, vous devez lui choisir une empreinte et générer la netlist

6. Le routage (PcbNew)

Nous allons maintenant passer à la phase routage, c'est à dire placer les empreintes sur la carte et tracer les pistes.

Cliquez sur l'icône "Run PcbNew", en haut à droite.
Encore une fois une belle fenêtre pleine de vide apparaît :


Vous allez commencer par lire la netlist. Cliquez sur l'icône "NET", puis sur "Read current netlist" puis sur OK.Vérifiez bien qu'aucun message d'erreur n'apparaît.
Les erreurs les plus courantes :
  • vous avez choisi pour un composant dont les pattes sont repérées par 1, 2 et 3 une empreinte dont les pins s'appellent A, B, C
  • il manque une patte du composant dans votre empreinte
  • etc.
Lorsque vous avez lu la netlist, les empreintes apparaissent sur la page.

Avoir fait tout ça pour voir un gros paquet d'empreintes regroupées au même endroit sur la page ? Eh oui. Il va falloir placer vous même les empreintes sur celle-ci.

Les professionnels avec lesquels je travaille n'utilisent pas le routage automatique. Je ne vous entraînerai pas dans cette voie.

Avant d'aller plus loin choisissez votre grille. Une liste déroulante (grid) vous permet de choisir l'espacement minimal que vous désirez fixer pour les pattes de vos composants. Rien ne vous empêche de fixer une grille de 1.27mm pour vos composants et une grille plus fine pour vos pistes. Changez-la à volonté en cours de routage.

Deux icônes à gauche vous permettent de choisir l'unité de la grille (inch ou mm).

6.1. Placer les empreintes

Commencez par les ranger sur un côté de la page en les regroupant par type.
On les déplace en pointant le composant, sans cliquer, et en appuyant sur "m" (move). Un clic de souris permet de le relâcher sur la page.

Maintenant on y voit un peu plus clair. Les composants sont rangés et les fils de votre schéma sont représentés par des lignes blanches. Quelques fois ils disparaissent (c'est rare). Relisez la netlist.

Placez vos composants sur la page. Pour éviter de générer un sac de nouilles je vous conseille de les placer de la même manière que sur le schéma pour commencer. Par la suite, vous pourrez les déplacer, les orienter, pour obtenir un résultat acceptable et compact.

Quand tous les composants sont placés, la phase de tracé des pistes peut commencer.

6.2. Règles de conception

Vous allez commencer par visiter le menu "Design Rules" et choisir la largeur de vos pistes, leur espacement minimal (clearance) et le diamètre des vias. Les vias sont des pastilles utilisées pour les passages entre couches. Ils doivent avoir un diamètre supérieur à la largeur de piste.






Il est possible de définir plusieurs largeurs de pistes. Dans l'exemple, une règle power est ajoutée, avec des piste de 1mm.

Vous devez aussi prêter attention à l'espacement entre pistes (clearance). Si vous avez des tensions de l'ordre de 110V ou 230V sur la carte, l'espacement devra être plus important, plusieurs millimètres.

Ensuite pour attribuer cette règle à certaines pistes (nets), vous devez sélectionner la règle "POWER" dans la liste et sélectionner les nets voulus dans la fenêtre de droite et les faire passer avec les flèches vers la fenêtre de gauche.

Validez pour fermer.

6.3. Tracer les pistes

Comme nous sommes débutants, nous allons router une carte avec des composants traversants. Commencez par cocher la case "B. Cu" (back copper) en haut à droite de la fenêtre PcbNew.
Les élèves doués qui ont choisi de directement commencer avec des composants CMS choisiront la case "F. Cu" (front copper).

Placez votre souris sur une patte d'empreinte et appuyez sur "x" ou cliquez sur l'icône "Add track and vias". Déplacez la souris dans la bonne direction. lorsque vous avez atteint la patte de l'autre empreinte auquel vous devez la relier, double-cliquez.

KICAD ne tire que des pistes horizontales, verticales ou à 45°. A chaque fois que vous voulez changer de direction, cliquez. Lorsque vous avez atteint la seconde empreinte, double-cliquez simplement sur la patte sur laquelle vous voulez que se termine la piste.

KICAD refusera de relier deux pattes d'empreintes qui ne doivent pas l'être. Lorsque deux pattes dont reliées, la ligne blanche qui les reliait auparavant disparaît. La piste est créée.
Quand toutes les lignes blanches ont disparu, c'est fini.

KICAD refusera de croiser deux pistes qui ne doivent pas l'être, sauf si elles sont situées sur deux couches différentes.

KICAD refusera qu'une piste passe trop près d'un pad ou une autre piste si la distance (clearance) que vous avez fixé n'est pas respectée.

Quelques trucs (presque les mêmes que pour le schéma):
  • démarrer un fil : "x"
  • faire tourner une empreinte "r"
  • déplacer une empreinte : "m". La même touche peut aussi déplacer une piste
  • draguer une empreinte (la déplacer avec ses pistes) : "g". La même touche peut aussi déplacer une piste
  • rafraîchissement : F3
  • zoom : utilisez la molette de la souris
  • défilement vers la droite ou la gauche : CTRL + molette
  • défilement vers le bas ou le haut : SHIFT + molette
Ici encore n'hésitez pas à utiliser le clic droit sur une empreinte ou une piste. Soyez curieux.

6.4. Les vias

Nous allons parler un peu des vias. Nous allons nous limiter à un PCB à deux couches, celle du dessus (rouge) et celle du dessous (verte).

A chaque fois que vous voulez passer d'une couche à l'autre pendant le tracé d'une piste, faites un clic droit puis "Place Trough Via". Votre piste change de couleur. Vous pouvez maintenant passer sous une piste située sur l'autre face de la carte. Pour revenir à la face précédente, utilisez la même méthode "Place Trough Via". Continuez votre tracé.

6.5. Les zones

Comme nous sommes sérieux, nous allons placer sur notre carte un plan de masse, car nous voulons nous préserver des parasites et interférences. De plus si vous gravez votre PCB vous-même cela réduit la quantité de cuivre à dissoudre et évite de saturer votre acide trop vite (écologie).

Utilisez le menu "Place / Zone".
Cliquez sur le coin de la carte où vous voulez démarrer la zone.



Dans la fenêtre qui apparaît, choisissez :
  • la couche (layer) : B. Cu pour dessous, F. Cu pour dessus
  • la piste (net) : GND
  • l'espacement minimal entre le plan de masse et les pistes (clearance)
Validez. La fenêtre disparaît. Cliquez sur les autres coins de la zone que vous voulez créer et terminez en double cliquant sur le premier coin que vous avez placé.

Appuyez sur "b".

Avec l'exemple du schéma présenté précédemment vous obtenez ceci :


6.6. Les trous de fixation, les boîtiers et le bord de carte

Sur ce routage on peut remarquer plusieurs choses :
  • il y a des trous de fixations représentés par deux gros pads isolés à droite
  • la carte est intégrée dans un boîtier (en bleu)
  • il y a un tracé de bords de carte (en jaune)
Les pads sont des empreintes comme les autres. On peut les ajouter à l'aide l'icône "Add Footprints" dans la barre d'outils de droite. Ensuite cliquez sur la page. Une boîte apparaît. Utilisez le bouton "Select by Browser".


La librairie Wire_Pads contient un certain nombre de pads. Choisissez celui qui convient au diamètre du trou que vous voulez créer.
Placez le sur la page.

Vous pouvez supprimer les libellés du pad. ils sont encombrants et inutiles.
Utilisez la touche "e" pour éditez l'empreinte.

Les boîtiers par contre ne font pas partie des librairies fournies. Vous devrez les dessiner par vous-même. Cela se fait comme pour les empreintes, avec le "Footprint Editor". Il vous faudra la datasheet du boîtier ou prendre les mesures vous-même.

Les tracés de bords de carte s'obtiennent en cliquant sur l'icône "Add graphic Line or Polygon".

6.7. Le DRC

Le DRC  (Design Rules Check) permet de vous assurer que les règles de conception sont respectées. Cliquez sur "Tootls / DRC", puis "Start DRC". Si certaines pistes sont trop proches des pads ou trop proches les unes des autres, DRC vous le dira.
Cliquez sur "List Unconnected" pour vérifier que vous n'avez pas oublié de piste.

6.8. Le copier / coller de PCB

Quand on réalise un PCB il peut arriver que l'on veuille graver plusieurs petites cartes sur la même plaque d'époxy.

Pour commencer il vaut mieux dessiner les bords de carte (voir paragraphe précédent). Ce sera plus facile pour placer les différentes cartes sur la plaque.

Ensuite, ouvrir PcbNew à l'aide du menu Démarrer de Windows ou du launcher Ubuntu. Il ne faut pas lancer PcbNew à partir de l'éditeur de schéma.

On peut aussitôt dessiner les bords de la plaque finale.

Ensuite dans le menu "File" cliquer sur "Append Board", choisir le fichier (extension .kicad_pcb), placer le premier PCB sur la plaque.
Ajouter autant de cartes que nécessaire en les espaçant légèrement de l'épaisseur de la lame de scie que vous allez utiliser pour les séparer.

6.9. Les conseils

J'ajoute ici quelques conseils pour bien router une carte. Tous ne sont pas de moi, loin de là. Merci entre autres à Bernard (68tjs) sur le forum ARDUINO :
https://forum.arduino.cc/index.php?board=33.0

6.9.1. Définir la taille du circuit imprimé

C'est un point important car sorti de la taille 10cm X 10 cm les prix explosent en amateur.
Autant savoir de suite que si la surface totale des composants dépasse 50 % de la surface du circuit imprimé il sera difficile de placer les pistes.

J'ajouterais que vous avez peut-être envie de placer votre carte dans un boîtier. Il vous faudra d'abord créer l'empreinte du boîtier, au minimum sa surface intérieure. N'oubliez pas de placer les plots de fixation et les trous pour les vis.


Sur ce boîtier KRADEX Z-123 on voit des clips de fermeture. Vous devrez dessiner le contour de carte en conséquence.
Il y a quatre plots de fixation pour une carte. Prévoir d'en utiliser au moins deux dans le routage de votre carte.

Si cela ne rentre pas, il ne vous reste plus qu'à changer de boîtier ou revoir la conception.

6.9.2. Placement des connecteurs et autres

En priorité je place les connecteurs de sortie car ce nouveau PCB devra être relié, autant avoir un plan de brochage cohérent avec le reste du matériel.

J'ajouterais également les potentiomètres, les contacteurs et autres interrupteurs qui seront ressortis en face avant. Faites un dessin de votre face avant avec un logiciel permettant de faire des dessins cotés, et placez les organes de commande de manière judicieuse, ergonomique et esthétique.

Et n'oubliez pas les dissipateurs. Les dissipateurs sont des composants comme les autres. Ajoutez-les au schéma (le composant existe), associez-le à une empreinte (vous devrez probablement la dessiner), et placez celle-ci sur votre routage.

Ne placez pas de condensateurs électrolytiques trop près d'un dissipateur, cela réduit leur durée de vie. CF les condensateurs gonflés que vous avez peut-être déjà remarqué près du processeur d'une carte mère de PC en panne. Ne cherchez pas la panne, elle est là.

6.9.3. Composants stratégiques

J'identifie les composants stratégiques et les pistes stratégiques sur lesquels j'apporte un soin tout particulier.
Bien sûr il faut aussi identifier les non stratégiques sur lesquelles on pourra faire ce qu'on veut car on ne peut pas avoir que des contraintes.

Par exemple, ne placez pas de pistes ou de plan de masse sous l'antenne d'un module radio.

6.9.4. Placer les composants et les pistes

Je place les composants et je commence le routage des pistes. J'apporte un soin particulier à la masse, il faut avoir en tête qu'il faudra que ce soit un plan.

De plus, avec un plan de masse, si vous gravez vos cartes vous-même, votre litre d'acide sera moins vite saturé.

6.9.5. Compromis

Commence une série d'aller et retours plus ou moins nombreux en fonction des contraintes sur le circuits, comme j'ai commencé par le dire tout n'est pas possible et il faut faire des compromis.

6.9.6. Composants multiples

Avec les circuits intégrés qui comportent plusieurs modules comme des portes par exemple, par défaut le logiciel choisi la A en premier. Ne pas hésiter à tester avec les autres pour voir si le routage n'est pas plus simple. Souvent rien que le fait de regarder le plan de brochage dans la datasheet du CI permet de faire le bon choix de suite et fait gagner du temps (encore un bon exemple pour inciter à consulter les datasheets :) )

Ce choix se fera sur le schéma. Si vous voulez intervertir les portes A et B, intervertissez-les sur le schéma, générez la netlist, retournez au logiciel de routage et relisez celle-ci.
Je vous conseille au préalable de supprimer du routage les pistes connectées à ces portes. KICAD ne les replacera pas tout seul.

6.9.7. Jamais de modifications de schéma dans le routage

Même si c'est possible ne JAMAIS faire de modifications de schéma ou de composant dans le module PCB, JAMAIS.
Les modifications se font dans le module de schématique, le nouveau fichier de schématique (netlist) doit être rechargé dans le module PCB.
C'est le seul moyen de garder la cohérence entre schéma et circuit imprimé.

Ce conseil est uniquement valable si votre logiciel de routage accepte de telles modifications. KICAD refusera de le faire.
Cependant il est possible d'ajouter des composants ne figurant pas sur le schéma. Cela se limite à des composants non reliés aux autres composants du schéma (boîtier, trous de fixation, etc.).

6.9.8. Changer une empreinte

Vous avez fait une erreur d'association d'empreinte et vous voulez corriger.

Un exemple simple : changer une empreinte de résistance 1/4W pour une 1W.
  • retournez à Eeschema
  • lancez CvPCB
  • sélectionnez la nouvelle empreinte, sauvegardez, fermez
  • dans Eeschema générez votre netlist
  • retournez à PcbNew
  • supprimez votre ancienne empreinte et relisez la netlist

6.9.9. Modifier une empreinte

Il arrive en cours de routage de s'apercevoir qu'une empreinte comporte une erreur ou un oubli, ou qu'elle ne convient pas.
  • lancez l'éditeur d'empreintes depuis PcbNew
  • chargez votre empreinte
  • faites vos modifications, sauvegardez, fermez
  • dans le routage supprimez votre ancienne empreinte et relisez la netlist
On peut aussi mettre à jour l'empreinte avec un clic droit puis "Edit" puis "Change Footprint" puis "Apply".

6.9.10. Modifiez votre schéma pour simplifier le routage

Pour illustrer, prenons un exemple. Vous devez router un circuit driver de LCD 4x7segments + point décimal. Le plus simple est que chaque pin (segment) du LCD soit proche de celle du driver et que les pistes ne se croisent pas.

Si les pistes des segments se croisent toutes, imaginez la complexité que cela va générer de placer des vias pour éviter cela. Nous avons en tout 4x8 = 32 pistes à placer !

Retournez au schéma, et faites en sorte de placer vos fils différemment. Générez la netlist, retournez à PcbNew et relisez-la.
Si des pistes de segments se croisent encore, recommencez.

Le logiciel devra simplement être conçu pour commander les nouvelles pins à la place des anciennes. Ce n'est pas plus compliqué.

6.9.11. Export de symboles et empreintes

A partir d'un schéma ou d'un routage existant il est facile de récupérer les symboles et les empreintes.
Schéma : CTRL-E sur le composant puis click sur l'icône Export Component
Routage : CTRL-E sur le composant puis click sur l'icône Export Footprint

7. Imprimer

Ceux qui comme moi gravent leurs cartes eux-mêmes peuvent directement imprimer leur routage sur un film transparent. Cliquez sur l'icône "Print Board", choisissez la couche que vous voulez imprimer et cliquez sur OK.

L'impression doit être noire. Si elle est gris foncé, paramétrez le contraste de votre imprimante. Si ce n'est pas possible, imprimez deux fois et superposez les deux films, fixez-les avec du ruban adhésif.

Insolation, passage au révélateur, gravure à l'acide, etc. On ne va pas expliquer tout cela ici. On trouve beaucoup de documentation sur le WEB.
Cela fera certainement l'objet d'un nouvel article sur ce blog.

Sachez quand même que c'est le meilleur moyen pour obtenir un PCB dans l'heure qui suit.

8. Fichiers GERBER

Il va falloir pour terminer générer vos fichiers GERBER, car bien entendu, vous n'avez pas le matériel pour graver vos PCB et vous faites appel à un professionnel.

Utilisez l'icône "Plot", à droite de l'icône "Print Board".

Une fenêtre bourrée d'options apparaît. Comment s'en sortir ?

A partir de là chaque fournisseur a ses propres règles en la matière. je vais vous en indiquer deux.

8.1. JLCPCB

Voici le lien qui vous permettra de paramétrer correctement votre génération de fichiers GERBER :

https://support.jlcpcb.com/article/44-how-to-export-kicad-pcb-to-gerber-files

Vous n'aurez plus qu'a créer une archive ZIP et à la transmettre sur la page de commande.

8.2.  PCBWAY

Chez PCBWAY, voici le lien utile :

https://www.pcbway.com/blog/help_center/Generate_Gerber_file_from_Kicad.html

Même chose ici. Une petite archive ZIP et en route pour la commande.

Comparez les prix, sans oublier les frais de port.

9. Conclusion

Cela fait maintenant deux ans que je pratique KICAD et je découvre sa puissance chaque jour.
C'est vrai que c'est un peu déroutant au début. On a l'impression de se retrouver dans un jeu vidéo avec tous ces raccourcis au clavier, mais cela s'avère très efficace à l'utilisation.

Beaucoup de tutoriels vous incitent à utiliser la souris et les icônes. Personnellement je pense que les raccourcis clavier à la main gauche et la souris à la main droite (ou le contraire) sont bien plus efficaces.

J'espère vous avoir donné envie de vous lancer et d'arrêter de relier des modules avec des fils DUPONT ou des PCB d'expérimentation.

Les questions et commentaires sont bien entendu les bienvenus. Ils peuvent contribuer à enrichir ce document.

Cordialement
Henri

10. Tutoriels

Tapez "kicad tutoriel" sous google, vous en trouverez des tas.
N'hésitez pas à choisir les vidéos qui vous aideront sur des points particuliers.

11. Liens utiles

Librairies de symboles :
https://github.com/KiCad/kicad-symbols

Librairies d'empreintes :
https://github.com/KiCad/kicad-footprints

Mes librairies personnelles :

12. Mises à jour

08/11/2018 : 6.6. Les conseils
11/11/2008 : 6.9.10. Modifiez votre schéma pour simplifier le routage
12/11/2018 : 4.8.4. Choix des composants
19/12/2018 : 6.9.11. Export de symboles et empreintes
29/12/2018 : 6.8. Le copier / coller de PCB