Archive

Archive for the ‘Arduino & Co’ Category

Pico-puter : Etat des lieux

13 août 2019 Laisser un commentaire

Cheap 8 Mk I

Il y a pas mal de temps, j’ai commencé à développer une espèce de pico-ordinateur à base d’ATtiny 85, avec un clavier réduit, une horloge, une petite mémoire flash , et un écran oled, le tout connecté via un bus à huit lignes — les huit de l’ATtiny 85 – et supportant le protocole I2C.

En tout, la RAM de l’ATtiny 85 se monte à 512 octets, plus 8ko pour la mémoire programme, un peu d’eeprom. Même avec les 4 ko de flash à côté de l’horloge RTC, ça fait réellement très peu. Je me suis inspiré de Chip 8, que l’on peut considérer comme l’émulation d’un ordinateur simple programmable directement en code machine.

De Chip 8, j’ai retiré tout ce qui a trait au graphisme, au son, réduit la mémoire à 256 octets, contre 4ko pour mon modèle, et réduit la taille des instructions à un octet. C’est encore plus léger, on pourrait dire « cheap », d’où le nom de « Cheap 8 » que j’ai retenu pour cette… hum… architecture.

Keep It Simple, Stupid !

Par contre, je me suis un peu emballé et ai créé toute une cathédrale d’appels au « matériel » dont un système de stockage primitif mais consommateur en espace programme. S’en est suivi une phase de debug laborieuse, et l’impression la certitude d’avoir fait trop complexe. Autre écueil, je n’ai prévu aucun moyen d’entrer du code dans ce pico-puter, et il faut ajouter un programme ad-hoc inclus dans le code source de « Cheap 8 ».

Je n’ai finalement jamais utilisé le bidule, mais rien n’est perdu. Le code de « Cheap 8 Mk I » est stocké dans mon dépôt mercurial perso, et il va me servir de base pour son successeur « Cheap 8 Mk II », qui devrait être beaucoup plus fun.

Cheap 8 Mk II

Cheap 8 MK II reprendra la base de son prédécesseur : une ALU à pile, 256 octets de mémoire programme et données, et quelques entrées/sorties. Pour l’utilisabilité, je me suis inspiré un peu de l’Altair, et beaucoup plus du « Digirule 2 » : quelques switches, une poignée de LEDs, et quelques artifices permettent d’examiner la mémoire, et de saisir un programme et de l’exécuter. Avec un Attiny85, les LEDs seront figurées sur l’écran OLED connecté en I2C, histoire d’économiser quelques-unes des pins au nombre déjà plus que compté. Je pourrais utiliser des LEDs avec quelques composants de type 74*595, mais ça ajouterait un peu de complexité.

Je conserve l’ATtiny 85 comme cible, mais pour des raisons pratiques, le développement se fera sur un Arduino UNO en gardant en mémoire les limites de l’ATtiny. La base du code actuelle prévoit déjà une bonne modularité, avec des fonctionnalités activées par quelques directives lors de la compilation, et ce principe sera reconduit.

La prochaine étape

La conception est quasiment terminée, à quelques détails près. J’ai une petite liasse de feuillets au format A5 contenant l’essentiel du projet. La prochaine étape est l’assemblage des switches. Suivra la partie codage.

Dernier détail, le Digirule est en open hardware, alors pourquoi ne pas faire de même ?

Publicités
Catégories :Arduino & Co Étiquettes : ,

Eclairage à Leds : le code

20 janvier 2019 1 commentaire

Lors des « épisodes » précédents , j’ai assemblé un prototype, puis réalisé sur stripboard un montage plus ou moins définitif.

Le code, écrit dans l’IDE Arduino, est fonctionnel. Plutôt que d’appliquer la dichotomie habituelle, en séparant le programme source entre fichiers d’entête (.h) et fichiers de code (.cpp), j’ai préféré coder chaque classe dans son propre fichier, un peu comme le langage Eiffel.

Découpage du programme

Le programme principal (rgb_strip_controler.ino) demande au récepteur infrarouge (IrKeyPad.h) quelle commande a été envoyée par la télécommande et la    fait appliquer au contrôleur (controler.h). Ce dernier règle alors les niveaux rouge, vert et bleu de la bande de leds (RgbLed.h).

J’ai créé une classe pour chaque partie du programme :

  • debug.h : affichage de messages d’information sur le moniteur série de l’Arduino
  • RgbLed.h : réglage de l’intensité des trois couleurs de base d’une bande de leds RGB
  • IrKeyPad.h :  traduction des codes envoyés par la télécommande infrarouge en commandes (On, Off, etc)
  • Controler.h : envoie une liste d’actions à effectuer à la classe RgbLed, en fonction de ce qui est fourni par la télécommande infrarouge
  • rgb_strip_controler.ino : initialise le bousin, lit les commandes reçues et les fait appliquer par le contrôleur.

Quelques avertissements

  • Le code n’est pas commenté ou pas assez commenté (honte à moi). C’est sur ma « to do list »
  • Une seule bande de leds pour le moment. J’en ajouterai une seconde une fois le code commenté
  • Le débug n’est pas désactivable. C’est également sur ma « to do list »
  • Le code n’est pas optimisé, mais il est relativement lisible, même si j’ai quelques moments « WTF! » en le relisant
  • Je n’ai pas respecté tous les canons de l’orientation objet

