Bateau autonome Coller aux parois d'une piscine 1/2

Oui mais je ne comprends pas la façon dont tu les résumes

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

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

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?)

Ensuite j'envoie sur A1 le signal

display.println("A1");//define analog pin**************** celui température******************
display.setTextSize(1); 
display.setTextColor(WHITE);//text color
 //*************************  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

//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 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 ? ****************
}

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

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

qui est valide

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

Ça fait beaucoup de questions :slight_smile:

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...

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) :slight_smile: :slight_smile:
Test d’un écran OLED 128×64 I²C – ouilogique.com "

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)

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

Ta fonction bordure (simplifiée) :

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
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 :

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

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.

Super explication !

Merci beaucoup :smiley: :smiley:

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.

et re merci :slight_smile: :slight_smile:

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

tu vas pouvoir passer de la théorie à la pratique :slight_smile:

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

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 :slight_smile: .

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

/*
   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

/*
   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 :slight_smile:
si j'ai bien intégrer le fonctionnement et les variables du servomoteur, je modifie le code suivant

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);

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

Mon 'code' pour les servo est bon ?

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.

ok et merci

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

Surtout par bateau !!! :grin:

Mais j'espère que celui-là il fonctionne au fuell bien gras pour arriver plus vite :grin: :grin: :grin:

Salut

Peut-on changer les input / output comme l'on veut ?

ici l'actuel

// set pin numbers:
const int pingPin = 7;
const int DetecteurPin1 = 2; // the number of the pushbutton pin  Le numéro de l'épingle à commande automatique(presse-bouton)
const int DetecteurPin2 = 4;
const int moteur1 = 3; // the number of the motor pin    le (numéro l'épingle du moteur
const int moteur2 = 11;
const int pompe = 10; // declaration pompe au pin 10

Puis-je faire ceci pour bien ' ranger' les câbles sur la carte ?

// set pin numbers:
const int pingPin = 1;
const int DetecteurPin1 = 2; // the number of the pushbutton pin  Le numéro de l'épingle à commande automatique(presse-bouton)
const int DetecteurPin2 = 3;
const int moteur1 = 4; // the number of the motor pin    le (numéro l'épingle du moteur
const int moteur2 = 5;
const int pompe = 6; // déclaration pompe au pin 6

Si tu n'as pas de problèmes de place, il vaut mieux éviter d'utiliser les pins 0 et 1, réservées pour la COM série (avec le PC notamment). Pour les moteurs, si tu veux faire du PWM, il faudra choisir les pins qui le peuvent. Sinon, pas de problème.

Merci