1. Présentation
Commande de moteur DC 500W avec un Arduino mega pour limiter le courant de démarrage et faire varier la vitesse de la trottinette. La batterie est en 24V, 10A.h. le tableau suivant résume leur caractéristiques :
2. Bibliographie :
Lien download :
sketch_escooter_feed_back_reel_V1.ino
escooter_ampli_SIMULINK.mdl
escooter feed back ISIS.DSN
En anglais
https://forum.arduino.cc/index.php?topic=477397.0
article : « Etude de trottinettes électriques 100W et 500W (Arduino), Revue 3EI 2017 »
En attente
3. Programme en boucle ouverte
Pour tester la programmation, nous simulons le programme dans ISIS, comme on peut le voir sur la figure suivante. De plus, nous avons un afficheur LCD pour afficher des données (rapport cyclique correspondant à la PWM à 32Khz, le courant moteur, la tension moteur, l’action sur les boutons poussoirs. En effet, 4 boutons poussoirs sont utilisés.
BP1 pour incrémenter manuellement le rapport cyclique, BP2 le décrémenter. BP3 mettre le rapport cyclique à 0, correspondant au contact frein.
La vitesse du moteur est pratiquement proportionnelle au rapport cyclique
Nous avons réalisé notre propre amplificateur de courant qui s’appelle un hacheur abaisseur mais il est possible d’acheter un shield
Il existe de nombreuses cartes pour Arduino pour commander des moteurs DC surtout de faibles puissances et aussi de grandes puissances comme on peut l’observer sur les liens suivants.
http://www.robotpower.com/products/MegaMotoPlus_info.html
http://www.robotshop.com/en/dc-motor-driver-2-15a.html
mais, tous ces hacheurs shields mesurent le courant en interne mais il n’y a pas de limitation de courant.
Pour avoir une limitation de courant il faut une boucle de courant analogique en utilisant des AOP ou CI spécialisée ou une boucle de courant numerique rapide.
Mais quel doit être la valeur du courant de limitation ?
Le choix de la valeur du courant est normalement pour le Service de fonctionnement 1 heure pour pouvoir effectuée des montées relativement longue sans atteindre la température critique du moteur.
Dans notre cas, le courant de limitation devra etre de
Imoteur limitation=Puissance/Ubatterie=500W/24 V=20A
De plus, le transistor de puissance du hacheur ne peut supporter que 50A dans notre cas.
Mais en boucle ouverte, il n’a pas de régulation de courant, pour ne pas avoir de dépassement du courant maximum, une rampe du rapport cyclique sera utilisé.
Une routine d’interruption de 0.1 seconde sera utilisé pour faire la mesure de la tension est du courant (échantillon de mesure, sample ). Ce temps de sampler est arbitraire, mais ne permet pas d’être plus rapide que le temps de montée du courant car la constante de temps électrique du moteur étant de L/R= 1.5ms.
Le fonctionnement en boucle ouverte avec une rampe de 25.5s (8bit et routine d’interruption de 0.1s) permet de bien comprendre la problématique du fonctionnement d’une commande à moteur DC.
l'affichage se fera seulement tous les 0.2s pour avoir une stabilité des chiffres à l'ecran. De plus, un filtrage numerique, se fera sur le courant et la tension sur 4 valeurs donc sur 0.4s.
[b]Algo boucle ouverte[/b]
Routine d’interruption toutes les 0.1S
Lire tension et courant
Boucle loop (scrutation des boutons poussoirs)
Si BP1=1 alors incrementer PWM
Si BP2=1 alors décrementer PWM
Si BP3=1 alors PWM=0
Affichage des variables tous les 0.2s
// include the library code:
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <TimerOne.h>
#define SERIAL_PORT_LOG_ENABLE 1
#define Led 13 // 13 pour la led jaune sur la carte
#define BP1 30 // 30 BP1
#define BP2 31 // 31 BP2
#define BP3 32 // 32 BP3
#define LEDV 33 // 33 led
#define LEDJ 34 // 34 led
#define LEDR 35 // 35 led
#define relay 36 // 36 relay
#define PWM10 10 //11 timer2
LiquidCrystal lcd(27, 28, 25, 24, 23, 22); // RS=12, Enable=11, D4=5, D5=4, D6= 3, D7=2, BPpoussoir=26
// Configuration des variables
unsigned int UmoteurF = 0; // variable to store the value coming from the sensor
unsigned int Umoteur = 0;
unsigned int Umoteur2 = 0;
unsigned int Umoteur3 = 0;
unsigned int Umoteur4 = 0;
unsigned int ImoteurF = 0;
unsigned int Imoteur = 0;
unsigned int Imoteur2 = 0;
unsigned int Imoteur3 = 0;
unsigned int Imoteur4 = 0;
byte Rcy=0 ; //rapport cyclique 8bit
unsigned int temps;
// the setup function runs once when you press reset or power the board
void setup() {
pinMode(Led, OUTPUT); //led carte arduino
pinMode(LEDV, OUTPUT);
pinMode(LEDR, OUTPUT);
pinMode(LEDJ, OUTPUT);
pinMode (PWM10,OUTPUT); // broche (10) en sortie timer2
// digitalWrite(LEDV,LOW);
Timer1.initialize(100000); // initialize timer1, and set a 0,1 second period => 100 000
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
lcd.begin(20, 4);
Serial1.begin(9600);
TCCR2B = (TCCR2B & 0b11111000) | 0x01; //pin 10 32khz http://playground.arduino.cc/Main/TimerPWMCheatsheet
//http://www.pobot.org/Modifier-la-frequence-d-un-PWM.html
// analogWriteResolution(bits) https://www.arduino.cc/en/Reference/AnalogWriteResolution
lcd.setCursor(0,1);
lcd.print("Rcy");
lcd.setCursor(10,1);
lcd.print("Um");
lcd.setCursor(5,1);
lcd.print("Im");
lcd.setCursor(10,1);
lcd.print("Um");
lcd.setCursor(20,1); //afficheur 4lignes*20 caracteres
lcd.print("BP1+");
lcd.setCursor(25,1);
lcd.print("BP2-");
lcd.setCursor(29,1);
lcd.print("BP3=0");
}
// Interruptions tous les 0.1s
void callback() {
temps++;
//toogle state ledv for check
if ( digitalRead(LEDV)== 1 ) {digitalWrite(LEDV,LOW);}
else {digitalWrite(LEDV,HIGH);}
analogWrite(PWM10,Rcy); //frequence
Umoteur=analogRead(A0);
Imoteur=analogRead(A1);
Imoteur2=Imoteur;
Imoteur3=Imoteur2;
Imoteur4=Imoteur3;
ImoteurF=(Imoteur4+Imoteur3+Imoteur2+Imoteur)/4 ;
Umoteur2=Umoteur;
Umoteur3=Umoteur2;
Umoteur4=Umoteur3;
UmoteurF=(Umoteur4+Umoteur3+Umoteur2+Umoteur)/4 ;
}//fin routine
// Boucle correspondant à la fonction main
void loop() {
// BP + LED
if ((digitalRead(BP1))==1) {
lcd.setCursor(20,0); //colonne, ligne
lcd.print("BP1");
digitalWrite(LEDR, LOW);
digitalWrite(LEDJ, LOW);
Rcy++; //incrementation PWM
if ( Rcy>254) {Rcy=254;}
delay(100); //8bits*100ms=25S pente de l'incremetation 25ssecondes
}
if ((digitalRead(BP2))==1) {
lcd.setCursor(20,0);
lcd.print("BP2");
Rcy--;
if ( Rcy<2) {Rcy=2;} //PWM presque à 0, arret moteur
delay(100);
digitalWrite(LEDR, HIGH);
digitalWrite(LEDJ, HIGH);
}
if ((digitalRead(BP3))==1) {
lcd.setCursor(20,0);
lcd.print("BP3");
Rcy=2; //PWM presque à 0, arret moteur
}
if (temps>=2) {
lcd.setCursor(0,0);
lcd.print(" "); //effacement ligne donnée
lcd.setCursor(0,0);
lcd.print(Rcy);
lcd.setCursor(5,0);
ImoteurF=(ImoteurF)/20; //resistance (5/1024)*(10/0.25ohm) si ACS712 66mV/A
//pour resistance 1ohm (ImoteurF)/20; simulation 5/25
lcd.print(ImoteurF);
lcd.setCursor(10,0);
UmoteurF=UmoteurF*10/38; //10/38 10/30 simula
if (Umoteur>ImoteurF){UmoteurF=UmoteurF-ImoteurF; } //U-R*I
lcd.print(UmoteurF);
temps=0;
}//fin if temps
} // fin loop
etant donné qu'il y a une limite de 9000 caracteres du forum la suite ci dessous