lundi 27 novembre 2017

Contrôle d'un moteur à courant continu avec MPLAB Xpress Evaluation Board

Faisons maintenant un peu de robotique avec le MPLAB Xpress Evaluation Board, un moteur à courant continu et un circuit intégré L293D.  Au besoin, vous pourrez facilement modifier ce projet pour contrôler simultanément deux moteurs à courant continu (plate-forme robotique).  De plus, rien ne vous empêche de remplacer le L293D par un autre circuit intégré comme, par exemple, le L298N.


Dans ce projet, l'utilisateur pourra contrôler la vitesse de rotation du moteur en tournant le potentiomètre intégré à la carte MPLAB Xpress Evaluation Board.  De plus, le sens de rotation du moteur s'inversera lorsque le bouton poussoir de la carte sera maintenu enfoncé.

Voici une courte vidéo montrant le dispositif en action:



Le circuit

Parce qu'il risque de consommer beaucoup de courant, le moteur ne doit pas être alimenté par la carte MPLAB Xpress Evaluation Board:  une alimentation externe est nécessaire.

Le MPLAB Xpress Evaluation Board contrôle les broches 1, 2 et 7 du L293D.  Le signal modulé en largeur d'impulsion (PWM) transmis à la broche 1 contrôlera la vitesse de rotation du moteur.  Lorsque la broche 2 sera soumise à une tension de 3,3 V pendant que la broche 7 sera à une tension nulle, le moteur tournera dans un sens.  Il tournera dans l'autre sens quand la tension de la broche 2 sera nulle, et que celle de la broche 7 sera de 3,3 V.



  • La broche 1 du L293D ("enable 1") est branchée à la sortie RA0 du MPLAB Xpress Evaluation Board.
  • La broche 2 du L293D ("input 1") est branchée à la sortie RA1 du MPLAB Xpress Evaluation Board.
  • La broche 3 du L293D ("output 1") est branchée à un des deux contacts du moteur.
  • La broche 4 du L293D (ou la broche 5, 12 ou 13)  (GND) est branché à une broche GND du MPLAB Xpress Evaluation Board et à la borne négative de l'alimentation du moteur.
  • La broche 6 du L293D ("output 2") est branchée à l'autre contact du moteur.
  • La broche 7 du L293D ("input 2") est branché à la sortie RA2 du MPLAB Xpress Evaluation Board.
  • La broche 8 du L293D ("Vs") est branchée à la borne positive de l'alimentation du moteur.
  • La broche 16 du L293D ("Vss") est branchée à la sortie 5 V du MPLAB Xpress Evaluation Board.

Les broches 9, 10, 11, 14 et 15 du L293D sont destinées à contrôler un deuxième moteur:  elle ne sont pas utilisées dans le présent projet.



Configuration avec MCC

Rendons-nous maintenant sur l'IDE en ligne MPLAB Xpress, et créons un nouveau projet.  Si vous ne savez pas comment procéder, vous devriez jeter un oeil sur ce précédent billet.

Vous accédez ensuite à MCC (MPLAB Xpress Code Configurator) et vous ajoutez trois éléments à votre projet:  ADCC, PWM6 et TMR4.  Ces trois éléments apparaîtront dans la zone "Project Resources" de MCC si vous cliquez deux fois sur leur nom dans la liste "Devices Resources".


Commençons par le réglage du timer TMR4, qui est nécessaire pour l'utilisation du module PWM6.  Cliquez sur TMR4 dans "Projects Resources", et réglez "Clock Source" à "FOSC/4".  Assurez-vous que "Enable Timer" est coché.


Réglons maintenant le générateur de modulation par largeur d'impulsion (PWM6) qui contrôlera la vitesse de rotation de notre moteur.  Après avoir cliqué sur PWM6 dans "Projects Resources", réglez "Select a Timer:" à "Timer4" et assurez-vous que "Enable PWM" est coché.


Cliquez maintenant sur "ADCC" dans la zone "Project Resources" afin de régler le convertisseur analogique-numérique qui sera associé au potentiomètre.  Cochez "Enable ADC", et réglez "Acquisition Count" à 1.


