Nous continuons cette semaine notre découverte des machines utilisées dans les Fablabs avec une vidéo sur les fraiseuses numériques. Contrairement aux imprimantes 3D qui viennent ajouter du plastique pour créer des objets, les fraiseuses numériques permettent de soustraire de la matière pour usiner des pièces mécaniques, des circuits imprimés et beaucoup d’autres choses décrites dans la vidéo !
- Corrigé du TP : Feu bicolore, barrière et LCD
- Les fraiseuses numériques
- Arduino et I²C
- Travaux pratiques
Corrigé du TP : Feu bicolore, barrière et LCD
Corrigé du TP : Feu bicolore, barrière et LCD
Voici la correction du TP de la semaine dernière qui reprend des éléments du TP Feu bicolore et barrière et du cours sur les écrans LCD.
Code
Voici une des solutions possibles pour répondre au problème dans l’état actuel de nos connaissances :
Montage
Schéma
Pour réaliser ce montage, vous avez besoin de :
- Un Arduino ;
- Une platine de prototypage ;
- Un câble USB ;
- Une résistance de 10kΩ ;
- Deux résistances de 220Ω ;
- Des fils de prototypage ;
- Une photorésistance ;
- Un servomoteur ;
- Un bouton poussoir ;
- Une LED rouge ;
- Une LED verte ;
- Une écran LCD ;
- Du temps
Notre correction s’arrête là. Pour des éclaircissements, nous vous invitons à poser vos questions sur le forum et à reparcourir le cours.
On vous laisse avec le montage un peu fouilli de Baptiste :
Ainsi qu’un affichage sur l’écran LCD rétroéclairé de ylc :
Les fraiseuses numériques
Merci d’avoir regardé cette vidéo sur les fraiseuses numériques. Cette vidéo décrit brièvement les principes de fonctionnement de ces machines.
Comme il existe de très nombreux logiciels pour passer d’un fichier
informatique aux instructions machine (le fameux .gcode
dont nous
parlions la semaine dernière), nous n’avons pas souhaité rentrer dans la
partie logicielle des fraiseuses. Nous vous invitons plutôt à visiter un
FabLab qui dispose d’une machine de ce type et de regarder la vidéo
ci-dessous produite par Dimitri du FabLab de
Lyon.
Références
- Une excellente vidéo sur les fraiseuses (youtube) produite par Dimitri du FabLab de Lyon\
Merci à Arthur Wolf et Stéphane Philippe, adhérents du TyFab et fondateurs de Ipso Factio. Merci également aux équipes des Petits Débrouillards Bretagne pour nous avoir permis de tourner au TéléFab à Brest.
La fraiseuse numérique en 3 parties par Dimitri
Arduino et I²C
Le bus I²C (Inter Integrated Circuit)
Les bits and bytes (and wires)
Commercialisée à la fin des années 80 par Philips, cette norme de communication "inter-circuits-intégrés" a été mise à jour deux fois durant les années 90 et est devenue un standard non seulement dans l’industrie mais aussi pour les amateurs. Souvent poussée beaucoup plus loin que l’idée d’origine : un système de branchements et un protocole de communication destiné aux liaisons courtes et entre circuits intégrés, elle est désormais utilisée comme interface pour les périphériques de tous genres et c’est même le point de départ pour d’autres normes de communication série (le bus CAN, par exemple). Moi-même j’ai utilisé le I²C 'tel quel' pour la communication entre modules de gestion sur une moto de compétition.
Côté branchements le bus I²C séduit car, en dehors de l’alimentation et le retour 0v, il n’y a besoin que de deux conducteurs : les données, appelées SDA, et une horloge appelée SCL. Le protocole de communication est relativement simple mais est conçu de sorte que plusieurs maîtres et plusieurs esclaves peuvent cohabiter sur le même bus sans soucis de collision. Eh oui, il est malheureusement impossible d’aborder ce sujet sans parler de choses très "époque coloniale" : les maîtres et les esclaves.
Maîtres et esclaves
Un maitre dans ce contexte est celui qui donne des ordres et, surtout, celui gère l’horloge - qui cadence le temps. D’habitude c’est le microcontrôleur. Un esclave est représenté par tout autre circuit ou périphérique connecté sur le bus. Avec une seule ligne de données (SDA) la communication est ce qu’on appelle half-duplex : la communication se passe dans un sens à la fois. Regardons la connectique d’un peu plus près :
Connectique I²C
Voici comment on branche les périphériques sur le bus. Pour fonctionner, bien sûr, il faut qu’il y ait aussi un retour (GND) commun pour tout le monde.
(image : source datasheet Philips)
Toutes les connexions SDA et toutes les connexions SCL sont reliées entre elles. Pour l’ensemble des circuits, on ajoute une résistance 'pull-up' sur la ligne SDA et une sur la ligne SCL. La valeur des deux résistances aide à optimiser le bus pour une meilleure performance, mais dans la plupart des cas des valeurs entre 4k7 et 10k donnent de bons résultats. Oui, parfois le bus fonctionne sans ces deux résistances, mais leur présence est TRÈS importante. Ne lésinez pas sur vos montages. Alors, si tout le monde est branché ensemble, comment démêler la communication ? Comment sait-on qui dit quoi ?
C’est moi le maître
Le protocole est défini de sorte qu’à un moment donné il n’y ait qu’un maître, et c’est lui qui dicte sa loi pendant la durée de son 'mandat’. À partir du moment où un maître 'prend le bus’, il est seul maître à bord tant qu’il ne le relâche pas. Chaque esclave est codé avec une adresse, et tous écoutent afin de savoir si leur numéro est appelé. Voici une photo d’un dialogue typique I2C :
Lisons de gauche à droite : d’abord la condition de démarrage (Start) : un maître prend le contrôle du bus en tirant la ligne de données à 0v pendant que tout le monde dort (toutes les sorties sont tirées par défaut à 5v par les deux résistances). C’est annoté sur cette trace par le point vert. Pour communiquer, le maître fait cycler la ligne d’horloge SCL. Chaque bit à transmettre ou à recevoir est validé sur les fronts montants du signal SCL. A partir de l’instant "Start", les esclaves écoutent pour savoir si leur adresse est annoncée. À la fin de l’adresse, un bit indique si le maître va envoyer des données à l’esclave, ou si l’esclave doit envoyer les données. Comme avec un talkie-walkie ou la phraséo VHF marine… Dans l’exemple ici, l’adresse annoncée est 0x68 (héxadécimal) ou 104 (décimal). Le drapeau lecture/écriture est à "0", ce qui veut dire que c’est le maître qui va parler à l’esclave à l’adresse 0x68. Si l’esclave est bien à l’écoute, et prêt à entendre les bonnes paroles, il signale sa présence en tirant la ligne SDA à 0v pendant le 9ème cycle. Le maître peut continuer à lui envoyer les données. La fin du "mandat", la condition terminé (Stop), est signalée par le relâchement de SDA après que SCL soit stabilisé à son niveau haut. On la voit ici repérée par le point rouge. Dans cet exemple, le maître envoie deux octets de valeur zéro à l’esclave avant de terminer le message.
Vous avez dit barbant ?
Eh oui, c’est assez laborieux tout cela ! Heureusement il y a Findu… non, je veux dire qu’heureusement nous avons déjà une bibliothèque prévue pour les interfaces 2-fils : Wire.h Nous n’avons plus qu’à lui donner l’adresse de l’esclave à qui on veut parler, et c’est la bibliothèque qui s’occupe du reste.
Un exemple concret
Pour expérimenter avec l’I²C, rien de mieux que de prendre un circuit intégré typique et de le faire parler ! J’ai choisi pour vous le DS1307, une horloge / calendrier / mémoire. Vous pouvez l’acheter complètement nu, une puce DIL-8 qui se branche directement sur une platine d’expérimentation, ou pré-monté sur un circuit imprimé (appelé souvent un breakout), souvent avec une pile de sauvegarde 3v. Voici les deux bêtes côte à côte :
(désolé pour la mise au point…)
À côté du DS1307 'tout nu' dans son lit douillet j’ai mis le quartz de 32KHz qu’il faut utiliser pour le faire fonctionner. Sur le breakout on distingue (à peine, je sais) une deuxième puce : c’est une EEPROM qui dialogue aussi avec l’I²C. L’emplacement pour la pile est sur l’autre face de la platine. Les branchements VCC, GND, SDA et SCL sont clairement repérés sur la platine, il n’y a qu’à les relier à l’Arduino car la platine est aussi équipée des deux résistances de pull-up (un souci, d’ailleurs, si on veut mettre plusieurs platines ensemble sur le même bus…). Voici le câblage sur la platine d’expérimentation :
Pas de soucis particuliers. Sur la platine vous remarquerez un fil noté "important". Non, ce n’est pas la couleur qui est importante, mais le fait de placer un fil de masse sur la rangée à côté du quartz. Cela aide à la stabilité des oscillations et ainsi à la précision de l’horloge. J’ai remarqué que le DS1307 était TRÈS sensible aux parasites, et aussi très sensible à la précision du quartz.
Le Sketch
La première ligne de notre Sketch est la déclaration de la bibliothèque :
#include <Wire.h>
Ensuite, il faut déclarer l’adresse de notre esclave. Pour connaître
les adresses des circuits intégrés, il est obligatoire d’aller
consulter la documentation technique. Pour le DS1307 je l’ai fait pour
vous : son adresse est 0x68. (Vous avez déjà vu la notation "0xnn" qui
exprime un nombre en hexadécimale, non?) Déclarer l’adresse avec un
#define
ou un const
au choix.
#define addr_ds1307 0x68
Pour initialiser l’environnement, c’est exactement comme pour la liaison série :
Wire.begin();
Et l’on peut sauter tout de suite dans la communication :
Wire.beginTransmission(addr_ds1307);
Wire.write(0); // adresse du registre
Wire.write(0); // octet à écrire
Wire.endTransmission();
Mais, un instant… On ne sait même pas comment dialoguer avec cette bête ! Il faut regarder encore dans la documentation. Le principe de la plupart des circuits compatibles I²C est que les fonctionnalités et paramètres sont accessibles comme étant des registres, ou des locations de mémoire, à l’intérieur du circuit. Le DS1307 n’est pas une exception. Pour les fonctions d’horloge / calendrier, 8 registres de 0x00 à 0x07 nous intéressent :
Les adresses 0x00 et 0x07 servent de registres de configuration. Les autres servent à initialiser la date et l’heure et, une fois l’horloge démarrée, pour lire la date / heure actuelle. Ce qui n’est pas clairement annoncé dans ces informations, c’est que les valeurs sont stockées en BCD : "décimale codée en binaire". C’est quoi ? Prenons l’exemple de la valeur 65. En binaire 'normale’, 65 = B01000001 ou 0x41. En BCD on fait en sorte que chaque demi-octet représente un chiffre de 0 à 9, pour faire une gamme de valeurs de 0 à 99. Dans ce système, 65 devient B01100101 ou 0x65.
Pour accéder aux registres, il faut faire comme suit :
- Annoncer l’adresse du circuit en mode écriture ;
- Envoyer l’adresse du registre auquel accéder ;
- Envoyer l’octet de données à stocker dans le registre.
Presque tous les circuits augmentent d’un le "register address" automatiquement après chaque écriture ou lecture : si l’on veut envoyer plusieurs octets, il suffit de les envoyer dans l’ordre des registres. Puis, comme nous l’avons vu tout à l’heure, il faut signaler la fin de transmission. Si maintenant on regarde à nouveau le dernier morceau de code que j’ai affiché, c’est peut-être un peu plus clair, non ?
La lecture des registres est assez simple aussi. Le protocole I²C nous demande de suivre cette séquence :
- Annoncer l’adresse du circuit en mode écriture ;
- Envoyer l’adresse du registre à accéder ;
- Annoncer l’adresse du circuit en mode lecture ;
- Annoncer combien d’octets on souhaite lire ;
- Lire les octets un à un ;
- Terminer la transmission.
On procède avec les commandes suivantes :
Wire.beginTransmission(addr_ds1307);
Wire.write(0); // adresse du registre de départ
Wire.endTransmission();
// Demande mode lecture, 7 octets
Wire.requestFrom(addr_ds1307, 7);
for (i=0; i<7; i++) {
time[i] = bcd2bin(Wire.read());
}
Wire.endTransmission();
Je vous laisse découvrir toutes les merveilles du Sketch de cette semaine ci-dessous, mais je voulais aussi vous montrer quelques astuces qui aident à la réalisation de ce logiciel.
Conversions BCD
Deux petites fonctions assez compactes pour convertir des valeurs en BCD et du BCD en 'vrai' :
Si on prendre notre exemple de tout à l’heure du numéro 65, la fonction bin2bcd divise la valeur par 10, la multiplie par 6 et ajoute la valeur d’origine. Cela donne : . En hexadécimale cela donne 0x65 !
Regardons la fonction inverse. L’opération (val >> 4) fait déplacer les bits de l’octet par 4 places vers la droite. C’est comme si on prenait le chiffre des dizaines. Et donc cela donne . CQFD !
Tableaux 2D
François, alias fb251, nous a documenté une première utilisation des tableaux avec son Sketch hyper puissant. Je vais vous montrer une autre utilisation des tableaux, les tables de conversion. Voici un exemple :
Nous avons vu les tableaux à une dimension, comme char message[21]. Ce qui est déclaré dans l’exemple c’est un tableau à deux dimensions : on peut l’imaginer comme 7 lignes de 10 colonnes. La déclaration fait aussi l’initialisation de chaque ligne avec les noms des jours de la semaine. De ce fait, si on accède à jours[3] nous allons tomber sur le séquence de caractères "Mercredi". Nous avons construit un tableaux de conversion entre une valeur numérique et un message associé. Vous allez voir dans le Sketch comment cette astuce facilite la tâche de décodage des données stockées dans les registres du DS1307.
Si vous avez des projets qui demandent une horloge fiable et la temporisation de périodes assez longues (des minutes ou heures), je vous conseille un autre circuit - le PCF8583. Un peu plus difficile à dénicher, un peu plus cher, mais moins sensible aux variations de quartz (il peut même être piloté par les 50Hz du secteur). Il fournit des fonctions de réveil par interruption afin de vous libérer de tout souci de temporisation.
Passez une bonne semaine,
Glenn Smith mai 2014
Travaux pratiques
TP à faire pour la semaine 10
Comme nous avons pu le voir dans les semaines précédentes, le port USB
permet d’échanger des informations entre Arduino et l’ordinateur à
l’aide de la librairie Serial
. L’objectif de ce TP est d’utiliser le
port série pour envoyer depuis Arduino des valeurs récupérées depuis un
capteur (potentiomètre, photorésistance ou autre) et de recevoir et
traiter cette information grâce à un logiciel appelé
Processing.
Ce logiciel (qui ressemble beaucoup au logiciel Arduino en terme de langage et d’interface utilisateur) va nous permettre de recevoir les caractères envoyés par Arduino pour ensuite les traiter. Processing dispose ensuite de nombreuses librairies pour afficher de l’image, jouer du son…
Un article sur le wiki (annexe) détaille son utilisation et un cours est disponible sur OpenClassRoom pour installer le logiciel.
Une fois Processing installé, vous n’aurez pas à taper de code puisque nous vous donnons le programme Processing qui va recevoir les caractères et les traiter. Une fois lancé, le programme suivant affichera une fenêtre plus ou moins blanche selon la valeur envoyée par Arduino :
Voici le programme Processing à copier-coller dans votre logiciel :
import processing.serial.*;
float valeurArduino = 0; // valeur envoyée par le capteur Arduino
Serial myPort;
void setup() {
// création d'une fenêtre de 400×400 pixels
size(400, 400);
// initialisation du port série pour communiquer avec Arduino
myPort = new Serial(this, Serial.list()[0], 9600);
myPort.bufferUntil('\n');
}
void draw() {
// set the background color with the color values:
background(valeurArduino);
}
void serialEvent(Serial myPort) {
// récupérer la valeur envoyée par Arduino
String inString = myPort.readStringUntil('\n');
if (inString != null) {
// supprimer les potentiels espaces et stocker la valeur
// reçue dans la variable valeurArduino
valeurArduino = float(trim(inString));
valeurArduino = map(valeurArduino, 0, 1023, 0, 255);
}
}
Votre mission (si vous l’acceptez…)
Est d’écrire un programme pour Arduino qui viendra lire la valeur d’un
capteur analogique (comme une photorésistance ou un potentiomètre)
branché sur la broche A0
et qui va ensuite envoyé cette valeur en
utilisant la fonction Serial.println( )
qui, rappelons-le, permet
d’envoyer du texte vers l’ordinateur.
Quelques indices
Vous aurez besoin de mobiliser toutes les compétences vues ces dernières semaines pour réaliser ce TP :
- L’utilisation d’une entrée analogique ;
- Utilisation de la librairie
Serial
.
Quelques conseils
- Avertissez-nous sur le fil de discussion ci-dessous si les consignes ne vous semblent pas claires ;
- N’allez pas regarder la solution sur Internet sinon il n’y a pas de fun ;
- Prenez toujours les hypothèses qui vous arrangent ;
- Seules les notions abordées dans le cours et sur cette page sont nécessaires pour mener à bien ce TP ;
- Il n’y a pas une mais plusieurs solutions à chaque problème. La meilleure est celle que vous comprenez !
Bon courage et bonne semaine,
L’équipe du MOOC