Aller au contenu


Photo
- - - - -

Protocole pour faire communiquer dans les deux sens un Arduino et une application Android (MIT App Inventor 2)


  • Veuillez vous connecter pour répondre
21 réponses à ce sujet

#1 Donovandu88

Donovandu88

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 634 messages
  • Gender:Male

Posté 16 février 2018 - 08:40

Salut les Makers.

 

Aujourd'hui j'ouvre ce sujet qui peut surement aider d'autres personnes sur la communication en Bluetooth entre une application Android et un Arduino.

 

Pour mon projet de Bras Robotique (http://www.robot-maker.com/forum/topic/11216-bras-robot-bcn3d-moveo/) j'ai conçu une application grâce à MIT App inventor 2.

J'ai réussi à faire quelque chose qui fonctionne facilement mais que dans un seul sens.

 

En  faite, j'aimerai pour éviter d'avoir des erreurs, transmettre des trames de l'application à l'arduino mais je voudrais que le robot envoi un message pour signaler qu'il veut une nouvelle trame.

 

En gros : l'application envoi la trame --> le robot applique cette trame --> le robot envoi ensuite un "c'est bon j'ai fini" --> une fois le "c'est bon j'ai fini" reçu par l'application, celle-ci envoi une nouvelle trame.

 

Pour l'instant j'essaye de cette manière en "demandant" d'abord avec l'application en envoyant "1" pour savoir si c'est bon ou pas. Si c'est le cas, il met transmission en true et entre dans une boucle pour recevoir la vraie trame :

void Bluetooth(){
  String trame = ""; 
  boolean transmission = false;
    if (Serial1.available()){ // regarde si il y a une trame disponible
    trame = Serial1.read();Serial.print(trame);}
    
    if (trame == "1") {Serial1.write("Go");Serial.println(" Go");transmission = true;trame ="";delay(200);}
    else if (trame == "2"){Serial1.write("Attend un peut");Serial.println(" Attend!");trame ="";delay(200);}
    
    while(transmission = true){

    trame = Serial1.readStringUntil(',');               //  Découpe une trame sous la forme : 25,18,10,56,47,90f (interprétée par le robot comme ceci, rotation 1 : 25°, bras 1 : 18°, bras 2 : 10°, etc... et le f pour la fin de la trame)
    nouvelles_positions[0] = trame.toFloat();
    trame = Serial1.readStringUntil(',');
    nouvelles_positions[1] = trame.toFloat();
    trame = Serial1.readStringUntil(',');
    nouvelles_positions[2] = trame.toFloat();
    trame = Serial1.readStringUntil(',');
    nouvelles_positions[3] = trame.toFloat();
    trame = Serial1.readStringUntil(',');
    nouvelles_positions[4] = trame.toFloat();
    trame = Serial1.readStringUntil('f');
    nouvelle_position_pince = trame.toFloat();
    
    if ((position_moteur[0] != nouvelles_positions[0]) || (position_moteur[1] != nouvelles_positions[1]) || (position_moteur[2] != nouvelles_positions[2]) || (position_moteur[3] != nouvelles_positions[3]) || (position_moteur[4] != nouvelles_positions[4]) || (nouvelle_position_pince != position_pince)){
    Mouvements_moteurs(nouvelles_positions[0], nouvelles_positions[1], nouvelles_positions[2], nouvelles_positions[3], nouvelles_positions[4]);
    position_pince = nouvelle_position_pince;
    servo_pince.write(position_pince);
    }
    transmission = false;
    delay(100);
  }
}

Je ne détail pas (sauf si vous voulez) comment l'application fonctionne dans MIT App inventor car je ne sais pas si beaucoup l'utilise ici. De toute manière, je pense pouvoir recréer facilement dans l'application un fonctionnement similaire à l'Arduino.

 

Beaucoup de tutos expliquent comment faire pour avoir une communication entre une appli et un android mais que dans un sens pas dans les deux sens.

 

Merci pour votre aide  :bye:



#2 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 012 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 16 février 2018 - 08:58

Hum tu as un problème avec ton code au dessus ? Peux tu éditer ton poste un chouille en précisant ce que tu veux modifier ou autre par rapport à ce code qui pour moi fais ce que tu as décris ? 

Sinon je te recommande aussi la mise en place d'un byte de start =) 
Quand j'utilisais encore ce genre de " trame compréhensible  " orienté humain j'utilisais le " $ " comme start. 

et tu commences ton code de réception par :  Serial1.readStringUntil('$'); Pour flush le buffer si jamais il y a eu un problème de trame ou autre. Et ainsi sécuriser d'avantage ... ( sans être 100% fiable quand même )


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#3 Donovandu88

Donovandu88

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 634 messages
  • Gender:Male

Posté 16 février 2018 - 09:44

Je peux en effet ajouter un byte de start mais la chose que j'aimerai faire avec mon code, c'est surtout d'être sur que le robot ai fini son mouvement avant d'envoyer un message qui permettra à l'application l'envoi d'une nouvelle trame par la suite.

#4 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 012 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 16 février 2018 - 11:30

ah ok ! 

Dans ce cas je te propose quelque chose de différent ! 

 

Ne bloque pas une transmission mais, enregistre les transmission dans l'arduino puis utilise les uniquement quand tu en as besoin! 

 

D'un point de vu général il ne faut pas conditionner une transmission mais utiliser les données dont tu as besoin ! 

Dans ton cas l'idée est de bufferiser les trames reçue dans l'arduino et de passer à la trame reçue suivante que quand on est prêt à la faire ;) 

