MODULE℠, l'électronique facile pour l'ATmega328P

Bonjour :slight_smile:

Dans cet article, je vais expliquer ce qu'est mon dernier projet MODULE℠, et vous montrer des exemples pour que vous puissiez tout comme moi réaliser des projets en électronique facilement.

J'ai programmé en html un blog qui regroupe ce concept global et qui sera agrémenté au fil du temps de nouveaux exemples et explications:

[u]Lien vers le Blog[/u]

Comprendre ce qu'est MODULE℠

MODULE℠ est une suite de classes écrites en C++ pur (sans bibliothèque additionnelle) dédiées à la programmation du microcontrôleur ATmega328P, ce dernier monté ici sur l'une de mes cartes modulaires:

Le plan de mise en production de cette carte est disponible en téléchargement dans cet article ou sur mon blog.

Dans les pages suivantes, j'appelle cette carte l'automate, ne soyez donc pas surpris si vous rencontrez ce terme.

MODULE℠ est également une suite de cartes électroniques partie commande avec microcontrôleur, affichage avec afficheurs à dels (digits et matrice), et électronique de puissance.

Historique du projet MODULE℠:
Le projet MODULE℠ à débuté en Août 2014 et aura demandé jours pour jours 2 ans de travail.

Depuis longtemps je me suis intéressé à l'électricité, mais l'électronique (embarquée) avant ce projet m'est toujours apparu comme obscure et difficile à appréhender. En Août 2014, j'ai donc décidé d'apprendre avec la meilleure volonté l'électronique, parce que c'était un domaine que je ne connaissais (sans même encore parler de maîtriser ou de pratiquer) absolument pas.

Sans formation dans le domaine, il aura fallut acharnement pour ainsi progresser (par les échecs, les erreurs, mais aussi les réussites) en lisant pendant des mois des articles sur internet (dans lesquels il convient souvent de trier et de recouper l'information) mais aussi et surtout à force de pratique et d'expériences personnelles.

La philosophie de MODULE℠:
MODULE℠ n'est pas programmé en surcouche d'une autre bibliothèque comme l'est la plupart des bibliothèques dont fait partie Arduino™, de fait, le code source C++ est dédié et optimisé pour le microcontrôleur ATmega328P afin d'obtenir le meilleur compromis en C++ en terme de rapidité et d'espace mémoire.

MODULE℠ est une bonne alternative à Arduino™ pour programmer plus efficacement l'ATmega328P.

L'idée de MODULE℠ veut qu'aucun code C++ n'ait été recopié d'un livre ou d'internet, tout est une création personnelle unique, ceci dans le seul but de comprendre le fonctionnement des choses, d'optimiser, et de partager une création personnelle tout simplement.

Aucune bibliothèque couramment admise comme faisant partie du standard du langage C++ n'a été utilisée pour programmer MODULE℠, comme par exemple stdlib.h, stdio.h, ou encore math.h, toujours dans un soucis de compréhension du fonctionnement. Cela m'a permis de par exemple faire un peu de mathématiques (sans math.h) et de construire des fonctions comme sinus, cosinus, ou encore arc tangente que l'on retrouve souvent dans les calculatrices modernes.

MODULE℠ c'est aussi redonner tout l'intérêt pour ce petit microcontrôleur 8 bits qu'est l'ATmega328P, de plus en plus délaissé au profit de microcontrôleurs 32 bits au fréquences de fonctionnement plus élevées du fait que les bibliothèques concurrentes demandent plus de cycles pour faire les mêmes opérations que MODULE℠.

Que peut-on faire avec MODULE℠?
MODULE℠ est comme son non l'indique modulaire, il n'a en soit pas de limite, la seule est notre imagination. Sachez qu'à l'époque de la conquête spatiale, des ingénieurs et techniciens ont envoyés des fusées dans l'espace avec bien moins comme calculateur qu'un ATmega328P !

Avec MODULE℠ vous pouvez faire fonctionner des gyroscopes, magnétomètres, baromètres, émetteurs/récepteurs 2.4Ghz, faire fonctionner des servos-moteurs et des esc, lire des pwm, créer une interface entre l'utilisateur et l'automate via des boutons, des potentiomètres, des afficheurs, des buzzers et divers haut-parleurs. Il est possible de gérer le temps, l'aléatoire, de filtrer des valeurs, de gérer la veille de l'automate, la communication entre plusieurs microcontrôleurs, ou encore de sauvegarder des valeurs dans la mémoire de l'ATmega328P.

Libre à vous de programmer d'autres fonctions dans MODULE℠ si vous le souhaitez !

Photo ci-dessous, un projet de quadri-hélicoptère réalisé avec MODULE℠:

[HR/]

Comment installer MODULE℠

Installer MODULE℠ est un grand mot, en réalité MODULE℠ ne demande qu'à être téléchargé et décompressé dans le répertoire de votre choix:

[u]Télécharger MODULE℠[/u]

Dans l'archive module.zip vous trouverez 2 principaux répertoires:

  • cpp, contenant la programmation C++ de MODULE℠.
  • pcb, contenant les plans des cartes électroniques de MODULE℠.

Le répertoire module du dossier cpp contient toutes les classes du programme MODULE℠, ce qui comprend les fichiers d'en-tête (.h) que vous aurez à inclure dans vos projets si besoin, et les fichiers C++ (.cpp) dans lesquels on trouve les fonctions.

Vous pouvez modifier le contenu de ce répertoire si vous souhaitez modifier et améliorer MODULE℠ !

Le répertoire linux du dossier cpp contient les routines linux (bash .sh) pour compiler et envoyer votre programme dans l'automate (l'ATmega328P) via un programmateur. Il contient également un fichier main.cpp, c'est le plus important car c'est dans ce fichier que vous écrirez votre programme en langage C++.

Même chose pour le répertoire windows du dossier cpp, à ceci prêt qu'il contient cette fois-ci les routines windows (bash .bat).

En fin, vous trouverez dans le répertoire pcb à la racine de l'archive les différents plans des cartes électroniques prêtes pour une mise en production par vos soins, ou par une usine de fabrication.

[HR/]

Comment programmer avec MODULE℠

Pour programmer avec MODULE℠, vous avez à disposition 25 classes organisées par fonctions. Toutes ses classes sont à la fois complètement indépendantes les unes des autres (au niveau du code source C++) et peuvent aussi fonctionner toutes ensembles sans problèmes d'interactions:

Gestion des entrées/sorties:

GpioRead.h
GpioWrite.h
AnalogRead.h
InterruptRead.h
PwmRead.h
PwmWrite.h
SoundWrite.h

Gestion du temps:

Timer.h
Delay.h

Mathématiques, filtres, cycle d'hystérésis, génération de nombres aléatoires:

Math.h
Iteration.h
Average.h
Filter.h
Hysteresis.h
Random.h

Afficheurs à deds, gyroscopes, magnétomètres, baromètres, communication sans fil:

Max7219.h
Mpu6050.h
Bno055.h
Hmc5883L.h
Bmp180.h
Nrf24L01P.h

Communication filaire entre les différents automates:

Network.h

Sauvegarde de données dans la mémoire interne, gestion de la veille du microcontrôleur, outils de diagnostique:

Memory.h
Power.h
Tool.h