Pour conclure

Ce code est fonctionnel, même si il peut et doit être amélioré.

Les prochaines actions de ce côté :

  • Ajouter des commentaires
  • Gérer une seconde bande de leds
  • Gérer l’activation et la desactivation des messages de debug

En attendant, j’ai déposé le code sur Framagit

Catégories :Arduino & Co Étiquettes : ,

Éclairage à leds : Réalisation

6 novembre 2018 4 commentaires

Mon contrôleur de leds RGB en est resté à… l’état de prototype. Un prototype fonctionnel et presque autonome avec son alimentation euh… intégrée. Il fait appel à des composants pour ainsi dire standard :

  • Bloc d’alimentation secteur, 12V en sortie, et assez d’ampères.
  • Convertisseur 12 volts vers 5 et 3.3 volts
  • Un clône d’Arduino Mini (5V, 16 MHz)
  • Un circuit UNL pour contrôler de petits moteurs ou des leds en PWM

ctrl_rgb_led_prptotype.jpg

Le circuit final est réalisé sur une plaquette type stripboard, et comprend plusieurs parties.

De gauche à droite :

  • Connecteur pour le convertisseur 12V vers 5V (je n’utilise pas le 3.3V sur ce projet)
  • Connecteur pour l’Arduino Mini
  • Connecteur pour le circuit UNL
  • Trois connecteurs pour trois bandes de leds …

En haut, un « rail » d’alimentation en 12 volts pour les bandes de leds.

En bas, une ligne de masse (0V) et une ligne d’alimentation en 5V

Chaque zone est reliée soit par les bandes conductrices du stripboard, soit par des fils en point à point.

Les connecteurs

Il s’agit essentiellement de barettes HE10 femelles. Le circuit UNL a, lui, droit à un connecteur du commerce, et trois barettes HE10 mâle serviront à connecteur des bandes de LEDs RGB. L’interrupteur (en bleu) n’a finalement pas été soudé sur la plaquette.

ctrl_rgb_led_connecteurs.jpg

Les fils de jonction

La majeure partie des bandes conductrices du stripboard ont été « coupées » pour isoler les différentes zones, et surtout isoler pour l’Arduino et l’UNL les pins droites et gauches.

Par convenance, les alimentations – 12 et 5V – sont câblées en rouge, et les masses en noir. Les signaux entre l’arduino et l’UNL et entre l’Arduino et le récepteur infra-rouge utilisent d’autres couleurs.

Esthétiquement, j’ai déjà fait mieux, mais les connections sont correctes… à part un défaut que je ne verrai que plus tard.

ctrl_rgb_led_fils.jpg

Le résultat

Les différents circuits sont fixés sur leurs connecteurs :

  • L’alimentation à gauche. Son fil 12 volts, en rouge, est connecté sur le rail 12 volts en haut de la carte.
  • L’Arduino mini au centre à gauche.
  • L’UNL au centre à droite
  • Le récepteur infra-rouge sous l’UNL
  • La bande de leds sur le premier connecteur en haut à droite.

Un pont à peine visible entre les pins 2 et 15 de l’UNL m’a donné une suée. Même en forçant les niveaux à 0, le bleu des RGB restait allumé. Après avoir identifié le pont avec un testeur de continuité, j’ai dû utiliser une loupe pour l’avoir en visuel. Un coup de mèche plus tard, tout rentrait dans l’ordre

ctrl_rgb_led_résultat.jpg

Les prochaines étapes

Plusieurs choses sont à voir, ou à revoir sur ce circuit.

  • Esthétiquement, on peut faire mieux, mais cette carte doit prendre place dans un boîtier. On ne verra à terme que l’interrupteur et la LED de l’alimentation, celles de l’Arduino, le récepteur infra-rouge et les trois connecteurs pour les bandes de LEDs.
  • Une fois l’alimentation branchée, le rail 12 volts est alimenté. Apparemment, c’est sans conséquence, mais par acquis de conscience, je vais lui ajouter un interrupteur.
  • Sur le dernier connecteur, seules deux couleurs pourront être utilisées, car la pin 9 du circuit UNL sert pour l’anti-retour nécessaire si on contrôle des moteurs à courant continu. Plutôt que d’utiliser une bande RGB sur ce connecteur, je pourrais me contenter de deux bandes de leds blanches. A étudier…
  • La programmation actuelle ne prévoit que l’utilisation d’une seule bande RGB. L’évolution du code est prévue, mais reste à valider.
  • Le contrôleur à l’origine de ce projet était sensé produire des animations, comme des effets de « pulse », des flashes, etc. Les sous programmes correspondants sont en place, mais sont vides pour le moment et restent à coder.
  • En cas de panne de la télécommande – pile épuisée ou autre – le contrôleur devient inutilisable. Une interface physique (boutons, variateurs, etc) pourrait prendre le relai, mais cela fera l’objet d’un autre projet.

En attendant la suite…

