Go Down

Topic: Projet Bar a Cocktail fonctionnel mais .... (Read 1 time) previous topic - next topic

dfgh

#30
Jul 16, 2017, 06:42 pm Last Edit: Jul 16, 2017, 07:07 pm by dfgh
dans le" if bouton3", tu ne fais que mettre le moteur à LOW.
puis tu mets "state"  à 0.

au tour suivant dans la loop, tu n'entres plus dans le "if (state == '1')" puisque tu viens de le mettre à 0.

tu ne scrutes donc plus les boutons.

et rien ne change pour les tours suivants dans la Loop.

à moins que tu ne redonnes une valeur par le serial

J-M-L

#31
Jul 17, 2017, 10:37 am Last Edit: Jul 17, 2017, 10:38 am by J-M-L
Bonjour

bon pour vous aider à mettre votre code en forme, voici la structure du code pour une machine à état avec un switch à droite et à gauche en bout de rail et 2 switches au milieu, un pour un coca et un pour du jus

Je vous propose d'étudier ce code

Il n'est pas complet mais devrait être fonctionnel au niveau des commandes par le port Série (à 115200 bauds). Attention j'ai changé vos Nos de pin, lisez le code pour voir qui doit se connecter où

le fonctionnement:

-->  On considère que l'anti-rebond des limit switch est géré en matériel (rajoutez un condensateur)

- à l'allumage le charriot doit aller tout à gauche et se mettre au repos, en attente de commande
- vous envoyez J pour Jus, ou C pour coca (ou D ou G pour aller à Droite ou Gauche)
- le chariot se met en marche, le système attend l'événement qui va bien
- une fois arrivé sous la bonne pompe le système sert pendant 2 secondes puis va se ranger à Droite pour livrer le verre au consommateur
- comme il n'y a pas de détecteur pour savoir si le verre a été pris, il faudra renvoyer à la main la commande 'G' pour retourner à Gauche en attente d'une autre commande. (on pourrait aussi modifier le code pour qu'une fois à droite la commande parte vers la gauche pour aller servir un coca ou un jus, je vous laisse le faire)
- la livraison du liquide ne devrait pas se faire avec un délai car vous ne pouvez pas envoyer de commande par le port série à ce moment là. En cas de problème avec les pompes (verre pas en dessous, pompe qui ne se ferme pas, verre qui fuit, ...) vous ne pouvez rien faire --> je vous laisse modifier la machine à état pour le faire


je n'ai pas votre système, j'ai tapé ça au kilomètre donc ce n'est pas testé (mais ça devrait compiler). dites moi si ça fonctionne pour vous.




Le code est en PJ car dépasse les 9000 caractères autorisés
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

eden99

Bonsoir,
c est vraiment agréable de constater que d autres que moi bossent sur le code.
Ce qui est motivant, c est de voir , qu il n y a pas une ni deux solutions mais de multiple combinaison de bonnes idées .
Honnêtement, je ne comprends pas tout chaque fois, j essaye , je teste, j'y vais a tatons ... parfois ca marche, d autres fois non !
Je vais tester ce code, voir si j en comprends toutes les lignes, tenter de le retravailler pour l adapter exactement a ma machine . Le comparer avec celui que je suis en train de faire ... au final, grave a votre aide a tous, je suis sur de parvenir a le boucler . Ce que je souhaite, c est en comprendre chaque ligne, savoir ce que je dois modifier pour tel ou tel autres cocktails, combinaison, switchs ...
C est du boulot, d autant que j apprends "sur le tas"
D autant que meme si elle n est pas parfaite, pour le moment cette machine fonctionne ... je me demande si je ne pourrais pas deja la mettre dans "projets et réalisations" !?
En tout cas, Merci beaucoup de l aide apportée !!!


J-M-L

Je suis un peu plus avancé que vous en programmation alors j'ai pris 30 minutes pour pondre une structure de machine à état qui sera évolutive

Si vous avez lu mon autre tuto, c'est le même principe

On attend des événements
On déclenche une action appropriée suivant l'événement et l'état dans lequel on se trouve et on passe dans un nouvel état
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

Artouste

Bonsoir,
c est vraiment agréable de constater que d autres que moi bossent sur le code.
Ce qui est motivant, c est de voir , qu il n y a pas une ni deux solutions mais de multiple combinaison de bonnes idées .
Honnêtement, je ne comprends pas tout chaque fois, j essaye , je teste, j'y vais a tatons ... parfois ca marche, d autres fois non !
Bonsoir
:smiley-mr-green:
C'est aussi un peu le but du jeu ! , non ? 8)
Tu es dans de bonnes mains avec les conseils/reponses de J-M-L

eden99

le paradoxe étant que, pour ma part, je ne bois jamais d alcool !!!  :smiley-roll:

J-M-L

Ben il suffit de remplacer les bouteilles par des jus - et faire des cocktails sans alcool :)
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

