aide pour déclenchement solénoide

Bonsoir à tous, ces temps ci je travaille sur un projet de borne arcade dédié aux jeux de tir avec pistolets.
je possède donc un ancien pistolet de la ps2 que j’ai adapté grace à un kit Aimtrak.
Jusque là tout va bien, cela fonctionne.
Pour rajouter du réalisme, j’ai décidé de placer une solénoide en 24v à l’intérieur du pistolet, afin de simuler un léger recul.
Et c’est là qu’il y a un soucis :

Une carte Mosfet reçoit le signal de l’arduino, et l’envoi vers la solénoide via le (-), le (+) vient directement de l’alimentation 24v vers la solénoide. Un transistor traverse le (+) et le (-) de la solénoide, comme il est souvent conseillé.
Les (-) sont tous raccordés ensembles (24v) et (arduino).

voici le code:

// RETOUR DE FORCE PISTOLET //
onst int pin1 = 12;     //bouton1
const int pin2 = 11;     //bouton2
const int Sol1 = 10;     //solénoide1
const int Sol2 = 9;     //solénoide2
//---------------------------------------------------------
int Buttonstate1 = 0;   //etat du bouton1
int Buttonstate2 = 0;   //etat du bouton2
//---------------------------------------------------------
void setup() {
pinMode(pin1, INPUT);
pinMode(pin2, INPUT); 
pinMode(Sol1, OUTPUT);
pinMode(Sol2, OUTPUT);   
}

void loop() {
 //---------------------------------------------------------
Buttonstate1 = digitalRead(pin1);
Buttonstate2 = digitalRead(pin2);
//------------------------------------------------------------- 

  if (Buttonstate1 == HIGH) // Si le bouton 1 est activé
  {
    digitalWrite(Sol1, HIGH); // Allumer la solénoide
    delay(100);
    digitalWrite(Sol1, LOW); // solénoide désactivée
    Buttonstate1 = 0;
  }//end boutton1
//------------------------------------------------------------- 
  
  if (Buttonstate2 == HIGH) // Si le bouton 2 est activé
  {
    digitalWrite(Sol2, HIGH); // Allumer la solénoide
    delay(100);
    digitalWrite(Sol2, LOW); // solénoide désactivée
      Buttonstate2 = 0;
}// end boutton 2
//--------------------------------------------------------------
}// end

Malgré des branchements qui semblent corrects, ma solénoide s’enclenche toute seule, malgré que je n’appuie pas sur le bouton. Elle reste bloquée enclenchée :o
J’ai essayé de changer de carte Mosfet, carte arduino, solénoide, rien n’y fait.
je n’y comprends plus rien :fearful:
C’est pourtant pas la mer à boire, mais il y a surement un truc qui m’échappe.

Merci d’avance pour votre aide

Les 4 premier messages de ce forum sont importants, pour la présentation de la question, en particulier pour la présentation du code. A LIRE ABSOLUMENT.

Une carte Mosfet reçoit le signal de l'arduino, et l'envoi vers la solénoide via le (-), le (+) vient directement de l'alimentation 24v vers la solénoide. Un transistor traverse le (+) et le (-) de la solénoide, comme il est souvent conseillé.
Les (-) sont tous raccordés ensembles (24v) et (arduino).

Un schéma permettrait de comprendre. Un papier, un crayon, une photo, on envoie le tout d'abord en pièce jointe, puis en éditant le message, dans le message



void loop() {
 //---------------------------------------------------------
Buttonstate1 = digitalRead(pin1);
//-------------------------------------------------------------

  if (Buttonstate1 == HIGH) // Si le bouton 1 est activé
  {
    digitalWrite(Sol1, HIGH); // Allumer la solénoide
    delay(100);
    digitalWrite(Sol1, LOW); // solénoide désactivée
    Buttonstate1 = 0;
  }//end boutton1
//-------------------------------------------------------------
}// end

Si je prend juste ça, et si le bouton est appuyé, c'est pareil que:

void loop() {
Buttonstate1 = digitalRead(pin1);
    digitalWrite(Sol1, HIGH); // Allumer la solénoide
    delay(100);
    digitalWrite(Sol1, LOW); // solénoide désactivée
    Buttonstate1 = 0;
}// end

Loop est exécutée en boucle, c'est comme si l'on faisait:

Buttonstate1 = digitalRead(pin1);
    digitalWrite(Sol1, HIGH); // Allumer la solénoide
    delay(100);
    digitalWrite(Sol1, LOW); // solénoide désactivée
    Buttonstate1 = 0;

Buttonstate1 = digitalRead(pin1);
    digitalWrite(Sol1, HIGH); // Allumer la solénoide
    delay(100);
    digitalWrite(Sol1, LOW); // solénoide désactivée
    Buttonstate1 = 0;

Buttonstate1 = digitalRead(pin1);
    digitalWrite(Sol1, HIGH); // Allumer la solénoide
    delay(100);
    digitalWrite(Sol1, LOW); // solénoide désactivée
    Buttonstate1 = 0;

...

La sélénoïde est allumée 100ms puis éteinte 20ns, le temps des instructions

    Buttonstate1 = 0;

Buttonstate1 = digitalRead(pin1);
    digitalWrite(Sol1, HIGH); // Allumer la solénoide

En gros, elle est toujours allumée si on appuie sur le bouton. Il en est de même pour l'autre bouton.

Pour résoudre ce problème, il faut une variable d'état supplémentaire, boutonPasVu1 qui est mis à faux quand le bouton n'est pas appuyé, et si le bouton est appuyé, on allume la solénoïde 100ms si boutonPasVu1 est faux, et on le passe à vrai. Ainsi si le bouton est toujours appuyé, on ne rallumera pas la solénoïde.

J'ai édité mon premier message, effectivement je n'ai pas pris la bonne balise pour le code, désolé.
J'ai vite fait un petit paint pour vous montrer le schéma de branchement.

Pour le code Arduino, il faut en fait que cela fonctionne de 2 manières différentes, soit on fait une pression simple sur le bouton et la solénoide s'enclenche et se relache, ou alors on reste appuyé et la solénoide refait le cycle indéfiniment tant que le bouton reste appuyé, pour simuler un mitraillage.

merci à vous

Bonjour,

Sur le schema on ne voit pas de résistance de pullup.
Soit il faut une résistance de pullup ou pulldown (selon le câblage) soit il faut utiliser INPUT_PULLUP et dans ce cas l'entrée est à LOW quand le bouton est enfoncé.

Effectivement je n'ai pas de résistance sur mon cablage, (je ne comprends pas trop pourquoi mettre une resistance en fait) la carte Arduino ne suffit pas pour gérer le High/LOW sur une pin ? La Carte Mosfet comprends elle des résistances il me semble, ce n'est pas elle qui agit ainsi ?

Merci pour votre aide, il y a encore beaucoup de flou pour moi, mais ça va rentrer :slight_smile:

Voir le blog Eskimon pour la gestion d'un bouton.

Très très bien fait ce blog, on y apprends pas mal de chose.
Après lecture, et comparaison avec mon utilisation, je vais rajouter une resistance de 10kohms à mon circuit sur l'interrupteur, puis également un condensateurs de 10nf autour de mon interupteur, car ma carte Arduino est toute proche de mon installation informatique qui fait fonctionner ma borne, cela pourrait générer ces fameux parasites.
Je fais les tests et je reviens exposer mes résultats.

Merci

Effectivement sans résistance de pull up (externe ou interne) l'état du bouton n'est pas défini, et l'Arduino peut lire n'importe quoi, en particulier "appuyé".