Pour comprendre comment utiliser les classes de MODULE℠:

  • Vous pouvez lire les exemples sur le blog (qui s'étofferont au fil du temps).
  • Vous pouvez copier le code source des mes projets.
  • Ou bien il est possible de regarder dans le répertoire module dans l'archive de MODULE℠ (téléchargeable dans cet article ou sur mon blog) le contenu des fichiers d'en-tête .h des classes correspondantes, ce qui vous donnera une bonne idée de comment utiliser les fonctions et variables si vous êtes déjà bien familiarisé à la programmation C++.

[HR/]

Les outils complémentaires de MODULE℠

En programmation C++ pour les microcontrôleurs de marque Atmel comme l'ATmega328P, des outils de compilation et de programmation de la puce performants et standards existent.

Ces outils sont disponibles pour les systèmes Linux (c'est mon cas), ou Windows. Pour Mac OS il faudra effectuer des recherches car je ne connais pas ce système, mais Mac OS étant une base Unix je pense que cela ne doit pas beaucoup différer de Linux.

Outils pour Linux:
Vous devez installer les paquets gcc-avr, avr-libc, binutils et avrdude. J'utilise Linux Ubuntu, voici la ligne de commande à écrire dans le terminal pour télécharger et installer les paquets sur Linux Ubuntu:

sudo apt-get install gcc-avr && sudo apt-get install avr-libc && sudo apt-get install binutils && sudo apt-get install avrdude

Outils pour Windows:
Vous devez télécharger et installer un programme qui se nomme WinAVR, ce programme contient les mêmes outils que sur Linux mais ici en version pour Windows:

[u]Site internet de WinAVR[/u]

Le programmateur:
Le programmateur est une petite carte qui fait l'interface entre votre ordinateur personnel et le microcontrôleur ATmega328P (l'automate), ce qui permet d'envoyer votre programme dans cette puce. Vous pouvez fabriquer un programmateur vous même, ou utiliser une carte toute faite. Pour ma part j'ai essayé les deux.

Je vous conseille d'utiliser le programmateur USBasp qui fonctionne à merveille, disponible à l'achat ici:

[u]Site internet de l'USBasp[/u]

Le programmateur USBasp est comme son nom l'indique équipé d'un port USB, à connecter directement à un port USB de votre ordinateur personnel, et à l'autre bout d'un port SPI, à connecter via une nappe adaptée (fournie) sur le port SPI de l'automate.

A noter que la programmation par le SPI de l'ATmega328P a plusieurs avantages:

  • Évite de contenir dans la mémoire un bootloader.
  • De ce fait, évite un délai au démarrage du microcontrôleur.
  • Minimise le nombre de composants embarqués sur la carte électronique.

Compiler et téléverser votre programme dans l'automate:

Pour compiler et téléverser votre programme dans l'automate (l'ATmega328P) via le programmateur USBasp, il vous suffit d'exécuter (de double-cliquer) les routines contenues dans l'archive de MODULE℠ (téléchargeable dans cet article ou sur mon blog) nommées ATmega328P compiler.sh pour Linux ou ATmega328P compiler.bat pour Windows.

Pour que cette opération de compilation mais surtout de téléversement fonctionne, sur Windows il faut installer le pilote de l'USBasp, sur Linux ou Mac OS en revanche il n'y a pas besoin de pilote. Par contre sur Linux Ubuntu que j'utilise il est tout de même nécessaire d'effectuer une petite opération décrite ci-dessous.

Procédure pour Linux Ubuntu:
Sur Linux Ubuntu, il convient d'écrire quelques lignes dans le terminal afin d'ouvrir un fichier qui permettra de spécifier quelques paramètres utiles pour l'USBasp:

sudo gedit /etc/udev/rules.d/99-USBasp.rules

Cette ligne ouvre l'éditeur de texte Gedit, ensuite il suffit de copier la ligne suivante dans cet éditeur de texte:

SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="plugdev", MODE="0666"

Une fois ceci effectué, vous enregistrez le fichier, et vous pouvez quitter Gedit.

Pilote de l'USBasp pour Windows:
Sur Windows le pilote de l'USBasp n'est pas présent par défaut sur ce système. Par conséquent vous devez le télécharger et l'installer vous même.

L'auteur de l'USBasp recommande d'utiliser un outil pour Windows qui se nomme Zadig et qui permet de rechercher ce pilote, personnellement je n'ai jamais essayé (ne possédant pas Windows) mais vu la qualité de son travail je pense que cela est de bon conseil:

[u]Site internet de Zadig[/u]

Les fusibles de l'ATmega328P:

