Je vais essayer ça lundi, merci Vincent
Est-ce que ceci pourrait fonctionner ?
90° = le ventilo fonctionne au ralenti (la soufflerie est à 13 cm ou moins du capteur, donc la soufflerie est "pleine")
180° = le ventilo fonctionne au max (la soufflerie est à plus d 13 cm du capteur, la soufflerie est "vide")
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include "Ultrasonic.h" Ultrasonic ultrasonic(8); // déclaration d'une instance de l'objet Ultrasonic, capteur branché sur D8 du shield #include <Servo.h> Servo myservo; //création de l'objet servo pour contrôler un servo int val; // variable qui lit les données du capteur ultra son void setup() { Serial.begin (9600); myservo.attach(8); // le servo est connecté sur la sortie 8 } void loop() { val = ultrasonic.MeasureInCentimeters(); //récupération de la distance en cm val = map(val, 3, 400, 0, 180); // échelle utiliser pour le servo (0-180) /le capteur ultra son peut aller de 3 à 400cm myservo.write(val); // règle le servo avec l'echelle delay(15); // attente pour que le servo va à la position } if (val >! 13) { myservo.write(180); //le servo va à 180° (simule le ventilo à vitesse max) } if (val <= 13) { myservo.write(90); //le servo va à 90° (simule le ventilo à vitesse réduite) }
Salut Tintin,
Dans une de mes réponses, je voulais te faire reformuler le problème car tu y étais presque. Toutes tes interrogations sont issues d'un problème mal posé.
Ce que tu souhaites faire c'est un asservissement proportionnel entre la distance que mesure un capteur et un débit d'air au travers d'un servomoteur.
La relation proportionnelle, et tu l'as écrit toit même, c'est :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 Valeur_Servo = kp * Distance_Capteur /* kp étant le coefficient de proportionnalité que toi tu appels "mise à l'échelle du servo" * * Si tu regardes sous forme de tableau les correspondances mesure capteur et valeur que tu envois au servo, ça donne ceci. * * +------+------+------+----------------+-----+ * Distance_Capteur : | 0 | 1 | 2 | . . . . | 400 | en cm * Valeur_Servo : | 0.00 | 0.45 | 0.90 | . . . . | 180 | en degrés d'ouverture * +------+------+------+----------------+-----+ * * Le coefficient de proportionnalité est de 0.45 * * Exemple : le capteur ultrason donne : * 13 cm, d'après le formule du dessus, la valeur donnée au servo sera => Valeur_Servo = 0.45 * 13 ce qui donne 5.85 à mettre dans Servo * 50 cm, d'après le formule du dessus, la valeur donnée au servo sera => Valeur_Servo = 0.45 * 50 ce qui donne 22.5 à mettre dans Servo * 1 cm, d'après le formule du dessus, la valeur donnée au servo sera => Valeur_Servo = 0.45 * 1 ce qui donne 0.45 à mettre dans Servo * 400 cm, d'après le formule du dessus, la valeur donnée au servo sera => Valeur_Servo = 0.45 * 400 ce qui donne 180 à mettre dans Servo */
A partir de là, on se rend compte qu'on a bien trouvé un rapport de proportionnalité entre ce qu'on mesure et ce qu'on veut faire.
Dans mon exemple j'ai des valeurs comme 5.85 ou 22.5, que tu peux bien sur arrondir à 6 et 22.
Si la fonction map fait bien le même calcul que moi et je le pense. Et bien ça répond parfaitement à un asservissement proportionnel.
Le code fonctionnel selon moi est bien celui-ci
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include "Ultrasonic.h" Ultrasonic ultrasonic(8); // déclaration d'une instance de l'objet Ultrasonic, capteur branché sur D8 du shield #include <Servo.h> Servo myservo; //création de l'objet servo pour contrôler un servo int val; // variable qui lit les données du capteur ultra son void setup() { Serial.begin (9600); myservo.attach(8); // le servo est connecté sur la sortie 8 } void loop() { /* * But du jeu * Valeur_Servo = kp * Distance_Capteur */ /* * Trouver la correspondance entre la valeur mesurée et une donnée cohérente pour le servo. * On cherche donc à mettre à l'échelle le servo. * +------+------+------+----------------+-----+ * Distance_Capteur : | 0 | 1 | 2 | . . . . | 400 | en cm * Valeur_Servo : | 0.00 | 0.45 | 0.90 | . . . . | 180 | en degrés d'ouverture * +------+------+------+----------------+-----+ */ val = ultrasonic.MeasureInCentimeters(); //récupération de la distance en cm val = map(val, 3, 400, 0, 180); // échelle utiliser pour le servo (0-180) /le capteur ultra son peut aller de 3 à 400cm /* A cet endroit val a été mis à l'échelle par rapport à la distance mesurée */ myservo.write(val); delay(15); // attente pour que le servo va à la position }
Pour répondre a ta question.
Si tu corriges la faute de le if(val >!13) alors le code est fonctionnel mais tu brises l'asservissement proportionnel, vu plus haut, qui selon moi doit fonctionner.
En mettant des bornes if (val >= 13) et if (val < 13) essaye et tu verras. Normalement tu vas fonctionner en tout ou rien (à fond puis plus rien.)
Pour te donner un exemple parlant :
Imagine que tu fais un asservissement pour un moto en jouant avec les freins et l'accélérateur pour atteindre 13km.
Je pense que tu as compris l'image, le système oscille et il n'y a aucun raison pour qu'il se stabilise a 13km !!!! Mais fait un essai car c'est formateur. Essaye aussi de changer les bornes par val > 13 et val < 13 pour voir si à 12 ça se stabilise.
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 if (val >= 13) { freine(); // j'embrasse le guidon } if (val < 13) { accelere(); // j'ai la tête qui part en arrière }
En espérant avoir été clair.
A+
La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
Richard Feynman
Oui, c'est très clair Vincent, je t'en remercie
Donc si j'ai bien compris, la vitesse sera proportionnelle à la distance. Plus la soufflerie sera loin du capteur, plus l’hélice accélérera et inversement
Voilà, tu as tout compris.
Je te serai reconnaissant si tu pouvais simplement me dire, si cela a fonctionné lors de tes prochains essais.
C'est dommage que tu n'aies pas reformuler le problème car tu tournais autour de la solution depuis le début et je suis persuadé que tu aurais trouvé ta réponse rien qu'en m'écrivant la question !
Par contre j'ai quand même quelques questions plus précises, c'est juste par curiosité :
- Dans ton code, la fonction "map" sort de où ? C'est toi qui a fait cette fonction ou bien c'est une bibliothèque d'ARDUINO ?
- Ton servomoteur, je ne comprends pas bien son rôle dans le montage.
Personnellement, si j'avais eu a faire ce montage, j'aurai bien sur eu le capteur ultrason mais en revanche je me serai passé d'un servomoteur. Je me serai servi d'une sortie PWM pour contrôler la vitesse du ventilateur (le PWM appliqué à un moteur de ventilateur permet de faire varier la vitesse sans modifié le couple) cette vitesse aurait été également proportionnelle à la distance qu'aurait donné le capteur ultrason.
Pour aller plus loin, tu verras sur internet qu'il y a mieux qu'une régulation proportionnelle "P", il y a le PID (Proportionnel, Intégral, Dérivé) qui n'est pas très compliqué à implémenter en C.
Merci pour ton retour.
A+,
Vincent
La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
Richard Feynman
-Je vais essayer ça demain, tu auras une réponse pour demain midi
-La fonction map est une fonction courante sans librairie : http://arduino.cc/en/reference/map
-Le servomoteur est un prétexte au programme la carte arduino sera directement relié a un capteur ultra son et au "ventilateur" (le servo était juste là pour vérifier que le signal pwm était correct, étant donné que nous utilisons un moteur brushless à 70€, nous ne voulions surtout pas essayer directement dessus )
D'accord, je comprends mieux car j'ai eu beau résonner avec un servomoteur, je ne voyais vraiment pas ce qu'il faisait la dedans.
A demain.
La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
Richard Feynman
Le programme fonctionne bien // maintenant j'aurai besoin d'aide pour faire du MIDI. Si quelqu'un s'y connaît
Toujours avec un capteur ultrasons et un ballon ?
Modérateur Langage SQL
Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
N'oubliez pas le bouton et pensez aux balises [code]
Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.
ouais alors là c'est pas gagné !!!
Bon je suis content pour toi Tintin.
Par contre, je te conseil d'ouvrir un nouveau sujet car si d'autres intervenants veulent t'aider, ils vont devoir lire tout le sujet et risquent d'être perdu si il y a deux demandes distincts.
Perso, je n'ai jamais travaillé sur le protocole MIDI mais ça n'a pas l'air bien compliqué (de prime abord biensur)
A+
La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
Richard Feynman
Bien évidemment non, le projet est de réaliser la modernisation d'un orgue j'ouvre un nouveau sujet : Arduino - MIDI
Je vous remercie tous pour votre aide longue vie à ce forum
Désolé de relancer ce sujet à nouveau, mais c'est juste pour préciser que le capteur à ultrason n'est pas assez rapide pour faire de l'asservissement, nous avons donc finis par prendre l'infrarouge.
Voici le code.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 //Ce programme fait fonctionner une soufflerie grâce a un asservissement de position. Le servomoteur est là juste pour nous aider a créer un signal PPM. Le contrôleur est un pro tronik pm 60a. #include "Servo.h" // librairie pour le servo Servo myservo; //création de l'objet myservo int BP = 2; // bouton poussoir connecté au port 2 int TenCapt; // variable de la tension du capteur pour une distance x unsigned long valCapt; // variable qui servira a faire du casting int distancePin = A1; // Capteur infrarouge connecté en A1 unsigned int angle; int lowVoltage = 80; //tension relevé pour une plage d'utilisation (le capteur n'étant pas linéaire) int highVoltage = 400; // tension relevé pour une plage d'utilisation int up = 180; //le servo monte au max int down = 20; // le servo ne doit jamais séteindre boolean start =0; //start est egale à 0 (start = lorsque on appui sur le BP) void setup () { Serial.begin(9600); //vitesse de transfert myservo.attach(8); //le servo est connecté au port 8 pinMode(BP, INPUT); // le BP est déclaré comme une entrée } void loop () { angle = 15; // pour que le contrôleur accepte de démarrer l'angle doit être faible myservo.write(angle); //le servo prend cette valeur delay(6000); // pause de 6s if (start==0){ //si le BP n'est pas enfoncé while (digitalRead(BP)==0){ //lit la valeur de BP Serial.println("waiting"); // le programme ne continue pas tant que le BP n'est pas enfoncé angle = 10; // l'angle reste à 10 pour le contrôleur myservo.write(angle); // le servo prend cette valeur } start = 1; //si le BP est enfoncé, alors le programme continue } angle = 40; // alors l'angle passe a 40 myservo.write(angle); // le servo prend cette valeur delay (5000); // pause de 5s Serial.println("regualtion"); //une fois cette étape réalisé, le moniteur série affiche "régulation", le système passe en régulation while(1){ //maintenant, ce programme sexécute indéfiniment TenCapt=analogRead(distancePin); //la tension du capteur = distance relevé par l'ir for(int i = 0; i < 10; i++) // ceci sert a faire une moyenne pour un asservissement stable { valCapt += analogRead(distancePin); delay(30); } valCapt /=10; // moyenne TenCapt = valCapt; // casting int vers unsigned long angle = map (TenCapt, lowVoltage, highVoltage, up, down); // mise en proportionnalité Serial.println(angle); // affichage sur le moniteur série de l'angle myservo.write(angle); // le servo prend la valeur } }
Salut Tintin,
Mais quelle est ta question ?
A+
La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
Richard Feynman
Aucune Vincent, c'est juste pour faire partager notre travaille avec la communauté je tiens à te remercier de nouveau
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager