Go Down

Topic: Bateau autonome Coller aux parois d'une piscine 1/2 (Read 3627 times) previous topic - next topic

lesept

Oui mais je ne comprends pas la façon dont tu les résumes
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

ArduinoFree

désolé, j'ai oublié les else à droite
4 choix sinon action par défaut recule        Si tout est négatif alors fonction par défaut recule
if A (avance +1)  ou                                     if A (avance +1 ) Ok alors on avance SINON on passe à
If B (avance +2)  ou                                  else B (avance +2)  Ok alors on avance SINON on passe à
if C (avance +3)  ou                                  else  C (avance +1)  Ok alors on avance SINON on passe à
if D (avance +4 )                                       else  D avance +1)  Ok alors on avance SINON on passe à
else E (recule)   Aucun des 4 alors recule    else E (recule) Tout est NON donc action par défaut
-------------------------------------
-------------------------------------

J'ai suivi ton idée de l'écran  i2C 128x64 OLED
J'ai trouvé ce code ici
http://www.instructables.com/id/Arduino-OLED-Voltage-Meter/

Si j'ai bien compris IC2 prend 2 pin numériques
Dans mon projet, il me reste les pin 13, 12, ~9, 8, ~6 ,~5
Donc 13 et 12 pour l'écran, reste 4 pin  ~9, 8, ~6 ,~5

Je pense ajouter la fonction température.

Chaque ligne
Code: [Select]
display.println();
Affiche une information, il y a donc 4 ligne possibles ?

Je pense ajouter en ajoutant une sonde de température qui prend 0 pin
Thermo resistance (modèle Keyes KY-013?)
http://edu.mrpigg.ca/termo.html
Ensuite j'envoie sur A1 le signal


Code: [Select]

display.println("A1");//define analog pin**************** celui température******************
display.setTextSize(1);
display.setTextColor(WHITE);//text color


Code: [Select]
//*************************  A voir forcement *****************
// température  maxi divisée en 1023 et affichage de 'V'
int sensorValue = analogRead(A1); // converti le signal numérique(va de 0 à 1023) en température
 (0 - ?° ):
float temperature = sensorValue * (?? / 1023.0); // écrit la valeur lue:
display.print(temperature);
display.println("°C");
display.display();

J'ai écrit ça comme ça donc pbssss  sûrement.
Je pense que ce doit être la variable 'temp' qui m'intéresse
Code: [Select]
//Lecture de la valeur du signal analogique de la thermo-résistance et stockage dans valTemp
  valTemp=analogRead(thermo); 
                         
  //Fonction f(signal)=température et stockage du résultat dans la variable temp
  temp = 0.1463 * valTemp - 51.713;   
 
  //Positionne le curseur de l'écran LCD sur la colonne 0, ligne 1
  lcd.setCursor(0, 1);
 
  //Affiche à cette position la valeur de 'temp'               
  lcd.print(temp);


code d'origine
Code: [Select]

/*code by Neranjan Walakulpola
for more help and diagram visit
http://www.http://circuitfreak.net/index.php/2015/05/05/arduino-oled-voltage-meter/
*/

#include #include #include #include
#define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 64) #error("Height incorrect, please fix Adafruit_SSD1306.h!"); #endif
}
void loop(){
delay(1);//delay time 1 mili second
display.clearDisplay();
display.setTextSize(1);//text size
display.setTextColor(WHITE);//text color
display.setCursor(0,0);
display.println("Analog Read V1.0");//affiche texte 1ere ligne
display.setTextColor(BLACK, WHITE);
display.println();
display.println("A0");//define analog pin**************** celui du voltage******************
display.setTextSize(1);
display.setTextColor(WHITE);//text color
display.println();
display.setTextSize(2);//text size
display.setTextSize(2);//text size



// tension de 5 V maxi divisée en 1023 et affichage de 'V' ******** puis-je mettre 12v ?********

int sensorValue = analogRead(A0); // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0); // print out the value you read:
display.print(voltage);
display.println("V");
display.display();

//**************************** Puis-je passer la valeur de 5 à 12 V ? ****************
}



ArduinoFree

On verra plus tard ma compréhension des if et else.



Petit retour sur les BordureDroite et BordureGauche.
Si on a un escalier en Polyester le bord sera incliné et /ou on a peut-être une marche sous peu d'eau mais assez pour le pas pouvoir déclencher les BtnContact.