Par contre dans ton code, il y a deux boutons, un delay pour le premier va empêcher le deuxième d'être analysé. Les deux solénoïdes ne peuvent pas êtres actifs en même temps. C'est un choix possible. Autre possibilité: que les deux boutons soient indépendants. On ne peut plus utiliser delay dans ce cas et il faut se rabattre sur millis (avec sauvegarde de l'instant de départ pour savoir quand agir).

Si on veut un effet "mitraillette", il faut que la solénoïde soit sous tension un certain temps et au repos un autre temps. Il faut donc l'équivalent d'une deuxième delay après le relâchement.

Là ou ce n'est pas clair: il y a un ou deux boutons? Le schéma indique 1, le code 2! Si il n'y a qu'un seul bouton, les delays vont fonctionner

Oui effectivement, il y a deux boutons, car a terme il y aura deux pistolets.
là pour le moment je teste sur un seul, pour voir que tout fonctionne bien.
Il faudra donc que je refasse un autre code en enlevant delay.

j'ai fais un test sur une bread-board, la carte Mosfet reçoit une info (la led du mosfet s'allume) sans que j'appui sur le bouton. et la solénoide s'enclenche et reste enclenchée.
Quand j'appui sur le bouton la led de la carte mosfet et la solénoide s'éteignent .

J'ai pourtant bien rajouté une résistance de 10k sur la pin12, juste avant le bouton, pour le Pullup.
Je suis un peu perdu là, mon Arduino envoi un input sur ma mosfet tout seul, sans appui.

inverse LOW et HIGH dans ton code .

J’y avais pensé également, mais ça ne me parait pas logique, qu’est ce qui fait que ça soit inversé d’un coups ?
j’ai déja fais des montages avec des leds, de ce type là ( sans mosfets) et ça n’était pas inversé.

J'ai refait un test, j'ai inversé dans mon code Low et High, pour que le bouton soit fonctionel:
dès branchement ça s'affolle, le mosfet et le solénoide s'enclenchent tout seul aléatoirement.
Je débranche toute la partie 24v avec le solénoide, la carte mosfet continue de s'affoller.
Je débranche le ground de l'Arduino, cela stoppe, en rebranchant cela s'affole à nouveau.

J'ai pourtant bien ma diode en parallele sur mon solénoide, je suis passé à 2 résistances de 10kohms sur le Input.
J'ai séparé les grounds du circuit 24v de celui de l'arduino, ça n'y a rien changé.

Le problème semble bien venir de l'arduino, qui semble perturbé et envoi des infos aléatoirement.

J'ai refait un test, j'ai inversé dans mon code Low et High, pour que le bouton soit fonctionel:
dès branchement ça s'affolle, le mosfet et le solénoide s'enclenchent tout seul aléatoirement.
Je débranche toute la partie 24v avec le solénoide, la carte mosfet continue de s'affoller.
Je débranche le ground de l'Arduino, cela stoppe, en rebranchant cela s'affole à nouveau.

En débranchant, ce qui n'est pas sous tension ne fonctionne plus, c'est normal. Peut-on avoir le schéma à main levé (c'est souvent mieux qu'un beau schéma mais qui ne correspond pas à la réalité)

Le problème semble bien venir de l'arduino, qui semble perturbé et envoi des infos aléatoirement.

Même combat, le code a bien changé, il nous faut le nouveau. Sans arrêt j'ai un code qui fonctionne un jour, et une petite modif de rien du tout a des conséquences inattendues ailleurs.

J’ai fais un petit schéma sur une feuille de papier de mon branchement
La solénoide et le Mosfet continuent de s’enclencher seuls, même en débranchant tout le 24v le Mosfet s’agite encore.
Lorsque je débranche le bouton+le 24v, le mosfet s’agite encore.
J’ai donc ciblé que le soucis se manifeste quand le ground et le Output sont branché sur le Arduino.

Je précise également qu’il n’y a que 1 bouton et 1 solénoide de branchée, malgré que le code en comporte 2 de chaque, à terme je veux brancher 2 pistolet quand je serais sur qu’un fonctionne bien.

Le code reste inchangé depuis le début, j’ai seulement fait un test d’inverser le HIGH et LOW, j’ai remis depuis à l’original:

