
Le croquis est l'un des éléments les plus importants du environnement de programmation IDEPar conséquent, si vous souhaitez devenir un véritable expert, il est nécessaire de connaître la structure des croquis.
Vous trouverez ces informations dans les paragraphes suivants. Nous allons vous expliquer en détail ce qu'est un Sketch et à quoi servent ces programmes. Également Nous allons montrer toutes les parties d'un Code Arduino.
Nous vous invitons à poursuivre votre lecture jusqu'au bout, car vous y trouverez des informations sur Exemples de croquis que vous pouvez utiliser Pour apprendre à programmer. Jetez un coup d'œil.
Qu'est-ce qu'un croquis Arduino et à quoi servent ces programmes ?
Vas SI A créer un projet avec une carte Arduino Vous devrez non seulement utiliser les broches pour connecter les différents éléments de la carte, mais aussi les broches pour relier les différents éléments de la carte.Vous aurez besoin des circuits et du matériel souhaités. Il vous faudra également programmer votre modèle Arduino pour qu'il puisse émettre des signaux électroniques et que le projet puisse progresser. Par exemple, si vous créez un robot, la première étape consistera à réaliser correctement les connexions nécessaires. Mais cela ne vous aidera absolument pas car le robot restera immobile..
Pour ce que Vous devrez programmer leurs mouvements pour que le projet ait du sens. Pour faire bouger le robot, en reprenant l'exemple, vous devez configurer la carte Arduino dans l'environnement IDE. Ce logiciel utilise un langage spécifique et divise chaque projet en un programme (Sketch). Un croquis Arduino est un programme dans lequel tout le code est stocké. qui servent à faire exécuter certaines tâches à la carte.
Si vous trouvez un fichier avec l'extension .ino, cela signifie qu'il s'agit d'un croquis.Pour que cela fonctionne correctement, vous devez garder à l'esprit le nom du dossier dans lequel il se trouve. enregistrer le croquis Il doit être inclus dans un répertoire portant le même nom que le Esquisser.
Vous pouvez enregistrer un programme de Arduino dans différents fichiers, mais ces dossiers doivent toujours se trouver dans le même répertoire que le fichier principal. Enfin, il faut garder à l'esprit que Un programme se compose de deux instructions : l’une appelée loop() et l’autre setup().La première est chargée d'exécuter les instructions du programme de manière cyclique, ou en boucle, tandis que la seconde est l'instruction utilisée pour effectuer la configuration.
Structure d'un croquis : Quelles sont les différentes parties d'un code Arduino ?
Comme nous l'avons mentionné précédemment setup() et loop() font partie d'un croquisMais ce ne sont pas les seuls éléments que l'on peut trouver dans un programme de Arduino.
Vous trouverez ci-dessous toutes les parties du code d'une carte électronique que vous pouvez utiliser dans l'IDE :
Structure
Analyse plus approfondie de la structure du croquis, on peut dire que La fonction setup() est utilisée pour démarrer un programme.initialisation des bibliothèques, des variables et de l'utilisation des broches de la carte, entre autres. Il est utilisé à chaque fois que l'Arduino est allumé ou redémarré. Par conséquent, il ne doit être écrit qu'une seule fois et au début du code.
En voici un exemple :
int buttonPin = 5; void setup() { begin(9600); pinMode(buttonPin, INPUT); } void loop() { // ... }
L'autre composant qui constitue le Sketch est la boucle loop(). Ce document ou cette instruction est utilisé après la création du configuration () pour Spécifiez les valeurs initiales que prendra une fonction donnée. Cela facilite grandement le contrôle de la carte à chaque utilisation de ces boucles.
Son utilisation est la suivante :
int buttonPin = 5; // Initialisation de la communication série et de la broche du bouton void setup() { begin(9600); pinMode(buttonPin, INPUT); } // Contrôle de la broche 5, // En cas d'appui, un signal est envoyé via la liaison série void loop() { if (digitalRead(buttonPin) == HIGH) { write('H'); } else { write('L'); } delay(1000); }
Comme on peut le constater dans les exemples précédents, d'autres comparateurs sont utilisés., par conséquent la structure d'un Croquis Il peut également être subdivisé en davantage de variables.
Ces composants comprennent :
- Contrôle: utilisé pour établir des conditions ou exécuter une procédure spécifique. Ce groupe comprend pause; continuer; do... tout en; pour; goto; if; if...d'autre; retourner; boîtier de commutateur y tout en.
- Arithmétique: Ces fonctions doivent être utilisées lorsque vous devez programmer une opération mathématique de base dans l'environnement de Arduino. Ces acheteurs sont =; +; -; /; * y %.
- Syntaxe: Ils permettent d'insérer des commentaires sur une ou plusieurs lignes, ainsi que de nommer une valeur constante ou de l'inclure dans la compilation d'un programme. Ils sont utilisés dans ce cas. #define; #comprendre; {}; point-virgule (;); // pour les commentaires d'une seule ligne à côté du code et / * * / Ouvrir et fermer un commentaire multiligne.
- Booléens : Lorsque vous devez introduire une variable logique, vous devez utiliser ces opérateurs dans l'EDI. Il s'agit notamment des suivants : || (ou); && (et) et ! (pas).
- À titre de comparaison : Cette sous-catégorie est l'une des plus utilisées en programmation. Comme son nom l'indique, elle sert à comparer une condition et à renvoyer un résultat pour poursuivre la procédure. Ce groupe utilise… = = (égal à); > (supérieur à); >= (supérieur ou égal à); < (moins que); <= (inférieur ou égal à) et != (différent de).
- Composés : Ces opérateurs sont utilisés dans une structure d'esquisse lorsqu'une combinaison d'autres composants est nécessaire. Autrement dit, ils ont une double fonction. Par conséquent, ils peuvent être utilisés &= (et composite bit par bit) ; - (diminuer); /= (division par méthode composite) ; ++ (augmenter); %= (module composite) ; *= (multiplication composée); |= (ou composite bit par bit) ; -=(soustraction composée) et += (somme composite).
- Petit à petit: Les opérateurs bit à bit fonctionnent avec les nombres binaires, établissant une relation selon une règle spécifique. Les opérateurs utilisés sont : >> (aller à droite); << (aller à gauche) ; ~ (pas bit par bit) ; | (ou petit à petit); ^ (XOR bit à bit) et & (et petit à petit).
- Accès au pointeur : * y & Voici les opérateurs que vous pouvez utiliser dans ce groupe.
Valeurs
Dans cette section Cela inclut les constantes, les qualificateurs, la portée et les types de données. qui sont utilisées pour programmer une carte Arduino.
Les variables peuvent être divisées en :
- Constantes : Ces informations facilitent la lecture du langage de la carte. Elles indiquent les valeurs que peut prendre une broche ainsi que son mode de configuration (entrée ou sortie). Les plus courantes sont : non; constantes à virgule flottante; HAUTE; BASSE; CONTRIBUTION; INPUT_PULLUP; constantes entières; LED_BUILTIN; SORTIE y oui.
- Classes de données : Lorsque vous devez spécifier dans un langage de programmation le type de données que vous manipulez, vous devez utiliser ce groupe. Par conséquent, les éléments suivants peuvent être regroupés dans cette catégorie : tableau; booléen; octet; carboniser; double; flotter; int; Long; court; string (sous forme de tableau de caractères) ; string (Objet); caractère non signé; entier non signé; non signé long; annuler y mot.
- Utilisations : Cette catégorie de variables permet au programme de renvoyer un nombre précis d'octets à partir d'un tableau. Elle peut donc être saisie dans l'IDE. PROGRAMME y taille de.
- Conversation: Les variables de ce groupe convertissent une valeur en un type de données spécifique. octet; carboniser; flotter; int; Long y mot.
- Qualificatifs de portée : Ces variables permettent de modifier le comportement de la variable elle-même. Elles indiquent notamment si elle est en lecture seule ou globale. Les plus courantes sont : const; statique; portée variable y volatile.
fonctions
Dans le langage utilisé dans le code ArduinoLa section des fonctions est la partie destinée à indiquer au programme le type d'action qu'une variable doit effectuer.
Ils peuvent être divisés :
- Entrée et sortie : Ces composants sont utilisés lorsqu'il est nécessaire de diriger le courant ou la forme d'onde reçue par la plaque. noTone; pulseIn; pulseInLong; décalage; shiftOut y poix.
- Temps: Dans le code, ces composants peuvent servir à indiquer une action temporelle, par exemple le nombre de millisecondes pendant lesquelles l'argent doit attendre avant qu'une action ne soit effectuée. C'est ainsi que ces composants sont utilisés. retarder; délaiMicrosecondes; micros y militaires.
- Numérique : Ceci permet de configurer les entrées et sorties des broches numériques de la carte. Il est donc possible d’y trouver les fonctions. digitalRead; numériqueÉcrire y PinMode.
- Analogue: Comme les fonctions précédentes, ces actions servent à configurer les broches analogiques d'une carte Arduino. De ce fait, vous pourriez rencontrer les problèmes suivants : lecture analogique; Écriture analogique y Référence analogique (PWM). Mais lorsque vous utilisez un modèle Arduino DEUX ou Arduino ZERO Vous devrez saisir les fonctions résolution de lecture analogique y résolution d'écriture analogique pour travailler.
- Matematiques: Ces fonctions permettent d'effectuer des calculs mathématiques directement dans le code du programme. Les plus couramment utilisées sont : Abdos; contraindre; plan; max; min; pow y sqrt.
- interruptions : Ces fonctions permettent d'activer ou de désactiver un processus spécifique. Ce groupe comprend : interruptions y noInterruptsToutefois, si une interruption externe est nécessaire, celles utilisées sont : attachInterrupt y détacherInterrupt.
- Bits et octets : Ces outils de programmation servent à indiquer que des bits ou des octets doivent être extraits d'une variable. Par conséquent, les fonctions généralement utilisées sont : bit; bitEffacer; bitRead; bitSet; bitWrite; highByte y octet faible.
- Communication: Ce groupe est l'un des plus utilisés en programmation IDE, car il permet à la carte Arduino de communiquer avec un ordinateur ou tout autre matériel. Voici les fonctions disponibles : Port série y Discussions.
- Nombres aléatoires : Ces fonctions permettent de générer des nombres afin de créer une séquence toujours identique. Celles qui appartiennent à ce groupe sont : graine aléatoire y aléatoireMais lorsque vous travaillez avec des modèles EN RAISON y ZÉRO Si vous devez connecter une souris et un clavier à un système 32u4, les fonctions que vous utiliserez sont : Clavier y Souris.
Apprenez étape par étape comment programmer un simple sketch pour votre projet Arduino
Dans cette section Nous mettrons en pratique tout ce qui a été exposé dans les paragraphes précédents.Par conséquent, vous devez être attentif et, si pour une raison quelconque vous avez commis une erreur, nous vous recommandons de recommencer les étapes afin de ne pas reproduire l'erreur.
Voici la procédure à suivre pour programmer un projet Arduino simple :
Commentaires
Les commentaires Il s'agit de toutes les annotations ajoutées au code pour expliquer le fonctionnement du programme, identifier l'auteur ou expliquer pourquoi une fonction est utilisée plutôt qu'une autre. Il existe deux types de commentaires : les commentaires multilignes et les commentaires multilignes. (qui se trouvent parmi les symboles /* y */) et la ligne seule (qui sont représentés par l'utilisation de //Il faut garder à l'esprit que Les commentaires ne font pas partie du programme. et est donc ignorée par Arduino.
En voici un exemple :
/* Internet Paso a Paso L'exemple pour Arduino consiste à allumer une LED pendant une seconde, puis à l'éteindre, créant ainsi une boucle. La broche 13 est utilisée, car elle est courante sur la plupart des cartes équipées d'une LED. Une résistance, intégrée à l'Arduino, est également nécessaire.
Variables
Les variables sont composées de un type, un nom et une valeur. Elles servent à permettre, à chaque fois que le nom de code est saisi, de récupérer la valeur de la variable.
Par exemple, si dans le programme créé pour allumer et éteindre une LED connectée à la broche 13 de la carte, vous devez écrire :
int ledPin = 13 ;
Cela signifie que le nom de la variable a été créé. LEDPin Pour modifier la valeur (si nécessaire ultérieurement), le type est int et sa valeur est 13.
fonctions
Il ne faut pas oublier ça Les fonctions sont des actions qui sont introduites pour que l'on variable effectue une procédure spécifique.
Voici comment vous devez vous connecter au logiciel que vous programmez :
void setup() { pinMode(ledPin, OUTPUT); // pour indiquer une sortie sur une broche numérique }
ligne configuration () Elle affiche les données du type de fonction, le type de retour que le code aura. annuler y (), tandis que le corps de la fonction est { pinMode(ledPin, OUTPUT); // pour indiquer une sortie sur une broche numérique }On trouve à l'intérieur de ce corps PinMode Cette fonction indique que les paramètres LEDPin y SORTIE Elles doivent transiter par une broche numérique en tant que sortie (c'est pourquoi cela est précisé dans le commentaire). // pour indiquer une sortie sur une broche numérique).
pinMode(), digitalWrite() et delay()
Ces fonctions fournissent des instructions spécifiques à la commande, vous devrez donc les connaître toutes :
- pinMode() : Ceci permet de déterminer si une broche de la carte Arduino fonctionnera comme entrée ou sortie du circuit. En entrée, le connecteur détectera un capteur ; en sortie, il s'agira d'un actionneur (dans l'exemple que nous développons, la LED).
- digitalWrite() : Cette fonction permet de définir la valeur d'une broche. Elle est directement liée à HAUTE y FAIBLE, Ces indicateurs permettent de configurer le type de tension. Par exemple, pour régler la fonction pinMode sur 5 V, saisissez… digitalWrite (ledPin, HAUT);S'il doit fonctionner à 0 volt, vous devez écrire digitalWrite(ledPin, BAS);.
- retard(): Cette fonction permet de retarder l'exécution du processus avant de passer à la ligne de code suivante. Elle est exprimée en millisecondes ; ainsi, la valeur 1000 représente une seconde. Son utilisation est : délai (1000);.
Configuration () et Boucle ()
Nous en avons déjà parlé. configuration () Il s'agit de la fonction permettant de configurer les options au sein d'un code, mais cet outil n'est pas le seul à utiliser fréquemment lors de la programmation d'une carte. Arduino. Il est aussi boucle()Cette fonctionnalité vous permet de surveiller le tableau en continu. Vous pouvez ainsi vérifier que vous êtes sur la bonne voie et que les fonctions ajoutées fonctionnent comme prévu.
Voici un exemple d'utilisation des fonctions setup() et loop() :
int buttonPin = 3; // Cette configuration initialise la communication série et la broche. void setup() { begin(9600); pinMode(buttonPin, INPUT); } // Cette boucle sert à vérifier l'état du bouton et à envoyer un signal série à chaque pression. // Le délai est de 1 seconde. void loop() { if (digitalRead(buttonPin) == HIGH) { write('H'); } else { write('L'); } delay(1000); }
Exemples de programmes Arduino pour vous aider à apprendre à programmer les vôtres
Ce que vous verrez ensuite Cela vous aidera à vous entraîner seul différent des projets
Portez attention aux détails et répétez-les encore et encore afin de bien comprendre l'ensemble du processus :
Clignement de l'esquisse
Ce projet vous aidera à faire clignoter une LED intégrée à une carte Arduino.qui comprend la plupart des modèles de cartes mères. Dans la version UNO, Yun Et Zero, la broche utilisée est la numéro 13, alors que dans le MKR1000 (par exemple), c'est la broche numérique 6.
Le code que vous utiliserez est :
void setup() { pinMode(ledPin, OUTPUT); } { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); }
Robot qui évite les obstacles
Dans ce projet, nous allons vous montrer le flux de processus à prendre en compte lors de la programmation, à juste titre, un dispositif qui évite les obstacles. Le diagramme que nous vous montrons dans la figure suivante Cela vous aidera à mieux comprendre le processus.
Le code du projet ressemblera à ceci :
#inclure #inclure #inclure #define TRIG_PIN A4 #define ECHO_PIN A5 #define MAX_DISTANCE 200 #define MAX_SPEED 190 #define MAX_SPEED_OFFSET 20 NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); AF_DCMotor motor1(1, MOTOR12_1KHZ); AF_DCMotor motor2(3, MOTOR12_1KHZ); Servo myservo; boolean goesForward=false; int distance = 100; int speedSet = 0; void setup() { attach(9); write(115); delay(2000); distance = readPing(); delay(100); distance = readPing(); delay(100); distance = readPing(); delay(100); } void loop() { int distanceR = 0; int distanceL = 0; délai(40); si(distance<=15) { déplacerStop(); délai(100); déplacerReculer(); délai(300); déplacerStop(); délai(200); distanceD = regarderDroite(); délai(200); distanceG = regarderGauche(); délai(200); si(distanceD>=distanceG) { tournerDroite(); déplacerStop(); }sinon { tournerGauche(); déplacerStop(); } }sinon { avancer(); } distance = lirePing(); } int regarderDroite() { écrire(50); délai(500); int distance = lirePing(); délai(100); écrire(115); retourner distance; } int regarderGauche() { écrire(170); délai(500); int distance = lirePing(); délai(100); écrire(115); retourner distance; délai(100); } int lirePing() { délai(70); int cm = sonar.ping_cm(); if(cm==0) { cm = 250; } return cm; } oid moveStop() { run(RELEASE); run(RELEASE); } void moveForward() { if(!goesForward) { goesForward=true; run(FORWARD); run(FORWARD); for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) { setSpeed(speedSet); setSpeed(speedSet+MAX_SPEED_OFFSET); delay(5); } } } void moveBackward() { goesForward=false; run(BACKWARD); run(BACKWARD); for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) { setSpeed(speedSet); setSpeed(speedSet+MAX_SPEED_OFFSET); delay(5); } } void turnRight() { run(FORWARD); run(BACKWARD); délai(300); courir(AVANT); courir(AVANT); } void tournerGauche() { courir(ARRIÈRE); courir(AVANT); délai(300); courir(AVANT); courir(AVANT); }
Système de contrôle d'accès utilisant la lecture de cartes RFID
Il est tout d'abord important de définir ce qu'est une carte RFID. Il s'agit d'un appareil fonctionnant par radiofréquence et servant à transmettre des informations permettant d'identifier un objet ou de communiquer des données spécifiques à son sujet. Il peut donc avoir des applications pratiques. une carte arduino créer un lecteur permettant de contrôler l'accès des utilisateurs.
Après avoir mis en pratique les deux projets précédents, vous pourrez programmer cela Croquis un peu plus complexe. À cause de cela Nous allons d'abord vous présenter l'organigramme des opérations. afin que vous puissiez accomplir votre tâche sans erreurs. Ce que vous devez faire maintenant, c'est écrire ces codesCes résultats ne sont pas définitifs, mais ils vous aideront à comparer les données que vous avez saisies. Environnement Arduino IDE.
Pour ce faire, vous devrez écrire :
#inclure #inclure #define RST_PIN 9 #define SS_PIN 10 MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { begin(9600); while (!Serial); begin(); PCD_Init(); delay(4); PCD_DumpVersionToSerial(); println(F("Scan PICC pour afficher l'UID, le SAK, le type et les blocs de données...")); } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } if ( ! mfrc522.PICC_ReadCardSerial()) { return; } PICC_DumpToSerial(&(mfrc522.uid)); }
Ce que vous devrez faire maintenant, c'est changer le mot de passe d'un secteur utilisant Clé A : A0 A1 A2 A3 A4 y Clé B : B0 B1 B2 B3 B4.
Vous devrez écrire :
#inclure #inclure #define RST_PIN 9 #define SS_PIN 10 MFRC522 mfrc522(SS_PIN, RST_PIN); MFRC522::MIFARE_Key keyA = {keyByte: {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; MFRC522::MIFARE_Key keyB = {keyByte: {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; // Nouvelles clés pour le chiffrement MFRC522::MIFARE_Key newKeyA = {keyByte: {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}}; MFRC522::MIFARE_Key newKeyB = {keyByte: {0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5}}; // Données du secteur auquel appartient l'utilisateur autorisé byte sector = 15; void showByteArray(byte* buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { print(buffer[i] < 0x10 ? " 0" : " "); print(buffer[i], HEX); } } void setup() { begin(9600); while (!Serial); begin(); PCD_Init(); println(F("Approchez la carte du lecteur.")); println(F("Les clés de cette carte doivent être :")); print("Clé A : "); showByteArray(keyA.keyByte, MFRC522::MF_KEY_SIZE); println(); print("Key-B: "); showByteArray(keyB.keyByte, MFRC522::MF_KEY_SIZE); println(); println(F("TRÈS IMPORTANT : pendant le processus de mise à jour de la clé ")); println(F("Ne retirez pas la carte du lecteur avant la fin de l'opération.")); } void loop() { // S'il n'y a pas de carte à utiliser, le programme ne progresse pas if (!mfrc522.PICC_IsNewCardPresent()) { return; } if (!mfrc522.PICC_ReadCardSerial()) { return; }
Ensuite, vous devrez programmer les informations pour qu'elles apparaissent sur le moniteur série :
print(F("UID de la carte :")); displayByteArray(mfrc522.uid.uidByte, mfrc522.uid.size); println(); print(F("Type de carte : ")); MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); println(mfrc522.PICC_GetTypeName(piccType)); boolean result = changeKeys(&keyA, &keyB, &newKeyA, &newKeyB, sector); if (result) { print(F("Clés de secteur ")); println(sector); print(F("Clé A : ")); showByteArray(newKeyA.keyByte, MFRC522::MF_KEY_SIZE); println(); print(F("Clé B : ")); showByteArray(newKeyB.keyByte, MFRC522::MF_KEY_SIZE); println(); } else { print(F("Clés de secteur ")); println(sector); print(F("Clé A : ")); showByteArray(keyA.keyByte, MFRC522::MF_KEY_SIZE); println(); print(F("Clé B : ")); showByteArray(keyB.keyByte, MFRC522::MF_KEY_SIZE); println(); } // Authentification à l'aide de la clé Key-A status = (MFRC522::StatusCode)mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, blockTrailer, oldKeyA, &(mfrc522.uid)); // Si l'authentification échoue, ne pas continuer if (status != MFRC522::STATUS_OK) { print(F("Échec de l'authentification Clé-A : ")); println(mfrc522.GetStatusCodeName(status)); return false; } // Afficher le secteur complet de l'utilisateur print(F("Informations dans le secteur : ")); PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), oldKeyA, sector); println(); // Lecture des données du bloc print(F("Lecture des données du bloc ")); Serial.print(blockTrailer); println(" ...")); status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockTrailer, buffer, &size); if (status != MFRC522::STATUS_OK) { print(F("Échec de la lecture du bloc : ")); println(mfrc522.GetStatusCodeName(status)); return false; } print(F("Information dans le bloc ")); Serial.print(trailerBlock); Serial.println(F("":")); showByteArray(buffer, 16); Serial.println(); println(); // Authentification avec la clé B status = (MFRC522::StatusCode)mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, oldKeyB, &(mfrc522.uid)); // En cas d'échec de l'authentification, ne pas continuer if (status != MFRC522::STATUS_OK) { print(F("Échec de l'authentification - Clé B : ")); println(mfrc522.GetStatusCodeName(status)); return false; } if (newKeyA != nullptr || newKeyB != nullptr) { // Pour parcourir tous les octets de la clé choisie. for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++) { if (newKeyA != nullptr) { buffer[i] = newKeyA->keyByte[i]; } if (newKeyB != nullptr) { buffer[i + 10] = newKeyB->keyByte[i]; } } } return true; }





