Dans la plus part des autres cas on préférera exactement le contraire !  C'est à dire exécuter la dernière trame envoyée indépendamment de ce qui a été envoyé précédemment ! =) 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#5 Donovandu88

Donovandu88

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 634 messages
  • Gender:Male

Posté 17 février 2018 - 09:42

Donc la pour gérer les trames, la manière la plus simple serai de les stocker dans un tableau je pense et de les prendre au fur et à mesure.

Mais je vais ajouter une contrainte que j'ai oublié de mentionner et qui à aussi dirigé mon choix vers une communication double sens.

Avec l'application, j'ai réussi à enregistrer des suites de trames que j'envoie l'une après l'autre avec la particularité d'avoir un temps présélectionné entre chaque envoi.
En gros, je choisis à l'aide d'un menu déroulant le temps que le robot doit attendre entre chaque mouvement.

#6 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 012 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 17 février 2018 - 10:09

eh bien pourquoi ne pas envoyer ce temps aussi dans les trames ?  Ainsi tu peux envoyer tes trames qui vont donner du travail à ton robot pendant une heure, et déconnecter ton téléphone, t'éloigner ou autre, et le robot continue son travail ... C'est pas mieux ? 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#7 Donovandu88

Donovandu88

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 634 messages
  • Gender:Male

Posté 17 février 2018 - 11:08

Oui c'est vrai mais un tableau peut stocker autant d'informations?



#8 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 012 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 17 février 2018 - 11:47

Oui sans problèmes =)  Ce qui limite c'est la taille mémoire de ta arduino après ... quand tu compiles ça te dit à combien de pourcent tu es à la fois pour la taille de ton code, et sur l'espace dispo pour tes variables avec une mega tu as de la place ;) 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#9 Donovandu88

Donovandu88

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 634 messages
  • Gender:Male

Posté 17 février 2018 - 11:49

D'accord, merci, je vais voir ce que je peux faire du coup.



#10 Donovandu88

Donovandu88

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 634 messages
  • Gender:Male

Posté 01 mars 2018 - 05:06

Salut  :bye:

 

Finalement après réflexion, je ne vais pas envoyer toute la trame d'un coup au robot pour lui donner du boulot pendant un certain temps.

Je préfère envoyer chaque trame à la suite afin de pouvoir annuler plus facilement des mouvements via l'application. 

 

J'ai donc réussi à me dépatouiller avec ceci :

void Bluetooth(){
  Serial1.write("ok"); // envoi en Bluetooth "ok" pour signaler que l'application peut envoyer une trame
  String trame = "";
  
  if (Serial1.available() > 0){ // regarde si il y a une trame disponible
    trame = Serial1.readStringUntil('$');
    
    Serial1.write("non"); //envoi en Bluetooth "non" pour que l'application ne renvoi pas une autre trame
    
    trame = Serial1.readStringUntil(',');
    nouvelles_positions[0] = trame.toFloat();
    trame = Serial1.readStringUntil(',');
    nouvelles_positions[1] = trame.toFloat();
    trame = Serial1.readStringUntil(',');
    nouvelles_positions[2] = trame.toFloat();
    trame = Serial1.readStringUntil(',');
    nouvelles_positions[3] = trame.toFloat();
    trame = Serial1.readStringUntil(',');
    nouvelles_positions[4] = trame.toFloat();
    trame = Serial1.readStringUntil('f');
    nouvelle_position_pince = trame.toFloat();

    Mouvements_moteurs(nouvelles_positions[0], nouvelles_positions[1], nouvelles_positions[2], nouvelles_positions[3], nouvelles_positions[4]);
    position_pince = nouvelle_position_pince;
    servo_pince.write(position_pince);
  }
    delay(100);
}

et l'application (clic droit --> "Ouvrir le lien dans un nouvel onglet" pour voir en plus grand) :

Fichier joint  Application.jpg   70,11 Ko   0 téléchargement(s)

 

L'application envoie la trame seulement si elle reçoit "ok". Vu que lorsqu'elle envoie une trame, elle reçoit "non" par le robot, elle va attendre. Le robot aillant ensuite fini son action, renvoie à son tour un "ok" et c'est reparti.



#11 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 012 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 02 mars 2018 - 11:05

Voir utiliser des trames comme ça ça me rappel mes débuts :) 
Pas de check sum du débug en clair en utilisant le moniteur série, des tailles variables et des séparateurs ^^ 

ça a des avantages : il y a du matériel pro qui utilise aussi ce genre de trame, comme le lidar "pro" SF40C qui vise à 100m et qui coûte environ 1000€ ^^ 

 

Surtout quand on débute =) Et qu'on a pas de problème de taille de trame =) . 

Par contre si un jour tu commence à avoir des bug ou autre, pense à mettre en place un checksum ;) 

En tout cas maintenant on veut une vidéo ! =) 

 

 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#12 gerardosamara

gerardosamara

    Membre passionné

  • Membres
  • PipPipPip
  • 373 messages
  • Gender:Male
  • Location:Costa Rica & Bretagne
  • Interests:La vie sous les tropiques

Posté 02 mars 2018 - 11:49

En place de checksum , J'utilise des délimiteurs "<" ">" pour  garantir l'intégrité d'un message envoyé ou recu  , par exemple pour l'envoi de la commande stop au robot

 

<stop>


Pura vida

 

Ma chaine youtube  https://www.youtube....EQ5MTR3A/videos

Tutoriel MIT Inventor2  https://www.robot-ma...e-robot-mobile/


#13 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 012 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 02 mars 2018 - 01:39

oui là donovan utilise le même principe avec $ et f =) 

Mais... C'est pas suffisant à 100% pour vérifier qu'une trame est intègre  :) si tu as <stpp> tu fais quoi ? ^^  

Il y a des trames qui peuvent être corrompue ... Un bit qui passe mal au milieu de la trame et ça peut changer beaucoup de chose... 
Pour éviter ce cas, avant d'executer une trame on vérifie si on intégrité avec un checksum par exemple ( d'autre méthodes que le checksum existent ) 
Si la trame est intègre on execute, sinon on le l'exécute pas et on redemande une trame...


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#14 gerardosamara

gerardosamara

    Membre passionné

  • Membres
  • PipPipPip
  • 373 messages
  • Gender:Male
  • Location:Costa Rica & Bretagne
  • Interests:La vie sous les tropiques

Posté 02 mars 2018 - 07:21

L'interface de communication et de commande du robot entre le RPI et l'App Android est de type API REST avec des requettes HTTP POST 

 

Le traitement de ce type d'erreur de transmission n'est pas implémenté actuellement  (mais ajouté à la To Do List )  et pourrais se faire de la facon suivante , dans mon cas , au niveau de l'API  python du RPI

 

App Android envoie au Rpi un Http Post / <stop>

Rpi réponds HTTP 200 OK si message recu = <stop>

 

App Android envoie au Rpi un Http Post / <stop>

Rpi réponds HTTP400 si message recu = <stp>

App Android renvoie une 2ème fois au Rpi un Http Post / <stop>

 

400 Bad Request

La requête n’était pas correcte d’une manière ou d’une autre, souvent à cause des données mal structurées dans les corps des requêtes POST et PUT (des requêtes qui ont souvent des informations dans leurs corps).


Pura vida

 

Ma chaine youtube  https://www.youtube....EQ5MTR3A/videos

Tutoriel MIT Inventor2  https://www.robot-ma...e-robot-mobile/


#15 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 012 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 02 mars 2018 - 07:29

L'interface de communication et de commande du robot entre le RPI et l'App Android est de type API REST avec des requettes HTTP POST 

 

Le traitement de ce type d'erreur de transmission n'est pas implémenté actuellement  (mais ajouté à la To Do List )  et pourrais se faire de la facon suivante au niveau de l'API  python du RPI

 

App Android envoie au Rpi un Http Post / <stop>

Rpi réponds HTTP 200 OK si message recu = <stop>

 

App Android envoie au Rpi un Http Post / <stop>

Rpi réponds HTTP400 si message recu = <stp>

App Android renvoie une 2ème fois au Rpi un Http Post / <stop>

 

400 Bad Request

La requête n’était pas correcte d’une manière ou d’une autre, souvent à cause des données mal structurées dans les corps des requêtes POST et PUT (des requêtes qui ont souvent des informations dans leurs corps).

 

Bon eh bien voilà en to do tu mets en place un système de validation de trame bien reçue =) 
Mais bon au début on s'en passe ^^ Tant qu'on ne voit pas de problème x) 
Une fois que tu as le problème tu te dit " Mince " ... et hop tu le mets en place =) 
C'est un peu comme une faille de sécurité qui ne nous inquiète pas tant qu'elle n'est pas exploitée ... =)

Mais parfois on a raison, genre quand le risque est réellement inexistant. 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#16 gerardosamara

gerardosamara

    Membre passionné

  • Membres
  • PipPipPip
  • 373 messages
  • Gender:Male
  • Location:Costa Rica & Bretagne
  • Interests:La vie sous les tropiques

Posté 02 mars 2018 - 07:34

Exactement mais c'est pas une bonne pratique de ne pas traiter ce type d'erreur ..... j'ai presque honte :excl:


Pura vida

 

Ma chaine youtube  https://www.youtube....EQ5MTR3A/videos

Tutoriel MIT Inventor2  https://www.robot-ma...e-robot-mobile/


#17 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 012 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 02 mars 2018 - 07:36

Bon après j'ai fait cette remarque mais pas pour critiquer hein ! Je dis ça juste pour dire que ça existe et le laisser en piste d'amélioration possible pour la suite ;) 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#18 gerardosamara

gerardosamara

    Membre passionné

  • Membres
  • PipPipPip
  • 373 messages
  • Gender:Male
  • Location:Costa Rica & Bretagne
  • Interests:La vie sous les tropiques

Posté 02 mars 2018 - 07:38

:)


Pura vida

 

Ma chaine youtube  https://www.youtube....EQ5MTR3A/videos

Tutoriel MIT Inventor2  https://www.robot-ma...e-robot-mobile/


#19 Donovandu88

Donovandu88

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 634 messages
  • Gender:Male

Posté 02 mars 2018 - 08:05

Oula vous êtes en train de me perdre la ^^
Un checksum serait une vérification de la trame si j'ai bien compris mais il faut que celle ci soit toujours de la même taille ?
Car si j'envoie une valeur d'angle par exemple 70° ou 125°, la seconde sera un octet plus ljd grande. C'est pareil si j'ai un angle positif ou négatif.

#20 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 012 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 02 mars 2018 - 08:32

non non un checksum fonctionne quelque soit la taille =) . 

 

 

grosso modo, un checksum, pour chaque caractère que tu vas mettre dans la trame tu fais côté emmetteur : 

uint8_t checksum = 0 ; 

for( i=0; i<NBCARACTERES; i++)
{ 
  checksum += carctere[i];
}

et avant de mettre ton f final, tu rajoutes l'envois du checksum. 

 

quand tu reçois ta trame tu refais l'opération côté récepteur pour tous les caractères reçu : 

for( i=0; i<NBCARACTERESRECU; i++)
{ 
  checksumCalcul += carctereRecu[i];
}

if ( checksumCalcul == checksumRecu) 
  // On execute la tral
else 
  // On execute l'action en cas d'erreur de trame
}

On pars du principe toujours pas 100% fiable ( mais bon là on s'en rapproche ) 
que si il y a un parasitage qui modifie un élément de la trame, il n'y aura pas comme par hasard un deuxième parasitage qui permettra de modifier la trame en conservant sont checksum ... 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 





0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users