[arduino] Projet de terminale

Projet de terminale [arduino] - C - Programmation

Marsh Posté le 20-05-2014 à 16:49:17    

Bonjour a tous, je viens sur ce forum car j'ai besoin d'aide !
 
Je suis en Terminale, et pour le bac, j'ai un projet a réaliser en groupe, et on a choisi de faire un velux automatisé.
 
Le principe est plutôt simple; on a un capteur de pluie, un capteur de position, un bouton poussoir et un capteur de température.
 
Le moteur du velux est actionné par un relais électromagnétique
 
Le cahier des charges est le suivant :
 
- Quand il pleut et que le velux est ouvert, il doit se fermer.
- Quand le capteur de température nous donne une température supérieure a 28°c et que le velux est fermé, le velux doit s'ouvrir.
- Quand le capteur de température nous donne une température inférieure a 15°c et que le velux est ouvert, le velux doit se fermer.
- Quand quelqu'un appuie sur le bouton poussoir, le velux doit s'ouvrir si il est fermé ou se fermer si il est ouvert.
 
Le capteur de température envoie un signal de 0-10V analogique, 15°c correspond a 3.6V et 28°c correspond a 5.1V.
 
J'ai pris l'initiative de m’occuper de la partie programmation, malgré le fait que je n'y connaisse rien. Les profs supposés nous aider en savent encore moins que moi, j'ai donc vu pas mal de tutoriels et de vidéo, et j'ai décidé d’utiliser une carte arduino. Après pas mal de recherches, j'en suis arrivé au programme suivant :
 

Code :
  1. const int bouton = 2;
  2. const int cpos = 4;
  3. const int cpluie = 5;
  4. const int relais = 12;
  5. const int ctemp = 0;
  6. // On défini les broches sur lesquelles seront attachées les differents composants
  7. boolean etatbouton;
  8. boolean etatcpluie;
  9. boolean etatcpos;
  10. int temp;
  11. // On défini les variables qui interviendront plus tard dans le programme
  12. void setup()
  13. {
  14.   pinMode(0, INPUT);
  15.   pinMode(2, INPUT);
  16.   pinMode(3, INPUT);
  17.   pinMode(4, INPUT);
  18.   pinMode(12, OUTPUT);
  19. }
  20. // on défini les broches comme entrées ou sorties
  21. void loop()
  22. {
  23. etatbouton = digitalRead(bouton);
  24. etatcpos = digitalRead(cpos);
  25. etatcpluie = digitalRead(cpluie);
  26. temp = analogRead(ctemp);
  27. // on lit l'état des differents capteurs
  28. if(etatbouton == HIGH)
  29. {
  30.     digitalWrite(relais, HIGH);
  31. }
  32. else
  33. {
  34.     digitalWrite(relais, LOW);
  35. }
  36. // on teste l'état du BP
  37. if((etatcpos == HIGH ) && (etatcpluie == HIGH ) )
  38. {
  39.     digitalWrite(relais, HIGH);
  40. }
  41. else
  42. {
  43.      digitalWrite(relais, LOW);
  44. }
  45. //on teste l'état du capteur de pluie
  46. if(temp >= 5.1)
  47. {
  48.      digitalWrite(relais, HIGH);
  49. }
  50.   else if(temp <= 3.8)
  51.  
  52. {
  53.      digitalWrite(relais, HIGH);
  54. }
  55.   else
  56.  
  57. {
  58.      digitalWrite(relais, LOW);
  59. }
  60. // On teste l'état du capteur de température  
  61. }


 
 
J'ai réussi a faire fonctionner la partie bouton poussoir une seule fois, plus moyen depuis ! (j'ai utilisé beaucoup de programmes différents, ce n'était peut être pas celui la qui l'a fait fonctionner)
 
De plus, je ne suis pas sur de la partie analogique, il me semble que la carte arduino ne peut recevoir qu'une tension de 0 a 5V, faut-il ajouter des résistances pour diminuer la tension ? Toutes les corrections seront les bienvenues, Je vous remercie d'avance !

Reply

Marsh Posté le 20-05-2014 à 16:49:17   

Reply

Marsh Posté le 20-05-2014 à 20:53:06    

Bonjour !
 
Plusieurs remarques ...
 
 * Coté matériel :
       - vous n'avez qu'un seul capteur de position ? C'est peu, pour savoir où en est le Velux ... Cela signifie que si le capteur indique la position "fermé", vous ne saurez jamais quand le velux est ouvert et donc quand stopper l'alimentation du moteur ?
       - concernant le moteur, vous n'avez qu'un seul relais ? Cela signifie que la position "0" le fait tourner dans un sens et la position "1" le fait tourner dans l'autre ? Il est donc toujours alimenté, même en fin de course ? Il va fatiguer, le pauvre :)  
 
 * Coté algorithme :
       - vous ne précisez pas l'ordre de priorité des règles, même si avec un peu de bon sens on peut assez aisément l'imaginer, mais ce serait bon de le préciser, car cela sera primordial pour l'ordre des "if" dans le code,
       - vous ne gérez pas l'état du velux (Ouvert, fermé, en cours d'ouverture, en cours de fermeture) ? Cette question rejoint celle sur le moteur, notamment pour savoir quand l'arrêter.
 
 * Coté code :  
       - Tel que c'est codé, les premiers tests ne servent à rien, l'état de la sortie est de toutes façons modifié par le deuxième test, puis par le troisième, seul ce dernier est réellement utile
       - AnalogRead renvoie une valeur entre 0 et 1023, 0 correspondant à 0 V et 1023 correspondant à la référence (voir la fonction analogReference()).
 
Pour la division de la tension, mes souvenirs d'électronique sont trop lointains, mais cela devrait pouvoir se faire avec deux résistances de même valeur (choisie pour être compatible avec les caractéristiques du capteur).
 
Avec tout ceci, vous devriez pouvoir arriver à une deuxième version de votre code, certes plus complexe, mais sans doute plus opérationnelle :)
 
Bonne continuation !
 

Reply

Marsh Posté le 21-05-2014 à 19:34:21    

Bonjour !
 
Tout d'abord, merci de m'avoir répondu :)
 
Pour ce qui est du moteur, c'est vrai que je ne l'ai précisé, c'est un moteur a chaîne spécial pour les fenêtres de toit, il est équipé pour s'ouvrir complètement (avec une course d'environ 24cm) et ce fermer jusqu'au bout, il fonctionne avec un simple bouton de la manière suivante : Fermé > appui sur le bouton > il s'ouvre > nouvelle pression en cours d'ouverture > il s'immobilise > troisième pression > il se referme, et ainsi de suite.  
 
J'ai donc tiré deux fils en court-circuit du bouton que j'ai relié au relais électromagnétique pour commander le bouton depuis la carte.  
 
J'ignorais que le placement des "if" permettait de mettre des fonctions en priorité, maintenant que je sais cela ça me semble plutôt logique, merci pour l'info !
également, je pense a inclure un délais de 1 min 30 après avoir commander un mouvement du moteur (une ouverture ou fermeture met environ 1 min 15) dans ce cas, je dois placer la fonction delay(90000); après chaque if ? ou bien a la suite de la commande permettant l'activation du relais ?
 
En tout cas merci beaucoup pour votre réponse, ça m'à encouragé a continuer et je posterais une nouvelle version du code dès que possible !

Reply

Marsh Posté le 21-05-2014 à 20:06:43    

Bonjour !
 
Le défaut, si vous mettez un "delay", c'est que le programme est arrêté pendant ces 90 secondes, les actions sur le bouton (ou, au pire, le début d'un gros orage juste au moment où l'ouverture commence :) :) ) n'auront aucun effet.
 
Cela peut ne pas être gênant, si vous estimez que cela l'est, à vous de le gérer, en stockant l'état "fermeture en cours" ou "ouverture en cours" et en tenant compte de cet état dans la gestion des actions (il faut alors modifier l'arbre de décision pour tenir compte du fait qu'une action X peut avoir un résultat différent selon l'état (ouvert, fermé, ouverture, fermeture) du velux).
 
Bonne continuation !


Message édité par Farian le 21-05-2014 à 20:07:16
Reply

Marsh Posté le 25-05-2014 à 20:09:46    

Bonjour ! J'ai continué d'avancer dans ce projet, je vous reposterais sous peu une nouvelle version ! seulement, j'ai été confronté a u nouveau problème : la valeur de la température se doit d’être plutôt précise, car elle sors de 0 à 5v pour représenter une plage de -20 a 70°c, j'ai donc défini la variable associée a cette valeur comme étant de type "float". J'ai donc ensuite fait un bref programme afin de tester la précision de cette valeur, en symbolisant le capteur de température par un potentiometre et en réalisant une liason série avec l'écran pour visualiser les résultats en direct.

Code :
  1. const int potentiometre = 0;
  2. int valeur;
  3. float tension;
  4. void setup()
  5. {
  6. Serial.begin(9600);
  7. }
  8. void loop()
  9. {
  10. valeur = analogRead(potentiometre);
  11. tension = valeur*5/1023;
  12.  
  13.   Serial.print(tension);
  14.  
  15.   delay(500);
  16.  
  17.   Serial.println();
  18.  
  19. }


 
Malheureusement, la valeur de la variable "tension" ne prend que les valeurs 1.00, 2.00, 3.00, 4.00 ou 5.00, je n'arrive pas a obtenir un résultat au dixième ou au centième près. Pouvez vous m'éclairer sur la démarche a suivre ?

Reply

Marsh Posté le 25-05-2014 à 22:13:07    

Bonjour !
 
Petit rappel : en C, une division d'un entier par un entier donne un entier (la partie entière du résultat attendu).
 
Il semblerait que ce soit la même chose sur l'implémentation de l'Arduino.
 
Il vous faut donc passer en flottant au milieu du calcul :  
 

Code :
  1. tension = valeur*5;
  2. tension = tension/1023;


 
(En C, vous pourriez aussi faire ceci, que je trouve moins lisibile

Code :
  1. tension = (valeur*5.0)/1023;


 
Ou alors, vous déclarez valeur en flottant, mais c'est moins propre :)
Bonne continuation !


Message édité par Farian le 25-05-2014 à 22:14:00
Reply

Marsh Posté le 26-05-2014 à 20:47:06    

Merci beaucoup pour la rapidité de vos réponses !  
 
Je vais tester le code mercredi, je vous donnerais des nouvelles !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed