lundi 15 janvier 2018

Busy Bee partie 5, boite à musique.

Lorsque j'étais enfant il y avait des boites à musique qui fonctionnaient avec un ressort. Un jour j'en ai démonté une pour voir comment c'était fait. Il y avait un cylindre avec des pointes de métal ainsi qu'un peigne en métal avec les dents de longueurs différentes. La longueur de chaque dent déterminait la fréquence de la note. Le ressort faisait tourner le cylindre et les pointes de métal du cylindre accrochaient les dents du peigne au passage. Les pointes étaient disposées pour jouer une mélodie en particulier.

Dans cet article je présente une version électronique de la boite à musique. Contrairement à la boite à musique mécanique celle-ci peu jouer plusieurs mélodies.

schématique

La boite à musique dans sa version minimale n'utilisait que les broches du port 1. Comme le port 0 était entièrement libre j'ai décidé d'y brancher 8 LEDS. Les LEDs branchées sur P0.0 à P0.4 servent à indiquer l'indice dans la table scale de la note qui est jouée. Les LEDS branchées sur P0.5 à P0.7 indique l'indice de la mélodie dans la table tunes_list. Les 2 groupes sont séparés par une LED rouge pour les distingués aisément. La LED rouge marque le bit le plus significatif du groupe.

Pour que le son soit moins saccadé j'ai ajouté un générateur d'enveloppe constitué du transistor Q1 et des résistances,R6,R10 et R12 ainsi que du condensateur C3. Au début de chaque note la sortie P1.1 est mise à 1 pendant 40 millisecondes. Pour permettre à C3 de se charger. Ensuite P1.1 est mise en haute impédance et C3 se décharge lentement à travers R10 et la base de Q1. l'effet produit est que le son monte en intensité en suivant la courbe de charge du condensateur et ensuite l'intensité diminue plus lentement par la décharge de C3. La montée sonore appelée attaque est déterminée par la constante de temps R6*C3 tandis que la descente est déterminée par la constante de temps C3*(R10+Rb)Rb est la résistance réfléchie par la base du transistor. Rb est approximativement G*R12, G étant le gain du transistor. Donc le transistor C3 se décharge beaucoup plus lentement qu'il ne se charge.

Les notes sont produites par le canal 0 du PCA0 dont la sortie est acheminée sur la broche P1.0.

Le bouton déclencheur est branché sur la broche P1.2. Chaque fois que le bouton est enfoncé une seule mélodie est jouée. Le bouton doit-être relâché et enfoncé à nouveau pour jouer la mélodie suivante.

Sur la broche P1.3 il y a un sélecteur de mode. On peut choisir entre le mode aléatoire et le mode séquentiel. Le mode doit-être sélectionné avant que l'appareil soit mis sous tension. Dans le mode séquentiel les mélodies sont jouées toujours dans le même ordre, celui où elles apparaîssent dans la table tunes_list. En mode aléatoire la mélodie est sélectionnée au hasard. En fait de hasard, il s'agit de lire le registre TL0 qui est la partie basse de la minuterie TIMER0 qui compte en boucle rapidement à la fréquence Fsys. Il est impossible de prévoir ou est rendu le compte dans TL0 au moment ou on presse le bouton d’où l'effet aléatoire.

Je n'ai pas fait de montage final de ce projet mais je pense que ça pourrait plaire à un jeune enfant. Sur le montage temporaire tel que vue dans la vidéo ci-bas je n'ai pas fait le montage au complet, je n'utilise qu'une alimentation de 3,3 volt et un petit ampli à transistors fait maison qui fonctionne à cette tension contrairement au LM386 qui nécessite un minimum de 4 volts.

Actuellement il y a 8 mélodies d'enregistrées dans la mémoire flash du MCU et il y a 1305 octets d'utilisés sur les 8Ko. Il est donc possible de rallonger cette liste. Il y a probablement assez d'espace pour une symphonie ;-)

Les mélodies que j'ai utilisées proviennent du site http://www.apprendrelaflute.com

Comme toujours l'ensemble du projet est sur github.

démo

vendredi 12 janvier 2018

Busy Bee partie 4, breakout