donc le bateau se colle à un bord.
            Btncontact ok, un moteur validé
Il arrive sur le bord incliné, pas de contact
            pendant 3 sec un moteur continue de tourner

Plus de signal ni de BtnContact ni de ultrasons
            Les 2 moteurs fonctionnent jusqu'à un contact
   Si c'est un bord incliné arrondi, le bateau va suivre la courbure  jusqu'à un contact
   Si c'est une marche noyée, le bateau suivra son  bord  jusqu'à un contact

Ma question est celle-ci
Ai je besoin de remettre une condition ?
Je dirai que si aucune des conditions sont réunie alors c'est
Code: [Select]

 // le bateau se dirige vers une parois.
    digitalWrite(moteur2, HIGH);
    digitalWrite(moteur1, HIGH);
qui est valide

Code: [Select]

void bordureDroite() { // BtnContact2


  // le bateau se dirige vers une parois.
    digitalWrite(moteur2, HIGH);
    digitalWrite(moteur1, HIGH);


  if (cm <= 5){ // parois détectée par ultrason, le bateau pivote à gauche pour coller sur la parois droite
    digitalWrite(moteur2, LOW);
    digitalWrite(moteur1, HIGH);
    //  la pompe fonctionne
    digitalWrite(pompe, HIGH);
  }

  if ( (BtnContact2) && (cm <= 5)) { // contact ET ultrason : le bateau est dans un angle ou arrondi détecté par ultrasons
    digitalWrite(moteur2, HIGH);
    digitalWrite(moteur1, LOW);
    //  la pompe fonctionne
    digitalWrite(pompe, HIGH);
  }

  if ( (BtnContact2) && !(cm <= 5)) { //contact SANS ultrason : le bateau est collé à un bord et le suit
    digitalWrite(moteur2, HIGH);
    digitalWrite(moteur1, LOW);
    //  la pompe fonctionne
    digitalWrite(pompe, HIGH);
    delay (3000);  //  le bateau va dépasser l'angle saillant de la piscine
                   //  on le force à continuer à tourner encore pendant 3 sec
                   //  pour le recoller au bord
  }


// le bateau ne touche pas le bord incliné d'un escalier
// ou le fond du bateau touche une marche immergée
if ( !(BtnContact2) && !(cm <= 5)) { //NI contact NI ultrason : le bateau suit la courbe ou suit la marche immergée
    digitalWrite(moteur2, HIGH);
    digitalWrite(moteur1, HIGH);
    //  la pompe fonctionne
    digitalWrite(pompe, HIGH);
      }
  button();
  }








lesept

Ça fait beaucoup de questions :)

Je ne comprends toujours pas les A, B, C, D et avance+1, 2, 3, 4...

Pour l'écran OLED, le nombre de lignes dépend de la taille de caractères que tu utiliseras. L'avantage de ces écrans c'est que tu peux mettre tes textes où tu veux, ce ne sont pas des lignes fixes comme pour un LCD classique. Tu peux aussi faire des dessins ou afficher des images. Il ne faut que 2 pins en effet : en attendant de le recevoir, tu peux te renseigner sur la mise en oeuvre de l'I2C.

Pour la sonde de température : je n'en ai jamais utilisé. Lorsque tu l'auras reçue, tu peux tester et créer un fil de discussion spécifique (celui-ci est déjà assez long et restera plus général sur l'appli globale).

Pour l'escalier, si le problème (tel que le montre ton schéma) est dû à une limitation des capteurs (le bouton n'est pas adapté à ce cas (tu pourrais le mettre au bout d'une tige ?)), il faut peut-être envisager un autre capteur. Le capteur US (ultrasons) risque de ne pas fonctionner si la paroi est inclinée : tu peux déjà vérifier ça avec ton matériel actuel. Dans ce cas, tu peux soit chercher d'autres capteurs, soit ouvrir un fil de discussion spécifique pour demander des avis à la communauté.
Peut-être qu'un capteur IR (infrarouge) pourrait marcher, mais si c'est dans une piscine en plein soleil, je ne sais pas...
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

ArduinoFree

#64
May 20, 2018, 02:11 pm Last Edit: May 20, 2018, 05:44 pm by ArduinoFree
1 J ai déjà chercher pour ic2 et je continue….

EDit "
Et j'ai trouvé pour expliquer les différentes lignes de l'écran ( voir image jointe)  :)  :)
http://ouilogique.com/test_ecran_oled_i2c_128x64/ "