// RETOUR DE FORCE PISTOLET //
const int pin1 = 12;     //bouton1
const int pin2 = 11;     //bouton2
const int Sol1 = 10;     //solénoide1
const int Sol2 = 9;     //solénoide2
//---------------------------------------------------------
int Buttonstate1 = 0;   //etat du bouton1
int Buttonstate2 = 0;   //etat du bouton2
//---------------------------------------------------------
void setup() {
pinMode(pin1, INPUT);
pinMode(pin2, INPUT); 
pinMode(Sol1, OUTPUT);
pinMode(Sol2, OUTPUT);   
}

void loop() {
 //---------------------------------------------------------
Buttonstate1 = digitalRead(pin1);
Buttonstate2 = digitalRead(pin2);
//------------------------------------------------------------- 

  if (Buttonstate1 == LOW) // Si le bouton 1 est activé
  {
    digitalWrite(Sol1, HIGH); // Allumer la solénoide
    delay(100);
    digitalWrite(Sol1, LOW); // solénoide désactivée
    Buttonstate1 = 0;
  }//end boutton1
//------------------------------------------------------------- 
  
  if (Buttonstate2 == LOW) // Si le bouton 2 est activé
  {
    digitalWrite(Sol2, HIGH); // Allumer la solénoide
    delay(100);
    digitalWrite(Sol2, LOW); // solénoide désactivée
      Buttonstate2 = 0;
}// end boutton 2
//--------------------------------------------------------------
}// end

l'image du post précédent (que l'on peut mettre en rééditant le post apès coup, en deux fois):

Pour les branchements:

Ce serait bien de savoir quel carte Mosfet tu as utilisé, Il y a 3 bornes + et 3 bornes -, cela nous permet de savoir.

La diode du solénoïde est placée à l'envers sur le schéma? Elle doit être placée de façon à ne pas conduire. Elle n'est là que pour le passage transitoire du courant. Quelle diode est utilisée? De quel côté se trouve la bague?
Tel qu'elle est là, si le mosfet entre en conduction, il va mettre le - solénoïde à au 0V, la diode est passante, elle va mettre le + de la solénoïde à la masse. L'alim a alors sa borne + à la masse.

Le bouton n'est pas câblé correctement, la résistance ne sert à rien. Vu le montage, on peut utiliser la résistance de pullup interne en remplaçant pinMode(pin1, INPUT); par pinMode(pin1, INPUT_PULLUP); . On peut aussi utiliser pour plus cher une résistance externe, mais à brancher entre l'inter et le +5V. telle qu'elle est là si l'interrupteur est ouvert, le niveau n'est pas défini.

Pour tester ce qui se passe, par exemple juste si le programme fonctionne, il vaut mieux y aller pas à pas. Juste d'abord l'Arduino et le bouton. Regarder la sortie avec un multimètre, si tu en as un parce que c'est facile, sinon avec une Led en série avec une résistance de 1kohms, branchées entre la masse et la sortie. La Led s'allume ou le voltmètre indique 5V -> le mosfet conduirait et la solénoïde aussi.

J’ai refait le test, rebranché en suivant mon schéma, et cette fois ci tout fonctionne en passant en INPUT_PULLUP.

je suis ravi, cela fonctionne, et vos aides m’ont appris pas mal de chose.
Merci à vous.
Je n’hésiterais pas à revenir vous exposer le fonctionement des 2 pistolets ensemble.

Comme quoi un bon schéma, ça aide.

Pour une seule solénoïdes, cela fonctionne avec des delay(), mais pour 2, il faudra passer par millis(). A toi de chercher... Pour chaque bouton, il y a trois états:

  • pas appuyé depuis longtemps
  • bobine alimentée
  • bobine plus alimentée, mais on ne peut pas la redéclencher de suite (deuxième temps d'attente). eux machines à états peuvent être une solution...

Bon courage.

Ok merci beaucoups, mais d'abordil y a la partie cablage et intégration dans le pistolet. :slight_smile: