PWM avec L293D

Bonjour
Je désire que mes moteurs démarrent progressivement de la vitesse nulle à la vitesse maxi

Ca j'y suis arrivé mais le pb c est que lorsque j'atteins la vitesse max, mes moteurs s 'arrêtent et se remettent à démarrer progressivement.

Or moi j 'aimerais que lorsqu'ils atteignent leur vitesse maxi ils y restent.

Je vous joint mon programme

Que dois je modifier pour obtenir le résultat que je souhaite ?

Avec toujours un grand merci aux "experts" qui aident les "amateurs"

Cordialement Chris

int motor1 = 6; //pwm
int motor1A = 13;
int motor1B = 12;
 
int motor2 = 5; //pwm
int motor2A = 8;
int motor2B = 7;

int vitesse = 0;
int acceleration =10;

 
void setup()
{
  
  Serial.begin(9600);
  
  //on initialise les pins du moteur 1
  pinMode(motor1, OUTPUT);
  pinMode(motor1A, OUTPUT);
  pinMode(motor1B, OUTPUT);
 
  //on initialise les pins du moteur 2
  pinMode(motor2, OUTPUT);
  pinMode(motor2A, OUTPUT);
  pinMode(motor2B, OUTPUT);
  
 
}
 
void loop()
{

Serial.println(vitesse,DEC);  
  
analogWrite(motor1,vitesse);
analogWrite(motor2,vitesse);
  
digitalWrite(motor1A,LOW);
digitalWrite(motor1B,HIGH);


digitalWrite(motor2A,LOW);
digitalWrite(motor2B,HIGH);

vitesse = vitesse + acceleration;

delay (1000);


}

analogWrite attend une valeur comprise entre 0 et 255. Or, tu lui envoies un entier qui va de 0 à 65536. analogWrite ne voit que l'octet de poids faible, donc à chaque fois que ton entier passe par un multiple de 256, l'octet de poids faible repasse par zéro.

Cordialement.

Pierre

merci pierre

je comprends mais que puis je faire pour résoudre ce pb

je comprends mais que puis je faire pour résoudre ce pb

  1. Changer le type des variables.
    Chaque compilateur est différent. Avec celui fourni par Atmel : une adaptation de GCC à savoir avr-gcc, les int sont codés sur 2 octets.
    Or la pwm n'est codée que sur un octet. A moins que tu n'ajoute un traitement pour limiter l'excursion des variables motor 1 à N il sera préférable que tu les définissent sur 1 octet.
    Il y a plusieurs façons de le faire : utiliser des char, des bytes ou ce que je préfère des intX_t
    Dans ton cas il faut même utiliser des non signé pour explorer de 0 à 255 sinon tu explorera ente -127 et +128.
uint8_t motor1 ;

int8_t -> impose au compilateur d'utiliser un entier codé sur 8 bits
int16_t -> impose au compilateur d'utiliser un entier codé sur16 bits
int32_t -> impose au compilateur d'utiliser un entier codé sur 32 bits

  1. Cela résoudra une partie de tes soucis mais pas tout :
    La fonction loop() comme son nom l'indique s'éxécute continuellement en boucle donc ce que tu constate est assez normal.

Il est préférable pour dominer la bête que tu ajoute une commande extérieure (un bouton + anti rebond (voir ce nom) pour lancer le démarrage.

Mais cela ne suffira toujours pas : il faut qu'une fois le démarrage effectué il ne se relance pas à chaque tour de loop() !
Pour cela tu utilise une variable auxiliaire appelée un drapeau.

Dans setup() tu positionne une variable "demarrage =0 "
Dans loop() tu utilise une bouche if

if (demarrage==00){ 
faire le démarrage;
demarrage = 1 ; // le démarrage est fait il ne se referra pas tant que tu ne mettra pas demarrage à 0
}

Ces drapeaux sont aussi appelés flag en anglais.
Ce sont de simple variables sur un octet auxquelles on donne par habitude la valeur 0 ou 1.

Tiens d'ailleurs pourquoi donner des nom de variable en anglais ? Écrire moteur1, moteur2 fonctionnera aussi bien :grin:

Bonjour et merci 68tjs

Le 1. est un peu du chinois pour moi

Mais je comprends mieux le 2.

J'ai encore du pain sur la planche donc .

Bonjour,

Le problème n'est pas tellement la taille de la variable, mais le fait que tu n'arrêtes pas de l'incrémenter. Au bout d'un moment, l'octet de poids faible revient à zéro (quelle que soit la taille de la variable).

Comme le dit 68tjs, il te faut un flag qui stoppe l'incrémentation quand le moteur est à sa vitesse maxi ou alors si vitesse>255-acceleration tu arrêtes d'accélérer.

ok merci Kamill

je regarde cela demain

si je trouve je mets la solution ici

Bonjour
J'ai trouvé une solution qui fonctionne mais je ne sais pas ce qu'elle vaut en terme de programmation

J ai donc crée deux sous programme

  1. accelere
  2. avance

dans "avance" j arrête l'incrémentation de la variable vitesse pour éviter de dépasser le seuil critique de 255 qui arrêtait mes moteurs

voila j ai fait avec mes connaissances

mais si qq à une solution plus professionnelle je suis preneur

cordialement

int motor1 = 6; //pwm
int motor1A = 13;
int motor1B = 12;
 
int motor2 = 5; //pwm
int motor2A = 8;
int motor2B = 7;

int vitesse = 100;
int acceleration =10;
int seuil = 200;

 
void setup()
{
  
  Serial.begin(9600);
  
  //on initialise les pins du moteur 1
  pinMode(motor1, OUTPUT);
  pinMode(motor1A, OUTPUT);
  pinMode(motor1B, OUTPUT);
 
  //on initialise les pins du moteur 2
  pinMode(motor2, OUTPUT);
  pinMode(motor2A, OUTPUT);
  pinMode(motor2B, OUTPUT);
  
 
}
 
void loop()
{

while (vitesse <= seuil )
{
  accelere();
}
  
  avance();
  
}

void accelere()

{
Serial.println(vitesse,DEC);  
  
analogWrite(motor1,vitesse);
analogWrite(motor2,vitesse);
  
digitalWrite(motor1A,LOW);
digitalWrite(motor1B,HIGH);


digitalWrite(motor2A,LOW);
digitalWrite(motor2B,HIGH);

vitesse = vitesse + acceleration;

delay (1000);
}

void avance()
{
Serial.println(vitesse,DEC);  
  
analogWrite(motor1,vitesse);
analogWrite(motor2,vitesse);
  
digitalWrite(motor1A,LOW);
digitalWrite(motor1B,HIGH);


digitalWrite(motor2A,LOW);
digitalWrite(motor2B,HIGH);
}

mais si qq à une solution plus professionnelle je suis preneur

Tu met un condensateur entre les bornes du moteur, simple et efficace.

j en ai mis un à chaque moteur