Novembre, c’est Nanovembre, et le NaNoWriMo prend tout mon temps libre. Ca laisse un bon mois pour laisser percoler de nouvelles idées pour améliorer ce qui peut l’être.

Creative Commons License

Catégories :Arduino & Co Étiquettes : ,

Éclairage à leds : le prototype

19 juin 2018 3 commentaires

Une impression 3D ne se passe pas toujours bien. La buse peut se boucher, le filament casser avant d’entrer dans le tube d’alimentation, le spool peut jammer, et il arrive même que ça flambe.

Je n’ai jamais eu à affronter le troisième cas, mais si cela arrivait, je préférerais m’en rendre compte dès le début du problème. Il vaut mieux avoir à changer quelques pièces que toute l’imprimante, ou même de maison pour cause d’incendie. Du coup, je garde un oeil sur l’impression en cours. Les petites impressions prennent vingt ou trente minutes, mais se déplacer pour vérifier la progression et l’absence de problème toutes les quelques minutes devient vite gênant, pour ne pas dire plus, parfois au point de ne pas pouvoir rester concentré sur autre-chose.

L’ajout d’une webcam a été une première avancée, mais sa résolution ainsi que son débit sont tous deux limités, et elle ne dispose pas d’un éclairage intégré. Sans demander du 4K, je préférerais avoir de bonnes images et pour obtenir de bonnes images, il faut un bon éclairage. En attendant de récupérer une meilleure webcam, commençons par l’éclairage du plateau.

Fiat lux !

Un ruban de leds RGB acheté pour quelques pièces dans un marché aux puces fera l’affaire.

rgb_led_strip_640

Ce ne sont pas des NeoPixels pilotables individuellement, mais de « simples » leds RGB montées en parallèle, avec tout de même leurs résistances protection. Le boîtier de commande et sa télécommande infra-rouge, sans oublier le bloc d’alimentation 12V sont un bonus bienvenu. Pourtant…

Et lux non fit.

La connexion du ruban de LEDs au boîtier de commande se fait par un connecteur qui ne fonctionne pas, malgré une apparence plus que convenable. Le boîtier ouvert, un test de continuité montre que le fil d’alimentation est rompu. On coupe, on remplace, on strappe, on teste et… toujours rien.

Sans alimentation, pas de lumière. Il existe d’autres points d’alimentation utilisables sur la carte électronique du boîtier. Tant qu’à faire, j’ai décidé de remplacer le connecteur « fancy » du boîtier par un bornier à vis. Mon multimètre a rendu l’âme, et son remplaçant n’a pas encore été livré, mais j’ai tout de même pu vérifier que le courant passe en pointant directement depuis le bornier vers le ruban de leds.

L’intensité est malheureusement insuffisante, malgré les tests et réglages à l’aide de la télécommande. Au lieu d’avoir des couleurs éclatantes, je n’ai qu’une très légère activation des leds. Apparemment le boîtier de commande hors service. Heureusement que le reste fonctionne !

Une solution, vite ! Un petit projet, on a dit.

Je pourrais passer des heures à tenter de comprendre ce qui ne fonctionne pas, mais je réserve l’exercice pour plus tard. Je vais « simplement » remplacer le boîtier par un équivalent.

Le ruban de leds mesure plusieurs mètres, largement trop pour mon projet, qui devrait en consommer une soixantaine de centimètres au plus. Il en restera assez pour d’autres usages. La télécommande fonctionne, ainsi que le bloc d’alimentation.

Le cahier des charges

Le nouveau boîtier de commande doit :

  • être utilisable avec une bande de 10 cm à 1 m
  • réutiliser la télécommande infra-rouge et le bloc d’alimentation
  • être facilement clôné
  • être facilement connectable et dé-connectable d’une bande de leds

Je me suis inspiré de plusieurs projets présentés sur youtube, instructables, et d’autres blogs pour développer ma petite solution à base d’Arduino :

  • Arduino Uno pour le prototype, un clone pour la cible
  • Récepteur infra-rouge
  • Commande de la bande de leds RGB via une puce UNL2803 commandée en PWM ( pseudo analogique)
  • Alimentation unique pour l’Arduino et la bande de leds

Première étape : piloter la bande de leds

L’UNL2803 est un petit circuit intégré à 20 18 pins permettant de piloter aussi bien des leds que de petits moteurs électriques. Il suffit de lui connecter une masse, les signaux d’entrée et les moteurs ou leds en sortie. Dans le cas d’un moteur, une pin supplémentaire doit être utilisée, pour éviter les « retours » de courant lors d’un arrêt de moteur.

Les pins 0 à 8 reçoivent les signaux PWM en provenance de l’arduino, les pins 10 à 17, juste en face, sont reliés aux leds ou moteurs à contrôler. Le pin 8 doit être relié à la masse, et le 9 ne sera pas utilisé.

La vitesse des moteurs ou l’intensité des LEDS peuvent être commandées finement en PWM – Pulse Width Modulation ou Modulation de longueur d’impulsion – et non en tout-ou-rien.

