4 servo drive CellBot qui peut être contrôlé à distance. (7 / 8 étapes)

É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() ;
}

Articles Liés

Faire un simple top jeu de strach qui peut être contrôlé manuellement

Faire un simple top jeu de strach qui peut être contrôlé manuellement

Hé là ! Il s'agit d'une toupie, créée à partir de la v 1.5 moteur à courant continuqui peut être contrôlé manuellement avec un aimant...espérons qu'il vous plairaÉtape 1: matériauxpour le jouet, vous aurez besoin :~ 1 moteur à courant continu~ tourne
Un contrôleur d’arrosage qui peut être mis en réseau Accueil

Un contrôleur d’arrosage qui peut être mis en réseau Accueil

Quelques semaines auparavant, j'ai publié un module de contrôleur peu grand qui fourni 6 relais de pouvoir être piloté depuis un ordinateur via un réseau.  Après que j'ai publié, je suis arrivé à penser que la même conception de base, avec quelques c
Comment faire un iphone/android/web contrôlable rallonge électrique qui peut être utilisé pour contrôler votre mijoteuse, porte de garage, cafetière, cuiseur à riz, blender smoothie... poisson barboteur de réservoir ou tout autre dispositif électronique d

Comment faire un iphone/android/web contrôlable rallonge électrique qui peut être utilisé pour contrôler votre mijoteuse, porte de garage, cafetière, cuiseur à riz, blender smoothie... poisson barboteur de réservoir ou tout autre dispositif électronique d

Cette instructable va vous apprendre comment créer un cordon ordinateur/iPhone/Android-contrôlables qui peut contrôler quoi que ce soit électrique de n'importe où avec un accès internet. La build vous coûtera 60$ et il est assez facile à faire. Il vo
Ce qui peut être fait d’une lampe à incandescence

Ce qui peut être fait d’une lampe à incandescence

Je suis très heureux de vous accueillir à ma chaîne et dans cette vidéo je vais vous montrer une idée intéressante sur ce qui peut être fait d'une ampoule grillée.
Ce qui peut être fait de couvercles de bouteille ?

Ce qui peut être fait de couvercles de bouteille ?

https://www.youtube.com/watch?v=a-Icu7fOCao&feature=youtu.beÉtape 1: C'est un projet très simple et ne nécessite qu'un cure-dent plus léger, casquettes, de bouteille en plastique, ciseaux ! Je montre comment modifier un bouchon de bouteille en plasti
Ce qui peut être fait de bouteille en plastique couvercles

Ce qui peut être fait de bouteille en plastique couvercles

https://www.youtube.com/watch?v=n3XvtZWPvUA&feature=youtu.beÉtape 1: je montre comment modifier un bouchon de bouteille en plastique dans une buse. Le bouchon de la bouteille en plastique est chauffé sur un briquet jusqu'à ce qu'il devient malléable
Un outil simple qui peut être fait à partir de déchets, mini couteau électrique de pcb

Un outil simple qui peut être fait à partir de déchets, mini couteau électrique de pcb

Parfois nous avons rattrapé à travailler quelque chose cause il est un outil dont vous avez besoin, mais vous ne l'avez pas. Peut-être que vous pourriez le faire des choses qui sont autour de vousÉtape 1 : ce dont vous avez besoin est :-x inutilisés
.25 ultra Wallet minimaliste slim, agrafe d’argent, métal décapsuleur, carte de crédit qui peut être attaché à votre cas android

.25 ultra Wallet minimaliste slim, agrafe d’argent, métal décapsuleur, carte de crédit qui peut être attaché à votre cas android

Salut les gars tout en essayant de modéliser un cas android similaire à mon cas iphone je suis sorti avec un portefeuille peu cool qui peut vous retenir jusqu'à ce que je reçois le cas android fait... Espèce ultra mince et minimaliste est imperméable
Entrer dans n’importe quel site qui peut-être être bloqués - Just ont accès au poste de travail

Entrer dans n’importe quel site qui peut-être être bloqués - Just ont accès au poste de travail

dans ce instructable j'utilise une page Web au hasard - yes.google.com pour accéder aux instructables.com lorsqu'il est bloqué. Ceci est possible en raison de remappage du domaine.Cette idée est également dans l'instructable ici.Étape 1: Ce que vous
HOMOPOLAIRE moteur qui peut être fait à la maison

HOMOPOLAIRE moteur qui peut être fait à la maison

il s'agit d'une instructable qui montrera à vous de faire un moteur de choses vous avez couché autour de la maisonÉtape 1: matériaux D-batterie, aimant plat, tige quelconque (j'ai utilisé une vis), fil, Casing(optional), de cuivre plat mince morceau
Ce qui peut être prouvée de bulles d’air | Bubble Wrap expérience

Ce qui peut être prouvée de bulles d’air | Bubble Wrap expérience

https://youtu.be/A2so-u0WkqsÉtape 1: De bubble wrap peut fait beaucoup d'idéesDans ce tutoriel d'instructables je vous montre comment faire des bonbons Jell-o en forme de bulles.Tu as besoin de:-bulles d'air ;-300 ml d'eau bouillante ;-70 g de gélati
Ce qui peut être fait de banane ?

Ce qui peut être fait de banane ?

https://youtu.be/FWNsXNEN3SsÉtape 1: Faire un Gummy Jello banane vous devez ! Ce que vous aurez besoin : - 3 bananes,-gélatine de kiwi (70g) + eau bouillante (300ml)-gélatine d'orange (70g) + eau bouillante (300ml)-gélatine de framboises (70g) + eau
Faire un ventilateur contrôlé à distance !

Faire un ventilateur contrôlé à distance !

Dans ce tutoriel, vous apprendrez comment faire un attachement de fan très simple qui peut être contrôlé par une télécommande.Étape 1: matériauxPour ce projet, vous aurez besoin du matériel suivant :1 9g Servo Micro + cor + vis pour cor - 2,00 $1 TSO
Arduino basé compteur d’énergie solaire PV avec connectivité Xively (peut être surveillée sur android ou iPhone)

Arduino basé compteur d’énergie solaire PV avec connectivité Xively (peut être surveillée sur android ou iPhone)

Ça fait environ deux jours que j'ai fait la génération Arduino PV compteur, mais c'était une erreur de ne pas de prendre des photos étape par étape avant de continuer pour les tests finaux. Et c'était une idée terrible pour afficher la boîte de brute