Pages: [1]   Go Down
Author Topic: Oscillateur de brassage aquariophile  (Read 2114 times)
0 Members and 1 Guest are viewing this topic.
Chateau-Thierry (02)
Offline Offline
Full Member
***
Karma: 0
Posts: 167
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour

L'aquariophilie récifale nécessite un fort brassage du volume d'eau pour le bien-être des animaux sessiles. Normalement créé par une multitude de pompes de brassages, les variations sont souvent réalisées par la mise en marche, l'arrêt, ou la variation de vitesse de certaines de ces pompes.  La mode actuelle s'oriente vers la mise en mouvement de celles-ci au profit d'une réduction de leur nombre (et donc de la consommation électrique globale).
J'ai réalisé deux oscillateurs supports de pompe, mus par des servomoteurs de modélisme. Bien qu'il existe sur le marché des systèmes de commande de ces servos, je m'oriente aujourd'hui vers une réalisation personnelle afin de rajouter quelques options que je ne pourrais obtenir avec les systèmes existants. Je ne suis pas sûr de pouvoir mener à bien ce projet sans votre aide.
Je n'ai jamais utilisé de système Arduino, et mes seules expériences en informatique se limitent à la création de quelques codes en VB (simples). L'écriture de programmes en PL7 fait également partie de mes expériences lointaines…

Je vous donne donc ci-dessous quelques-unes de mes idées afin d'en valider la possibilité.

Chaque oscillateur aura deux butées programmables (fins de course), et à une vitesse également programmable. Ceci de manière indépendante pour chacun des oscillateurs.

A cela des paramètres différents devront être appliqués en fonction du moment :
- une phase « nocturne » où les vitesses des oscillateurs seront fortement réduites, et les butées de course également (afin de ne pas avoir une pompe qui souffle directement sur un corail pendant une trop longue période).
- Une phase « nourrissage » où les pompes iront se positionner à un endroit précis (ou avec une plage très réduite) durant un temps programmable.
La phase nocturne sera donc fonction de l'heure sans pour autant avoir besoin d'une précision à la seconde. La durée de la phase nourrissage ne nécessite pas non plus une grande précision. Elle sera activée par un bouton poussoir.