2 Pour les fonctions Bordure***, c'est bon  avec le dernier if ou bien je l'enlève ?
Mais je pense que je peux l'enlever non ?



3 mon explication pour IF

les conditions A B C D ( les contacts)
avancer, sauter, courir, dormir dont les actions liés aux conditions (contacts) validés
Reculer est l'action qui se produit APRES  vérifications des 4 premières

4 choix sinon action par défaut recule        
if la condition A est vraie, alors l'action est de (avancer)  
ou                                  
If la condition B est vraie, alors l'action est de  (sauter)  
ou                                  
if la condition C est vraie, alors l'action est de  (courir)  
ou                                  
if la condition D est vraie, alors l'action est de  (dormir )  
                                   
else la condition E est vraie, alors l'action est de  (recule)  

Aucun des 4 actions précédentes étant vraie, alors on (recule)  

lesept

J'ai du mal à comprendre ton explication, désolé.

Ta fonction bordure (simplifiée) :
Code: [Select]

void bordureDroite() {
    digitalWrite(moteur2, HIGH);
    digitalWrite(moteur1, HIGH);

  if (cm <= 5){ }

  if ( (BtnContact2) && (cm <= 5)) { }

  if ( (BtnContact2) && !(cm <= 5)) { }

  if ( !(BtnContact2) && !(cm <= 5)) { }

  button();
  }

Tu lances les moteurs, puis tu passes aux tests et enfin tu vérifies les boutons. Ça veut dire déjà que les tests se font avec les états des boutons antérieurs à l'appel de la fonction, ce qui est anormal. Tu dois passer la ligne
Code: [Select]
button();avant les tests.

Ensuite les tests: chaque test est fait et définit une action. Si l'état du bateau vérifie deux tests, tu peux donc avoir les deux actions faites. Par exemple si BtnContact2 est différent de 0 ET si la distance est inférieure à 5cm, les deux premiers tests sont bons, les deux premières actions sont faites. Je pense que ce n'est pas ce que tu veux.

Tu dois formuler tes tests de manière 'exclusive', c'est à dire que tu n'as pas deux tests vérifiés par un état donné. Par exemple :
Code: [Select]

void bordureDroite() {
    digitalWrite(moteur2, HIGH);
    digitalWrite(moteur1, HIGH);
    button();

  if ( !(BtnContact2) && (cm <= 5)){ }

  if ( (BtnContact2) && (cm <= 5)) { }

  if ( (BtnContact2) && !(cm <= 5)) { }

  if ( !(BtnContact2) && !(cm <= 5)) { }

  }
que tu peux écrire aussi
Code: [Select]
void bordureDroite() {
    digitalWrite(moteur2, HIGH);
    digitalWrite(moteur1, HIGH);
    button();

  if (BtnContact2) {
     if (cm<5) { }  // bouton et distance inférieure
     else {  }      // bouton et distance supérieure
    } else {
     if (cm<5) { }  // pas bouton et distance inférieure
     else {  }      // pas bouton et distance supérieure
   }
Là tu es sûr que tous les cas sont testés et sont indépendants.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

ArduinoFree


lesept

Un dernier point : puisque les tests sont exhaustifs, donc il n'y a pas de cas non couvert par les tests, il est inutile de lancer les moteurs avant de faire les tests : les deux premiers digitalWrite de la fonction sont inutiles.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

ArduinoFree

#68
May 21, 2018, 10:52 am Last Edit: May 21, 2018, 10:53 am by ArduinoFree
et re merci  :)  :)

Les pièces commandées commencent à arriver en France

lesept

tu vas pouvoir passer de la théorie à la pratique :)
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

ArduinoFree

C'est ce qui va me paraitre le plus long  >:(  >:(  >:(

ArduinoFree

#71
May 21, 2018, 08:55 pm Last Edit: May 21, 2018, 09:33 pm by ArduinoFree
Bonjour

Bon ben en attendant tous mes jouets, je tente de faire une version avec un servomoteur pour diriger un gouvernail.
Comme cela je pourrai tester les 2 versions de maquette ( avec et sans gouvernail) et me concentrer sur les  pb de conception de la coque  :) .