Dans mon cas, les connections sont les suivantes :

  • pin 0, 1 et 2 de l’UNL sur les pins 9, 10 et 11 de l’arduino
  • pin 9 de l’UNL sur la masse de l’arduino
  • pins 16, 17 et 18 de l’UNL sur les lignes Bleu, Vert, et Rouge de la bande de leds
  • ligne 12V de la bande de leds sur le 12V de l’alimentation
  • Masse de l’Arduino sur la masse de l’alimentation

Un petit programme trouvé ici permet de vérifier que tout fonctionne correctement. Les différentes couleurs devraient s’éclairer suivant une animation simple.

Seconde étape : identifier le type de télécommande infra-rouge

Là aussi, je me suis inspiré d’un travail existant. J’ai flashé sur l’Arduino un programme permettant de décoder ce qu’envoie chaque touche de la télécommande infra-rouge.

La librairie InfraRed pour l’Arduino offre largement assez de possibilité, et de multiples exemples permettent de s’y retrouver. Malheureusement, elle n’est pas directement utilisable dans mon cas. La classe (le module) sensée gérer le codage « NEC1 » se contente d’afficher des valeurs sur le port série de l’Arduino. Je pourrais lui ajouter ce qui manque (une simple routine de lecture en lieu et place d’un affichage), mais j’ai suivi une autre piste, celle de la librairie IRLib2, que j’ai découverte via un tutorial chez Adafruit.

L’exemple « comboDump » affiche le détail du signal reçu par l’Arduino et identifie le codage utilisé :

Decoded NEC(1): Value:F7E817 Adrs:0 (32 bits)
Raw samples(68): Gap:9364
Head: m9300 s4400
[ . . . ]
Space min:550 max:1750

C’est peu lisible, et j’ai abrégé, mais l’essentiel se trouve sur la première ligne : ma télécommande générique utilise le codage NEC, un classique du genre.

Troisième étape : décoder les touches de la télécommande

J’ai modifié la fonction loop() de l’exemple comboDump fourni avec la librairie IRLib2 pour afficher les codes des touches de la télécommande.

Une fois le programme flashé sur l’Arduino, le moniteur série de l’IDE Arduino affiche effectivement les codes envoyés par la télécommande, qu’il « suffit » de noter pour les utiliser dans le programme final :

Code : F730CF
Code : FFFFFFFF
Code : F708F7
Code : FFFFFFFF
Code : F700FF
Code : FFFFFFFF
Code : FFFFFFFF
Code : FFFFFFFF

Le code FFFFFFFF est un code de répétition, lorsque l’on appuie longuement sur une touche sans la relâcher.

Quatrième étape : choisir et programmer le comportement des LEDS

La télécommande doit permettre de :

  • allumer et éteindre les leds
  • augmenter et diminuer l’intensité des leds
  • allumer toutes les leds en blanc
  • sélectionner l’intensité d’une des trois couleurs
  • si possible sélectionner une animation des couleurs (flash, fading, etc)

Rien n’empêche de l’utiliser autrement, mais je vais tenter de copier le comportement d’origine. Le but premier est de produire de la lumière, pas de créer de nouveaux effets façon boîte de nuit

Toutes les fonctions, à part les quatre animations, devraient être assez simples à développer, en jouant sur le niveau des signaux en entrée de l’ULN.

Les animations demandent de jouer avec des temporisations, mais rien de vraiment compliqué à la base. Pour limiter les manipulations sur la télécommande pendant les tests, on pourra éventuellement flasher l’Arduino pour démarrer directement sur l’animation testée.

Le programme

Le programme final n’est pas très compliqué. A chaque exécution, la fonction principale effectue les actions suivantes :

  1. Si un signal infra-rouge valide est détecté, agir en conséquence :
    • changement d’animation
    • ou changement d’intensité d’une couleur
    • ou passage en mode « blanc » continu
    • ou allumer ou éteindre toutes les leds
  2. Mettre à jour l’intensité des leds suivant l’animation en cours

Le code sera disponible librement.

Bilan d’étape

Le montage et le programme fonctionnent correctement. Il me reste encore à coder les animations (flash, etc), mais pour l’instant cela peut attendre. Il suffira de reflasher l’Arduino.

Pour le moment le montage consiste en :

  • une carte arduino uno
  • une petite alimentation 12, 5 et 3.3V. Seul le 12V est utilisé pour le moment car l’Arduino est alimenté par sa prise USB
  • un breadboard supportant l’unl2803 et le récepteur infra-rouge
  • une bande de douze leds RGB
  • de la filasse pour relier le tout.
  • le bloc d’alimentation 12V
  • un petit transformateur 12V vers 5 et 3.3 V, pour le moment utilisé en 12V uniquement

unl2803_640

breadboard_640

led_strip_controler_640

Le programme comprend quatre modules :

  • affichage de messages sur un terminal série (xterm, putty, etc), pour suivre la progression du programme
  • lecture des signaux infra-rouge et décodage/transformation en numéro de touches
  • gestion des leds RGB
  • programme principal

Quelques liens utilisés

Les prochaines étapes

Ce projet n’aurait dû durer qu’une petite semaine, si le boîtier de contrôle d’origine avait fonctionné. J’y ai gagné au change, en découvrant le décodage de commandes infra-rouge, ainsi que le composant unl2803, qui permettent de contrôler de petits moteurs ou des leds RGB .