Cinq clics sont requis dans la zone des cadenas, dans le bas de la fenêtre de MCC:  la pin RA0 est assignée au PWM6, les pins RA1 et RA2 sont désignées comme sorties (output) GPIO, la pin RA4, qui est soudée au potentiomètre de la carte, est associée au convertisseur analogique-numérique (ANx) et la pin RA5, qui est soudée au bouton poussoir de la carte, est désignée comme une entrée (input) GPIO.


Finalement, un click sur "Pin Module" dans la zone "Project Resources" permet de modifier le nom de nos entrées/sorties.  Pour faciliter la programmation, les broches RA1 et RA2 s'appellent respectivement "sortie_1" et "sortie_2", la broche RA4 s'appelle "potentiometre" et la broche RA5 s'appelle "bouton".  J'ai décoché les cases "Analog" pour RA1 et RA2.


Il ne reste plus qu'à cliquer sur le bouton "Generate", et à retourner dans MPLAB Xpress.

Le script

Après tout ce qui a été configuré dans MCC, le programme à écrire dans  le fichier "main.c" est plutôt simple:  le rapport cyclique du signal PWM est réglé selon la position du potentiomètre.  L'état logique des sorties 1 et 2 (broches RA1 et RA2) est réglé de façon différente selon que le bouton est enfoncé ou non.



Yves Pelletier   (TwitterFacebook)

jeudi 23 novembre 2017

Afficheur 8 chiffres, 8 LEDs, 8 boutons TM1638 et STM32 Nucleo

J'ai déjà eu l'occasion de parler des modules d'affichage "LED and KEY", qui comportent 8 chiffres, 8 LEDs et 8 boutons poussoirs, le tout contrôlé par un circuit intégré TM1638: au cours des derniers mois, je les ai utilisés avec une carte Arduino, et ensuite avec un ATTiny85.

Cette fois-ci, j'en ai utilisé un avec une carte STM32 Nucleo (programmée sur mbed, comme d'habitude).

Le circuit

Les branchements sont un peu particuliers, puisque sur le module d'affichage, une seule broche est consacrée à l'envoi et à la réception des données, alors que sur la carte Nucleo, les données sont reçues par la broche MISO et envoyées par la broche MOSI.

Par conséquent, les broches MISO et MOSI de la carte Nucleo sont toutes les deux branchées à la broche DIO du module TM1638, en prenant soin, cependant, de placer une résistance de 1 kΩ entre MOSI et DIO.

  • Broche VCC du module afficheur:  sortie 3V3 du Nucleo
  • Broche GND du module afficheur:  broche GND du Nucleo
  • Broche STB du module afficheur:  broche CD/D10 du Nucleo
  • Broche CLK du module afficheur:  broche SCK/D13 du Nucleo
  • Broche DIO du module afficheur:  broche MISO/D12 et résistance de 1 kΩ - broche MOSI/D11 du Nucleo



Importation de la bibliothèque

Après avoir créé un nouveau projet dans mbed, on y importe la bibliothèque TM1638 par Wim Huiskamp.

Premier exemple:  affichage d'un nombre croissant

Ce premier script affiche un nombre entier qui augmente d'une unité à chaque demi seconde.



Deuxième exemple:  utilisation des boutons

Dans ce deuxième script, on affiche un numéro et on allume une LED chaque fois qu'un des 8 boutons est enfoncé.






À lire également:

Yves Pelletier
   (TwitterFacebook)

dimanche 19 novembre 2017

Nouveau Launchpad MSP430FR2433


Texas Instruments offre son nouveau modèle de MSP430 Launchpad au prix spécial de $4,30 jusqu'au 31 décembre 2017 , à la condition d'utiliser le code-coupon "NewMSP430LP" (le prix régulier est de $9,99).  De plus, en Amérique du Nord, la livraison est gratuite (j'ignore toutefois si c'est également le cas en Europe).

Puisque j'utilise depuis 6 ans mon vieux modèle MSP430G2 (basé sur le microcontrôleur MSP430G2553), je me suis dit que l'occasion était belle de renouveler un peu mon matériel.

Lorsqu'on compare le nouveau MSP430FR2433 avec l'ancien MSP430G2, quelques différences sautent aux yeux:
  • Une broche fournissant une tension de 5 V est maintenant disponible (auparavant, il fallait souder une broche supplémentaire près du connecteur USB).
  • Les broches ne sont pas disposées dans le même ordre qu'avant (par exemple, P1.5 se trouve là où se situait auparavant P1.1)
  • Il y a un bouton poussoir supplémentaire (donc deux boutons et deux LEDs) en plus du bouton "reset".
  • Un espace sur la carte est spécialement conçu pour accueillir un supercondensateur (non fourni) servant d'alimentation rechargeable.
  • Le microcontrôleur n'est pas amovible.