Je commence à lire les différents articles sur le sujet des Arduinos (je suis loin d'avoir fini) et je me pose encore de nombreuses questions :
Que se passe-t-il en cas de coupure de courant ? Dans quelle configuration sera l'horloge au retour de la tension ?
Je me demande même si je n'aurais pas intérêt à créer une entrée « remise à midi » (c'est l'heure où j'ai le plus de chance d'être devant le système  ;D) de l'horloge via un bouton Poussoir.
Le positionnement d'un servo sur une consigne est-elle possible ? (je ne l'ai pas encore lu, mais j'imagine que oui).

Bref, je n'en suis qu'au début …Mais il fallait bien se présenter

Franck
Logged

Chateau-Thierry (02)
Offline Offline
Full Member
***
Karma: 0
Posts: 167
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quelques photos des oscillateurs





Logged

Sophia-Antipolis (06)
Offline Offline
God Member
*****
Karma: 4
Posts: 618
Rejoignez le club !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Très intéressant comme projet.

En fait, ce que tu souhaites est tout à fait faisable avec une Arduino, des servomoteurs et un composant qu'on appelle "horloge RTC" : tu peux trouver une extension pour Arduino pour une douzaine d'euros.

L'horloge conserve l'heure et le jour grâce à une pile "bouton" plate comme dans une montre. Tu l'interroges (il existe des librairies pour ne pas avoir à comprendre/apprendre le protocole de communication I2C) quand tu as besoin de vérifier l'heure.

Selon la version du composant, tu peux même avoir une alarme (tu programmes une heure et tu reçois un signal quand cette heure est arrivée) ce qui évite de communiquer en permanence donc de dépenser moins d'énergie.

Pour ma part, j'ai utilisé le DS1307 mais sans Arduino. Le code est donc plus complexe que ce qu'on peut trouver : http://www.pobot.org/Horloge-et-calendrier-I2C.html
« Last Edit: December 26, 2010, 09:40:14 am by julien@pobot.org » Logged

Chateau-Thierry (02)
Offline Offline
Full Member
***
Karma: 0
Posts: 167
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Merci Luj06. smiley-wink

J'étais déjà tombé sur ton site en cherchant les premières infos.

Premières questions :
Je commande cette version : http://radiospares-fr.rs-online.com/web/search/searchBrowseAction.html?method=getProduct&R=696-1655

Puis-je alimenter la carte avec une alim régulée 12Vdc et connecter les servos en direct sur la carte ? Ou bien il me faut une alim en 5Vdc obligatoirement
(La carte intègre-t-elle déjà un régulateur de tension ?)
Alim actuellement retenue : http://radiospares-fr.rs-online.com/web/search/searchBrowseAction.html?method=getProduct&R=4006793

Merci pour votre aide
Edit : correction du 1er lien
« Last Edit: December 27, 2010, 03:44:00 am by Bubule » Logged

Sophia-Antipolis (06)
Offline Offline
God Member
*****
Karma: 4
Posts: 618
Rejoignez le club !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Le premier lien ne fonctionne pas, je ne sais pas quelle version tu commandes.

La carte Arduino intègre bien un régulateur 5 volts, donc il faut juste donner entre 7 et 12 volts à la carte, et reprendre son 5 volts pour alimenter les servomoteurs.

Le régulateur Motorola sort jusqu'à 800 mA, le régime idéal se situant lorsque la différence entre tension d'entrée et tension de sortie est de 2 volts : il serait peut être bon de prendre une alimentation à 7 ou 9 volts plutôt qu'à 12 volts.

Datasheet ici : http://www.datasheetcatalog.org/datasheet/motorola/MC33269D-5.0.pdf


Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

Pour alimenter l'arduino et les montages qui vont autour j'ai fait une petite alim sur une simple carte perforee a bande. Il y a 12V, 9V et 5V a prtir d'une alim 12V et de regulateurs 9V et 5V.

J'ai utilise ce montage, ca fonctionne tres bien sans prise de tete : http://www.pobot.org/A-manger.html
« Last Edit: December 26, 2010, 04:12:06 pm by ostrakow » Logged

Chateau-Thierry (02)
Offline Offline
Full Member
***
Karma: 0
Posts: 167
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah oui, effectivement. Ça fait deux fois que je me plante dans le lien.
Il s'agit de cette version (duemilove328) : http://radiospares-fr.rs-online.com/web/search/searchBrowseAction.html?method=getProduct&R=696-1655
C'est surtout qu'elle était en stock. Livraison prévue demain avant midi
Logged

Chateau-Thierry (02)
Offline Offline
Full Member
***
Karma: 0
Posts: 167
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour
Meilleurs vœux à tous.

Voilà, j'ai passé quelques heures lors de ma semaine de congés à découvrir et plancher sur le programme de mes oscillateurs.

Ce programme fonctionne et permet donc :
- De commander deux oscillateurs indépendamment avec chacun leur vitesse et fins de course.
-  De changer les paramètres butées de fins de course ainsi que la vitesse en fonction de la plage horaire (accalmie nocturne)
- Positionner les pompes durant un temps programmé en position souhaitées, de manière à éviter que les aliments ne partent vers la sur-verse.
Cependant, quelques questions seront émises en fin de post...
Logged

Chateau-Thierry (02)
Offline Offline
Full Member
***
Karma: 0
Posts: 167
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
//  Programme de pilotage oscillateurs de brassage

      // Franck Pongnan - Décembre 2010
  
 //*************************************************************//

#include <Servo.h> //intègre la librairie servomoteurs

// Déclaration des entrées
  int nourrissage = 16;       // Broche Entrée Analogique 2 (pin16) déclarée "top nourrissage"
  
// Déclaration des variables et constantes horloge
  long compteur_top=0;        // Initialisation des tops horloge
  long ancien_millis=0;       // Mémoire de l'horloge millis
  int minute = 0;             // Minutes de l'horloge
  int heure = 19;             // Heures de l'horloge (avec inscription "19h" comme heure initiale)
                                   // Permet de remettre l'horloge à l'heure sur init à 19h00
  
// Déclaration des variables et constantes oscillateur 1
  int bute_J_AV_oscil_1 = 10; // limite débattement avant phase "jour" Oscillateur 1
  int bute_J_AR_oscil_1 = 110;// limite débattement arrière phase "jour" Oscillateur 1
  int bute_N_AV_oscil_1 = 10; // limite débattement avant phase "nuit" Oscillateur 1
  int bute_N_AR_oscil_1 = 90; // limite débattement arrière phase "nuit" Oscillateur 1
  
  int bute_AV_1;              // Variable contenant la butée avant en fonction de la phase horaire
  int bute_AR_1;              // Variable contenant la butée arrière en fonction de la phase horaire
  int vit_J_oscil_1 = 100;    // Vitesse d'oscillation "jour" Oscillateur 1
  int vit_N_oscil_1 = 5;      // Vitesse d'oscillation "nuit" Oscillateur 1
  int vit_1;                  // Variable contenant la vitesse d'oscillation en fonction de la phase horaire
  
  int tps_nourrissage = 5;    // Temps de pause oscillateurs positionnés pour éviter un envoi des aliments vers la surverse (en minutes)
  int posi_nourrissage_1 = 90;// Position oscillateur 1 pendant la phase de nourissage
  int attente_nourrissage = 0;// Variable temps de nourrissage
  
  long calculV_1;             // Calculateur vitesse oscillateur 1
  int sens_1 = 0;             // Sens d'oscillation oscillateur 1
  int pos_servo_1;            // Position du servo de l'oscillateur 1
  Servo servo_oscil_1;        // Consigne variable du servo d'oscillateur N°1 (valeur comprise entre 0 et 180)
  
// Déclaration des variables et constantes oscillateur 2
  int bute_J_AV_oscil_2 = 10; // limite débattement avant phase "jour" Oscillateur 2
  int bute_J_AR_oscil_2 = 95; // limite débattement arrière phase "jour" Oscillateur 2
  int bute_N_AV_oscil_2 = 10; // limite débattement avant phase "nuit" Oscillateur 2
  int bute_N_AR_oscil_2 = 85; // limite débattement arrière phase "nuit" Oscillateur 2
  
  int bute_AV_2;              // Variable contenant la butée avant en fonction de la phase horaire
  int bute_AR_2;              // Variable contenant la butée arrière en fonction de la phase horaire
  int vit_J_oscil_2 = 110;    // Vitesse d'oscillation "jour" Oscillateur 2
  int vit_N_oscil_2 = 4;      // Vitesse d'oscillation "nuit" Oscillateur 2
  int vit_2;                  // Variable contenant la vitesse d'oscillation en fonction de la phase horaire
  
  int posi_nourrissage_2 = 20;// Position oscillateur 2 pendant la phase de nourissage
    
  long calculV_2;             // Calculateur vitesse oscillateur 2
  int sens_2 = 0;             // Sens d'oscillation oscillateur 2
  int pos_servo_2;            // Position du servo de l'oscillateur 2
  Servo servo_oscil_2;        // Consigne variable du servo d'oscillateur N°2 (valeur comprise entre 0 et 180)
  
  
 const int led_int = 13;
 int etat_led = LOW;
 
 

void setup() {

  pinMode (nourrissage, INPUT);     // Déclaration de l'entrée nourrissage
  digitalWrite(nourrissage, HIGH) ; // Activation du pullup de l'entrée 2 (pin 16)

  pinMode (led_int, OUTPUT);

  // Initialise la liaison série
  Serial.begin(19200);
   delay(50);
      
  // Initialise la position du servo d'oscillateur 1
  pos_servo_1 = bute_J_AV_oscil_1;
  // Attache le servo oscilateur 1 à la sortie 8
  servo_oscil_1.attach(8);
    
  // Initialise la position du servo d'oscillateur 2
  pos_servo_2 = bute_J_AV_oscil_2;
  // Attache le servo oscilateur 2 à la sortie 9
  servo_oscil_2.attach(9);
}



void loop() {
  
// Création d'une impulsion temporisée (top) pour déplacements oscillateurs sur la base de l'horloge interne millis()
  int top;
      if (millis() >= ancien_millis) { // Vérifie que le temps millis() est bien supérieur à l'ancienne valeur mémorisée
                                       // >> risque à l'init et au retour à zéro de l'horloge interne.
      if (millis() - ancien_millis >= 100){ top = 1;  // création d'un top toutes les 100ms
              ancien_millis = millis();               // réinitialisation ancien_millis
          compteur_top = compteur_top + 1; }          // Incrémente le compteur de tops
                      }
        
// HORLOGE
    if (compteur_top >= 500) {minute = minute + 1; //Incrémentation des minutes
        compteur_top = 0;        
    }
    if (minute >= 60) {heure = heure + 1; //Incrémentation des heures
        minute = 0;}
    if (heure >=24) {heure = 0;} // réinitialise l'horloge toutes les 24h
    
 // Phase jour / Phase nocturne
   int Periode;  
    if ( heure >= 10 && heure < 22) {Periode = 1;} //Phase diurne (entre 10h et 22h)
        else {Periode = 0;} // Phase nocturne
        
 // Inscription des valeurs en fonction des phases jour / nuit
    if (Periode == 1){ //Phase "jour"
    // pour oscillateur 1
      bute_AV_1 = bute_J_AV_oscil_1;  // Butée AV
      bute_AR_1 = bute_J_AR_oscil_1;  // Butée AR
      vit_1 = vit_J_oscil_1;          // Vitesse oscillateur 1
    // Pour oscillateur 2
      bute_AV_2 = bute_J_AV_oscil_2;  // Butée AV
      bute_AR_2 = bute_J_AR_oscil_2;  // Butée AR
      vit_2 = vit_J_oscil_2;          // Vitesse oscillateur 2
            }
    if (Periode == 0){ //Phase "nocturne"
    // pour oscillateur 1
      bute_AV_1 = bute_N_AV_oscil_1;  // Butée AV
      bute_AR_1 = bute_N_AR_oscil_1;  // Butée AR
      vit_1 = vit_N_oscil_1;          // Vitesse oscillateur 1
    // pour oscillateur 2
      bute_AV_2 = bute_N_AV_oscil_2;  // Butée AV
      bute_AR_2 = bute_N_AR_oscil_2;  // Butée AR
      vit_2 = vit_N_oscil_2;          // Vitesse oscillateur 2
            }
 
// OSCILLATEUR 1
 // Calculateur vitesse Oscillateur 1    
        calculV_1 = calculV_1 + (top * vit_1);//incrément Vitesse "jour" Oscillateur 1  
    if (calculV_1 >= 1000){  //demande mouvement d'un pas (1°) sur servo oscillateur 1
        calculV_1 = 0;      // RAZ calcul incrément
 
 // Incrémente ou Décrémente en fonction du sens (sens_1)      
    if (sens_1 == 1 ) { pos_servo_1 = pos_servo_1 + 1;}
    if (sens_1 == 0 ) { pos_servo_1 = pos_servo_1 - 1;}
  }
  
 // Changement de sens oscillateur 1
   if (pos_servo_1 >= bute_AR_1){sens_1 = 0;}
   if (pos_servo_1 <= bute_AV_1){sens_1 = 1;}
    
 // Attache la variable du servo oscilateur 1
   if (attente_nourrissage == 0){servo_oscil_1.write(pos_servo_1); } // Si temps de nourrissage pas en cours      
     else {servo_oscil_1.write(posi_nourrissage_1);}                 // Sinon, Force le positionnement de l'oscillateur 1 durant le comptage
    
      
// OSCILLATEUR 2
 // Calculateur vitesse Oscillateur 2
        calculV_2 = calculV_2 + (top * vit_2);//incrément Vitesse "jour" Oscillateur 2
    if (calculV_2 >= 1000){  //demande mouvement d'un pas (1°) sur servo oscillateur 2
        calculV_2 = 0;      // RAZ calcul incrément
 
 // Incrémente ou Décrémente en fonction du sens (sens_2)      
    if (sens_2 == 1 ) { pos_servo_2 = pos_servo_2 + 1;}
    if (sens_2 == 0 ) { pos_servo_2 = pos_servo_2 - 1;}
  }
  
 // Changement de sens oscillateur 2
   if (pos_servo_2 >= bute_AR_2){sens_2 = 0;}
   if (pos_servo_2 <= bute_AV_2){sens_2 = 1;}
    
 // Attache la variable du servo oscilateur 2
   if (attente_nourrissage == 0){servo_oscil_2.write(pos_servo_2); } // Si temps de nourrissage pas en cours      
     else {servo_oscil_2.write(posi_nourrissage_2);}                 // Sinon, Force le positionnement de l'oscillateur 2 durant le comptage
    
    
// Phase nourrissage  
   if (((digitalRead (nourrissage) == 0)||(attente_nourrissage != 0) == 1) && top == 1) {attente_nourrissage = attente_nourrissage ++ ;} // Si demande de pause nourrissage, incrémente l'attente nourrissage et compte les tops (100ms)
      if (attente_nourrissage >= tps_nourrissage * 700){   // fin du temps de pause nourrissage atteint
           attente_nourrissage = 0;                        // RAZ du compteur
            }
    
    
// LIAISON SERIE POUR TESTS

 if (top = 1){
      Serial.print("Butee AV 2 : ");
      Serial.print(bute_AV_2);
      Serial.print("     Butee AR 2 :  ");
      Serial.println(bute_AR_2);
      Serial.print("   ");
      Serial.print(heure);
      Serial.print("   ");  
      Serial.print(minute);
      Serial.print("  Periode : ");    
      Serial.println(Periode);
      Serial.print("   ");
      Serial.print(calculV_2);
      Serial.println("   ");
      Serial.print("Pos. servo 2 : ");
      Serial.print(pos_servo_2);  
      Serial.println("     ");
      
}
  top = 0; // Remise à zéro impulsion "Top"
 
 // Test
      Serial.print("attente nourrissage :  ");
      Serial.print(digitalRead (nourrissage));
      Serial.print("   ");
      Serial.print(attente_nourrissage);      
      Serial.println("   ");
      Serial.println("   ");
      Serial.println("   ");
      
// temoin période nourrissage en cours : avec la LED (sortie 13) de la carte      
       if (attente_nourrissage != 0)
           etat_led = HIGH;
       if (attente_nourrissage == 0)
        etat_led = LOW;
        digitalWrite(led_int, etat_led);
}
    
« Last Edit: January 02, 2011, 10:44:09 am by Bubule » Logged

Chateau-Thierry (02)
Offline Offline
Full Member
***
Karma: 0
Posts: 167
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quelques points qui ne me plaisent pas à vous soumettre :

- L'horloge interne millis() ne semble pas être une horloge, mais plutôt un compteur de cycle, car les temps mesurés sont loin d'être fiables (20% d'erreur). Me trompe-je ???
Pour le moment, je triche avec les valeurs de bouclage comme là en mettant 500 au lieu de 600 :
Code:
HORLOGE
    if (compteur_top >= 500) {minute = minute + 1; //Incrémentation des minutes
        compteur_top = 0;        
    }

- L'entrée analogique 2 (pin16) est en logique inverse. (0V sur l'entrée = 1 //  pin libre = 0 )
Ne souhaitant pas utiliser de résistance externe, j'utilise la fonction PullUp dans le setup afin d'utiliser la résistance interne. Y a-t-il moyen de passer l'ensemble en logique positive ? (5V sur Pin = 1).

- Enfin comme il s'agit d'un programme de débutant, si vous avez des remarques.... Je suis preneur !

Merci
Franck
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Merci bubule, je vais regarder sa avec attention, cela me plait bien en tout cas.
Logged

Pages: [1]   Go Up
Jump to: