Étape 7: Le Code d’Arduino (non modifié)
/*Robot de moteur servo commandée par entrée série
Cherche un jeu de caractères ASCII dans le signal à envoyer
commandes à un ensemble de servos à conduire un petit robot. Goupille de LED #13
reste allumé pendant le mouvement du servo et clignotent pour changements de vitesse.
Le circuit d’au moins :
* LED attaché de pin 13 au sol (ou utiliser des LED intégrée sur la plupart de l’Arduino)
* Servos avec des fils de signaux connectés aux broches 3 et 5 (5v alimentation et masse pour
servos peuvent également être branchés sur Arduino, ou puissance peut provenir de sources externes)
* Entrée série relié à la broche RX 0
* Série sortie raccordée à la broche TX 1
Autres circuits (facultatifs) :
* En avant face à télémètre à ultrasons sur la broche numérique 7
* Vers le bas face à télémètre à ultrasons sur la broche numérique 8
Remarque : Si vous n’avez pas encore un équipement de série pour se connecter avec, vous pouvez utiliser le
construit en Serial Monitor dans le logiciel Arduino quand vous connecter via le port USB pour tester.
Veillez également à disconect RX et TX broches provenant d’autres appareils en essayant de programmer
l’Arduino via le port USB.
création 2010
par Tim Heath, Ryan Hickman et Glen Arrowsmith
Visitez http://www.cellbots.com pour plus d’informations
*/
#include < Servo.h >
#include < EEPROM.h >
#define BUFFERSIZE 20
#define EEPROM_servoCenterLeft 1
#define EEPROM_servoCenterRight 2
#define EEPROM_speedMultiplier 3
#define EEPROM_servosForcedActive 4
#define EEPROM_lastNeckValue 5
#define DEFAULT_servoCenterLeft 90
#define DEFAULT_servoCenterRight 90
#define DEFAULT_speedMultiplier 5
#define DEFAULT_servosForcedActive faux
#define DEFAULT_servosForcedActive faux
#define DEFAULT_lastNeckValue 255
** PARAMÈTRES généraux **-réglages des préférences générales
DÉBOGAGE booléen = false ; Si sortie de débogage au cours de la série est activé par defauly (peut être retournée avec la commande « h »)
const int ledPin = 13 ; LED s’allume lors de l’exécution des servos
char * driveType = « servo » ; Utilisez « moteur » quand les bots dispose d’un moteur DC ou « servo » pour alimenter les roues de servos
** PARAMÈTRES de SERVO **-valeurs configurables issu des pins utilisés et de la servo direction
const int servoPinLeft = 9 ;
const int servoPinRight = 10 ;
const int servoPinHead = 12 ; Servo contrôle l’angle du téléphone
const int servoDirectionLeft = 1 ; Utiliser 1 ou -1 pour la marche arrière
const int servoDirectionRight = -1 ; Utiliser 1 ou -1 pour la marche arrière
int servoCenterLeft = DEFAULT_servoCenterLeft ; Réglage PWM pour aucun mouvement sur la servocommande gauche
int servoCenterRight = DEFAULT_servoCenterLeft ; Réglage PWM pour aucun mouvement sur le servo de droite
int servoPowerRange = 30 ; Gamme PWM hors Centre de servos réagissent mieux à (la valeur 30 à travailler dans la fourchette de 60 à 120 décentré de 90)
durée maximale d’exécution longue const = 2000 ; Durée pour servos sans commande supplémentaire d’exécution maximale. * Doit utiliser une commande pour le définir. *
int speedMultiplier = DEFAULT_speedMultiplier ; Réglage de vitesse par défaut. Utilise une plage de 1 à 10
int lastNeckValue = DEFAULT_lastNeckValue ;
** PARAMÈTRES du pilote moteur ** - pour utilisation avec panneaux comme le moteur de Pololu (aussi utilisations gauche/droite paramètres de pin servo ci-dessus)
int leftMotorPin_1 = 9 ;
int leftMotorPin_2 = 8 ;
int rightMotorPin_1 = 10 ;
int rightMotorPin_2 = 11 ;
int motor_stby = 12 ;
** GAMME trouver ***-les paramètres suivants sont pour les télémètres à ultrasons. OK pour lave comme-est si vous ne les avez pas sur votre robot
longue dist, microsecondes, cm pouces ; Utilisé par le télémètre pour le calcul des distances
const int rangePinForward = 7 ; Broche numérique pour le télémètre face vers l’avant (pour la distance de l’objet en face de bot)
const int rangeToObjectMargin = 0 ; Gamme en cm de l’objet vers l’avant (bot s’arrete lorsque ne distance plus proche que ce - la valeur 0 si aucun capteur)
const int rangePinForwardGround = 8 ; Broche numérique pour la baisse télémètre face à l’avant (pour bord de détection de la table)
const int rangeToGroundMargin = 0 ; Gamme en cm de la table (bot s’arrête lorsque la distance est supérieure à cette valeur 0 si aucun capteur)
const int rangeSampleCount = 3 ; Nombre de mesures à prendre et en moyenne pour une valeur plus stable
Créer des objets pour commander les servos servo
Servo myservoLeft ;
Servo myservoRight ;
Servo myservoHead ;
Aucune configuration requise pour ces paramètres
servosActive booléen = false ; suppose que les servos ne se déplacent pas quand on commence
Boolean servosForcedActive = DEFAULT_servosForcedActive ; ne s’arrêtera que lorsque considérés comme dangereux
unsigned long stopTime=millis() ; utilisé pour le calcul de la durée d’arrosage pour servos
char incomingByte ; Contient des valeurs sérielles entrants
msg de char [8] ; Pour faire passer des messages retour Séris
char inBytes [BUFFERSIZE] ; Tampon pour la série dans les messages
int serialIndex = 0 ;
int serialAvail = 0 ;
void setup() {}
pinMode (servoPinLeft, sortie) ;
pinMode (servoPinRight, sortie) ;
pinMode (servoPinHead, sortie) ;
pinMode(leftMotorPin_1,OUTPUT) ;
pinMode(leftMotorPin_2,OUTPUT) ;
pinMode(rightMotorPin_1,OUTPUT) ;
pinMode(rightMotorPin_2,OUTPUT) ;
pinMode (ledPin, sortie) ;
digitalWrite(servoPinLeft,0) ;
digitalWrite(servoPinRight,0) ;
digitalWrite(servoPinHead,0) ;
digitalWrite(motor_stby,HIGH) ;
Serial.Begin(115200) ;
servoCenterLeft = readSetting (EEPROM_servoCenterLeft, servoCenterLeft) ;
servoCenterRight = readSetting (EEPROM_servoCenterRight, servoCenterRight) ;
speedMultiplier = readSetting (EEPROM_speedMultiplier, speedMultiplier) ;
servosForcedActive = readSetting (EEPROM_servosForcedActive, servosForcedActive) ;
lastNeckValue = readSetting (EEPROM_lastNeckValue, lastNeckValue) ;
Si (lastNeckValue! = DEFAULT_lastNeckValue) {}
myservoHead.attach(servoPinHead) ;
myservoHead.write(lastNeckValue) ;
}
}
Lit en toute sécurité les EEPROM
int readSetting (int memoryLocation, int defaultValue) {}
int valeur = EEPROM.read(memoryLocation) ;
Si (valeur == 255) {}
EEPROM.write (memoryLocation, defaultValue) ;
}
retourne la valeur ;
}
Définit les paramètres EEPROM pour les valeurs par défaut
void setEepromsToDefault() {}
servosForcedActive = DEFAULT_servosForcedActive ;
speedMultiplier = DEFAULT_speedMultiplier ;
servoCenterRight = DEFAULT_servoCenterRight ;
servoCenterLeft = DEFAULT_servoCenterLeft ;
lastNeckValue = DEFAULT_lastNeckValue ;
EEPROM.write (EEPROM_servosForcedActive, DEFAULT_servosForcedActive) ;
EEPROM.write (EEPROM_speedMultiplier, DEFAULT_speedMultiplier) ;
EEPROM.write (EEPROM_servoCenterRight, DEFAULT_servoCenterRight) ;
EEPROM.write (EEPROM_servoCenterLeft, DEFAULT_servoCenterLeft) ;
EEPROM.write (EEPROM_lastNeckValue, DEFAULT_lastNeckValue) ;
Si {(débogage)
Serial.println ("EEPROM tous les valeurs définies par défaut.") ;
}
}
Convertir des commandes de texte directionnel ("avant" / "descendante") en vitesse calculée servo
int directionValue (char * directionCommand, int servoDirection) {}
Si (directionCommand == « forward ») {}
retour (10 * speedMultiplier * servoDirection) ;
}
ElseIf (directionCommand == « en arrière ») {}
retour (-10 * speedMultiplier * servoDirection) ;
}
else {}
Si (débogage) {Serial.println ("Houston, nous avons un problème!");}
return 0 ; La tentative de définir valeur à centrer - cela ne devrait pas être nécessaire
}
}
Traduire les commandes de texte en valeurs PWM pour le bot déplacer (commande de la servocommande gauche, commande servo de droite)
{' unsigned long moveBot (char * commandLeft, char * commandRight)
valueLeft int = directionValue (commandLeft, servoDirectionLeft) + servoCenterLeft ;
valueRight int = directionValue (commandRight, servoDirectionRight) + servoCenterRight ;
driveWheels (valueLeft, valueRight) ;
}
Servo Drive ou DC moteurs pour déplacer le robot à l’aide de valeurs dans la plage de -100 à 100 pour gauche et droite
les driveWheels long non signé (valueLeft int, int valueRight) {}
Détachez les deux broches de servo qui seront arrêtera pleurnicher et se désactivent les moteurs afin qu’ils ne tuent pas la boussole
Si (valueLeft == 0 et valueRight == 0) {}
myservoLeft.detach() ;
myservoRight.detach() ;
}
Conduire les roues basés sur « servo » driveType
Si (driveType == « servo ») {}
valueLeft = valueLeft * servoDirectionLeft ; Flip de positif à négatif si nécessaire basée sur le paramètre de valeur servo direction
valueRight = valueRight * servoDirectionRight ;
Mapper les valeurs de « w » à la marge étroite qui les servos répondent aux
valueLeft = carte (valueLeft, -100, 100, (servoCenterLeft - servoPowerRange), (servoCenterLeft + servoPowerRange)) ;
valueRight = carte (valueRight, -100, 100, (servoCenterRight - servoPowerRange), (servoCenterRight + servoPowerRange)) ;
digitalWrite (ledPin, HIGH) ; la valeur de la LED sur
Redémarrer le servo PWM et leur envoyer des commandes
myservoLeft.attach(servoPinLeft) ;
myservoRight.attach(servoPinRight) ;
myservoLeft.write(valueLeft) ;
myservoRight.write(valueRight) ;
Cracher quelques informations de diagnostic sur la série
Si {(débogage)
Serial.Print ("servo gauche à Moving") ;
Serial.Print (valueLeft, DEC) ;
Serial.Print ("et servo de droite") ;
Serial.println (valueRight, DEC) ;
}
}
Conduire les roues basés sur driveType « moteur »
else {}
Définissez des broches moteurs gauche pour tourner dans la direction souhaitée
Si (valueLeft < 0) {}
digitalWrite(leftMotorPin_1,LOW) ;
digitalWrite(leftMotorPin_2,HIGH) ;
}
else {}
digitalWrite(leftMotorPin_1,HIGH) ;
digitalWrite(leftMotorPin_2,LOW) ;
}
Réglez de façon strictement à droite moteur à tourner dans la direction souhaitée
Si (valueRight < 0) {}
digitalWrite(rightMotorPin_1,LOW) ;
digitalWrite(rightMotorPin_2,HIGH) ;
}
else {}
digitalWrite(rightMotorPin_1,HIGH) ;
digitalWrite(rightMotorPin_2,LOW) ;
}
Mappe les valeurs de « w » à la plage plus large que le moteur répond aux
valueLeft = map(abs(valueLeft), 0, 100, 0, 255) ;
valueRight = map(abs(valueRight), 0, 100, 0, 255) ;
analogWrite(servoPinLeft,valueLeft) ;
analogWrite(servoPinRight,valueRight) ;
}
stopTime=millis() + durée maximale d’exécution ; Régler l’heure d’arrêter l’exécution basé sur la durée d’exécution autorisée
retour stopTime ;
}
Arrêter le bot
void stopBot() {}
driveWheels(0,0) ;
digitalWrite (ledPin, basse) ; Éteindre la LED
Si (débogage) {Serial.println (« les deux roues d’arrêt");}
serialReply ("i", « st ») ; Dire au téléphone que le robot s’est arrêté
}
Lire et traiter les valeurs d’un télémètre à ultrasons (vous pouvez laisser ce code en même si vous n’en avez pas)
{getDistanceSensor(int ultrasonicPin) long
Prendre des lectures multiples et leur moyenne
microsecondes = 0 ;
pour (int échantillon = 1; échantillon < = rangeSampleCount ; échantillon ++) {}
La parallaxe PING))) est déclenchée par une impulsion forte de 2 ou plusieurs microsecondes.
Donner une brève impulsion faible au préalable pour s’assurer une impulsion propre élevée :
Le Maxsonar ne semble pas avoir besoin de cette partie, mais il ne pas mal non plus
pinMode (ultrasonicPin, sortie) ;
digitalWrite (ultrasonicPin, basse) ;
delayMicroseconds(2) ;
digitalWrite (ultrasonicPin, HIGH) ;
delayMicroseconds(5) ;
digitalWrite (ultrasonicPin, basse) ;
Le même NIP est utilisé pour lire le signal du détecteur à ultrasons : un sommet
impulsion dont la durée est la durée (en microsecondes) de l’envoi
du ping à la réception de son écho hors d’un objet.
pinMode (ultrasonicPin, entrée) ;
microsecondes += pulseIn (ultrasonicPin, HIGH) ;
delayMicroseconds(5) ; Très courte pause entre les lectures
}
microSeconds microsecondes de = / rangeSampleCount ;
Convertir le capteur moyenne lecture centimètres et de le retourner
cm = microsecondsToCentimeters(microseconds) ;
po = microsecondsToInches(microseconds) ;
Si {(débogage)
Serial.Print ("Micro:") ; Serial.Print(microSeconds) ;
Serial.Print ("pouces:") ; Serial.Print(inches) ;
Serial.Print (« cm: ") ; Serial.println(cm) ;
}
retour cm ;
}
{microsecondsToCentimeters(long microseconds) long
La vitesse du son est de 340 m/s ou 29 microsecondes par centimètre.
Le ping déplace dehors et en arrière, afin de trouver la distance de la
objet, que nous prenons la moitié de la distance parcourue.
retourner les microsecondes / 29 / 2 ;
}
{microsecondsToInches(long microseconds) long
Selon fiche technique de parallaxe pour le PING))), il y a
73,746 microsecondes par pouce (c'est-à-dire son voyage à 1130 pieds /
en second lieu). Cela donne la distance parcourue par le ping, sortant
et revenez, pour nous diviser par 2 pour obtenir la distance de l’obstacle.
Voir : http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
Il en est de même pour le MaxSonar par MaxBotix
retourner les microsecondes / 74 / 2 ;
}
Répond à plus de série et gère une pause et de rinçage les données à traiter avec Android comms série
void serialReply (char * sensorname, char * tmpmsg) {}
Serial.Print(sensorname) ;
Serial.Print(":") ;
Serial.println(tmpmsg) ; Envoyer le message retour à la ligne sérielle
Attendez que le débogueur série se taire
Delay(200) ; Il s’agit d’un nombre magique
Serial.Flush() ; efface toutes les données entrantes
}
Vérifie les télémètres pour voir si il est sûr de continuer à se déplacer (* il faut ajouter le moyen de savoir quelle direction nous sommes mobiles *)
Boolean safeToProceed() {}
coffre-fort booléen = false ; Supposons que ce n’est pas sécuritaire de procéder
Vérifier la distance à l’objet le plus proche devant le bot et arrêter si trop étroite
Si (rangeToObjectMargin! = 0) {/ / Don ' t bother envoi si marge définie à zéro car il se bloque lorsque aucun capteur présente
Dist = getDistanceSensor(rangePinForward) ;
Si (dist > rangeToObjectMargin) {}
sécurité = true ;
}
ElseIf (débogage) {Serial.print ("objet trop près devant -");}
}
Vérifier la distance au sol devant le bot pour s’assurer que la table est toujours là
Si (rangeToGroundMargin! = 0) {/ / Don ' t bother envoi si marge définie à zéro car il se bloque lorsque aucun capteur présente
Dist = getDistanceSensor(rangePinForwardGround) ;
Si (dist > rangeToGroundMargin) {}
sécurité = true ;
}
ElseIf (débogage) {Serial.print ("fin de surface atteint -");}
}
Si (rangeToGroundMargin == 0 & & rangeToObjectMargin == 0) {return true;}
Retournez le coffre ;
}
Vérifiez si le temps s’est écoulé pour arrêter le bot et s’il est sûr d’aller de l’avant
void checkIfStopBot() {}
Si (pas servosForcedActive et servosActive et (stopTime < {millis() ou pas safeToProceed()))
stopBot() ;
servosActive = false ;
} ElseIf (pas safeToProceed()) {}
stopBot() ;
servosActive = false ;
}
}
Envoyer commande au dispositif de Bluetooth pour débuter pairing
void pairBluetooth() {}
Serial.Print("\r\n+INQ=1\r\n") ; Il s’agit de Seeedstudio maître/esclave (variation selon les besoins pour votre modèle)
}
Lit entrée série si disponible et analyse des commande lorsque le commandement intégral a été envoyé.
void readSerialInput() {}
serialAvail = Serial.available() ;
Lire ce qui est disponible
pour (int i = 0; i < serialAvail; i ++) {}
Stocker dans la mémoire tampon.
inBytes [i + serialIndex] = Serial.read() ;
Vérifier la fin de la commande.
Si (inBytes [i + serialIndex] == « \n » || inBytes [i + serialIndex] == «; » || inBytes [i + serialIndex] == ' >') {//Use ; lorsque vous utilisez le Serial Monitor
inBytes [i + serialIndex] = « \0 » ; fin du char de la chaîne
parseCommand(inBytes) ;
serialIndex = 0 ;
}
else {}
attend plus de la commande à venir plus tard.
serialIndex += serialAvail ;
}
}
}
Nettoie et traite la commande
void parseCommand(char* com) {}
Si (com [0] == « \0 ») {return;} //bit de vérification des erreurs
début int = 0 ;
commencer de commande
tandis que (com [Démarrer]! = ' <') {}
Start ++ ;
Si (com [Démarrer] == « \0 ») {}
ce n’est pas là. Doit être ancienne version
Démarrer = -1 ;
rupture ;
}
}
Start ++ ;
Passer au début
int i = 0 ;
tandis que (com [i + début - 1]! = « \0 ») {}
com [i] = com [start + i] ;
i ++ ;
}
performCommand(com) ;
}
void performCommand(char* com) {}
Si (strcmp (com, « f ») == 0) {/ / avance
stopTime = driveWheels (speedMultiplier * speedMultiplier, 10 * 10) ;
servosActive = true ;
} else if (strcmp (com, « r ») == 0) {/ / droite
stopTime = driveWheels (speedMultiplier * 10, speedMultiplier * -10) ;
servosActive = true ;
} else if (strcmp (com, « l ») == 0) {/ / gauche
stopTime = driveWheels (speedMultiplier * -10, speedMultiplier * 10) ;
servosActive = true ;
} else if (strcmp (com, « b ») == 0) {/ / vers l’arrière
stopTime = driveWheels (speedMultiplier * -10, speedMultiplier * -10) ;
servosActive = true ;
} else if (strcmp (com, « s ») == 0) {/ / Stop
stopBot() ;
servosActive = false ;
} else if (strcmp (com, « fr ») == 0 || strcmp (com, « fz ») == 0 || strcmp (com, « x ») == 0) {/ / Read et avant impression face à capteur de distance
Dist = getDistanceSensor(rangePinForward) ;
EGTI (dist, msg, 10) ; Transformer un char de l’int dist
serialReply (« x », msg) ; Envoyer la distance sur la ligne série
} else if (strcmp (com, « z ») == 0) {/ / lecture et impression au sol face à capteur de distance
Dist = getDistanceSensor(rangePinForwardGround) ;
EGTI (dist, msg, 10) ; Transformer un char de l’int dist
serialReply (« z », msg) ; Envoyer la distance sur la ligne série
} else if (strcmp (com, « h ») == 0) {/ / Help mode - activer/désactiver le débogage
Imprimez quelques instructions de base lorsque vous allumez tout d’abord le débogage
Si (ne pas à un débogage) {}
Serial.println ("prêt à écouter les commandes ! Essayez ome d'entre eux: ") ;
Serial.println ("F (avec impatience), B (backward), L (gauche), D (droite), S (arrêt), D (démo)") ;
Serial.println ("également utilisation nombres 1-9 pour régler la vitesse (0 = lent, 9 = rapide).") ;
}
DÉBOGAGE = ! LE DÉBOGAGE ;
} else if (strcmp (com, « 1 ») == 0 || strcmp (com, « 2 ») == 0 || strcmp (com, « 3 ») == 0 || strcmp (com, « 4 ») == 0 || strcmp (com, « 5 ») == 0 || strcmp (com, « 6 ») == 0 || strcmp (com, « 7 ») == 0 || strcmp (com, « 8 ») == 0 || strcmp (com, « 9 ») == 0 || strcmp (com, « 0 ») == 0) {
Je sais que la condition précédente est douteux mais cela va changer bientôt
Si (débogage) {Serial.print ("Changing vitesse à");}
int i = com [0] ;
speedMultiplier = i - 48 ; Paramétrer le multiplicateur de vitesse à une gamme de 1-10 d’entrées ASCII 0 à 9
EEPROM.write (EEPROM_speedMultiplier, speedMultiplier) ;
Si (débogage) {Serial.println(speedMultiplier);}
Clignotement de la LED pour confirmer le nouveau réglage de vitesse
pour (int speedBlink = 1; speedBlink < = speedMultiplier ; speedBlink ++) {}
digitalWrite (ledPin, HIGH) ; la valeur de la LED sur
Delay(100) ;
digitalWrite (ledPin, basse) ; déclencher la LED
Delay(100) ;
}
} ElseIf (com [0] == « c ») {/ / calibrer Centre paramètres PWM pour les deux servos ex: "c 90 90"
valueLeft int = 90, valueRight = 90 ;
sscanf (com, « c %d de %d », & valueLeft et valueRight) ; Analyser l’entrée en plusieurs valeurs
servoCenterLeft = valueLeft ;
servoCenterRight = valueRight ;
stopTime = driveWheels(0,0) ; Conduire les servos avec la valeur 0, qui devrait déboucher sur aucun mouvement lorsque étalonné correctement
servosActive = true ;
EEPROM.write (EEPROM_servoCenterLeft, servoCenterLeft) ;
EEPROM.write (EEPROM_servoCenterRight, servoCenterRight) ;
Si {(débogage)
Serial.Print ("calibré servo centres à") ;
Serial.Print(servoCenterLeft) ;
Serial.Print (« et ») ;
Serial.println(servoCenterRight) ;
}
} else if (strcmp (com, « i ») == 0) {/ / activer/désactiver servo à l’infini mode actif, donc ce n’est pas expirer automatiquement
servosForcedActive =! servosForcedActive ; Arrêter seulement quand c’est dangereux
EEPROM.write (EEPROM_servosForcedActive, servosForcedActive) ;
Si {(débogage)
Serial.Print ("infinie rotation basculée à") ;
Si (servosForcedActive){Serial.println("on");}
else {Serial.println("off");}
}
} ElseIf (com [0] == « w ») {/ / gérer « roue » commande et convertir en valeurs PWM ex: « w-100 100"[plage va de -100 à 100]
valueLeft int = 90, valueRight = 90 ;
sscanf (com, « w %d %d », & valueLeft et valueRight) ; Analyser l’entrée en plusieurs valeurs
stopTime = driveWheels (valueLeft, valueRight) ;
servosActive = true ;
} else if (strcmp (com, "reset") == 0) {/ / réinitialise les paramètres eeprom
setEepromsToDefault() ;
} ElseIf (com [0] == ' n ') {/ / déplacer la tête vers le haut
sscanf (com, « n %d », & lastNeckValue) ; Analyser l’entrée en plusieurs valeurs
myservoHead.attach(servoPinHead) ;
myservoHead.write(lastNeckValue) ;
EEPROM.write (EEPROM_lastNeckValue, lastNeckValue) ;
Si {(débogage)
Serial.Print ("cou déplacé vers") ;
Serial.println(lastNeckValue) ;
}
} ElseIf (com [0] == « p ») {/ / initie Bluetooth appairage jusqu'à un autre périphérique peut se connecter
pairBluetooth() ;
} else {}
serialReply ("e", com); / / Echo commande inconnue retour
Si {(débogage)
Serial.Print ("commande inconnue:") ;
Serial.println(com) ;
}
}
}
Boucle principale en cours d’exécution à tout moment
void loop()
{
readSerialInput() ;
checkIfStopBot() ;
}