À gauche:  mon vieux Launchpad MSP430G2.  À droite, le nouveau launchpad MSP430FR2433

Lors de la première connexion de mon Launchpad MSP430FR2433 sur un ordinateur muni de Windows 7, j'ai été témoin d'une vaine tentative d'installer les pilotes de périphérique.


Pas de panique: j'ai pu constater un peu plus tard que les pilotes s'installent correctement lorsqu'on tente de programmer la carte.

Une visite sur TI Cloud Tools

On peut programmer le nouveau Launchpad MSP430FR2433 au moyen de Code Composer Studio, ainsi qu'avec sa version en ligne "CSS Cloud". Pour l'instant, il ne semble pas supporté par Energia.

Voyons voir ce qu'on peut faire au moyen de notre navigateur internet:  je me dirige donc vers la page "TI Cloud Tools".  Un volet situé à gauche de l'écran m'invite à installer le "Cloud Agent", constitué d'une extension pour le navigateur web, et d'une application à installer localement sur l'ordinateur.  
Cette combinaison permettra à la page web d'identifier la présence du Launchpad.




Suite à l'installation du Cloud Agent, la présence du Launchpad est correctement détectée, mais son ID et son numéro de série demeurent inconnus.  Ça ne semble pas avoir affecté le fonctionnement par la suite.




Pour tester le fonctionnement correct de la carte, on peut essayer une démonstration spécialement conçue à cette fin:  "out-of-box demo", qui affiche graphiquement dans une page web la température mesurée par le capteur interne du Launchpad.

Dans le coin inférieur gauche de la page, assurez-vous que la connexion a correctement été établie avec votre carte; si c'est bien le cas, vous devriez lire  "waiting for data...".