Pour termine complètement ce projet, il me reste à :

  • Améliorer et documenter le code
  • Rendre les sorties terminal série désactivables
  • Remplacer l’Arduino Uno par un Arduino Mini ou une Menta
  • Réaliser un boîtier et le câble de connexion d’une bande de leds

Pour le remplacement de l’Arduino Uno, la première option est d’utiliser une carte Menta dont la partie prototypage recevrait les composants du montage. La seconde est d’utiliser un clone d’Arduino mini. Vu l’encombrement, celle-ci a ma préférence.

arduino_menta_640

L’Arduino mini est posée sur la zone de prototypage de la carte Menta.

Encore quelques petites heures de travail en vue. Je documenterai cette seconde partie dans un prochain article en incluant le programme de l’Arduino.

Creative Commons License

Catégories :Arduino & Co Étiquettes : ,

Cheap8, un système pour le pico puter


(Cet article était planifié en… mai 2018, mais n’a jamais été publié. Vieux motard Japonais. )

Pour résumer le projet « Pico-Puter », il s’agit de concevoir, assembler et programmer un pico-ordinateur basé sur un ATTny85. A terme, il comprendra :

  • 512 octets de mémoire vive
  • 512 octets de mémoire EEPROM
  • 8 k octets de mémoire programme
  • un clavier 4×4 touches
  • un écran, une horloge RTC, et une mémoire EEPROM de 4k octets , le tout connecté via un bus I2C

Etat des lieux

J’ai assemblé :

  • une carte supportant un ATtiny85
  • une alimentation double 5V et 3.3V sur USB ou pile 9V
  • un fond de panier supportant un bus passif
  • l’écran OLED, une tinyRTC et son EEPROM

Je n’ai toujours pas réalisé le clavier.

Le choix du système

Je m’étais laissé quelques semaines pour décider du système :

Quelques semaines…
… Presque six mois ont passé, mais j’ai fait mon choix.

Cheap8

Je sais, ce n’est pas un nom très original très original. J’ai donc choisi un système de type chip8.

Pour rappel, Chip8 est une machine virtuelle créée, de mémoire, au début des années 70, et tournant sur des machines à base de processeur RCA 1802, comme le Cosmac ELF.

L’espace mémoire était limité à 4 k octets, code et variables compris, le clavier comportait seize touches et l’affichage se faisait en mode graphique sur une simple télévision. Les instructions occupaient chacune deux octets, et l’affichage de sprites était géré « nativement ». Une vraie machine de jeux ! A tel point qu’une version est sortie sur calculatrice HP 48.

Mon Cheap8 sera plus simple :

  • 256 octets de mémoire
  • 16 registres 8 bits V0 à VF superposés à 8 registres de 16 bits W0 à WF occupant les 16 premiers octets de la mémoire
  • V0 et W0 sont l’accumulateur pour les calculs. VF et WF forment le registre d’état (flags). Enfin, VE est un pointeur en mémoire.
  • Pas d’instruction d’appel de procédure (CALL), mais une table de vecteurs située en fin de mémoire
  • Une petite double pile, façon Forth, pour les évaluations (partie basse) et les adresses de retour (partie haute), située hors mémoire principale
  • Les instructions de calcul utilisent la pile d’évaluation, le registreV0 étant le haut de la pile
  • Certaines instructions permettent de sauter l’instruction suivante si le flag vaut 0 (SKNZ – SKip if Not Zero). Par exemple DEC I DEC ; SKNZrémente le registre I, puis incrémente le pointeur d’instruction de 1 si I vaut 0, de 2 sinon)
  • L’instruction 00 (I/O) permet d’effectuer des entrées/sorties vers les périphériques (écran, RTC, EEPROM, etc)

Les prochaines étapes

Le développement de Cheap8 ne devrait pas prendre trop de temps. Non content d’être très limité, cheap8 n’est pas très orthodoxe, mais pour une première approche, je pense que c’est une bonne base. L’important est d’apprendre.
Les prochaines étapes seront :

  • Développer et tester cheap 8
  • Développer les I/O d’affichage
  • Réaliser le clavier et les I/O nécessaires

Entre ça et mes autres projets en cours, difficile de prévoir une échéance.

Les articles précédents de la série

Creative Commons License

Catégories :Arduino & Co Étiquettes : ,

Pico puter : de la théorie à la pratique

19 septembre 2017 Laisser un commentaire

Mon mini cluster est cassé. Nœud principal HS. Diagnostic à venir. Du coup, je n’ai toujours pas de « vrai » serveur Mercurial…

En attendant, j’ai relu et (re-)*dé-coquillé mon premier NaNoWriMo (merci encore Titi !) , et j’ai un peu avancé sur mon projet de « Pico ordinateur« .

Yeps ! Les premiers écueils apparaissent à l’horizon.

Pour rappel, un ATtiny85 vu du programmeur, c’est :

  • 8 kilo-octets de mémoire flash pour les programmes et données statiques
  • 512 octets de mémoire RAM

