# boitarire

Kit pour fabrication d'une boîte à rire, ou tout autre objet de petite taille pouvant jouer un son déclenché par un évenement (mouvement, contact ...).

# Description

Une boîte à rire est un objet qui produit un son suite à un évènement déclencheur. Le présent projet contient une implémentation de boîte à rire, comprenant un circuit électronique pemettant de réaliser cette fonction.

# Spécifications / Cahier des charges

* Circuit imprimé avec configurations multiples par montage ou non des modules / composants et par re-programmation
* Dimensions max : sphère 60mm
* Fonctionnement sur batterie intégrée dans l'enceinte (donc doit tenir dans la sphère de 60mm)
* Sortie haut-parleur de 1W min - 3W max + haut-parleur 8 Ohms/3W
* Doit pouvoir mémoriser et jouer un son de 20 secondes max -> mémoire requise en qualité CD mono non-compressé -> 1.72Mo min
* Options de capteurs en entrée : capteurs tactiles ou capteur d'inclinaison ou accéléromètre, connectables via connecteurs
* Doit permettre la recharge via USB sur un port mini- ou micro-USB, ou via une alim 5V en connecteur jack DC 2.1mm
* Doit disposer d'une autonomie de 8h min en fonctionnement, 12h max en recharge

* Profil d'usage en fonctionnement : 25% du temps à plein volume, 8h par jour
* Puissance consommée en fonctionnement à plein volume : 3W (consommation de la carte électronique négligeable en comparaison de l'ampli audio)
* Courant consommé en fonctionnement à plein volume : 600mA
* Capacité requise : 25% x 8h x 0.6A = 1.2 A.h
* Capacité de charge requise : 1.2 A.h / 12h = 100mA min

* Design libre et open-source (schéma, routage, software, outils)
* Modules avec connecteurs traversants, boîtiers de composants traversants ou CMS soudable au fer à souder manuel (pas de BGA, pas de QFN, pas de composants à semelle)
* BOM max 40€
* Boîtier et éventuels supports du PCB dans le boîtier : doit pouvoir être tenu dans un boîtier (trous de fixation, "surfaces de contact" pour tenue par un support), mais le design d'un éventuel boîtier ou la forme mécanique du support ne sont pas définis ni imposés.

# Contenu du projet

Ce projet regroupe le design électronique ainsi que le code embarqué.

# Outils 

Circuit imprimé (schéma, routage) : Kicad (6.0)
Design mécanique : FreeCAD (0.19 24291)
Software : Arduino IDE (1.8.15)

# Arcitecture hardware

Le produit est un circuit imprimé accueillant plusieurs modules:
* Arduino Nano ou équivalent
* Module MP3 DY-SV17F ou équivalent
* Module accéléromètre GY-521 ou équivalent
* Module de charge pour 1 cellule li-ion HW-107 ou equivalent

Ainsi que des capteurs:
* Capteur d'inclinaison mécanique (tilt sensor) type SW520D ou équivalent
* 2 Connecteurs 3 voies pour capteurs alimentés en 5V délivrant un signal tout-ou-rien en 5V (pour l'application d'origine il s'agit de capteurs capacitifs type TTP223 ou équivalent)

Ainsi qu'un connecteur pour une batterie li-ion 1 cellule et un connecteur pour haut-parleur (3W max, attention le connecteur est 3 voies mais seules 2 sont connectées, voir schéma pour pinout).

Le rôle du module Arduino est de lire et conditionner les signaux provenants des capteurs, et déclencher la lecture de sons sur le module MP3.
le module Arduino est connecté:
* Au module MP3 par UART
* Au module accéléromètre par I2C

Le chargement de fichiers sons dans le module MP3 se fait via le connecteur micro-USB dont dispose celui-ci. le module s'identifie comme une clé USB (la mémoire est embarquée sur le module) et il suffit de copier les fichiers que l'on veut jouer.

# Architecture software

Le software du produit est prévu pour fonctionner avec un seul type de capteur à la fois, le sélection se faisant par la définition d'un switch de compilation:
* Capteur d'inclinaison : SENSOR_INCLINATION
* Capteur externe (capacitif / touch) : SENSOR_TOUCH_SENSOR1 et SENSOR_TOUCH_SENSOR1
* Accéléromètre : SENSOR_ACCELEROMETER

La sélection du capteur se fait en laissant non-commenté le #define du(des) capteur(s) voulu(s). Mélanger plusieurs types de capteurs sur une même application est sans doute possible mais n'a pas été testé.

Les traitements sont tous effectués dans la boucle principale loop(). Utiliser des appels réguliers serait sans doute plus approprié.

La gestion de la lecture des sons est effectuée à travers une machine d'état (stmState).

	----------
	|STM_INIT|
	----------
	    |
	    V
	----------
	|STM_IDLE| <--------------------
	----------                     |
	    |                          |
	    - tilt sensor              |
	    | OR touch sensor          |
	    | OR accel sensor          |
	    |                          |
	    V                          |
	----------                     |
	|STM_PLAY|                     |
	----------                     |
	    |                          |
	    V                          |
	-----------                    |
	|STM_BLANK|                    |
	-----------                    |
	    |                          |
	    - wait blanking delay      |
	    |                          |
	    |  ( --------------- )     |
	    |  ( |STM_MP3_RESET| )     |
	    |  ( --------------- )     |
	    |                          |
	    ----------------------------

Chaque capteur doit générer un trigger pour déclencher la lecture d'un son. Le traitement des signaux externes pour définir les conditions de déclenchement du son doivent être réalisés en-dehors de la machine d'état stmState.
L'état STM_PLAY va envoyer la commande UART pour jouer un son.
Après avoir joué un son, la machine détat attend dans un état STM_BLANK pendant un temps défini, de façon à éviter les re-déclenchements intempestifs. Il est conseillé de définir le temps d'attente pour être d'une longueur légèrement supérieure au son qui doit être joué.
Si le switch de compilation MP3_RESET est défini, un autre état intermédiaire STM_MP3_RESET va déclencher un reset hardware du module MP3 avant de revenir à l'état initial STM_IDLE. Ce reset est facultatif, mais peut être nécessaire si des comportements aléatoires sont constatés.

## Playlist

Le software permet de définir une playlist de fichiers sons, avec une occurence et un temps de blanking associé. La playlist est définie en constante dans le tableau cPlaylistIndif_TA. Ce tableau est de longueur PLAYLIST_LENGTH et constitué de structures tSongItem, contenant :
* song_index_u8 : l'index du fichier dans la mémoire du module. A noter que les fichiers sont ordonnés par ordre alphabétique des noms de fichiers, le plus pratique est d'ajouter systématiquemetn un préfixe avec le numéro d'index complété à gauche par des zéros (0000_morceau1, 0001_morceau2 ...)
* cycles_number_u8 : le nombre de répétition du morceau, doit être égal au moins à 1, permet de lire plusieurs fois de suite le même morceau sans avoir besoin de le recopier plusieurs fois dans le tableau
* blank_delay_u16 : délai de blanking pour éviter les re-déclenchements qui pourraient interrompre le son avant qu'il soit fini, défini en millisecondes, il est conseiller de le définir légèrement supérieur à la longueur du fichier son

## Capteur d'inclinaison

Le capteur d'inclinaison étant un intrrupteur à contact sec, il est sans surprise très bruité, et nécessite un filtrage anti-rebond (debounce filter). Ce filtrage est réalisé grâce à une machine d'état stmDebounceState. Cette machine d'état permet de filtrer les fonts montants et descendants séparément, mais de façon symmétrique via la constante DEBOUNCE_DELAY qui définit le délai de filtrage en millisecondes. Plus le délai est long, mieux le signal est filtré, mais moins le déclenchement est réactif, ce paramètre est à ajuster en fonction du capteur utilisé et de l'usage.
Le déclenchement est effectué en lisant l'état de la machine d'état stmDebounceState, STM_DEBOUNCE_DEBOUNCE_0 ou STM_DEBOUNCE_DEBOUNCE_1 en fonction du "sens" que l'on veut pour déclencher. Ajouter les deux états avec un OR permet de déclencher dans les deux changement de sens.

## Capteurs externes

Les capteurs utilisés sur l'application d'origine étant correctement filtrés, aucune filtrage n'a été ajouté en software, létat logique des pins est directement écrit dans les variables input_touch_sensor1 et input_touch_sensor2 qui sont ensuite lues par la machine d'état stmState. L'utilisation de capteurs externes bruités pourrait nécessiter l'ajout de filtrage, no nprésent dans le code publié.

## Accéléromètre

L'accéléromètre dans son application d'origine est utilisé pour détecter la rotation du produit. la communication I²C est effectuée grâce à la librairie Wire.
A chaque passage dans la boucle principale, les mesures de vitesse linéaire et angulaire sont lues sur les 3 axes, et stockées dans la structure AccelData_T.

Si le switch de compilation ACCEL_ROTATION_DETECT est defini, un filtrage IIR passe-haut de taille 1 avec alpha = 0.5 est utilisé pour détecter les variations de l'accélération sur les axes de rotation, puis intégré pour recomposer ue image de la variation de position. Cela est utilisé pour détecter une amplitude de rotation, le seuil est défini par la constante ACCEL_TRIG_ROT.

Il est à noter que la plage de mesure du module GY-521 est limitée, si l'objet bouge "trop vite" la vitesse est écretée, et la position reconstruite est fausse et ne "bouge" pas assez vite. C'est à prendre en compte.

Si ACCEL_ROTATION_DETECT n'est pas défini, le software va identifier un déclenchement lorsque l'un des axes atteint la vitesse seuil définie par ACCEL_THRES_GYX / ACCEL_THRES_GYY / ACCEL_THRES_GYZ.

Si le switch de compilation DEBUG_UART_ACCELEROMETER est défini, les mesures de l'accéléromètre sont transférées sur la liaison UART pour debug, lisibles via le moniteur série de l'IDE Arduino. Il est à noter que si cette fonctionnalité est activée elle entre en conflit avec la communication entre le module Arduino et le module MP3, et risque de perturber le déclenchement des sons.





