Introduction
Après avoir fait fonctionner le lecteur MP3 à sortie vocale et développé un flux de programmes dans la première partie de cette série de blogs, je vous ai montré comment connecter et programmer le capteur de couleurs TCS3200 dans la deuxième partie. Maintenant, dans la troisième et dernière partie, nous allons mettre les deux ensemble, scanner les couleurs et faire parler le détecteur de couleurs. Nous allons implémenter un mode de calibration en direct et rendre l'alimentation mobile avec une batterie rechargeable. Allons-y.
Ce dont nous avons besoin
Nombre | Composant |
---|---|
1 | Module capteur de couleurs TCS3200 |
1 | DFPlayer Mini MP3 Player Modul |
1 | Carte micro SD |
1 | Arduino Nano V3.0 |
1 | Haut-parleurs (Max 3W) |
Câble de connexion | |
1 | Résistance 1 KOhm |
1 | Résistance variable (potentiomètre) |
2 | Bouton |
Computer mit Arduino IDE und Internetverbindung | |
Externe Spannungsquelle (empfohlen), 7 - 12V | |
Farbreferenzkarten | |
Batterie LiPo Lithium 3,7 V | |
1 | MT3608 Step up Module |
1 | TP4056 Module contrôleur de charge |
1 | Voltmeter |
Préparation
Je suppose que vous avez construit le circuit de la partie 2 et que vous avez inséré la carte SD contenant les fichiers vocaux dans la fente SD du lecteur MP3.
DFPlayer Mini Pins |
Arduino Nano Pins |
VCC |
5V |
GND |
GND |
RX |
sur 1 KOhm à D11 (TX) |
TX |
D10 (RX) |
|
Haut-parleur |
SPK_1 |
Rouge (Plus) |
SPK_2 |
Noir (Moins) |
Potentiomètre |
Arduino Nano Pins |
1 |
GND |
2 (Milieu) |
A0 |
3 |
+5V |
Bouton-poussoir |
Arduino Nano Pins |
1 |
D12 |
2 |
GND |
TCS3200 Pins |
Arduino Nano Pins |
VCC |
5V |
GND |
GND |
OE |
D3 |
S0 |
D4 |
S1 |
D8 |
S2 |
D6 |
S3 |
D7 |
OUT |
D5 |
Pour un test fonctionnel, nous chargeons le programme de la partie 1 sur l'Arduino :
Code Source Complet: 1.2DFPlayerSon de départPotiBouton-poussoir.ino
Nous testons également le capteur de couleur avec le programme de la partie 2:
Code Source Complet: 2.0TCS3200Test.ino
Fusionner des programmes
Notre tâche consiste maintenant à combiner les programmes des parties 1 et 2. Avec le programme de la première partie, nous pouvons déjà faire fonctionner l'appareil relativement simplement. Il peut même émettre des couleurs via la sortie vocale. Avec les programmes de la partie 2, nous pouvons scanner les bonnes couleurs. Nous devons donc "seulement" les passer au code source de la partie 1.
Tout d'abord, nous changeons à nouveau le programme "tcs3200calibration" pour le calibrage de la bibliothèque tcs3200, que nous avons déjà utilisé dans la partie 2. Comme je l'ai mentionné à la fin de la partie 2, nous étendons les tableaux distinctRGB, distinctColors et colorNames. Nous en avons besoin car nous utilisons plus de couleurs. Nous devons donc modifier les lignes suivantes :
#define num_of_colors 9
int distinctColors[num_of_colors] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
String colorNames[num_of_colors] = {"Rouge", "Vert", "Bleu", "Noir", "Blanc", "Jaune", "Orange", "Rose", "Brun"};
Ainsi, nous avons fixé le nombre et l'ordre de nos couleurs. La liste correspond maintenant aux fichiers audio que nous avons créés dans la première partie.
Pour faciliter la reprise des couleurs par la suite, j'insère une interruption dans le déroulement du programme. C'est ce que nous avions fait dans l'exemple "Calibrate_TCS230" déjà dans la partie 2. Nous formatons également la sortie afin de pouvoir copier les valeurs plus facilement. Nous réécrivons le tableau distinctRGB[] [] pour une meilleure lisibilité sans modifier le contenu :
int distinctRGB[num_of_colors][3] = {
{17, 4, 7},
{9, 11, 11},
{4, 8, 18},
{3, 3, 4},
{32, 26, 45},
{27, 20, 14},
{28, 15, 12},
{18, 7, 17},
{7, 4, 6}
};
Cela nous permet d'accéder plus facilement aux trois valeurs par couleur. Nous déclarons maintenant un tampon de caractères pour la sortie formatée :
char serialBuffer[55];
Nous modifions la fonction loop() comme suit :
void boucle() {
// En attente de saisie
while (Série.available ()= = 0) {
if (Série.available ()!= 0) {
pause;
}
}
// Serial libérer le tampon
while (Série.read ()!= -1) {}
Série.println(colorNames[tcs.closestColor(distinctRGB, distinctColors, num_of_colors)] );
red = tcs.colorRead('r'); // reads color value for red
Série.imprimer("R= ");
Série.imprimer (rouge);
Série.imprimer(" ");
Vert = tcs.colorRead('g'); // reads color value for green
Série.imprimer("G= ");
Série.imprimer (Vert);
Série.imprimer(" ");
bleu = tcs.colorRead('b'); // reads color value for blue
Série.imprimer("B= ");
Série.Imprimer (Bleu);
Série.imprimer(" ");
Série.println();
// Édition
sprintf(serialBuffer, Rouge Vert Bleu: {%d, %d, %d} ", rouge, vert, bleu);
Série.println(serialBuffer);
}
Le programme attend l'entrée sur le moniteur série. Ensuite, la couleur est enregistrée une fois et les valeurs sont sorties pour que nous puissions les copier directement et les coller ici dans le code source. Nous faisons cela l'un après l'autre avec toutes les couleurs que nous avons saisies dans la liste ci-dessus. Faites attention à la position correcte dans le tableau correspondant, afin qu'aucune couleur ne soit mélangée.
Vous pouvez ignorer la sortie du nom de la couleur pour le moment. Après avoir enregistré toutes les couleurs et les avoir inscrites ici dans le code source, nous transférons à nouveau le programme sur l'Arduino. Si nous scannons les couleurs maintenant, le mot affiché devrait correspondre à la couleur.
Code Source Complet: 3.0tcs3200calibration_new.ino
Nous transférons maintenant ce code source dans le programme que nous avions écrit dans la première partie. Nous reprenons les constantes, les variables et les tableaux. Il ne nous reste plus qu'à entrer dans la machine à états du cas 6, quelle couleur doit être sortie. Actuellement, cette ligne produit le fichier audio avec le mot "Red" :
myDFPlayer.jouer(4);
Avec cette ligne, nous donnons le nom de la couleur sur l'écran dans le programme de calibration :
Série.println(colorNames[tcs.closestColor(distinctRGB, distinctColors, num_of_colors)]);
nous n'avons besoin que de l'appel de fonction closestColor() de celui-ci :
tcs.closestColor(distinctRGB, distinctColors, num_of_colors)
Cela nous renvoie le numéro de la couleur détectée. Cependant, les numéros des couleurs commencent à 0. Nos numéros pour les fichiers audio contenant les couleurs commencent à 1. La première couleur a le numéro 4. Regardez à nouveau le tableau de la partie 1 dans la section "Sortie de la parole" pour cela. Nous avons besoin d'un décalage pour les chiffres du tableau. Notre couleur reconnue, le rouge, a le numéro 0. Dans le tableau, c'est le numéro 4, donc un décalage de 4. Pour cela, nous déclarons une autre constante :
#define FILEOFFSET 4
La ligne pour la sortie du fichier audio est alors une combinaison des lignes mentionnées ci-dessus :
myDFPlayer.jouer (tcs.closestColor(distinctRGB, distinctColors, num_of_colors) + FILEOFFSET);
Nous passons le numéro détecté au lecteur audio et ajoutons également notre décalage. Pour la sortie du mot de la couleur nous prenons la ligne du programme pour la calibration :
Série.println(colorNames[tcs.closestColor(distinctRGB, distinctColors, num_of_colors)]);
Si vous chargez maintenant le programme sur l'Arduino, après avoir scanné la couleur, le mot correspondant devrait être lu et affiché dès que vous relâchez le bouton.
Code Source Complet: 3.1parlantDétecteur de couleur.ino
À ce stade, le détecteur de couleurs parlantes fonctionne déjà comme prévu. Il peut reconnaître les couleurs et les exprimer à voix haute.
D'autres Voix
Nous aimerions maintenant utiliser d'autres voix. Pour cela, nous avons besoin de nouveaux fichiers audio. Encore une fois, utilisez les pages Web liées de la première partie ou enregistrez-les vous-même. Puis les éditer pour qu'ils aient le même ordre que nos fichiers audio existants. J'ai ajouté une voix masculine et une autre langue. Donc maintenant j'ai femme et homme en allemand, et femme et homme en anglais. Après avoir édité les fichiers audio, je les copie sur la carte SD. Veillez à transférer les fichiers dans l'ordre correct, de préférence un par un. Ma numérotation des fichiers audio va maintenant jusqu'à 53.
Nous avions déjà inséré un décalage auparavant, afin que le numéro du fichier corresponde au numéro de la couleur. Maintenant, nous pouvons également utiliser un tel décalage pour changer la voix. Voici une liste de la numérotation de mes voix :
Numéros |
Voix |
2 - 14 |
femme, allemand |
15 - 27 |
homme, allemand |
28 - 40 |
femme, anglais |
41 - 53 |
homme, anglais |
Deux considérations importantes doivent maintenant être mises en œuvre :
- Comment changer la voix ?
- Où devons-nous le modifier dans le programme ?
Pour la première question, nous devons considérer pour quel groupe cible nous concevrions normalement l'appareil. Étant donné que je concevrai l'appareil principalement pour les personnes souffrant de déficiences visuelles, je veillerai à ce que son fonctionnement soit aussi simple que possible. Le bouton que nous utilisons déjà est un bouton de pression courte et de maintien. Nous pourrions maintenant ajouter des doubles clics ou des triples clics. Cependant, nous pouvons réaliser une opération plus simple si nous ajoutons un autre bouton. Nous le connectons à A5 de l'Arduino et à GND :
Nous définissons et initialisons la broche du bouton poussoir dans le programme (pourquoi j'utilise la broche analogique A5 comme entrée numérique ici, je l'explique dans la conclusion) :
#define TasterPin2 A5
// dans la configuration:
pinMode(TasterPin2, INPUT_PULLUP);
Nous avons besoin de plus de variables. Un compteur avec lequel on définit le vote, un décalage par rapport aux autres votes et un nombre maximum de votes :
int voiceNumber = 0;
unsigned int offsetVoice = 13;
int maxVoices = 4;
Nous avons besoin d'une fonction pour lire le deuxième bouton et réagir à un changement. Nous utilisons comme modèle la fonction taster(), que nous avons déjà. De cette façon, nous pouvons faire le débouclage. Nous pourrions éventuellement combiner les deux fonctions plus tard pour éviter la redondance du code source. Pour l'instant, nous copions la fonction, la renommons en changeVoice() et la modifions comme suit :
void changeVoice() {
taster_status_neu_2 = digitalRead(TasterPin2); // le bouton-poussoir est active low
// Détecter le changement de touche et démarrer le temporisateur de rebond
if (taster_status_re_2! = taster_status_alt_2 & &! taster_change_ 2) {
start_heure = millis () ;
taster_change_2 = vrai;
}
// si le bouton de la touche est drume
if (taster_status_new_2 == LOW & & taster_status_alt_2 == LOW & & taster_change_ 2) {
// Poster des touches
if (millis ()-start_tempor_2> prell_delay) {
taster_change_2 = false;
voiceNumber + + ;
if (voiceNumber> maxVoices- 1) {
voiceNumber = 0;
}
myDFPlayer.play (14 + voiceNumber * offsetVoice) ;
Serial.println ("Langue de la langue");
état = 1;
}
}
taster_status_alt_2 = taster_status_new_2 ;
}
Nous avons également besoin des variables appropriées.
unsigned long dernière_2 = 0;
unsigned long start_start_2 = 0;
bool taster_status_nouveau_2 = HIGH ;
bool taster_status_alt_2 = HIGH ;
bool taster_change_2 = false;
Si le bouton a été pressé, nous comptons le nombre de voix par 1. Lorsque nous avons atteint le nombre maximum de voix, la valeur est remise à 0 et la première voix est donc utilisée à nouveau. Ensuite, nous émettons la voix maintenant définie par le biais de la lecture audio. Le lecteur reçoit le numéro du fichier audio. Pour la première voix, il s'agirait du numéro de fichier 14. Nous ajoutons la multiplication du numéro de voix et du décalage. Cela donne 14 pour la première voix comme dit précédemment (car 0 * 13 est 0 et 14 + 0 reste 14), pour la seconde voix c'est 14 + 1 * 13, ce qui donne 27. C'est le même mot pour moi, seulement prononcé par la voix masculine. Il continue ensuite comme ça. La deuxième voix est 14 + 2 * 13 = 40 et 14 + 3 * 13 = 53. Nous avons donc un petit algorithme qui nous donne toujours le même mot prononcé par une voix différente. Il est donc important que l'ordre des fichiers soit le même pour toutes les voix.
Nous donnons ensuite à la variable d'état la valeur 1, ce qui nous ramène dans la machine d'état au moment où le texte d'information a été prononcé. Si quelqu'un a déjà numérisé la couleur et change ensuite de langue, le texte d'information doit être édité une nouvelle fois dans la nouvelle langue avant d'être numérisé à nouveau.
Dans la fonction statemachine(), nous ajoutons maintenant les sorties respectives :
...
case 2: { // Déjouer de l'aide
myDFPlayer.play (2 + voiceNumber * offsetVoice) ;
...
case 4: { // Examen initial
myDFPlayer.play (3 + voiceNumber * offsetVoice) ;
...
case 6: { // imprimer la couleur
myDFPlayer.play( tcs.closestColor (distinctRGB, distinctColors, num_of_colors) + FILEOFFSET + voiceNumber * offsetVoice) ;
...
La dernière étape est que nous devons: changeVoice ()Appeler une fonction dans la boucle principale:
void loop () {
taster () ;
changeVoice () ;
les villes de la ville () ;
statemachine () ;
}
Lorsque nous chargeons le programme sur l'Arduino, nous pouvons faire fonctionner le détecteur de couleurs de la même manière que précédemment. De plus, nous pouvons changer la voix ou la langue avec le deuxième bouton.
Code source complet: 3.2langueDétecteur de couleurpluslangue.ino
Étalonnage en direct
Nous avons vu que nous devons calibrer le capteur, c'est-à-dire le régler sur nos couleurs. Pour le moment, nous avons besoin d'un programme Arduino séparé pour cela, nous devons copier les valeurs de couleur et ensuite transférer le tout dans notre programme. Si le capteur se trouve dans un boîtier solide où il est protégé de la lumière ambiante, nous n'avons généralement besoin de l'étalonner qu'une seule fois. Car la distance entre le capteur et la surface de la couleur et la lumière ambiante sont deux facteurs perturbateurs dès qu'ils changent. Pour résoudre le problème, c'est-à-dire pour que vous puissiez effectuer l'étalonnage sans copier les valeurs dans les deux sens, nous avons besoin d'un moyen de capturer les données et de les transférer directement dans le tableau avec les valeurs de couleur. Mais seulement si nous sommes en mode d'étalonnage.
Il serait logique que l'étalonnage soit effectué au début du programme. Cependant, pas toujours, mais seulement si un bouton ou un interrupteur était pressé. La question est de savoir si l'étalonnage doit toujours être exécuté en mode direct, ou seulement une fois, par exemple après un redémarrage en appuyant sur un bouton. Je décide d'utiliser les deux boutons. Lorsqu'ils sont pressés ensemble et que vous démarrez l'Arduino, vous entrez dans le mode de calibration. Ensuite, vous pouvez passer en revue toutes les couleurs avec le premier bouton et scanner la couleur de référence pour chacune d'elles. Après cela, vous passez en mode normal comme d'habitude.
Nous avons besoin de nouvelles variables. Le mode d'étalonnage doit être défini comme un indicateur. Ensuite, je veux juste faire une boucle au début en attendant que les deux touches soient libérées. De plus, nous comptons nos numéros de couleur à partir de 0 pour pouvoir les scanner un par un. Pour la sortie formatée, j'utilise un tableau de chars comme dans le programme de calibrage séparé :
bool calibrés = false;
bool firstStart = vrai;
int calcounter = 0;
char serialBuffer [55];
Nous fixons toutes les valeurs de la matrice avec les valeurs de couleur sur 0:
int distinctRGB [num_of_colors] [3] = {0};
Au début du programme, c'est-à-dire dans la setup ()La fonction, nous reconnaissons le maintien simultané des deux palpeurs:
// doivent être calibrés si les deux tasters ont été étirés au démarrage
if (! digitalRead (TasterPin) & &! numérisalRead (TasterPin2)) {
calibrés = vrai;
}
Les broches des boutons sont faiblement actives et, en raison du double & logique, l'expression n'est vraie que si les deux ont l'état LOW. Ensuite, le drapeau, variable booléenne calibrer, est mis à true. Le mode d'étalonnage est alors actif.
Ma première pensée a été d'écrire une fonction où le calibrage a lieu. J'ai remarqué que je devais y copier une grande partie du code déjà écrit. Je suis alors arrivé à la conclusion que je n'avais pas du tout besoin de faire ça. J'ai juste besoin de distinguer à certains endroits dans mon code source existant si le mode d'étalonnage est actif ou non.
Dans ce mode, j'aimerais pouvoir changer la voix comme auparavant. Cependant, le mot pour la langue ne doit pas être édité lors du changement et je voudrais revenir au début du programme complet. Nous ajoutons donc le passage suivant à la fonction changeVoice() :
myDFPlayer.play (14 + voiceNumber * offsetVoice) ;
Serial.println ("Langue de la langue");
état = 1;
est modifié dans:
Serial.println ("Langue de la langue");
if (calibrés) {
état = 0;
}
else {
myDFPlayer.play (14 + voiceNumber * offsetVoice) ;
état = 1;
}
Partout où je fais la distinction entre le mode calibré et le mode normal, je place la partie précédente du programme dans la branche else des requêtes if. Si le drapeau de calibrage n'est pas activé, le programme fonctionne exactement comme avant. C'est pourquoi je fais toujours référence à la branche if dans ce qui suit.
Toutes les autres modifications ont maintenant lieu dans la fonction statemachine(). Dans le cas 0, nous distinguons si nous sommes en mode d'étalonnage ou non. Si c'est le cas, nous sortons le mot "calibrer" ou ses équivalents anglais. Nous distinguons maintenant si nous exécutons cette partie du programme pour la première fois (rappelez-vous, tout fonctionne en boucle infinie), ou non. Seulement la première fois, nous voulons voir si les deux boutons sont toujours enfoncés. Jusqu'à ce que les deux soient libérés, le programme tourne dans une autre boucle infinie à ce stade. Nous devons aussi débloquer le communiqué. Comme nous sommes au début du programme ici, je l'ai résolu avec un delay(), puisque nous n'avons pas besoin d'un flux ininterrompu ici. Nous mettons ensuite l'indicateur firstStart à false, afin que cette partie ne soit pas exécutée à nouveau. Parce que si on change la voix, on revient à cette affaire. J'ai choisi cela parce qu'après avoir changé la voix, je ne joue pas le mot pour la langue, mais le mot "Calibrer" avec la nouvelle voix :
case 0: {
if (calibrés) {
myDFPlayer.play (13 + voiceNumber * offsetVoice) ; // "Calibres". Ja
Serial.println ("Calibration.");
if (firstStart) {
while (! (lecture numérique (TasterPin) & & numérisalRead (TasterPin2))) {
// Serial.println ("relâchez les deux tasters") ;
}
// dirty realease debounce
// nonblocking n'est pas encore nécessaire ici
delay (prell_delay) ;
firstStart = false;
}
}
else {
myDFPlayer.play (1); // Jetez à la fin du démarrage
Serial.println ("Démarrage du programme.");
}
état = 1;
} break;
Le prochain cas que vous modifiez est le numéro 4. En mode normal, voici le mot "Scanne." - En mode Calibration, je veux que la couleur soit la suivante, que vous voulez. Pour donner la bonne couleur, nous avons besoin d'un décalage:
case 4: { // Examen initial
if (calibrés) {
myDFPlayer.play (FILEOFFSET + kalCounter + voiceNumber * offsetVoice) ;
Serial.println (colorNames [kalCounter]) ;
}
else {
myDFPlayer.play (3 + voiceNumber * offsetVoice) ;
Serial.println ("Scanne ...");
}
émis = false;
état = 5;
} break;
Le décalage est composé de plusieurs décalages partiels. FILEOFFSET déplace le compteur vers la première couleur, dans notre cas le rouge. Le kalCounter se déplace vers le nombre actuel, la couleur à scanner. La multiplication de voiceNumber et offsetVoice donne la voix que nous avons sélectionnée, comme d'habitude.
Le dernier changement a lieu dans le cas 6. Ici, nous avions initialement sorti la couleur que nous avions scannée. Nous voulons le stocker dans le tableau des couleurs en mode d'étalonnage. Le kalCounter indique le numéro de la couleur. Ici, il est incrémenté de 1 à chaque passage. Nous utilisons la lecture des valeurs de couleur unique du capteur à partir du programme pour l'étalonnage séparé. Là, il était déjà repris de l'exemple de la bibliothèque.
Lorsque toutes les couleurs sont passées, le kalCounter correspond au nombre de couleurs numofcolors. À ce stade, l'ensemble des valeurs de couleur est à nouveau transmis au moniteur série, le mode d'étalonnage est quitté et la machine d'état est réinitialisée au cas 0. Avec cela, le programme continue à fonctionner en mode normal et peut être utilisé comme avant :
case 6: { // Afficher la couleur
if (calibrer) {
distinctRGB[kalCounter][0] = tcs.colorRead('r');
distinctRGB[kalCounter][1] = tcs.colorRead('g');
distinctRGB[kalCounter][2] = tcs.colorRead('b');
Série.print(distinctRGB[kalCounter][0]);
Série.imprimer(" ");
Série.print(distinctRGB[kalCounter][1]);
Série.imprimer(" ");
Série.println(distinctRGB[kalCounter][2]);
kalCounter++;
if (kalCounter >= num_of_colors) {
pour (int n = 0; n < num_of_colors; n++) {
sprintf(serialBuffer, "- Rouge Vert Bleu: {%3d %3d %3d}",distinctRGB[n][0], distinctRGB[n][1], distinctRGB[n][2]);
Série.imprimer(colorNames[n]);
Série.println(serialBuffer);
}
calibrer = false;
état = 0;
pause;
}
}
autre {
myDFPlayer.jouer (tcs.closestColor(distinctRGB, distinctColors, num_of_colors) + FILEOFFSET + voiceNumber * offsetVoice);
Série.println("Couleur: ");
Série.println(colorNames[tcs.closestColor(distinctRGB, distinctColors, num_of_colors)]);
}
état = 3;
} pause;
Notre détecteur de couleur peut maintenant être calibré sans avoir à copier des valeurs du moniteur série et à les coller dans le code source. Tenez les cartes de couleur de référence prêtes, chargez le programme sur L'Arduino et maintenez les deux boutons enfoncés au démarrage du programme.
Code Source Complet: 3.3parlantDétecteur de couleurplusSprachen_LiveKalibrierung.ino
Enregistrer les données de façon permanente
La tâche suivante consiste à enregistrer quelque part les valeurs de couleur issues de l'étalonnage, car sinon elles seraient perdues après un redémarrage.
Il existe plusieurs solutions pour la mémoire. Des mémoires flash externes de conception I²C et SPI sont disponibles dans le commerce sous forme de cartes de dépannage. On peut aussi utiliser un module externe de carte micro SD et stocker les données sur une carte SD. De même, un module I²C-EEPROM externe serait concevable. La carte SD serait un peu surdimensionnée pour si peu de données. Une mémoire flash ou EEPROM externe augmenterait le coût, mais serait une solution en tant que plan B. L'interface I²C de l'Arduino Nano se trouve sur les broches A4 et A5. Nous pourrions mettre le deuxième bouton sur une autre broche, alors cela pourrait être réalisé.
Cependant, comme l'Arduino Nano possède une EEPROM embarquée, nous pouvons également l'utiliser. Il convient de noter que cette mémoire ne peut pas être écrite à l'infini (100 000 écritures). En revanche, la lecture est toujours possible.
Note : Dans la série de blogs "Arduino : Multi-IO et EEPROM" J'ai déjà travaillé sur ce sujet. Dans la partie 2, j'ai utilisé l'EEPROM interne.
Je suppose que nous n'avons pas besoin de calibrer souvent. C'est pourquoi j'opte pour cette solution.
Au moment où, dans le programme, toutes les couleurs ont été passées en mode d'étalonnage et où, une fois de plus, l'ensemble de la matrice de couleurs est sortie sur le moniteur série, nous voulons transférer les données vers l'EEPROM. Cela se produit dans le cas 6. Nous ajoutons avant ou après cette ligne :
calibrer = false;
nouvelle Ligne suivante:
L'EEPROM.mettre(0, distinctRGB);
La fonction put() nous permet de transférer des objets complets dans l'EEPROM. Seules les valeurs qui diffèrent sont écrasées. Nous écrivons le tableau complet avec les couleurs nouvellement scannées dans l'EEPROM en commençant par l'adresse 0.
C'était facile. Ce qui manque maintenant est la lecture de l'EEPROM lorsque l'Arduino est démarré. Mais seulement si le mode d'étalonnage n'est pas exécuté. Pour cela nous ajoutons dans setup() à la position :
// calibrer si les deux boutons sont enfoncés au démarrage
if (!digitalRead (bouton-poussoir) && !digitalRead (bouton-poussoir PIN2)) {
calibrer = true;
}
un autre- Ajouter une branche:
autre {
L'EEPROM.obtenir(0, distinctRGB); // Lire les données de L'EEPROM
pour (int n = 0; n < num_of_colors; n++) {
sprintf(serialBuffer, "- Rouge Vert Bleu: {%3d %3d %3d}",distinctRGB[n][0], distinctRGB[n][1], distinctRGB[n][2]);
Série.imprimer(colorNames[n]);
Série.println(serialBuffer);
}
}
Avec la fonction get(), nous lisons le tableau complet en commençant par l'adresse 0 et l'écrivons dans notre tableau de couleurs vide. Pour vérifier si cela a fonctionné, nous avons encore sorti les valeurs sur le moniteur série.
Code Source Complet: 3.4parlantDétecteur de couleurmultilingueLiveKal_EEPROM.ino
Chargez le programme sur l'Arduino, maintenez les deux boutons enfoncés et exécutez le mode de calibration une fois. Redémarrez ensuite l'Arduino via le bouton de réinitialisation sans appuyer sur les boutons. Vous verrez alors si les valeurs ont été chargées et si le détecteur de couleurs reconnaît vos couleurs.
Source de tension mobile
Si quelqu'un veut utiliser l'appareil, il ne veut certainement pas être dépendant de la prise de courant la plus proche. Je vais donc passer au fonctionnement sur batterie. Vous pouvez soit connecter un bloc de 9V directement au Vin de l'Arduino, car il y a un régulateur de tension intégré pour cela. Il est également possible de connecter une powerbank (qui peut ne pas s'éteindre si la charge est trop faible) ou la batterie Raspi au port USB.
Je voudrais utiliser une batterie LiPo (Lithium-Ion Polymère). Ils existent en différentes formes, tailles et capacités. J'utilise une batterie plate d'une capacité de 2000 mAh et d'une tension de 3,7V. Cette forme favoriserait la construction d'un boîtier plat. Je ne veux pas m'étendre sur la façon de calculer l'autonomie de la batterie maintenant.
Comme la tension d'alimentation externe de l'Arduino au niveau du Vin doit être d'au moins 7 V, nous avons besoin d'un convertisseur élévateur. Avec cela, nous régulons la tension à 9 V. Ça devrait aller. Pour pouvoir également charger la batterie, nous utilisons un module contrôleur de charge micro USB. Gerald Lechner montre comment connecter ces composants dans son blog "5V Battery Power Supply with 3.7 V LiPo Battery and Charge Controller". Une fois que nous avons connecté le voltmètre à la sortie Vout du convertisseur de tension, nous tournons le potentiomètre jusqu'à ce que nous atteignions 9V.
Remarque : il se peut que vous deviez tourner le potentiomètre très longtemps contre l'aiguille de l'horloge (comme si vous ouvriez un robinet d'eau) jusqu'à ce que la tension augmente. J'ai eu besoin de plusieurs tours et je soupçonnais déjà que l'appareil était défectueux.
Nous remplaçons maintenant la source de tension externe précédente (si vous en avez utilisé une) et connectons les connexions Vout du convertisseur élévateur à Vin ou GND de l'Arduino à la place. Je vous recommande d'ajouter un interrupteur à bascule entre Vin de l'Arduino et Vout du convertisseur. Ainsi, vous n'avez pas besoin de débrancher la batterie à chaque fois pour éteindre l'appareil. Dans l'image suivante, vous pouvez voir à nouveau le schéma complet :
Conclusion
Nous avons maintenant construit l'électronique d'un détecteur de couleur mobile, parlant et calibrable. Vous ne le faites fonctionner qu'avec deux boutons, un interrupteur et un potentiomètre. L'utilisation de vos propres couleurs est quelque peu limitée. Moins vous utilisez de couleurs, moins la pondération est précise. Un rouge foncé est alors parfois reconnu comme brun. Pour le contrôle du capteur de couleur j'ai finalement choisi la bibliothèque tcs3200. Il est également possible d'utiliser la bibliothèque MD_TCS230. Le code d'exemple est juste un peu plus étendu et vous devez compter sur la broche D5. C'est pourquoi j'ai décidé de cette façon.
Il est certainement encore possible de simplifier le code source. Le capteur de couleurs pourrait être mis en veille avec un délai d'attente pour prolonger la durée de vie de la batterie. Pour cela, vous pouvez régler le diviseur de fréquence sur LOW / LOW et la broche OE sur HIGH. Malheureusement, vous ne pouvez pas désactiver les quatre LED. Pour cela, il faudrait concevoir un circuit à transistors qui désactive complètement le capteur.
Un mot rapide sur le choix des broches numériques. Malheureusement, je n'ai pas encore trouvé de solution à ce problème. Si vous connectez le capteur de couleur et l'initialisez dans le programme, les résistances internes de pullup des broches D3, D9 et D13 ne fonctionnent plus. C'est pourquoi j'ai connecté les boutons poussoirs aux broches D12 et A5. Comme vous pouvez le constater, les broches analogiques peuvent être utilisées comme des broches numériques. J'ai fait des tests avec des résistances pull-down externes. Ça devrait fonctionner avec ça. Cependant, vous auriez à nouveau plus de composants et vous devriez modifier le code source. Si vous en trouvez la cause, n'hésitez pas à le signaler en commentaire.
Instructions d'utilisation
Mode d'étalonnage
Doit être effectuée lors de la première utilisation ou modification du boîtier.
- Maintenez les boutons 1 et 2 enfoncés et allumez l'appareil.
- Sortie audio "Calibrer" (augmenter le volume si nécessaire)
- Les couleurs sont données
- Tenez le scanner contre une surface de la couleur correspondante.
- Appuyer une fois sur le bouton 1
- L'information est produite
- Ensuite, appuyez et maintenez le bouton
- La couleur par défaut est la sortie
- Maintenez le capteur contre la surface colorée et relâchez le bouton.
- Appuyez à nouveau sur le bouton et maintenez-le enfoncé
- la couleur suivante est donnée
- Lorsque toutes les couleurs spécifiées ont été scannées, le son de départ est entendu.
- Le détecteur de couleurs fonctionne alors en mode de balayage normal
Mode de numérisation couleur
- Allumez l'appareil sans appuyer sur aucune touche
- Appuyez une fois sur le bouton 1
- La note est sortie
- Maintenez le bouton 1 enfoncé et maintenez-le sur la zone de couleur souhaitée.
- Bouton de libération 1
- La couleur est en sortie (augmenter le volume si nécessaire)
- Rescan sans préavis
- Appuyez sur le bouton et maintenez-le enfoncé, puis relâchez-le pour obtenir le résultat
Changer de voix
- Appuyez brièvement sur le bouton 2
- Changements de voix
- En mode balayage, la langue est sortie
- En mode d'étalonnage, l'indication du mode sonne
- Si la voix a été modifiée, il faut appuyer à nouveau brièvement sur le bouton 1 pour le balayage dans les deux modes.
- Remarques
- Ensuite, appuyez et maintenez le bouton 1
- La voix peut être changée à tout moment
Modification des fichiers de langue
- L'ordre de copie doit être respecté
- Changez les textes dans le tableau colorNames[] pour d'autres couleurs
- Lors de la modification du nombre de couleurs : modifier numofcolors, distinctColors, colorNames et offsetVoice
- En cas de modification du nombre de voix : change maxVoices
- Effectuer un nouvel étalonnage
Demovideo
Andreas Wolter
pour AZ-Delivery Blog