Côté pratique, l’électronique est à l’avenant :

  • une masse et une alimentation
  • 1 reset qui peut éventuellement être utilisé comme entrée/sortie
  • 5 entrées/sorties, dont deux que je réserve pour le « bus » I2C
  • 512 octets de mémoire de stockage de type EEprom.
  • un capteur de température (si-si)
  • des timers
  • des interruptions

Bref, de quoi s’amuser, surtout vu ce que je compte lui adjoindre :

  • un petit écran OLED
  • un clavier 4 x 4 touches
  • une horloge/calendrier, sa ram intégrée sauvegardée par pile, ainsi que la mémoire EEProm qui l’accompagne
  • une entrée et une sortie « analogiques » dont l’usage reste à déterminer
  • d’autres petites choses connectées en I2C.

Ça parait léger.

De la théorie …

En principe, tout ça devrait se programmer sans trop de problèmes. I2C ici, I2C là, un clavier « lu » comme une entrée analogique, etc.

Eh bien, non !

… à la pratique

L’I2C n’est pas implémenté en matériel sur l’ATTiny85, et j’utilise une librairie ad-hoc. Et hop, quelques centaines d’octets consommés dans la mémoire flash du contrôleur, plus une quarantaine en RAM.

L’écran OLED a son petit protocole bien à lui, et il faut lui fournir le bitmap (5 octets) de chaque caractère à afficher. Un écran LCD 4×20 aurait été plus simple à programmer mais, je l’ai déjà dit, moins fun. Ce sera une solution de repli au cas où…

L’horloge RTC stocke l’heure et la date au format BCD dans sa RAM « non volatile » – comprendre, « sauvegardée par pile ». Elle propose au total dans cette RAM 64 octets de RAM dont l’usage d’une bonne partie est, à priori, laissé libre pour le programmeur. Hop, on ajoute un mini-protocole supplémentaire, et deux routines de conversion BCD <-> binaire.

L’EEPROM de trente deux kilo-bits  – 4 kilo octets – qui squatte la carte de l’horloge a, devinez quoi, son petit dialecte propre, mais c’est peut-être le composant le plus simple à utiliser dans ce projet.

J’oubliais l’EEPROM de l’ATtiny, utilisable librement, lui aussi. Heureusement, la librairie standard de l’Arduino suffit. Ouf !

Un peu d’unification

L’EEPROM de l’Attiny – 512 octets – , celle de la carte horloge – 4 kilo octets – , la RAM de l’horloge – 64 octets – ont des besoins assez simples. On peut les considérer comme des périphériques de stockage, mais à la base il faudra y lire et y écrire des valeurs, généralement un octet à la fois. Lent mais simple, et inversement.

Vu la mémoire RAM totale de l’ATtiny85 – 512 octets – ne pourrai pas je n’aurai pas à y manipuler de grosses structures. Partant de là, stocker ou récupérer des informations pourra se faire par paquets de huit, seize, trente-deux octets ou plus à la fois. Je ne suis pas encore fixé là dessus, mais un stockage « de masse » – tout est relatif – par blocs de 32 octets devrait suffire.

On sort son cahier, ses stylos, on dessine l’organisation générale du bousin, les classes, leurs héritages, bref, on fait ses plans, et on se retrouve avec plusieurs « périphériques » de stockage présentant les mêmes routines d’accès. Merci la POO ! Classe de base : I2C, classe abstraite stockage, une classe par périphérique, une pour le clavier, une pour l’écran. Ça a … de la classe !

** /me court se planquer comme un bourrin des Flandres **

Mise en oeuvre

L’écriture du code se passe bien. On joue un peu avec le C++. Et oui, l’IDE Arduino, à la base, c’est du C++ !

Les tests se déroulent bien, l’écran affiche, l’horloge donne la date et l’heure, sa RAM est lue et écrite sans soucis, idem pour sa colocataire l’EEPROM I2C, et le clavier attend sagement qu’on passe à l’étape du fer à souder, même si son code est presque terminé.

Bilan d’étape

La compilation donne :

Le croquis utilise 6862 octets (83%) de l’espace de stockage de programmes. Le maximum est de 8192 octets.
Les variables globales utilisent 439 octets (85%) de mémoire dynamique, ce qui laisse 73 octets pour les variables locales. Le maximum est de 512 octets.

6862 octets de flash utilisée, avec uniquement quelques tests, sans aucun logiciel de mon système cible (qu’il reste d’ailleurs à définir). Je suis encore confiant là-dessus : les tests prennent de la place qui sera à terme libérée pour autre-chose.

Mais 73 octets de RAM disponible ! SOIXANTE TREIZE ! Même si j’ai réservé 256 octets de RAM pour le futur système, clairement, ça va coincer. Un stack overflow sur PC, ça éclabousse un peu, mais là, ça va frotter sévère !

J’ai choisi la bonne méthode…

