Problème séléction pseudo aléatoire d'une sortie

Bonjour à tous,

Voilà je vous expose mon problème, je veux élaborer un programme qui, à l'aide d'un pont en H permettant de faire passer la puissance (ici modélisé par un L293D) et d'un arduino permet de faire la chose suivante :

Faire tourner un Moteur de manière aléatoire soit à gauche soit à droite à une vitesse aléatoire pendant une durée aléatoire, sauf si une des deux limites du moteur est atteinte, alors il ira forcément dans l'autre sens et toujours à une vitesse aléatoire et pendant une durée aléatoire, puis marquer une pause d'une durée aléatoire et recommencer son cycle.

Le soucis est que je ne parviens pas à le faire tourner de manière aléatoire d'un sens ou de l'autre... Le reste semble fonctionner avec le code suivant, mais cette partie me bloque un peu, donc si l'un d'entre vous avait une idée pour me mettre sur la voie...

`int MotorLeft = 2;
int MotorRight = 4;
int MotorSpeed = 3;
int LeftLimit = A0;
int RightLimit = A1;

void setup() {
  // put your setup code here, to run once:
  pinMode(MotorLeft, OUTPUT);
  pinMode(MotorRight, OUTPUT);
  pinMode(MotorSpeed, OUTPUT);
  pinMode(LeftLimit, INPUT);
  pinMode(RightLimit, INPUT);
  randomSeed(analogRead(A2));
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(random(2000, 5000));
  if (LeftLimit == 0 && RightLimit == 0) analogWrite(MotorSpeed, random(0, 256));
  digitalWrite(MotorLeft || MotorRight, HIGH);
  delay(random(2000, 5000));
  if (LeftLimit != 0) digitalWrite(MotorRight, HIGH);
  digitalWrite(MotorLeft, LOW);
  analogWrite(MotorSpeed, random(0, 256));
  delay(random(2000, 5000));
  if (RightLimit != 0) digitalWrite(MotorLeft, HIGH);
  digitalWrite(MotorRight, HIGH);
  analogWrite(MotorSpeed, random(0, 256));
  delay(random(2000, 5000));
}`

Bonjour bencash62

Tout d'abord, corriges ton post pour mettre ton code entre les balises idoines image

Pour sélectionner un port de façon aléatoire, il faut mettre les ports en tableau,
const int motorLefrRightPorts[ ] = {2, 4};

Si tu n'as que 2 ports, les indices de ces ports seront 0 et 1.
Tu sélectionne un indice de façon aléatoire et tu fait
digitalWrite(motorLefrRightPorts[nombreAléatoire], HIGH);

Cordialement
jpbbricole

:warning: La rédaction de votre message ne répond pas aux critères attendus. Il n'aura sans doute pas de réponse tant que vous n'aurez pas pris en compte et mis en application les recommandations listées dans "Les bonnes pratiques du Forum Francophone”

il n'a rien non plus à faire dans Réalisations et Projets Finis donc je l'ai déplacé dans le forum principal


comme indices

  • vous ne lisez pas LeftLimit et RightLimit
  • cette commande
    digitalWrite(MotorLeft || MotorRight, HIGH);

ne veut rien dire (le ou logique va dire vrai ou faux, ici vrai qui sera traduit en 1 et donc vous envoyez HIGH sur la pin D1...)

plus d'infos / de discussion si vous corrigez votre premier post, merci d'avance.

image
Et donc j'ai oublié de vous joindre un schéma du montage que voici.

J-M-L

Oui le "||" "ou" logique ne fonctionne pas mais c'était pour indiquer l'endroit du code où se situe mon problème. Lire LeftLimit et RightLimit ?
Je ne comprend pas pourquoi je devrais le faire...

jpbbricole

Je devrais donc insérer dans mon setup une commande
const int MotorLRPorts[] = {2, 4};
Sommes nous bien d'accord que je ne dois rien mettre entre les crochets ?

Puis je n'aurais qu'à appeler un des deux ports au hasard dans mon loop à l'aide de la commande
digitalWrite(MotorLRPorts[random(0, 2)], HIGH);

