je commence la programmation avec Arduino et me lance dans un premier projet.
Je souhaite commander un bras sur pivot, permettant l'ouverture précise d'une vanne suivant la demande d'un opérateur.
L'ensemble sera équipé d'un système de recopie pour obtenir une correction de la position par PID.
Un interrupteur devra permettre d'ouvrir la vanne à 90° soit 100% pendant un temps donné.
Je dispose donc:
d'un moteur électrique 12V avec réducteur à pignons
d'un module de commande avec pont en H
d'un potentiomètre 90° pour la commande
d'un potentiomètre de recopie identique à celui de commande
d'un interrupteur permettant d'outrepasser les autres conditions et d'ouvrir la vanne en grand
d'un Arduino méga et du nécessaire de câblage
Voilà le code sur lequel je travail et a propos duquel je souhaiterai un avis avant essai:
Merci d'avance pour le retour d'informations, au plaisir de vous lire
premier avis: vous n'avez pas lu les règles du forum... faites le et corrigez le post ci dessus...
sinon ce truc là ne sent pas très bon commande = map (analogPin,0,1023,0,255);(vous avez eu la bonne idée d'appeler les N° de pins par un petit nom, ça devrait vous mettre la puce à l'oreille...)
Un numéro de pin se déclare sous forme d’un nombre entier positif constant tenant sur un octet (type byte ou plus standard uint8_t)const uint8_t analogPin = A0;le N° de pin ne va pas changer, la tension sur cette pin, éventuellement...
la représentation numérique de la tension sur cette pin à un instant est obtenue en appelant digitalRead() ou analogRead()
Vous êtes tout à fait sur la bonne route pour la compréhension des déclarations des types et l'usage de map() ! bravo
idéalement trouvez un autre nom que analogPin et analogPin2 pour le nom des variables. Qu'est-ce qui est connecté au bout des pins ? est-ce que ce sont les potentiomètres ? si oui par exemple vous pourriez les appeler pinPotentiometreCommande et pinPotentiometreRecopie, ce serait plus parlant ensuite dans le code.
de même DIRA et DIRB sont des pins, donc autant mettre pin dans le nom de la constante et A et B ça n'est pas parlant. si ça pilote quelque chose de particulier autant le mettre dans le nom de la variable, le fait que ce soit connecté sur A ou B peut être mis en commentaire pour documentation (je dis n'importe quoi mais c'est pour l'exemple);
const uint8_t pinDirectionFermeture = 3; // connecté sur port A
const uint8_t pinDirectionOuverture = 4; // connecté sur port B
Voilà le code complet et retravaillé suivant vos indications (noms des variables, annotations, ...).
Je vais l'essayer dans la semaine pour voir s'il n'y a pas d'erreurs à trainer et régler les coefficients P,I,D, pour la régulation.
//affectation des pins aux entrées et sorties
const uint8_t outputValue = 5;//sortie PWM pour commande moteur
const uint8_t DIRECTIONNEG = 3;//connecté à la borne A du pont en H IBT-2, si - sens de rotation +
const uint8_t DIRECTIONPOS = 4;//connecté à la borne B du pont en H IBT-2, si + sens de rotation +
const uint8_t potcom = A0;//mesure potentiomètre de commande
const uint8_t potrec = A1;//mesure potentiomètre de recopie
const uint8_t shift = 8;//entrée par interrupteur 0/1
//declaration des variables
float valec;
float valrec;
float erreur;
float errprec;
float deltaerr;
float sommerr;
float pilotage;
float commande;
float correction;
int8_t full;
void setup()
{
Serial.begin (9600);
pinMode(outputValue,OUTPUT);
pinMode(DIRECTIONNEG,OUTPUT);
pinMode(DIRECTIONPOS,OUTPUT);
pinMode(potcom,INPUT);
pinMode(potrec,INPUT);
pinMode (shift, INPUT_PULLUP);
//initialisation des variables
valec=0;
valrec=0;
erreur=0;
errprec=0;
deltaerr=0;
sommerr=0;
pilotage=0;
commande=0;
correction=0;
full=1;
}
void loop()
{
//commande en PWM du moteur fonction de la valeur de lecture du potentiomètre de commande
digitalWrite(DIRECTIONNEG,LOW);
digitalWrite(DIRECTIONPOS,HIGH);
valec = analogRead (potcom);
valrec = analogRead (potrec);
full = digitalRead (shift);
erreur = valec - valrec;
sommerr += erreur;
deltaerr = erreur - errprec;
errprec = erreur;
analogWrite(outputValue,pilotage);
commande = map (valec,0,1023,0,255);
//régulation de la position de l'actuateur par PID fonction de la valeur de lecture du potentiomètre de recopie
if (erreur == 0)
{
pilotage = commande;
}
if (erreur != 0)
{
correction = (3*(erreur)) + (2*(sommerr)) + (5*(deltaerr));
pilotage = commande + correction;
analogWrite (outputValue,pilotage);
}
if (pilotage <0) //limite le PWM à sa valeur minimale
{
pilotage = 0;
}
if (pilotage > 255) // limite le PWM à sa valeur maximale
{
pilotage = 255;
}
//commande par mise à la masse, si l'entrée shift est à l'état bas, le PWM est max pdt 500ms quelque soit la commande
if (digitalRead (shift) == 0)
{
analogWrite (outputValue,255);
delay (500);
analogWrite (outputValue,pilotage);
}
}
Une foi cette base de code terminée je souhaite ajouter deux modes de calibration:
un pour le potentiomètre de commande, de façon à régler la proportionnalité entre commande et réactions de l'actuateur, que mon échelle "0-1023" corresponde à 30, 40, 60, ... degré de rotation potentiomètre
un pour le potentiomètre de recopie, en effet se dernier étant fixe sur l'axe de vanne, il sera nécessaire de le paramétrer suivant la position initiale de la vanne. Autrement dit, pour que le "0 mesure" corresponde à la position "repos de la vanne". Position repos pouvant être réglée par vis de buté à une valeur comprise entre 0 et 15°.
Je vais déjà essayer le code de base avant de rajouter des difficultés supplémentaires...