… pour un Arduino Mega (256 ko de flash, 8 Ko de RAM) , ou un Arduino Due (512 ko de flash, 96 ko de RAM). Pour un micro contrôleur beaucoup plus petit comme l’ATTiny85, il faut revoir sa copie car la programmation objet, pour sexy élégante qu’elle soit, n’est pas vraiment indiquée vu le peu d’espace disponible.

  • L’héritage, et en particulier la surcharge de méthodes couplée au polymorphisme consomment énormément de RAM.
  • Il vaut mieux utiliser la composition et la délégation. Les classes de bases fournissent les fonctions simples et se fichent éperdument de ce qu’on en fera. La classe auparavant héritée devient une classe chargée de les coordonner et leur déléguer les fonctions de base. On utilise plus de mémoire programme en flash, mais beaucoup moins de RAM. Si j’étais « jusqu’au bout-iste », je n’utiliserais que des fonctions (au sens C), mais la programmation orientée objet en mode light a quelques petits avantages.
  • Les attributs (variables internes) des classes consomment de la RAM. Il faut donc en limiter le nombre et la taille.
  • Les paramètres passés aux méthodes (fonctions) consomment de la pile, donc de la RAM. Même punition.
  • Les appels de méthodes consomment également de la pile pour les variables locales, mais uniquement lors de l’exécution de la méthode. A la sortie, de la pile est libérée, mais les appels de méthodes en cascade (et encore plus la récursion) multiplient d’autant l’utilisation de la pile. Il faut donc limiter les profondeurs d’appels. Un maximum de trois ou quatre fonctions/méthodes en cascade est une bonne règle. Pour les fonctions très simples (une ligne ou deux), préférer utiliser des macros (#define)
  • Même si ça reste à confirmer, les « switch » occupent apparemment moins de mémoire programme si les valeurs recherchées dans les clauses « case » sont triés par ordre croissant.
  • Les variables, attributs, fonctions et méthodes inutilisés n’occupent pas de mémoire de programme, mais complexifient le projet. Il faut rester simple.

Résumé simple de ce qui précède :

  • éviter l’héritage
  • utiliser la composition et la délégation
  • limiter au strict nécessaire l’utilisation de variables globales et de variables internes aux classes
  • limiter le nombre de paramètres passés aux fonctions/méthodes
  • limiter la profondeur d’appel des fonctions/méthodes
  • ordonner les valeurs testées dans les clauses « switch »
  • diminuer la complexité tant matérielle que logicielle – le fameux « KISS principle »

Après mise en pratique, la compilation de mon programme enrichi d’une foultitude de tests donne :

Le croquis utilise 7434 octets (90%) de l’espace de stockage de programmes. Le maximum est de 8192 octets.
Les variables globales utilisent 383 octets (74%) de mémoire dynamique, ce qui laisse 129 octets pour les variables locales. Le maximum est de 512 octets.

La RAM disponible pour la pile est maintenant de 129 octets sur les 512 que contient l’ATTiny85, toujours en réservant un bloc de 256 octets. Cela devrait suffire, même s’il faudra veiller au grain…

Les prochaines étapes

  • Décider du système qui animera le bousin. J’hésite toujours entre un Forth et un Chip-8 fortement dégraissé. Si j’étais cintré du chapeau, BrainF*, pourrait coller. Le Forth a ma préférence, mais avec un clavier 4×4, ça risque de ne pas être pratique.
  • Assembler et tester le clavier 4×4
  • Donner une fonction aux deux entrées/sorties encore libres

Mais d’abord

Un grand merci à Alex Wulff dont la « Business Card/Game Console » m’a donné plusieurs pistes pour mon projet, notamment le code de gestion de l’I2C et de l’écran OLED.

Creative Commons License

Catégories :Arduino & Co Étiquettes : ,

Pico puter, les specs

12 septembre 2017 2 commentaires

Dans un billet précédent, j’ai abordé mon projet de créer un (tout) petit ordinateur, limité, mais simple à comprendre. Les projets, c’est bien. Créer, c’est bien mieux.

Je n’ai rien imaginé qui soit révolutionnaire. Au contraire, je vais m’appuyer sur des composants existants, assez récents pour éviter les problèmes d’approvisionnement, mais pas trop pour limiter les coûts, mais surtout simples à utiliser tant côté connectique que côté logiciel.

La cible

Les premières machines de découverte et d’expérimentation des années 70, comme le KIM-1 comportaient quelques centaines d’octets de mémoire vive, une ROM à peine plus grande contenant le programme de base (un simple moniteur), un clavier numérique et un petit afficheur, quand ce n’étaient pas de simples leds.

Les routines d’accès aux périphériques pourront occuper toute la mémoire programme (Flash) inutilisée par le système, et il faudra limiter l’usage de variables globales et, si possible, de pile. Je pense à une petite abstraction de type Chip8 largement downsizé ou encore à un Forth minimaliste. Je sais, limiter l’usage de la pile alors que Forth utilise deux piles… Deux piles, certes, mais quasiment aucune variable.

Au final, les 512 octets de RAM suffiront à peine, mais si c’était simple, ce serait beaucoup moins fun, non ?

Le processeur/contrôleur

Côté processeur, je délaisse les ATmega que je réserve pour le moment à des usages plus « arduinesques ». J’ai finalement opté pour un ATtiny85. Ses capacités sont limitées, mais c’est ce qui pimente l’histoire :

  • 8 kilo-octets de mémoire flash pour les programmes et données statiques
  • 512 octets de mémoire RAM
  • 512 octets de mémoire de stockage de type EEprom.
  • Masse et VCC pour l’alimentation
  • 1 reset qui peut éventuellement être utilisé comme entrée/sortie
  • 5 entrées/sorties

Ça parait léger, et effectivement, ça l’est réellement.  Ça change des Arduino Due avec leurs centaines de kilo octets de mémoire programme et leurs dizaines de kilos de RAM. Ça change également des Arduino Uno, déjà plus limités mais suffisant pour la plupart de mes usages. Pour se faire une idée, lire ce comparatif entre ATmega et ATtiny85.

J’ai sélectionné quelques composants repêchés dans ma boîte à rabiots.

Affichage

Il s’agit d’un petit écran OLED à la résolution faramineuse de 128×64 pixels, mais que j’utiliserai en mode texte pour limiter la consommation mémoire. Au final, huit lignes de texte. Un écran LCD 4 x 20 aurait été plus simple à utiliser, mais aurait nécessité une interface I2C, et j’ai préféré aller au plus court.

Horloge et Stockage

Là encore, une petite carte est venue à ma rescousse. Elle comporte une horloge / calendrier sauvegardée par pile, ainsi qu’une mémoire EEprom de 32 kilo bits (et non bytes, comme j’avais d’abord compris ; c’était pleine lune ou un truc du genre, mais passons ! )

On passe donc de 32 ko à … 4 ko. On verra plus tard pour un upgrade.

Clavier

J’ai ressorti de mes armoires un clavier numérique au format USB. En théorie, tout va bien avec un petit adaptateur, ça peut se brancher sur un port PS/2, l’ancienne norme de connecteur pour les claviers et souris, et il existe plusieurs librairies pour utiliser les claviers PS/2. Làs, après pas mal d’essais, ça ne veut pas. Le clavier fonctionne sur un PC, mais un arduino n’en veut pas.

Tant pis, on reviens aux bases. Un clavier, c’est des boutons, quelques résistances et un petit contrôleur. Sachant parler PS/2 ou USB. Sur le principe du diviseur de tension, on peut interfacer 4 à huit boutons sur une seule entrée analogique. Edit: depuis le premier brouillon de ce billet, j’ai trouvé (merci Glouglou) un schéma sur le même principe pour 16 boutons.

Ce sera dont un clavier à base de boutons « tact-switch », du genre de ce qu’il y a dans les télécommandes de portières de voitures.

Alimentation

Pour le moment, j’utilise une alimentation 5V/3.3V pour plaquette de prototypage, alimentée par une prise USB ou une prise 9V. Deux sorties sont utilisables en même temps, avec chacune une DDP de 5 ou 3.3V, sélectionnable par cavalier.

Le « Bus »

Pas besoin de chercher loin : l’écran, l’horloge et la mémoire externe communiquent en I2C. Le format du bus restera tout simple : Masse, 5V et 3.3V pour l’alimentation, et clock plus data pour l’I2C

Autres E/S

Résumons : huits pins moins le reset, la masse, l’alimentation, les deux pins pour l’I2C, celui du clavier, restent…

Une sortie et une entrée analogiques. C’est très peu, mais avec l’I2C, et sous réserve qu’il reste assez de mémoire, il y a de quoi faire.

La programmation

L’ATtiny85 ne possède ni I2C ni USB, mais une interface série programmable. L’USB et l’I2C sont donc à portée, via vUSB pour le premier, et TinyWireM pour le second. Utiliser les deux en même temps me semble un poil complexe, mais surtout, cela monopoliserait deux E/S supplémentaires sur l’ATtiny.

Exit donc l’USB ; je programmerai l’ATtiny avec un programmateur ad-hoc. Ça tombe bien, j’en ai justement un qui me fait signe de ses LEDs.

Conclusion provisoire

Voilà donc les « spécifs » pour ce projet, et ça me semble parfait pour un premier projet un peu plus complexe que ce que j’ai pu faire jusque lors.

La feuille de route qui en découle est des plus simples :

  1. Comprendre et utiliser le protocole I2C sur Arduino, et communiquer avec l’écran OLED
  2. Appliquer le tout à l’ATtiny pour l’écran OLED. Itérer en 1 si le besoin s’en fait sentir
  3. Recommencer pour l’horloge et la mémoire Flash externe
  4. Assembler, tester un clavier et en écrire les routines d’interface

A ce stade, je devrais avoir une pico-machine comportant un clavier, un écran, de la RAM et de la ROM (flash), ainsi qu’un système de stockage (EEprom).

En fonction de la RAM et de la flash restant disponible, il restera encore à écrire le « système » du pico-ordinateur. Ah oui, ça serait bien d’avoir un boîtier assez sympa pour cacher les soudures de sauvage abriter le tout.

La todo list est déjà longue, tant côté logiciel que matériel. Ca tombe bien, il fait noir de plus en plus tôt, et comme je ne regarde pas la télébidon…

Comment ça, je dois avancer sur mon mini cluster ? Et Comment ça, c’est bientôt Nanovembre ?

Creative Commons License

Catégories :Arduino & Co Étiquettes : ,
%d blogueurs aiment cette page :