D'avance merci à vous, ma femme me harcèle pour que je termine ce projet...

Un digitalRead serait pas mal

if (LeftLimit == 0 && RightLimit == 0)

Parce que les valeurs sinon sont connues

int LeftLimit = A0;
int RightLimit = A1;

Oui le compilateur va calculer la taille pour vous

Pas tout à fait car si on met un port à HIGH, il faut mettre l'autre à LOW (ne pas donner les deux sens en même temps. Pour éviter un problème:

digitalWrite(MotorLRPorts[0], LOW);
digitalWrite(MotorLRPorts[1], LOW);
digitalWrite(MotorLRPorts[random(0, 2)], HIGH);

Ainsi ils ne peuvent être à HIGH en même temps même pendant 1µs

Parce que les valeurs sinon sont connues

Ah oui effectivement je n'avais pas prêté attention à ce détail comme je n'ai pas mis les capteurs sur le montage mais ç peut être utile pour la suite.
Ce qui nous donne

int MotorLeft = 2;
int MotorRight = 4;
int MotorSpeed = 3;
int LeftLimit = A0;
int RightLimit = A1;
const int MotorLRPorts[] = {2, 4};

void setup() {
  // put your setup code here, to run once:
  pinMode(MotorLeft, OUTPUT);
  pinMode(MotorRight, OUTPUT);
  pinMode(MotorSpeed, OUTPUT);
  pinMode(LeftLimit, INPUT);
  pinMode(RightLimit, INPUT);
  randomSeed(analogRead(A2));
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(random(2000, 5000));
  digitalWrite(MotorLRPorts[0], LOW);
  digitalWrite(MotorLRPorts[1], LOW);
  digitalRead(LeftLimit);
  digitalRead(RightLimit);
  if (LeftLimit == 0 && RightLimit == 0) analogWrite(MotorSpeed, random(0, 256));
  digitalWrite(MotorLRPorts[random(0, 2)], HIGH);
  delay(random(2000, 5000));
  if (LeftLimit != 0) digitalWrite(MotorLRPorts[1], HIGH);
  digitalWrite(MotorLRPorts[0], LOW);
  analogWrite(MotorSpeed, random(0, 256));
  delay(random(2000, 5000));
  if (RightLimit != 0) digitalWrite(MotorLRPorts[0], HIGH);
  digitalWrite(MotorLRPorts[1], HIGH);
  analogWrite(MotorSpeed, random(0, 256));
  delay(random(2000, 5000));
}

Mais lorsque j'exécute le code en simulation sur le montage précédent mon moteur effectue un mouvement dans le sens anti-horaire, puis, sans marquer de temps d'arrêt comme je le voudrais, il repars dans le sens horaire, et seulement après marque un temps d'arrêt, je pense qu'il y a une histoire de commande else if et else à insérer sur le loop à la place des deux derniers if mais je n'y parviens pas sans erreur...

Ceci lit le port LeftLimit et ne fait rien de la lecture. Puis la condition porte sur les numéros des broches et pas leur état. Ces trois lignes seraient à remplacer par

  if (digitalRead(LeftLimit) == 0 && digitalRead(RightLimit) == 0) analogWrite(MotorSpeed, random(0, 256));

digitalRead(LeftLimit) == 0 ne serait pas plutôt digitalRead(LeftLimit) == LOW?

Avec des commentaires dans le code, on est plus à même de savoir ce que tu veux faire.

Pour moi le premier delay(random(2000, 5000)); et le tout derniers sont l'un à la suite de l'autre...

Les delay sont bloquant. Ce qui veut dire que si le moteur tourne, il ne s'arrêtera pas sur les fins de course, mais au bout de 3 à 5 secondes.

C'est le sauf si qui ne peut pas être pris en compte

Ce qu'il faut par exemple faire, en français:
~ prendre un temps au hasard
~ arrêter le moteur
~ en fonction des capteurs faire démarrer le moteur
~ ne rien faire si le temps n'est pas écoulé et si on n'arrive pas sur un fin de course
~ attendre 2 à 5 secondes