Bonjour,
J'ai comme projet un placard comprenant de nombreuses portes qui s'ouvriraient de manière aléatoire.
Une porte s'ouvre, reste ouverte quelques secondes, puis se ferme et une autre s'ouvre, ainsi de suite.
Les Servomoteurs seraient choisis par la fonction Random.
Je découvre Arduino et l'essai de programme ci-joint doit comporter des erreurs de conception, car rien ne se passe.
Pouvez-vous m'éclairer sur ce sujet, merci.
#include <Servo.h>
Servo myservo;
int data;
int pos = 0;`Texte préformaté`
void setup()
{
Serial.begin(9600);
myservo.attach(data);
}
void loop()
{
data = random(6,11);
Serial.println(data);
delay(1000);
for (pos = 0; pos <= 180; pos += 1)
myservo.write(pos);
delay(10);
for (pos = 180; pos >= 0; pos -= 1)
myservo.write(pos);
delay(10);
}
Il est préférable d'attacher les servos une bonne fois pour toute dans le setup() et de ne plus les détacher pour éviter des mouvements aléatoires lorsqu'on les rattache.
Si les servos doivent fonctionner sur une zone limitée de leur course, il est prudent de fournir les valeurs min et max dans attach(). voir ici: https://www.arduino.cc/reference/en/libraries/servo/attach/
Personnellement je ferais un truc dans ce genre là (pas testé):
#include <Servo.h>
// On suppose que les servos sont au nombre de 6 branchés de la pin D6 à D11
Servo mesServos[6];
void setup() {
for (byte i = 0; i<5; i++){
mesServos[i].attach(i + 6);
}
randomSeed(analogRead(A0) + micros()); // un semblant de hasard pour ne pas avoir toujours la même séquence
}
void bougeServo (Servo unServo){
for (int pos = 0; pos <= 180; pos += 1){
unServo.write(pos);
delay(10);
}
for (int pos = 180; pos >= 0; pos -= 1){
unServo.write(pos);
delay(10);
}
}
void loop() {
int data = random(6,11);
Serial.println(data);
delay(1000);
bougeServo(mesServos[data]);
}
Bonjour,
merci messieurs pour l'attention apporté à mes difficultés de codage pour faire fonctionner les servomoteurs en aléatoire.
Je suis allé sur Tinkercad essayer le code proposé, mais au démarrage de la simulation, j'ai quelques messages d'alerte concernant "bougeServo" et aussi de déclaration manquante de "Servo".
Je vous transmets le lien pour votre précieux aide, merci d'avance.
Apparemment il y a un bug dans tinkercad. Le compilateur ne reconnait pas la class Servo dans la déclaration de bougeServo().
En précisant explicitement que c'est une class, ça semble fonctionner: void bougeServo(class Servo unServo){
Remarque:
Il y a un bug ici int data = random(6, 11);
ce doit être int data = random(0, 6);
Bonjour chers soutiens,
Grâce à votre aide, je suis enfin arrivé à faire fonctionner 6 servomoteurs en aléatoire sur une carte Arduino Uno.
Et aussi avec Module d'extension de capteur NANO e/s IO, pour Arduino UNO R3 Nano V3.0 3.0 c !
Encore merci et à bientôt pour votre aide précieuse.
Bonjour,
je reviens vers vous, car je ne suis pas au bout de ma programmation.
1/ je souhaiterais avoir un délai entre les étapes d'ouverture et de fermeture des servomoteurs. J'ai tenté ce programme, mais j'ai un message d'erreur.
2/ Là dans les essais, je suis avec 6 servomoteurs, mais dans mon projet, c'est 20 (ou 40) commandés par un seul programme... Comment ça se passe pour attribuer 20 services ou plus ?
une des modifications apportée est la mise en tableau des pin des servo (mesServoPin[]), ainsi, il ne sera plus nécessaire que ces pin soient contiguës, tu pourras les "piquer" n'importe où dans les pin disponibles. Avec ce tableau, l'extension de ton programme sera plus aisée.
Ainsi, pour étendre le nombre de servo, il suffit d'en mettre le port dans le tableau mesServoPin[].
J'ai ajouté quelques variables pour te faciliter le travail.
Au départ, tout les servo sont mis sur fermé
for (byte s = 0; s < ServoNombre; s++)
{
mesServos[s].attach(mesServoPin[s]); // Initialisation du servo s
mesServos[s].write(pos_ferme);; // Servo s sur fermeture
}
Bonjour,
mon projet fonctionne grâce à vos soutiens . Actuellement les servomoteurs sont raccordés sur un module pour Nano Arduinode de 13 servomoteurs.
Je voudrais passer au PCA9685 comme encouragé. Je me pose la question fatidique, en plus de nouvelle bibliothèque pour prendre en charge le PCA9685 faut-il changer le code pour le programme ARDFR_42david_Servo.ino (1.5 KB)
-Est-ce que je pourrais utiliser une source de type courante :Transformateur d'alimentation secteur 5V-15V 3 A.
Merci pour vos lumières,
Cordialement David
Oui, en le réglant sur 5V et tu le connectes sur les bornes du PCA9685
Je de donne la version PCA9685, tu verra, le fond du code ne change pas beaucoup, tu peux chaîner les PCA en indiquant leur adresse en soudant les ponts idoines.
Le premier PCA (No. 0) n'a pas de pont, le 2ème (No. 1) a A0 de soudé le 3ème (No.2) a A1 de soudé et ainsi de suite (c'est du comptage binaire)
Tu peux chaîner 64 PCA9685, de quoi voire venir!
Le reste des explications sont dans le programme.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h> // https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
// Ce tableau contient les pin des hub utilisées, le 2ème hub a A0 ponté
// La numérotation débute à 0 (hub 0) le hub 1 débute à 16 et ainsi de suite,
const int mesServoPin[] = {3, 11, 16, 27};
const int ServoNombre = sizeof(mesServoPin)/sizeof(mesServoPin[0]);
Adafruit_PWMServoDriver servoHub[] =
{
Adafruit_PWMServoDriver(0x40), // Servos de 0-15
Adafruit_PWMServoDriver(0x41), // Servos de 16-31
};
const int servoHubNombre = sizeof(servoHub) / sizeof(servoHub[0]);
//-------------------------------------A régler en fonction des servo utilisés
const word servoPulseMin = 125; // Impulsion minimum
const word servoPulseMax = 575; // Impulsion maximum
int pos = 0;
int pos_ferme =5;
int pos_ouverte = 120;
int servoHazard = 0;
int pos_ferme_Delay = 30;
int pos_ouverte_Delay = 30;
void setup()
{
Serial.begin(9600);
//--------------------------------- Initialisation hub servo
for (int h = 0; h < servoHubNombre; h ++)
{
servoHub[h].begin();
servoHub[h].setPWMFreq(60); // Analog servos run at ~60 Hz updates
servoHub[h].setPWMFreq(60); // Analog servos run at ~60 Hz updates
}
randomSeed(analogRead(A0) + micros()); // un semblant de hasard pour ne pas avoir toujours la même séquence
}
void loop()
{
servoHazard = mesServoPin[random(0,ServoNombre)]; // Choix d'un servo "au hazard"
servoOuverture(servoHazard);
delay(1500); //temporisation entre l'ouverture et la fermeture
servoFermeture(servoHazard);
delay(3000); //temporisation avant le servo suivant
}
void servoOuverture(int servoNum)
{
Serial.println("Servo : Ouvrir servo " + String(servoNum));
for (int pos = pos_ferme ;pos <=pos_ouverte; pos++)
{
servoMouvement(servoNum, pos);
delay(pos_ouverte_Delay);
}
}
void servoFermeture(int servoNum)
{
Serial.println("Servo : Fermer " + String(servoNum));
for (int pos = pos_ouverte; pos >= pos_ferme; pos--)
{
servoMouvement(servoNum, pos);
delay(pos_ouverte_Delay);
}
}
void servoMouvement(int servoNum, int servoPosition)
{
//Serial.print("\tServo HUB: " + String(servoNum / 16));
//Serial.println("\tSlot : " + String(servoNum % 16));
servoHub[servoNum / 16].setPWM(servoNum % 16, 0, angleToPulse(servoPosition));
}
word angleToPulse(int angle)
{
return map(angle,0, 180, servoPulseMin, servoPulseMax); // map angle of 0 to 180 to Servo min and Servo max
}
En principe tu n'as que ça à régler:
//-------------------------------------A régler en fonction des servo utilisés
const word servoPulseMin = 125; // Impulsion minimum
const word servoPulseMax = 575; // Impulsion maximum
PS: Fais un test pour contrôler si ton Arduino "voit" ton PCA9685, charges ce programme, un scanner i2C, et, avec ton moniteur série à 9600 tu dois voir:
Scanning...
I2C device found at address 0x40 !
I2C device found at address 0x70 !
done
la réponse au scanner de la carte PCA9685 est correcte :
I2C device found at address 0x40 !
done
Voici le programme qui a tout pour fonctionner. Les étapes de fermeture et d'ouverture sont bien indiquées dans l'exécution. Pourtant quand le programme tombe sur la broche où se trouve le servomoteur pour le test, rien ne se passe.
Bonjour jpbbricole,
La solution pour que le courant passe a été de rajouter un cinquième fil reliant la carte Uno à la carte PCA9685 de la broche Vin à V+.
Le programme est au top, mais il y a un bug. Au bout de cinq, dix minutes, le programme cafouille et s'arrête. Est-ce dû à des interférences, car les câbles sont asses proches ou dois-je rehausser les impulsions... ou autre chose.
Cordialement,
David
Le courant vient de l'alimentation de la carte Uno qui est relié à un transformateur de type smartphone de 5v- 2 A.
Si je ne rajoute pas ce cinquième fil (vin/v+) je n'ai que 1v en sortie.