Projet de solénoïdes se déclenchant aléatoirement

Bonjour à tous !
J’espère que le sujet que je vais créer va parfaitement respecter les règles.

Je me présente brièvement, je suis en fin d’études en création artistique numérique (5ème année après le bac).

J’ai pour projet cette année de créer un circuit électronique contrôlant 6 électrovalves (solénoïdes) via une carte Arduino Mega. Ces 6 électrovalves seront reliés à 6 différents liquides.
Les liquides seront libérés aléatoirement par les solénoïdes grâce à un code de randomisation.
J’ai deux questions : l’une portant sur le circuit électronique même, l’autre sur le code du programme.
Je commencerai pas résoudre celle portant sur l’électronique d’abord.

Je me suis inspiré de ce projet sur instructables pour réaliser le montage du circuit, lui-même inspiré de ce montage.

Les solénoïdes que j’ai acheté sur eBay possèdent les propriétés suivantes :

Material: body adopts nylon plastic, metal protective casing outside
Pressure range: 0 ~ 0.4 MPA
Temperature range: 0 ~ 80 °
Resistance: 49 Ω around
Current: about 250 ma
Voltage: DC12V

Le transistor utilisé est un TIP120 et la diode est une 1N4004. (Je peux fournir les datasheets s’il le faut).
Contrairement au projet dont je me suis inspiré, j’ai décidé d’alimenter les solénoïdes à l’aide d’une alimentation (le type d'alimentation avec différents embouts) dont voici les propriétés :

12v - 2,5A

Je poste donc une image de mon circuit:

Étant extrêmement novice en électronique, ma question est la suivante :

Le circuit électronique vous semble-t-il correct ? Mais surtout, est-ce que l’alimentation présentée précédemment vous semble suffisante ? Mon programme déclenchant les solénoïdes de façon aléatoire, il se peut que plusieurs solénoïdes se déclenchent au même moment, durant un certain temps : est-ce un soucis ? Est-ce que cela peut-être dangereux ? Si oui, comment puis-je faire ?

Merci d’avance à vous tous, et j'espère ne pas poser des questions trop ridicules...
Fabien.

bonjour
tes 6 solenoïdes vont consommer si tous ON 6*250 mA soit 1.5A
ton alim est prevue pour pouvoir debiter 2.5A donc tu es OK

ton cablage (ce n'est pas un schema) semble aussi OK

Le montage est bon.
Si tu ne veut pas avoir 2 solénoïdes en même temps, tu peux rajouter un petit delay(50) après chaque déclenchement et le tour est joué.

Merci beaucoup de vos réponses, je suis rassuré !

J'ai bien compris pour l'ampérage, c'est ok. Ce que je ne comprends pas c'est pour le voltage, l'alim est de 12v, et les solénoïdes idem, donc si par exemple deux solénoïdes fonctionnent en même temps je n'ai pas besoin de 24v ?
(C'est une question très idiote mais je préfère comprendre ce que je fais quand je fais quelque chose!).

Pour le câblage (merci de la précision), je l'ai fait avec fritzing, cependant j'aimerai remplacé la breadboard par un circuit imprimé pour plus de stabilité (soudures, etc).

Dans fritzing (vous devez surement tous connaître), il y a une section "circuit imprimé", mais cela me paraît peu clair. J'ai trouvé une personne faisant des circuits imprimés près de ma ville (ici) et voudrait lui donner une image claire...
Avez-vous déjà effectué cela ? Peut-être existe-t-il un site web spécialisé dans la réalisation de CI, puis livraison, ce serait une meilleure idée ?

Ci-joint, une photo de la section CI de mon montage dans fritzing :

Merci beaucoup pour votre attention et vos réponses.

Fabien.

PS : Merci pour l'astuce Christian, je reviendrais au code par la suite, je l'ai déjà écrit, j'aurais juste une toute petite question à poser ensuite !

Bonjour,
J'ai essayé de router un circuit avec Fritzing mais j'ai vite abandonné, trop peu pratique.
J'en ai profité pour me mettre à Kicad et là c'est le bonheur. C'est infiniment plus simple que ce que je pensais (à condition d'avoir lu le guide de démarrage qui donne les indispensables raccourcis clavier).
J'ai donc refait mon schéma avec Kicad et je viens d'en terminer le routage.

Je pense graver le circuit moi-même (avec la technique d'impression laser sur papier glacé+fer à repasser, etc..).
Sinon y'a des tarifs abordables chez http://www.circuit-electronique.fr/ (à partir de 20 euros environ), tant qu'on reste dans ce qui se fait de standard. C'est une solution que j'envisage d'utiliser si j'arrive pas à le graver moi-même :slight_smile:

Befa:
Merci beaucoup de vos réponses, je suis rassuré !

J'ai bien compris pour l'ampérage, c'est ok. Ce que je ne comprends pas c'est pour le voltage, l'alim est de 12v, et les solénoïdes idem, donc si par exemple deux solénoïdes fonctionnent en même temps je n'ai pas besoin de 24v ?
(C'est une question très idiote mais je préfère comprendre ce que je fais quand je fais quelque chose!).
...

la tension utile pour chaque solenoïde est de 12V et chaque solenoïde consomme 250 mA
c'est le courant qui doit etre disponible par l'alimentation sous X fois 250 mA.

Pour analogie , chez toi EDF fourni une tension de 230V et ton contrat prevoit un courant disponible MAX, EDF ne modifie pas la tension lorsque tu allume une ou plusieurs lampes :grin:

pour ton circuit imprimé, tu peux aussi utiliser les "cartes à bandes" ... ça permet de faire un prototype évolutif d'un circuit ... c'est plus stable qu'une breadboard et plus souple que le fer à repasser ou les fabricants en ligne

Merci pour le logiciel Kicad, mais il n'a pas l'air si simple que ça... pour un néophyte comme moi en électronique ahah ! :slight_smile:
Et merci pour l'exemple EDf ça me paraît tout à fait clair ! ahah :slight_smile:
Je vais regarder de ce pas du côté des cartes à bandes !

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Je vous poste le code commenté que j'ai commencé pour le déclenchement aléatoire des solénoïdes :

/*
* Solénoïdes Randomisés
*
* Modifié à partir de l’example blink d’Arduino.  Allumé le solénoïde pour un certain 
* nombre de temps, l’éteindre pour un certain nombre de temps.  
*
* Original - http://www.arduino.cc/en/Tutorial/Blink
*/

int analogPin = 1;                  // Solénoïde 1 connecté à l’analogPin 1
int analogPin = 2;                  // Solénoïde 2 connecté à l’analogPin 2
int analogPin = 3;                  // Solénoïde 2 connecté à l’analogPin 3
int analogPin = 4;                  // Solénoïde 2 connecté à l’analogPin 4
int analogPin = 5;                  // Solénoïde 2 connecté à l’analogPin 5
int analogPin = 6;                  // Solénoïde 2 connecté à l’analogPin 6
long randOn = 0;                  // Initialisé une variable pour le temps ON
long randOff = 0;                 // Initialisé une variable pour le temps OFF


void setup()                      // une lecture, quand le sketch démarre
{
 randomSeed (analogRead (0));    // randomisation
 pinMode(A1, OUTPUT);        // définir l’analogPin 1 comme output
 pinMode(A2, OUTPUT);        // définir l’analogPin 2 comme output
 pinMode(A3, OUTPUT);        // définir l’analogPin 3 comme output
 pinMode(A4, OUTPUT);        // définir l’analogPin 4 comme output
 pinMode(A5, OUTPUT);        // définir l’analogPin 5 comme output
 pinMode(A6, OUTPUT);        // définir l’analogPin 6 comme output
}

void loop()                       // lecture en boucle
{
 randOn = random (1000, 2000);    // génère temps ON entre 1 et 2 secondes
 randOff = random (300000, 600000);    // génère temps OFF entre 5 et 10 minutes
   digitalWrite(A1, HIGH);   // ON - déclenche le solénoïde 1 
   delay(randOn);                // attend un temps randomisé pendant ON
   digitalWrite(A1, LOW);    // OFF - éteint le solénoïde 1 
   delay(randOff);               // attend un temps randomisé pendant OFF
//
   digitalWrite(A2, HIGH);   // ON - déclenche le solénoïde 2
   delay(randOn);                // attend un temps randomisé pendant ON
   digitalWrite(A2, LOW);    // OFF - éteint le solénoïdes 
   delay(randOff);               // attend un temps randomisé pendant OFF
//
   digitalWrite(A3, HIGH);   // ON - déclenche le solénoïdes 
   delay(randOn);                // attend un temps randomisé pendant ON
   digitalWrite(A3, LOW);    // OFF - éteint le solénoïdes 
   delay(randOff);               // attend un temps randomisé pendant OFF
//
   digitalWrite(A4, HIGH);   // ON - déclenche le solénoïdes 
   delay(randOn);                // attend un temps randomisé pendant ON
   digitalWrite(A4, LOW);    // OFF - éteint le solénoïdes 
   delay(randOff);               // attend un temps randomisé pendant OFF
//
   digitalWrite(A5, HIGH);   // ON - déclenche le solénoïdes 
   delay(randOn);                // attend un temps randomisé pendant ON
   digitalWrite(A5, LOW);    // OFF - éteint le solénoïdes 
   delay(randOff);               // attend un temps randomisé pendant OFF
//
   digitalWrite(A6, HIGH);   // ON - déclenche le solénoïdes 
   delay(randOn);                // attend un temps randomisé pendant ON
   digitalWrite(A6, LOW);    // OFF - éteint le solénoïdes 
   delay(randOff);               // attend un temps randomisé pendant OFF
}

Les liquides sont libérés avec une fonction ON et une fonction OFF aléatoire sur chaque solénoïdes : La fonction OFF dure entre 5 et 10 minutes aléatoirement, la fonction ON dure entre 1 et 2 secondes (temps d'écoulement du liquide). J'ai essayé de choisir un intervalle qui permettrait d'avoir une libération régulière mais pas trop récurrentes pour ne pas avoir à remplir les bouteilles de liquide tous les quarts d'heures ! (l'installation doit être prévu pour fonctionner la journée, en continue).

Le code vous semble-t-il correct ? Je n'ai pas fait d'erreur ?

c'est correct mais tout dépend de ce que tu appelles "allumer des vannes aléatoirement"

tu allumes vanne1 pendant randOn
tu attends randOff
tu allumes vanne2 pendant randOn
tu attends randOff
etc ...

donc tes vannes sont allumées l'une après l'autre ... dans l'ordre ... et tant que tu n'as pas bouclé sur tes 6 vannes, le délai randOn et randOff reste le même ...

ce ne sera pas les grandes eaux de Versaille ...

meme remarque que B83s
il ne faut pas jouer avec delay, mais avec millis()
de plus tel que defini tes random genereront toujours la meme chose apres un reset , le random est un generateur pseudo aleatoire.

une bonne solution est d'utiliser un randomSeed();
avec comme argument une entrée analogique laissée en l'air
par exemple

randomSeed(analogRead(0));

Ah non mince...
Je voudrais que les 6 vannes fonctionnent "en même temps" (enfin pas l'une après l'autre obligatoirement).
Et pas le même délai pour les 6 à chaque boucle.

Je comprends que j'ai mal géré le code au niveau du loop mais comment je dois modifier si je veux vraiment de l'aléatoire ?

Est-ce que je suis clair ?

Exemple si la vanne 1 se déclenche (ON : 2 secondes) puis s'arrête (OFF : 6 minutes). Je voudrais qu'une autre vanne démarre n'importe quand et n'ai pas besoin d'attendre la fin du OFF de la vanne 1 pour démarrer

:frowning:

Bonjour,
Pour chaque vanne il faut en fait découpler le calcul des moments d'ouverture/fermeture, de leur commande.
En gros tu calcules d'abord quand tu dois allumer/fermer les vannes et ensuite dans la boucle du vérifies pour chaque vanne ce que tu dois faire en fonction du temps indiqué (typiquement par millis()).

Ainsi chaque vanne est commandée indépendamment des autres, sans blocage.

Comme l'a dit Artouste ... il ne faut pas utiliser les delay (ça fige le programme) mais millis() qui compte le temps qui passe (en millisecondes) ...

par exemple ... pour chaque vanne tu dois gérer une "date" d'allumage et une "date" d'extinction

tu initialises ces "dates" dans des tableaux (plus facile à gérer par la suite)
unsigned long dateON[6]; //dates en milliseconde d'alumage des vannes
unsigned long dateOFF[6]; //dates en milliseconde d'extinction des vannes

dans le setup tu initialises ces tableaux avec des valeurs "aléatoires "

for (byte i = 0; i < 6; i++) {
       dateON[i] = random(600000); //allumage entre 0 et 10 min ... soit 600 000 ms ... on part de zero ici, sinon tu dois attendre au moins 5 minutes avant qu'une vanne s'allume
       dateOFF[i] = dateON[i] + random(1000,2000); //date d'extinction entre 1 et 2 s après la date d'allumage
}

le loop

void loop() {
for (byte i = 0; i < 6; i++) { //on teste toutes les vannes
     if (millis() > dateON[i]) { //la date d'allumage de la vanne i est atteinte
           //allumer la vanne i
     }

     if (millis() > dateOFF[i]) {  //la date d'extinction de i est atteinte
           //eteindre la vanne i

           //ensuite on doit recalculer une nouvelle date d'allumage et d’extinction de cette vanne
            dateON[i] = millis() + random(300000,600000); //date allumage dans 5 à 10 min à partir de maintenant
            dateOFF[i] = dateON[i] + random(1000,2000); //date d'extinction entre 1 et 2 s après la date d'allumage
     }
} //fin du loop

B83s:
Comme l'a dit Artouste ... il ne faut pas utiliser les delay (ça fige le programme) mais millis() qui compte le temps qui passe (en millisecondes) ...

par exemple ... pour chaque vanne tu dois gérer une "date" d'allumage et une "date" d'extinction

tu initialises ces "dates" dans des tableaux (plus facile à gérer par la suite)
unsigned long dateON[6]; //dates en milliseconde d'alumage des vannes
unsigned long dateOFF[6]; //dates en milliseconde d'extinction des vannes

dans le setup tu initialises ces tableaux avec des valeurs "aléatoires "

AMHA il faut relancer un random pour la vanne considérée lorsque le temps de OFF est atteint pour cette vanne
sinon une vanne donnée aura toujours le meme comportement apres le setup

@Artouste ...

oui

Artouste:
AMHA il faut relancer un random pour la vanne considérée lorsque le temps de OFF est atteint pour cette vanne
sinon une vanne donnée aura toujours le meme comportement apres le setup

oui c'est ce que je propose dans le loop ... quand on éteind la vanne, je recalcule la prochaine date d'allumage et une nouvelle durée d'allumage ...

B83s:
@Artouste ...

oui
oui c'est ce que je propose dans le loop ... quand on éteind la vanne, je recalcule la prochaine date d'allumage et une nouvelle durée d'allumage ...

:grin:
J'avais parcouru trop vite :sunglasses:

Merci de m'aider, et avec les commentaires j'ai plus ou moins compris ce qui m'a été donné
Donc pour l'instant j'ai ce code :

unsigned long dateON[6] = {1, 2, 3, 4, 5, 6};  
unsigned long dateOFF[6] = {1, 2, 3, 4, 5, 6}; 

void setup()             
{
for (byte i = 0; i < 6; i++) {
       dateON[i] = random(600000); 
       dateOFF[i] = dateON[i] + random(1000,2000); 
}

void loop() {
for (byte i = 0; i < 6; i++) {            
     if (millis() > dateON[i]) }

     if (millis() > dateOFF[i]) {  
                    dateON[i] = millis() + random(300000,600000);
                    dateOFF[i] = dateON[i] + random(1000,2000); 
     }
}

Mais je comprends pas trop où et quand déclarer mes analogpin ?
Enfin je dois pas être clair mais je pense comprendre qu'il manque quelque chose pour faire fonctionner mes 6 valves puisque le code ne les mentionnes à aucun moment (mis à part i).

Ce que j'ai rajouté au début ce n'est pas suffisant quand même ?

unsigned long dateON[6] = {1, 2, 3, 4, 5, 6};  
unsigned long dateOFF[6] = {1, 2, 3, 4, 5, 6};

En fait je ne sais même pas si c'est correct...
Désolé de mon amateurisme... J'essaie de comprendre.

Bonjour,
il manque en effet la déclaration des pin... et l'écriture de leur état! Il faut un autre tableau contenant les pin utilisées :

/*
* Solénoïdes Randomisés
 *
 */

int digitalPin[6] = {1, 2, 3, 4, 5, 6};    // déclatation des 6 pin utilisées

unsigned long dateON[6];      // temps en ms avant ON
unsigned long dateOFF[6];     // temps en ms avant OFF

void setup()             
{
  randomSeed (analogRead (A0));    // randomisation
  for (byte i = 0; i < 6; i++) 
  {
    pinMode(digitalPin[i], OUTPUT);        // déclaration output
    dateON[i] = random(600000);     // premier déclenchement
    dateOFF[i] = dateON[i] + random(1000,2000); 
  }
}

void loop() 
{
  for (byte i = 0; i < 6; i++)    // Gestion en boucle des 6 solénoïdes
  {            
    if (millis() > dateON[i]) 
    {
      digitalWrite(digitalPin[i], HIGH);   // ON - déclenche le solénoïde
    }

    if (millis() > dateOFF[i]) 
    {  
      digitalWrite(digitalPin[i], LOW);   // OFF - éteint le solénoïde
      dateON[i] = millis() + random(300000,600000);    // prochain déclenchement
      dateOFF[i] = dateON[i] + random(1000,2000);    
    }
  }
}

je n'ai pas essayé, mais en théorie ça marche!

oui ton dernier code a l'air pas mal ...

tu peux le rester sans les électrovannes avec des Serial.print à chaque fois que tu allumes/eteinds une vanne ...

Je vous donne des infos, dès que j'ai essayé le code !

Par contre j'ai deux autres questions :

  • Est-ce que je peux brancher mon alim 12v/2,5A directement sur le power jack (je sais pas comment ça s'appelle?) de la carte arduino ? (je pense que oui mais je préfère être sûr...)
    Ou alors il faut que je passe par un cablage vers le GND comme sur mon montage page 1 ?

  • A votre avis, est-ce que je peux faire passer du sel dans un solénoïde ?! Question étrange, mais je préfère vous demander avant d'essayer et d'en détériorer un (ça coûte assez cher). Je vais avoir plusieurs liquides mais j'ai besoin de sel aussi...
    Je vous met le datasheet de mes valves :