Artouste

le paradoxe étant que, pour ma part, je ne bois jamais d alcool !!!  :smiley-roll:

Il existe peu ou prou des capteurs pour "tout" 8)

Mettre dans la gestion de ta  machine à état un capteur "vérifiant"  que c'est bien "sans alcool" sera alors une simple formalité ..  

eden99

#38
Jul 18, 2017, 12:16 am Last Edit: Jul 18, 2017, 12:30 am by eden99
Voici une photo du prototype, tel qu'il est remonté a ce jour .
Avec les bouteilles/Jus dans l ordre ou je les ai mis. J ai aussi modifier un peu l application ANdroid pour coller au plus pres aux différents cocktails réalisables.
D ailleurs si quelqu un ici est capable de la devellopper sous Xcode pour IPhone, ca en interessera plus d un, ne serait ce que dans mon entourage.

Vous verrez que j ai changer le servo Moteur par un actuateur linéaire (mini verin 12v), un peu plus lourd, certes, mais aussi plus puissant et efficace .

Les tuyaux transparents qui ressortent, sont ceux reliés au pompes 1.2.3 et 4 dans cet ordre.
C est pas encore tres propre, mais c'est en en voie !

Je  poste car ca peut inspirer ceux qui passent du temps sur le code.

eden99

Merci a JML pour son Code que j ai un peu retravaillé, pour l adapter a la machine et aux différents cocktails. Si vous pouviez y jeter un œil, histoire de contrôler que je n'ai pas fais de boulettes...

 2 interrogations toutefois:

-qu entendez vous exactement par "anti-rebond" au niveau de la gestion matériel ?

- Dans le programme, il est question de livrer le verre servi vers le REPOS_DROITE, pourtant, lors de l envoi d ordre (case 1.2 ...) on part toujours du switch REPOS_GAUCHE,
est ce a dire qu il faudra toujours faire repartir le mobile sur REPOS_GAUCHE une fois la précédente livraison effectuée avant d envoyer un nouvel ordre ?
auquel cas, ne serait il pas plus simple de faire la livraison directement sur REPOS_GAUCHE ?

Bonne journée

J-M-L

#40
Jul 18, 2017, 03:07 pm Last Edit: Jul 18, 2017, 03:41 pm by J-M-L
-qu'entendez vous exactement par "anti-rebond" au niveau de la gestion matériel ?
Vos limit switch ne sont que des boutons. les boutons ça "rebondit" (bounce) et comme votre programme peut tourner vite il se peut que cela génère des incohérences pendant quelques millisecondes (le programme voit le verre au bon endroit puis ne le voit plus). A priori tel que c'est codé ce n'est pas un soucis mais si vous vouliez faire de l'analyse plus fine du déplacement ça pourrait l'être. (impression d'avoir quitté un des switch en se déplaçant à gauche par exemple puis dans le tour d'après voir qu'on y est encore).


- Dans le programme, il est question de livrer le verre servi vers le REPOS_DROITE, pourtant, lors de l envoi d ordre (case 1.2 ...) on part toujours du switch REPOS_GAUCHE,
est ce a dire qu il faudra toujours faire repartir le mobile sur REPOS_GAUCHE une fois la précédente livraison effectuée avant d envoyer un nouvel ordre ?
auquel cas, ne serait il pas plus simple de faire la livraison directement sur REPOS_GAUCHE ?
Oui c'est un choix que j'ai fait (histoire de vous laisser un peu de boulot et de compréhension du code :) ) en me disant que s'il y a un barman d'un côté qui met le verre et de l'autre le client qui le prend ça permet de différencier les 2 bouts.

cf l'explication que j'avais donné plus haut:
- comme il n'y a pas de détecteur pour savoir si le verre a été pris, il faudra renvoyer à la main la commande 'G' pour retourner à Gauche en attente d'une autre commande. (on pourrait aussi modifier le code pour qu'une fois à droite la commande parte vers la gauche pour aller servir un coca ou un jus, je vous laisse le faire)

------
Sinon j'ai jeté un coup d'oeil au code

- je vous ai donné le squelette du code, faudrait maintenant nettoyer. vous voyez qu'il y a beaucoup de code qui se ressemble dans chacune des fonctions appellées lors d'un click sur un des switch, tout cela pourrait donc être fait dans une seule fonction qui prendrait en paramètre le switch activé et comparerait cela avec l'état à atteindre.

-  pour faire des mélanges ça ne va pas fonctionner. Vous faites cela dans le "si j'ai reçu une commande"
Code: [Select]
        case '3':
          if (etatCourant == REPOS_GAUCHE) { // On ne peut commander que quand le système est au repos
            // on se met alors en mouvement et on attend le switch Rhum
            etatCourant = Vers_Rhum;
            allerVersLaDroite();
            // on se remet alors en mouvement et on attend le switch Curacao
            etatCourant = Vers_Curacao;
            allerVersLaDroite();
            // on se remet alors en mouvement et on attend le switch Lait de Coco
            etatCourant = Vers_LaitdeCoco;
            allerVersLaDroite();
            // on se remet alors en mouvement et on attend le switch Jus Ananas             
            etatCourant = Vers_Ananas;
            allerVersLaDroite();
          }
          break;

ce qu'il va se passer c'est que vous allez enchainer toutes le actions les unes après les autres si vous êtiez sur le repos Gauche -> passer à l'état Vers_Rhum, déclencher le moteur vers la droite, puis tout de suite changer l'état Courant à  Vers_Curacao, continuer à aller à droite, changer encore l'état Courant à Vers_LaitdeCoco, continuer à droite et changer enfin encore l'état Courant à Vers_Ananas et continuer à droite. Là vous sortez du if et la machine à état se lance et ne va attendre que le dernier état choisis, Vers_Ananas

si vous voulez plusieurs boisson il faut complexifier un peu votre machine a état. Si vous commandez un "Blue Hawaiian" (Rhum, Curacao, Lait Coco, Ananas) vous devez mémoriser dans une variable globale que vous avez commandé un cocktail.

vous déclenchez d'abord Vers_Rhum et sortez du if. la machine a état va se mettre à tourner et attendant d'arriver sous le Rhum. là vous mettez une dose de Rhum et ensuite il faut tester la commande de cocktail pour décider quoi faire ensuite. si le cocktail est "Blue Hawaiian" alors seulement à partir de ce moment là le prochain état sera Vers_Curacao. Une fois le Curacao, là encore il faut tester quel cocktail a été choisi et passer l'état à Vers_LaitdeCoco etc...


--> tout cela va être un peu laborieux, et donc si vous voulez servir des cocktails il faudra changer à mon avis la structure du programme et fabriquer un tableau de struct qui contiennent pour chaque cocktail

- le No de commande
- un tableau de limitSwitch (ou de structure si chaque dosage doit être précis, par exemple éventuellement une durée et nombre de dose de versement de liquide).

le code ensuite se simplifiera grandement, pour définir un cocktail il suffit de rajouter une struct dans le tableau des commandes en donnant (dans l'ordre sinon faudra complexifier les tests de déplacement) la liste des arrêts sous les bouteilles jusqu'à la livraison --> toutes les commandes seront traitées de la même façon en cherchant dans le tableau quelles sont les instructions à suivre


Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

eden99

Merci de ces éclaircissements.

Quote
-  pour faire des mélanges ça ne va pas fonctionner. Vous faites cela dans le "si j'ai reçu une commande"
Evidement ca paraissait trop facile  :smiley-confuse:

Quote
'si vous voulez plusieurs boisson il faut complexifier un peu votre machine a état. Si vous commandez un "Blue Hawaiian" (Rhum, Curacao, Lait Coco, Ananas) vous devez mémoriser dans une variable globale que vous avez commandé un cocktail.'
Si vous vous pensez a ceci(voir code ci apres), en fait c est ce que j avais commencé a faire grace a votre Tuto.

Code: [Select]

void BlueHawaiian()
{
  switch (etatCourant) {
    case REPOS_GAUCHE:
      break;

    case MOUVEMENT_VERS_REPOS_GAUCHE:
      break;

    case Vers_Whisky:
      break;

    case Vers_CitronVert:
      break;

    case Vers_Rhum:
     // On arrête le moteur
      arretMoteur();

      // On sert le Rhum
        digitalWrite(Doseur_Pousse, HIGH);                 // Declenche le bouchon doseur grace a l actionneur Lineaire
        delay(1500);
        digitalWrite(Doseur_Pousse, LOW);
        delay(1000);
        digitalWrite(Doseur_Retour, HIGH);
        delay(1500);
        digitalWrite(Doseur_Retour, LOW);

      // On se remet en marche pour aller livrer le Verre à Droite
      allerVersLaDroite();
      etatCourant = MOUVEMENT_VERS_REPOS_DROITE;
      break;

    case Vers_Coca:
      break;

    case Vers_Sprite:
      break;

   case Vers_Curacao:
      // On arrête le moteur
      arretMoteur();
     
      // On sert le Curacao
        digitalWrite(Doseur_Pousse, HIGH);                 // Declenche le bouchon doseur grace a l actionneur Lineaire
        delay(1500);
        digitalWrite(Doseur_Pousse, LOW);
        delay(1000);
        digitalWrite(Doseur_Retour, HIGH);
        delay(1500);
        digitalWrite(Doseur_Retour, LOW);

      // On se remet en marche pour aller vers le Rhum à Gauche
      allerVersLaGauche();
      etatCourant = MOUVEMENT_VERS_REPOS_GAUCHE;
      break;

    case Vers_LaitdeCoco:
      // On arrête le moteur
      arretMoteur();
     
      // On sert le Lait de Coco
        digitalWrite(Doseur_Pousse, HIGH);                 // Declenche le bouchon doseur grace a l actionneur Lineaire
        delay(1500);
        digitalWrite(Doseur_Pousse, LOW);
        delay(1000);
        digitalWrite(Doseur_Retour, HIGH);
        delay(1500);
        digitalWrite(Doseur_Retour, LOW);

      // On se remet en marche pour aller vers le Curacao à Gauche
      allerVersLaGauche();
      etatCourant = MOUVEMENT_VERS_REPOS_GAUCHE;
      break;

    case Vers_Orange:
      break;

    case Vers_Ananas:
      // On arrête le moteur
      arretMoteur();
     
      // On sert le Jus Ananas
      allumerPompe(pompeJusAnanasPin);
      delay(5000);
      eteindrePompe(pompeJusAnanasPin);

      // On se remet en marche pour aller vers la lait de Coco à Gauche
      allerVersLaGauche();
      etatCourant = MOUVEMENT_VERS_REPOS_GAUCHE;
      break;

    case Vers_Vodka:
      break;

    case Vers_Canne:
      break;

    case Vers_Tequila:
      break;

    case MOUVEMENT_VERS_REPOS_DROITE:
      break;

    case REPOS_DROITE:
      break;
    }
  }


Esr ce bon ? au moins en partie... SVP dites Oui   :smiley-red:

Quote
donc si vous voulez servir des cocktails il faudra changer à mon avis la structure du programme et fabriquer un tableau de struct qui contiennent pour chaque cocktail
- le No de commande
- un tableau de limitSwitch (ou de structure si chaque dosage doit être précis, par exemple éventuellement une durée et nombre de dose de versement de liquide).
Alors, déclarer, initialiser une structure, oui j ai fait ca une fois ... mais un Tableau de structure !!! ca ressemble a quoi.?

Pour les N° de commande, je reprendrais les memes que sur l Appli Android.
Pour les dosages, si on exceptent les pompes, que l on peut gerer avec du delay ... si si on peut  :P  !!!
Les bouchons doseurs les geres deja (50cl, 35cl et 25cl)
Quant a l'ordre, oui on ira dans l ordre des bouteilles tels qu elles sont disposées, pas la peine de gerer des aller-retour pour certains cocktails

De toutes les facons, les 2 solutions, meme le premiere, laborieuse peut etre, m interressent . Plus j en apprends, moins stupides seront mes questions.

  :'(  ... mais ou est mon minuscule code remplis de "delay"qui tenait en 3 lignes et qui somme toute, ne fonctionnait pas trop trop mal....  ;)

J-M-L

Quote
:'(  ... mais ou est mon minuscule code remplis de "delay"qui tenait en 3 lignes et qui somme toute, ne fonctionnait pas trop trop mal....  ;)
oui bien sûr... mais vous étiez le premier à dire que ça ne tenait pas la route à l'usage et qu'il se désynchronsait... donc code simple, mais bar inutilisable... :)


---

Non malheureusement il faut comprendre que la machine à état telle que définie gère des cibles basées sur la définition d'un état (versJus par exemple) et donc si vous voulez la laisser telle quel il faut que lorsque vous arrivez à l'état cible, dans dans la définition de la nouvelle action suivante,  il faudra prendre en compte le composant du cocktail qui suit donc pas juste demander d'envoyer le chariot à droite.
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

J-M-L

#43
Jul 20, 2017, 11:51 am Last Edit: Jul 20, 2017, 11:53 am by J-M-L
Bon j'ai eu un peu de temps hier soir, j'ai pondu un nouvelle mouture du code qui est plus simple (tableaux pour la gestion des pins, structures pour la définition des boissons) à étendre.

je vous laisse explorer cela, je n'ai absolument pas testé, donc c'est à vérifier. Mais vous aurez une idée de comment utiliser des structures et tableaux pour simplifier le nombres de callbacks à coder dans la machine des événements. (plus besoin de définir un état par destination)

Bien sûr la machine est en conséquence un peu plus difficile à lire, mais le principe reste le même. On attend un ordre, on démarre la machine, on attend un événement particulier, on le traite et on redonne/attend un nouvel ordre jusqu'à arriver à un état de repos.
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

Go Up