Dans certains cas, nous sommes amenés à devoir réguler un système. On utilise dans ce cas un régulateur PID (Proportionnel Intégrale Dérivé)
Un PID est constitué d'additions, de soustractions, et de multiplication, ce qui nous amène d'abord à traiter en premier lieu les calculs de bases.
Vous avez ci-dessus un tableau récapitulant le temps que prend une carte arduino pour traiter une instruction. Les instructions sont basiques sauf pour le PID. Pour trouver ces valeurs, nous avons défini notre sortie LED sur la pin 13. Nous l'avons mise à 1 avant le calcul et remise à 0 après. On mesure ensuite le temps lorsque la sortie est à 1 en simulation sur ISIS ou en réelle grâce à un oscilloscope. On écrit sur un terminal pour vérifier si le calcul est correct.
Le programme de base est le suivant : la ligne de calcul est à changer ainsi que la déclaration en int ou float.
#define LED 13
int a = 10, b=5,c; //ligne de déclaration
void setup() {
// put your setup code here, to run once:
pinMode(LED,OUTPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(LED, 1);
c=a+b; //ligne de calcul
digitalWrite(LED, 0);
Serial.print(c);
Serial.print("\n\r");
}
Soustraction
c=a-b
Multiplication
c=a*b
Division
c=a/b
/!\ si en int, la valeur sera arrondi a l'entier près.
Exposant
pow(a,b)
/!\ cette commande ne fonctionne correctement que si vous utilisez des floats. Si vous utilisez des entiers, il faudra « caster » le calcul c'est-à-dire forcer le résultat à être en float. On écrira donc
Pow(float(a),float(b));
Le cast ajoute du temps au calcul et il est donc plus rapide d'utiliser des floats.
PID
Nous n'utilisons que des floats pour le PID
#define LED 13
float c;
const float kp = 2;
const float ki = 1;
const float kd = 1;
byte PWM=0 ;
float erreurP = 0;
float erreur = 0;
float Integral = 0;
float derive = 0;
float Proportionnel = 0;
float output = 0;
float Setpoint=0;
void setup() {
// put your setup code here, to run once:
pinMode(LED,OUTPUT);
Serial.begin(9600);
}
void loop() {
erreurP=erreur; //erreur precedente ou erreur erreur*Z^Ts pour faire le calcul de la derive
erreur=Setpoint-a;
Proportionnel=kp*erreur;
Integral= Integral+erreur*ki;
if (Integral>=255) Integral=255;
derive=(erreur-erreurP)*kd; //derive=(erreur-erreur*Z^Ts)/Ts avec Ts=Tsampleur
output=Proportionnel+Integral+derive; //ce n'est pas la peine de divisée par Ts car si Ts est petit cela donne des valeurs enormes
if (output>=255) {output=255;}
if (output<=0) {output=0;}
PWM=output;
analogWrite(PWM10,PWM); //PWM
digitalWrite(LED, 0);
Serial.print(c);
Serial.print("\t");
Serial.println(";");
}
On peut remarquer que les temps de calculs sont plus rapides pour une arduino nano que pour une Mega. Sauf que la carte Méga possède plus de ports. Si vous cherchez la vitesse d'exécution, vous prendrez une nano, si vous avez besoin de beaucoup de pin, vous prendrez une méga.
A savoir que ce que nous avons fait peut être fait pour n'importe quelle instruction ou série d'instructions que vous voulez (pas forcément des calculs).
edit : Concernant le carte Arduino DUE, j'ai rencontré quelques problèmes : quelques difficultés à compiler mon programme à cause d'un fichier du logiciel (https://arduino.stackexchange.com/questions/24143/unable-to-upload-to-arduino-due-using-version-1-6-8-of-sam-tools-bossac-exe-thr aller sur ce site (en anglais) pour voir comment résoudre le problème si vous l'avez).
Cette carte est plus rapide que les autres comme on peut le voir (en écrivant en langage C/C++ comme j'ai pu voir les commentaires plus bas). Donc pour ceux qui ne veulent pas mettre les mains dans l'assembleur et qui veulent juste écrire leur ligne de code.