code original ici
https://www.carnetdumaker.net/articles/controler-un-servomoteur-avec-une-carte-arduino-genuino/

Code: [Select]

/*
   Exemple de code pour un servomoteur, il fait faire des va-et-vient à la tête du servomoteur.
*/

/* Inclut la lib Servo pour manipuler le servomoteur */
#include <Servo.h>

/* Créer un objet Servo pour contrôler le servomoteur */
Servo monServomoteur;

void setup() {

  // Attache le servomoteur à la broche D9
  monServomoteur.attach(9);
}

void loop() {

  // Fait bouger le bras de 0° à 180°
  for (unsigned long position = 1000; position <= 2000; position += 5) {
    monServomoteur.writeMicroseconds(position);
    delay(15);
  }

  // Fait bouger le bras de 180° à 10°
  for (unsigned long position = 2000; position >= 1000; position -= 5) {
    monServomoteur.writeMicroseconds(position);
    delay(15);
  }
}


 

Voici ce que j'ai fait.
J'ai déclaré mon contact BTnContact1, mon pin pour récupérer l'info.
Si BtnContact2 est actif (HIGH), on tourne de 135°  : à fond à droite

Code: [Select]

/*
   exemple de code rotation de 45°( gauche), rotation de 135°( droite),
*/

/* Inclut la lib Servo pour manipuler le servomoteur */
#include <Servo.h>

/* Créer un objet Servo pour contrôler le servomoteur */
Servo monServomoteur;

// set pin number
const int DetecteurPin1 = 4; // le contact 1 est au pin 4
// variables
int BtnContact2 = 0; //  variable pour lire le statut du 1er bouton de contact


void setup() {
  // initialise les boutons contact pins à INPUT, soit actif:
  pinMode(DetecteurPin1, INPUT);
  // Attache le servomoteur à la broche D9
  monServomoteur.attach(9);
  // Relie le BtnContact2 au résultat du DetecteurPin1
  BtnContact2 = digitalRead(DetecteurPin1); // bouton contact à gauche
}

void loop() {

  if (BtnContact2 == HIGH) {
    monServomoteur.write (135); // tourne à fond à droite
  }
  else {
    monServomoteur.write (0);  // on reste à 0° par défaut
  }
}


Le code dit simplement :  si contact rotation du servo de 135°, sinon par défaut je reste à 0°.
Je regarde les autres conditions(BtnContact2) après la validation du prof  :)
si j'ai bien intégrer le fonctionnement et les variables du servomoteur, je modifie le code suivant

Code: [Select]
if ( !(BtnContact2) && !(cm <= 5)) { //Pas de contact et Pas de son
    // le bateau ne touche pas le bord incliné d'un escalier
    // ou le fond du bateau touche une marche immergée
    //NI contact NI ultrason : le bateau suit la courbe ou suit la marche immergée
    digitalWrite(moteur2, HIGH);
    digitalWrite(moteur1, LOW);
    //  la pompe fonctionne
    digitalWrite(pompe, HIGH);
  }


 (les 2 moteurs tournent ensemble sur le même pin donc
digitalWrite(moteur2, HIGH); fait marcher les 2 moteurs
digitalWrite(moteur1, LOW); devient   monServomoteur.write (45);

Code: [Select]
if ( !(BtnContact2) && !(cm <= 5)) { //Pas de contact et Pas de son
    // le bateau ne touche pas le bord incliné d'un escalier
    // ou le fond du bateau touche une marche immergée
    //NI contact NI ultrason : le bateau suit la courbe ou suit la marche immergée
    digitalWrite(moteur2, HIGH); // les moteurs soudés en parallèle sur la carte arduino
   monServomoteur.write (135); // BtnConatct2 dit de tourner à droite, soit 135°
    //  la pompe fonctionne
    digitalWrite(pompe, HIGH);
  }



ArduinoFree


lesept

Je pense que oui, mais je ne suis pas un pro du servo, c'est pourquoi je passais la main à Kammo dans ton autre fil de discussion, car il s'y connait bien mieux que moi.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

ArduinoFree

ok et merci

Je reviendrai quand j'aurai reçu tous mes petits jouets  :)  :) ... Ça va être long  :(  :(  :(  :(  le voyage Chine France

Go Up