Vous devez alors programmer la carte au moyen du menu "File", "Program Device".  (Si ce menu n'est pas disponible, vous pouvez essayer de changer le port USB au moyen du menu "Options").



Si vos pilotes de périphérique sont toujours manquants, c'est à ce moment qu'on vous proposera de les installer.


En cliquant sur le bouton situé à gauche de la carte, les températures mesurées et mises en mémoire par la carte sont présentées à l'écran sous forme de graphique.  Ça donne une idée de ce qu'il est possible d'accomplir avec l'outil "GUI Composer".


J'ai aussi fait un essai rapide avec CSS Cloud (un simple clignotement de LED) et tout a fonctionné sans problème.

Il reste à espérer qu'il sera bientôt possible de programmer cette carte avec des sketches Arduino, grâce à Energia.

Yves Pelletier   (TwitterFacebook)

mardi 14 novembre 2017

Horloge temps réel (RTC) DS3231 et Arduino

Une horloge temps réel (ou RTC pour Real Time Clock) est un circuit intégré spécialement conçu pour permettre à un microcontrôleur de connaître en tout temps la date et l'heure.

Dans le passé, j'ai déjà eu quelques occasions d'utiliser le modèle DS1307, qui est conçu pour fonctionner à un niveau logique de 5 V.  Le DS3231 dont il est question aujourd'hui s'accommode aussi bien des niveaux logiques de 5 V ou de 3,3 V; il est donc facile de l'utiliser avec Arduino, Raspberry Pi, Nucleo, etc.

Je me suis donc procuré à très bas prix un module DS3231 sur eBay.  Côté face:  le circuit intégré, deux résistances pull-up de 4,3 kΩ pour la connexion I2C, et un condensateur pour stabiliser l'alimentation.


Côté pile:  5 connecteurs femelles pour l'alimentation du module et la communication I2C, et un espace prévu pour la pile qui permet à votre horloge de continuer de tenir le temps pendant que votre Arduino n'est pas alimenté.

Petite surprise:  mon module était vendu sans support pour la pile: on doit utiliser les deux connecteurs pour y souder un support de pile, ou encore bricoler son propre support de pile.


Avantage intéressant:  vous pouvez donc choisir vous-mêmes le modèle de pile de 3 V qui vous convient le mieux, plutôt qu'être obligé de vous procurer le modèle exact dont les dimensions correspondraient à un support de pile pré-installé.

En concordance avec mon tempérament pressé et peu perfectionniste, je me suis contenté de souder un court fil conducteur à chacun des deux connecteurs.  Sur la photo ci-dessous, le fil rouge est pour la borne positive de la pile, alors que le fil noir est pour la borne négative.  C'est important de ne pas inverser la polarité...


Ensuite, un petit bout de ruban gommé pour tenir les deux fils sur la pile, et voilà:  j'ai fabriqué mon support de pile!



Le circuit

Voyons maintenant comment brancher l'horloge à une carte Arduino Uno.

Le connecteur "+" du DS3231 se branche à la sortie 5 V de l'Arduino
Le connecteur "-" du DS3231 se branche à une des broches GND de l'Arduino
Le connecteur "D" (data) se branche à la broche A4 de l'Arduino*
Le connecteur "C" (clock) se branche à la broche A5 de l'Arduino*
Le connecteur "NC" (no connect) ne se branche nulle part!

* Attention: si vous utilisez un modèle d'Arduino autre que le Uno, les connecteurs réservés pour l'I2C ne sont pas nécessairement les mêmes.



Si par hasard vous vous interrogez sur la pertinence du connecteur "NC", c'est que ce module DS3231 a été spécialement conçu pour être inséré directement sur les broches GPIO du Rasbperry Pi.  Les broches du Raspberry Pi qui sont réservées à l'I2C sont adjacentes à une des sorties 3,3 V du Raspberry Pi (broches 1, 3 et 5), mais la masse est située sur la broche 9.  Le connecteur "NC" est donc là pour accueillir la broche 7, qui ne peut donc pas être utilisée.


Installation de la bibliothèque

Si ce n'est pas déjà fait, vous devez installer la bibliothèque RTCLib.  La version proposée par Adafruit est probablement la meilleure.

Résultats

Il s'agit ensuite d'ouvrir un des exemples fournis avec la bibliothèque:  la version d'Adafruit comporte un exemple intitulé "ds3231".  Si vous avez une autre version (probablement plus ancienne) de la bibliothèque, vous pouvez très bien utiliser l'exemple intitulé "ds1307", il devrait fonctionner sans le moindre problème.

Il ne reste plus qu'à modifier le sketch en fonction de vos besoins.



Yves Pelletier   (TwitterFacebook)

jeudi 9 novembre 2017

MPLAB Xpress Evaluation Board: utilisation d'une entrée analogique

Dans ce troisième tuto concernant l'utilisation du MPLAB Xpress Evaluation Board, nous allons utiliser le potentiomètre de la carte pour faire varier un signal analogique qui sera mesuré par le microcontrôleur.

(Dans les billets précédents, nous avons appris comment gérer les entrées et sorties, et comment acheminer des données de la carte vers l'ordinateur.)

Commençons donc par créer un nouveau projet dans l'IDE en ligne MPLAB Xpress (voir le premier billet de la série pour plus de détails sur la façon de procéder).

Ensuite, nous utilisons MCC (MPLAB Xpress Code Configurator) pour générer quelques fichiers qui faciliteront l'utilisation du convertisseur analogique-numérique.

Cliquons deux fois sur "ADCC" dans la zone "Device Resources" de MCC.


Le module ADCC est maintenant visible dans la zone "Project Resources".


La zone centrale de MCC montre les réglage du convertisseur analogique-numérique (ADC).   Il est important que "Enable ADC" soit coché.  Il est prudent de laisser une période d'horloge au convertisseur pour faire sa mesure (régler "Acquisition Count" à la valeur "1").  "Result Alignment" (right ou left) permet de déterminer dans quel sens (horaire ou antihoraire) il faut tourner le potentiomètre pour que la valeur analogique (située entre 0 et 1023) augmente ou diminue.


Sur la carte MPLAB Xpress Evaluation Board, le potentiomètre est relié à la broche RA4.  Pour cette raison, nous allons lier le convertisseur analogique-numérique à cette broche, en cliquant sur le cadenas de la colonne  "Port A, 4"  dans la ligne "ANx".



Si vous cliquez "Pin Module" dans la zone "Project Resources", vous pouvez voir les caractéristiques de cette pin (qui est, pour l'instant, la seule utilisée sur notre carte).  Par défaut, elle porte le nom "channel_ANA4", ce qui est très laid.  Appelons-la plutôt "potentiometre".



Notre ADC est maintenant configuré:  on peut cliquer sur le bouton "Generate" pour que les fichiers appropriés s'ajoutent à notre projet.

Pour lire l'état du potentiomètre à l'intérieur d'un programme, il s'agira d'utiliser "ADCC_GetSingleConversion(potentiometre)".

Que faire avec cette valeur?  Je vous propose deux options:  la faire apparaître à l'écran de votre ordinateur, ou l'utiliser pour contrôler la luminosité d'une LED.

Exemple 1:  Affichage d'un signal analogique à l'écran de l'ordinateur

Pour que votre programme puisse transmettre des données à l'ordinateur par l'entremise du câble USB de la carte, vous devez configurer l'EUSART dans MCC.  Pour ce faire, suivez les instruction énumérées dans mon billet précédent:  Communication série avec un ordinateur.



En plus du module ADCC, votre projet comporte maintenant un module EUSART.  Vous n'avez pas oublié de cocher les cases "Enable Transmit" et  "Redirect STDIO to USART", en plus d'assigner TX et RX aux pins RC0 et RC1.

On clique sur le bouton "Generate" pour mettre à jour les fichier de notre projet.

De retour dans l'IDE MPLAB Xpress, on écrit notre programme (minimaliste!) dans le fichier "main.c":




On peut ensuite ouvrir notre programme de communication série préféré (ici, le moniteur série de l'IDE Arduino) pour observer le résultat à l'écran:


Le traceur série de l'IDE Arduino donne aussi des résultats intéressants:


Exemple 2: luminosité d'une LED contrôlée par le potentiomètre

Une autre option consiste à utiliser l'état du potentiomètre pour contrôler la luminosité d'une des 4 LEDs de la carte.

Dans MCC, en plus du module ADCC (convertisseur analogique-numérique), nous aurons besoin d'un module PWM (modulation par largeur d'impulsion) ainsi que d'un module timer, nécessaire au fonctionnement du module PWM.

En supposant que votre module ADCC a déjà été ajouté et configuré (si ce n'est pas le cas, retournez au début de ce billet pour effectuer les réglages nécessaires), vous ajouter les modules "PWM6" et "TMR4".


Dans la zone des cadenas, nous assignons le signal PWM à l'une des LEDs de la carte (pin RA0):


Cliquez sur "PWM6" dans la zone "Project Resources" afin de modifier les paramètres du module PWM.  Dans "Select a Timer", sélectionnez "Timer4".


Cliquez sur "TMR4" dans la zone "Project Resources"  pour modifier les paramètres du timer.  Dans "Clock Source", choisissez "FOSC/4".


Vous cliquez sur le bouton "Generate" afin que ces réglages soient transmis à l'IDE en ligne MPLAB Xpress.

Le programme à écrire dans le fichier "main.c" ne comporte qu'une modeste ligne de code:  il s'agit d'assigner au PWM6 (associé à notre LED) le résultat de notre convertisseur ADC (associé au potentiomètre).



Après avoir téléchargé ce programme dans la carte, vous pouvez constater que, tel que prévu, la luminosité de la LED "D2" sur la carte varie lorsque vous tournez le bouton du potentiomètre.

Sources:

Pour la rédaction de ce billet, j'ai consulté cette vidéo et ce tuto mis en ligne par Microchip.


Yves Pelletier   (TwitterFacebook)

dimanche 5 novembre 2017

Robot à base de moteurs pas à pas (Arduino)

Pour le roboticien amateur, la plate-forme robotique la plus répandue est constituée de deux (ou quatre) moteurs à courant continu.  Je propose ici une version similaire, facile à construire soit-même, mais constituée de deux moteurs pas à pas.

La raison?  Après avoir démonté quelques vieilles imprimantes, je me retrouve avec un impressionnant stock de moteurs pas à pas:  il faut bien que je les utilise pour quelque chose! De plus, un moteur pas à pas peut être contrôlé avec une meilleure précision qu'un moteur à courant continu muni d'une boîte d'engrenages.

Des inconvénients?  Vous aurez besoin de deux L293D ou L298N plutôt qu'un seul, ce qui accaparera 8 sorties de votre microcontrôleur (une carte Arduino, en l'occurence) et la programmation est peut-être légèrement plus complexe qu'avec des moteurs à courant continu.

Choix des moteurs

Le premier défi, si vous utilisez comme moi du matériel de récupération, c'est de trouver deux moteurs identiques.  Ce qui est surtout important, pour des raisons de symétrie, c'est que vos deux moteurs comportent le même nombre de pas par tour. Dans mon cas, mes deux moteurs n'avaient pas le même numéro de modèle, mais ils comportaient tous les deux 200 pas par tour.

Il faut aussi prendre garde de choisir des moteurs qui offrent un couple suffisant pour faire avancer le véhicule.  Mon premier prototype utilisait une paire de moteurs beaucoup plus petits, qui fonctionnaient à merveille en absence de charge, mais qui étaient tout simplement incapables de faire avancer le véhicule!

Roues

Puisque mon but était d'utiliser autant que possible du matériel récupéré, j'ai utilisé deux couvercles (ils avaient servi à fermer des bocaux d'arachides). Leur diamètre doit être plus grand que celui du moteur (j'avais choisi mes roues en fonction de moteurs plus petits que ceux que j'ai finalement utilisés.  Résultat:  la plate-forme est vraiment très proche de la surface du plancher.)  J'ai ajouté une bande élastique autour de chaque roue afin d'améliorer l'adhérence.

J'ai fixé chaque roue à son moteur en utilisant un peu de colle epoxy.



Plateforme

Là aussi, pas de dépense inutile:  un bout de planche de bois, une plaque de plastique... Pourvu que ce soit rigide, avec une surface suffisante pour supporter l'Arduino, les piles, les pilotes de moteur et les capteurs...  J'ai utilisé un petit panneau d'aggloméré issu d'une caisse de clémentines du Maroc.

Chaque moteur-roue est fixé à l'arrière de la plate-forme au moyen de colliers de serrage en plastique, et on ajoute une petite roue à l'avant (la mienne vient d'une imprimante, probablement).

Dessous de la plate-forme

Dessus de la plate-forme


Le circuit

Module L298N
Ce premier prototype ne comporte pas de capteurs:  nous nous contenterons de le faire bouger selon une routine pré-établie.

Le circuit est constitué d'une carte Arduino, de deux modules L298N (des L293D auraient fait l'affaire aussi) et de 8 piles AA (12 V au total).

La présence d'un interrupteur est particulièrement pratique pour éviter que votre robot ne se mette en mouvement pendant que vous reprogrammez l'Arduino...

L'Arduino est alimenté au moyen de la sortie 5 V d'un des modules L298.

Des cavalier (jumpers) sont en places pour que les pins "enable" des modules L298N soient à 5 V (en absence de cavaliers, il faut brancher les 4 pins enable à 5 V).



L298N de gauche:

+12V:  12 V
GND:  GND de l'Arduino et borne négative de l'alimentation 12 V
5 V:  VIN de l'Arduino (pour alimenter ce dernier)
ENA:  5 V
IN1:  Arduino 4
IN2: Arduino 5
IN3: Arduino 6
IN4: Arduino 7
ENB: 5 V

L298N de droite:

+12V:  12 V
GND:  GND de l'Arduino et borne négative de l'alimentation 12 V
ENA:  5 V
IN1:  Arduino 8
IN2: Arduino 9
IN3: Arduino 10
IN4: Arduino 11
ENB: 5 V

Prenez soin de relier ensemble toutes les masses:  borne négative de la source de tension, GND de l'Arduino et GND de chaque module L298 N.

Exemple de sketch

Grâce au sketch ci-dessous, le robot avance en ligne droite pendant 2 secondes, tourne sur lui-même pendant 2 secondes, puis recule en ligne droite pendant 2 secondes.

Notez que la fonction "setSpeed" de la bibliothèque "Stepper" ne permet pas de régler les deux moteurs à des vitesses différentes l'un de l'autre.  C'est pourquoi je ne l'ai pas utilisée.



Vidéo du robot en action



Nous devrions pourvoir y ajouter des capteurs pour en faire un véhicule téléguidé, un suiveur de ligne, un éviteur d'obstacles, un chercheur de lumière, un longeur de mur, etc.

Yves Pelletier   (TwitterFacebook)