Quand vous achetez un microcontrôleur ATmega328P, les fusibles qui permettent de définir des paramètres comme la vitesse de téléversement, l'utilisation d'un quartz externe ou encore le verrouillage du SPI, sont définis par défaut par le constructeur de la puce.

L'opération de téléversement décrite ci-dessus ne fonctionnera pas tant que vous n'aurez pas modifié les valeurs de ses fusibles !

Pour modifier les valeurs de ses fusibles, vous pouvez exécuter (double-cliquer) la routine contenue dans l'archive de MODULE℠ (téléchargeable dans cet article ou sur mon blog) nommée ATmega328P fuse.sh pour Linux ou ATmega328P fuse.bat pour Windows. Les valeurs que j'ai indiqué sont les plus optimisées pour l'automate que j'utilise (dont le plan est également disponible dans l'archive de MODULE℠).

Cette opération est à effectuer une seule fois dans deux cas précis, lorsque vous recevez un ATmega328P neuf n'aillant jamais été programmé, ou lorsque vous récupérez un ATmega328P qui possiblement dans sa mémoire contient un bootloader, ou des paramètres de fusibles inadaptés.

[HR/]

Lire l'état d'un bouton avec GpioRead.h

La classe GpioRead.h permet de lire l'état 0 ou 1 (0V ou 5V) d'une ou plusieurs broches de l'automate avec la possibilité d'utiliser une résistance de rappel interne à l'ATmega328P, et d'avoir un système anti-rebonds bien pratique pour filtrer les rebonds et autres parasites provoquées par les boutons et interrupteurs.

#include "../module/GpioRead.h"

int main()
{
	GpioRead myButton = GpioRead (1, true, 20);
	
	while (true)
	{
		myButton.read();
		
		if (myButton.continuous == true)
		{
			//allumer une del
		}
		else
		{
			//éteindre une del
		}
		
		if (myButton.momentary == true)
		{
			//allumer une del pendant la durée de ce tour de boucle uniquement
		}
	}
	
	return 0;
}

Dans cet exemple, un objet myButton de type GpioRead est déclaré:

  • Le 1er paramètre indique d'utiliser la broche numéro 1 de l'automate.
  • Le 2ème paramètre permet d'utiliser une résistance de rappel interne.

Attention, ne connectez pas un bouton sans résistance de rappel externe à une broche de l'automate sans avoir au préalable défini ce paramètre sur vrai afin d'utiliser une résistance de rappel interne, dans le cas contraire vous risquez de griller l'ATmega328P !

  • Le 3ème paramètre est le temps en millisecondes pour filtrer les rebonds.

A noter que 20ms est une valeur qui fonctionne bien pour filtrer la plupart des boutons. Plus votre bouton ou interrupteur sera d'une qualité médiocre, plus il faudra augmenter cette valeur.

Plus loin cet objet myButton appelle la fonction read() dans une boucle ce qui permet de lire l'état de la broche concerné.

Cet état 0 ou 1 est stocké dans deux variables, continuous et momentary:

  • continuous signifie que tant que le bouton est appuyé, cette variable renvoie vrai.
  • momentary signifie que si le bouton est appuyé, la variable renvoie vrai à la première lecture (1er tour de boucle généralement), mais qu'elle renvoie faux aux lectures suivantes (aux tours de boucle suivants), en attendant que le bouton soit relaché puis par la suite appuyé une seconde fois.

Cet état momentané permet d'appeller des blocs de code une seule fois lorsqu'un bouton est pressé, cela peut être utile pour réaliser des incréments de valeurs par exemple, ou bien encore des signaux sonores lorsqu'on presse des boutons.

Récapitulatif des fonctions et variables de cette classe:

myButton.read()
myButton.continuous
myButton.momentary

Bien entendu vous pouvez utiliser cette classe pour d'autres applications (lire autre chose que des boutons ou interrupteurs).

[HR/]

Allumer une DEL avec GpioWrite.h

C'est la classe la plus simple à utiliser de MODULE℠ et la première à avoir été créée. Elle permet de mettre à l'état 0 ou 1 (0V ou 5V) une ou plusieurs broches de l'automate.

#include "../module/GpioWrite.h"

int main()
{
	GpioWrite myLed = GpioWrite (1);
	
	myLed.on();
	
	return 0;
}

Dans cet exemple, un objet myLed de type GpioWrite est déclaré, en paramètre est indiqué d'utiliser la broche numéro 1 de l'automate, puis cet objet myLed appelle la fonction on() ce qui permet de mettre à l'état 1 la broche concernée. Ainsi une del connectée à cette broche s'allumerait.

D'autres fonctions existent, off() pour passer la broche à l'état 0, et toggle() pour changer l'état de la broche quel que soit sont état initial (0 ou 1).

myLed.off()
myLed.on()
myLed.toggle()

Attention, l'ATmega328P ne peut pas fournir beaucoup de puissance sur ses broches en sortie !

Il est donc indispensable de piloter un transistor de puissance pour la partie puissance de votre montage. Néanmoins, si il s'agit de quelques 10ènes de milliampères comme dans le cas d'une del ou d'un buzzer, il n'y aurra aucun problème à l'alimenter de cette façon.

[HR/]

L'automate à base d'ATmega328P

L'automate (terme souvent utilisé dans ce blog), est une petite carte de conception personnelle que j'utilise dans tous mes projets:

Le plan de mise en production de cette carte est disponible ici:

[u]Télécharger le plan de l'automate[/u]

Cette carte est le coeur des mes montages électroniques (tout gravite autour d'elle), parce qu'elle contient dans le microcontrôleur (l'ATmega328P) le programme binaire écrit à l'origine en language C++ qui permet de gérer toute la logique combinatoire et mathématique du montage.

Les caractéristiques de la carte:

  • Alimentation de 7V à 20V.
  • Port SPI pour la programmation.
  • 20 entrées/sorties en ligne (partie commande) et 20 positifs et négatifs (partie puissance).
  • Régulateur de tension LM7805 1A 5V.
  • Fréquence de fonctionnement: 16Mhz.
  • Dimensions: 66.04mm x 40.64mm.
  • Entres-axes de fixations: 58.42mm x 33.02mm.
  • Fixations par vis M3 (perçages diamètre 3.2mm).
  • Faible coût (environ 10$ de composants).
  • Plan conforme au datasheet de l'ATmega328P.

Liste des composants:

1x Microcontrôleur ATMEGA328P-PU
1x Régulateur LM7805
1x Résistance 10kΩ carbone 0.25W
1x Résistance 220Ω carbone 0.25W
2x Condensateurs 22pF céramique
3x Condensateurs 100nF tantale
1x Condensateur 100nF électrolytique radial
1x Condensateur 220nF électrolytique radial
1x Inductance 10μH self axiale
1x Quartz 16Mhz
1x Del 3mm
1x Support PDIP 28 300mil
68x Broches mâles 0.1"

Quelques photos du prototype:

[HR/]

L’afficheur à digits MAX7219

L’afficheur à diodes électroluminescences est le compagnon idéal de l’automate parce qu’il permet de créer une interface visuelle entre l’utilisateur et la machine:

Le plan de mise en production de cette carte est disponible ici:

[u]Télécharger le plan de l’afficheur à digits[/u]

Cet afficheur est très utile pour réaliser des projets demandant un retour d’informations visuelles de la par de l’automate. Il est équipé du très populaire MAX7219, un composant qui communique en SPI avec l’ATmega328P.

Connections (afficheur sur automate):

  • Broche positive sur broche positive disponible
  • Broche négative sur broche négative disponible
  • Broche SS (slave select) sur PB2 (11) ou toute autre broche d’entrée/sortie disponible (sauf PB4 qui est MISO)
  • Broche MO (mosi) sur PB3 (12)
  • Broche SC (sclk) sur PB5 (14)

Les caractéristiques de la carte:

  • Alimentation 5V.
  • Port SPI pour la communication.
  • Branchements en cascade.
  • 8 digits pour l’affichage des caractères.
  • Dimensions: 76.2mm x 20.32mm.
  • Entres-axes de fixations: 68.58mm.
  • Fixations par vis M3 (perçages diamètre 3.2mm).
  • Plan conforme au datasheet du MAX7219.

Liste des composants:

1x Contrôleur d’affichage MAX7219CNG
1x Résistance 10kΩ carbone 0.25W
1x Condensateur 100nF céramique
1x Condensateur 10μF électrolytique radial
2x Afficheurs à Digits (2 blocs de 4), 0.36" 7 segments, cathode commune
1x Support PDIP 24 300mil
10x Broches mâles 0.1"

Ci-dessous, 2 exemples d’utilisation de l’affichage à digits:

  • Monté sur un niveau à bulle digital pour connaître l’angle.
  • Scindé en 2 sur une carte de jeu Pong afin de visualiser les scores.

[HR/]

L’afficheur à matrice MAX7219

À l’instar de l’afficheur à digits, l’afficheur à matrice 8 x 8 permet un visuel graphique (pixels) et offre l’avantage de pouvoir dessiner des formes ou des symbols:

Le plan de mise en production de cette carte est disponible ici:

[u]Télécharger le plan de l’afficheur à matrice[/u]

Cet afficheur est équipé du MAX7219, un composant qui gère le multiplexage des dels, il communique en SPI avec l’ATmega328P.

La vitesse de communication SPI et le nombre de ports sur l’ATmega328P sont suffisants pour pouvoir réaliser un montage avec 8 x 8 afficheurs, soit 64 matrices de 64 dels chacune (4096 dels au total). Seul l’alimentation 1A de la part de l’automate ne suffira pas (prévoir plusieurs ampères).

Connections (afficheur sur automate):

  • Broche positive sur broche positive disponible
  • Broche négative sur broche négative disponible
  • Broche SS (slave select) sur PB2 (11) ou toute autre broche d’entrée/sortie disponible (sauf PB4 qui est MISO)
  • Broche MO (mosi) sur PB3 (12)
  • Broche SC (sclk) sur PB5 (14)

Les caractéristiques de la carte:

  • Alimentation 5V.
  • Port SPI pour la communication.
  • Branchements en cascade.
  • 8 x 8 pixels pour l’affichage.
  • Dimensions: 48.26mm x 35.56mm.
  • Entres-axes de fixations: 40.64mm x 27.94mm.
  • Fixations par vis M3 (perçages diamètre 3.2mm).
  • Plan conforme au datasheet du MAX7219.

Liste des composants:

1x Contrôleur d’affichage MAX7219CNG
1x Résistance 10kΩ carbone 0.25W
1x Condensateur 100nF céramique
1x Condensateur 10μF électrolytique radial
1x Afficheur à Matrice 8 x 8, pixels de 3mm, cathode commune
1x Support PDIP 24 300mil
10x Broches mâles 0.1"

Ci-dessous, un effet facile à réaliser avec MODULE℠:

[u]Lien vers la vidéo[/u]

Code source de la vidéo:

#include "../module/Max7219.h"
#include "../module/Random.h"
#include "../module/Timer.h"

int main()
{
 unsigned char line = 1;
 Max7219 matrix = Max7219 (11, 1);
 
 Random::seed (15);
 
 while (true)
 {
 for (line = 1; line <= 8; line++)
 {
 matrix.draw (Random::integer (0, 255), line);
 }
 
 Timer::pause (100);
 }
 
 return 0;
}

[HR/]

N’hésitez pas si vous avec des questions ou suggestions à apporter, j’y répondrais volontiers :slight_smile:

Nouvel article à propos de mon quadri-hélicoptère programmé avec MODULE℠ :slight_smile:

"L'hélicoptère de voltige à 4 hélices"

Le code source C++ du programme de vol est disponible en téléchargement dans l'article :wink:

Pour ceux qui m’ont demandé Module℠ en pièce jointe:

module.zip (215 KB)