Dans cette quatrième partie consacrée au EFM8BB10F8G je discute de l'implémentation du jeu breakout. Il s'agit d'un jeu d'arcade datant de 1976. Il s'agit de casser un mur de brique à l'aide d'une balle qui rebondie sur les murs extérieurs ainsi que sur la palette que le joueur déplace de gauche à droite dans le bas de l'écran.

Breakout

Le MCU EFM8BB10F8G ne possède que 512 octets de mémoire RAM divisé en 256 octets de mémoire interne idata et 256 octets de mémoire externe xdata. La mémoire externe est utilisée comme mémoire vidéo ce qui limite la résolution d'écran à 64 pixels par 32 pixels en monochrome. C'est suffisant pour ce jeu. J'ai créé un projet appellé BBchip8 dans simplicity studio. je l'ai appellé ainsi pour 2 raisons. La première étant que la résolution est la même que pour l'émulateur CHIP-8 et la seconde est que j'ai implémenté dans les fichiers chip8.c et keypad.c des fonctions qui permettent d'écrire d'autre jeux dans le style CHIP-8 en utilisant la même base de code. D'ailleurs le jeu breakout utilisant moins de la moitié de la mémoire programme il serait possible d'ajouter un autre jeu sur la même plateforme et d'offrir un menu de sélection à l'utilisateur. Le jeu tétris entrerais dans la mémoire restante.

schématique du circuit

schématique

prototype

Bien que le jeu breakout n'utilise que 2 boutons j'ai installé 6 boutons, 4 boutons de directions et plus les boutons A et B. Ça donne plus de flexibilité à la plateforme matérielle pour l'installation d'autres jeux.

Utilisation du configurateur

Il s'agit d'un projet créer avec le configurateur.

Un oscillateur à cristal externe avec une fréquence de 25.175Mhz est utilisé. Fsys fonctionne à la fréquence maximale.

Le watchdog timer est désactivé.

Le Programmable counter array est utilisé pour générer le signal NTSC. Les 3 canaux sont utilisés.

Les 3 canaux fonctionnent en mode 1, 16 bits software timer.

Le périphérique SPI est utilisé pour sérialiser les pixels vidéo.

La minuterie 0 est utilisée pour les délais et la minuterie 1 pour les sons.

Les interruptions sur le PCA et sur le TIMER0 sont activées.

Une fois la configuration matérielle complétée j'ai modifié le type d'interruption pour le périphéarique PCA dans le fichier interrupts.c de la façons suivante:

SI_INTERRUPT_USING (PCA0_ISR, PCA0_IRQn,1)// use register bank 1
L'objectif de cette modification est de réduire le temps de réponse de l'interruption en utilisant la banque de registre 1 au lieu de la banque 0. Ça évite d'avoir à sauvegarder le contenu des registres de la banque 0 sur la pile. Si on retourne dans le configurateur pour faire des modifications après cette modification manuelle. Le configurateur va regénérer l'interruption originale sans effacer cette modification. Le compilateur va signaler une erreur puisqu'il y aura 2 routines pour PCA0_ISR. Il faudra donc supprimer celle créée par le configurateur.

organisation du code.

  • Le fichier chip8.c contient les routines pour la gestion vidéo, les sons, la routine pause() pour les délais ainsi que des routines pour le générateur pseudo-aléatoire. Le générateur pseudo-aléatoire utilise le convertisseur analogue/numérique pour lire une entrée inexistante. En effet à la mise sous tension le registre ADC0MX contient 0x1F. Avec cette valeur l'entrée du convertisseur est flottante. On lit donc le bruit produit par le MCU. Seul le bit le moins significatif est conservé, celui-ci étant suffisamment aléatoire pour cette application. La fonction random() accumule le nombre de bits demandés en appelant répétitivement rand_bit() qui est la fonction qui lit la sonde de température.
  • Le fichier keypad.c contient les routines pour la lecture des boutons.
  • Le fichier breakout.c contient la logique du jeu.
  • Les autres fichiers sont ceux générés automatiquement par le configurateur. Dans le fichier interrupts.c le code pour la gestion des interruptions PCA et TIMER0 a été ajouté manuellement.
L'ensemble du projet est disponible sur github.

vidéo démo