cherche aide pour codage PID sur arduino !

  • Auteur de la discussion Doctor_itchy
  • Date de début
D

Doctor_itchy

Compagnon
hello as tous :)

voila j'ai besoin d'un pro de l'arduino et servo , j'explique

je suis occuper a fabriquer une cnc graveuse laser sur base d'une imprimante jet d'encre epson PRO taille A2 (imprimais des plans ) j'ai garder le châssis la mécanique et les moteur qui sont des bon moteur DC sur roulement ! avec encodeur quad , trouvant les prix des drivers servo assez elever (70€ le moins chère ) et n'en trouvant pas d'occasion je me suis décider et j'ai acheter sur ebay des drivers 4ampere DC ultracompact de 40*40*32mm contrôler en pwm high et pwm low , entrée enable et sortie current sense , j'ai acheter deux petite arduino NANO , j'ai assemblé le tout , et coder sur base d'un code venant de chez makerbot , cela fonctionne le servo est bien "servo"


par contre le code trouver n’intègre pas de PID , donc la posistion demandée n'est pas tjrs la meme , bcp d'erreur de pas :/ se code est opensource et doit etre amélioré ! , j'ai bien commencer en integrant une sortie enabled , modifier le pinout initial ect mais le pid j'ai tenter et je patauge :/

si une personne a un code opensource qui gere les entrée step/dir , encodeur , et sortie pour pont en H deux fils avec le PID et que cela fonctionne nikel , je prend :)

j'ai beau chercher sur le net j'ai trouver du code pid mais il sont tous différent , j'ai meme le code du yapsci ( qui tourne sur pic mais le code est en C++ donc portable ) et je n'arrive pas a l’intégré ( et j'aimerais un autotune si possible :) )

au pro de l'arduino merci d'avance :)

P1040148.JPG
le drivers

P1040149.JPG
l'arduino

P1040150.JPG
la carte interface entre arduino et drivers qui serais faite "correctement" des que la machine fonctionneras :)

P1040152.JPG
en test sur le moteur :)
 
E

erolhc

Guest
Bonjour

Avant de parler PID je vois deux problèmes potentiels :

1 - Est-ce que les signaux A et B de l'encodeur sont gérés par des interruptions ?
2 - Est-ce que l'adressage des sorties se fait à l'aide d'une librairie "rapide" (du genre digitalwritefast.h) ou mieux par adressage direct des ports I/O. Si c'est la librairie standard de l'arduino pour les entrées/sorties il y a de grandes chances que cela marche sur 3 pattes car elle est très chronophage
 
G

gaston48

Compagnon
Bonjour,

je suis occuper a fabriquer une cnc graveuse laser sur base d'une imprimante jet d'encre epson PRO taille A2 (imprimais des plans ) j'ai garder le châssis la mécanique et les moteur qui sont des bon moteur DC sur roulement ! avec encodeur quad , trouvant les prix des drivers servo assez elever (70€ le moins chère ) et n'en trouvant pas d'occasion je me suis décider et j'ai acheter sur ebay des drivers 4ampere DC ultracompact de 40*40*32mm contrôler en pwm high et pwm low , entrée enable et sortie current sense


Doc ! mais quand vas-tu te mettre à Linuxcnc/emc2 ? :wink:
tu serais opérationnel depuis longtemps ...
 
D

Doctor_itchy

Compagnon
haaa emc² ben si je l'utilise sur mes autres cnc :wink:

mais ici c'est un projet as base d'un controleur autonome qui tient dans l'imprimante avec un ecran 128*64 graphique sur un pic ( schéma et code de arnaud :) ) un pc ne rentre pas :/ donc je met le code sur une carte sd et la machine execute , et comme j'ai tout pour le faire :)


pour le code

c'est baser sur le code makerbot servo !

tout tient dans un seul programme , pas de librairie (j'ai d'autre code avec librairie , mais il ne gere pas les entrée stepdir et me font plien d'erreur en compilation :/

l'encodeur est addressé comme suit

#define QUAD_A_PIN 7 //encodeur
#define QUAD_B_PIN 2 //encodeur

et dans void setup

pinMode(QUAD_A_PIN, INPUT);
pinMode(QUAD_B_PIN, INPUT);

et dans les derniere ligne


void read_quadrature_a()
{
// found a low-to-high on channel A
if (digitalRead(QUAD_A_PIN) == HIGH)
{
// check channel B to see which way
if (digitalRead(QUAD_B_PIN) == LOW)
position--;
else
position++;
} // found a high-to-low on channel A
else
{ // check channel B to see which way
if (digitalRead(QUAD_B_PIN) == LOW)
position++;
else
position--;
}
}

void read_quadrature_b()
{
// found a low-to-high on channel A
if (digitalRead(QUAD_B_PIN) == HIGH)
{
// check channel B to see which way
if (digitalRead(QUAD_A_PIN) == LOW)
position++;
else
position--;
} // found a high-to-low on channel A
else
{ // check channel B to see which way
if (digitalRead(QUAD_A_PIN) == LOW)
position--;
else
position++;
}

les sortie sont gérée direct sur le code principal

genre

digitalWrite(MOTOR_RPWM_PIN, LOW);
digitalWrite(MOTOR_LPWM_PIN, LOW);

et

analogWrite(MOTOR_LPWM_PIN, motor_speed);


je pense que je vais devoir refaire un code complet :/
 
D

Doctor_itchy

Compagnon
j'ai un autre coe qui gere le codeur avec des interruption :) , mais celui la controle le tout via les entrée analog , pour un potard :/ , j'ai encore un autre code qui lui ne fait que balader le chariot de droite a gauche , j'ai potasser le codage arduino mais je suis un peu perdu avec tout ses codes ! , mais j'en démors pas ^^
 
E

erolhc

Guest
Bonjour

Effectivement à la vue du code il ne semble pas (pas de déclaration) que les signaux du codeur soient traités par des interruptions.
A mon avis il est impératif que cela soit le cas sinon tu ne seras jamais sur que tu n'as pas loupé des "ticks".
De même je pense qu'il aussi impératif que tu lises les entrées de la façon la plus rapide possible et donc soit en utilisant la librairie "digitalwritefast" soit en codant en "vrai" C c'est à dire en adressant directement sur les ports I/O (PORTB, ...).
Soit tu n'utilises qu'une seule interruption (sur A) puis tu lis B pour incrémenter / décrémenter la valeur absolue des "ticks". Soit tu utilises les deux interruptions dispo sur la NANO et tu fais pareil pour B en lisant A. Dans un cas tu est en "x2" dans l'autre en "x4"

Pour le PID , la majorité des codes que j'ai vu "strappent" la valeur temps et calculent le PID à intervalle donné en utilisant une interruption logicielle (timer), cela simplifie le code (pour une régulation de température c'est suffisant) mais Je ne pense pas que pour un servo cela soit très adapté surtout si il y des rampes d'accélération ou de ralentissement sans parler que cela risque d'entrer en conflit avec la gestion des entrées A-B.
 
D

Doctor_itchy

Compagnon
okay :) , tu as un exemple de code pour l'encodeur ? avec des interruption ?

car oui j'ai bien l'impression que le code zap des impultion du codeur ( et le moteur ne tourne pas a fond , il doit etre a 300tmins alors que en dc 24V directement il tourne a 2000tmins .... ( et tout est as fond sur mach3 !!! )

bien que je pense avoir un code avec ça , il faudrais que je l'essaie mais je doit supprimé le controle par pot analogique et mettre en step dir , se soir cafer fort papier crayon , bien assis et je tente ça :)

nuit blanche en vue haha ^^ et la nano va chauffer :)

je suppose que si le code n'integre pas de pid la précision ne sera pas au top non plus :)
je mettrais mon code ici tantot si tu sais m'aider , car le c++ et moi houlaaaa :/
 
G

gaston48

Compagnon
( et tout est as fond sur mach3 !!! )

???

j’insiste peut être lourdement mais avec emc2 configuré avec pwm high et pwm low etc tu testes et mets au point ,
avec tout le conforts, tous les éléments de ton imprimante: encodeurs, servomoteurs, drives, jeux, PID, FF, etc
(emc2 n’est pas seulement un interpolateur comme mach3, il sait faire l’acquisistion de codeurs et piloter un pont en H)
Peut être que seule une action proportionnelle P est suffisante ?
A la fin, tu bascules le juste nécessaire sur Arduino.
 
D

Doctor_itchy

Compagnon
ha oui vu comme ça :) pour ajuster le pid et co

mais j'aimerais faire un code qui fait de l'auto pid , donc ajustement auto :)

pas pour se soir finalement :/
 
E

erolhc

Guest
Bonjour

Ici un exemple de code pour décodage complet (x4) des signaux A-B avec interruption (changement d'état) et utilisation de la librairie "digitalwritefast".

@Gaston48 : j'ai quelques doutes sur la capacité d'un PC à générer un signal PWM tout en surveillant les signaux d'un codeur sur son port parallèle et ce quelque soit l'OS/programme derrière.
 
N

nopxor

Compagnon
Bonjour,

Arduino -> 16 Mhz , PC -> ~= 1.6 GHz
Soit une cadence 100 fois plus élevée.
Même en tenant compte de RISC / CISC, la puissance de calcul d'un PC est énorme.
Et le noyau temps réel linux est optimisé pour l'application CNC.
 
G

gaston48

Compagnon
@gaston48 : j'ai quelques doutes sur la capacité d'un PC à générer un signal PWM tout en surveillant les signaux d'un codeur sur son port parallèle et ce quelque soit l'OS/programme derrière.

Pour être à l’aise il faut doper les entrées / sorties avec une carte à FPGA Mesa.
Le premier prix étant de 88 euros sur port // ou USB.

http://www.duzi.cz/shop_cnc/index.php?main_page=index&cPath=1_4

Suivant ces cartes, les fréquence d’échantillonnage des encodeurs sont de 33 ou 50 Mhz.
Celles des PDM ou PWM sont de 2 MHz et 190 KHz.
Par défaut, une boucle PID est calculé toutes les 1 ms … ce qui nous ferait tous les 0.01 mm
pour une avance de travail de 800 mm/mn. certains descendesnt à 0.1 ms
 
Dernière édition par un modérateur:
E

erolhc

Guest
Ok, donc il faut rajouter (acheter) une carte ... tout ca pour mettre au point sur du matériel qui n'a strictement aucun rapport avec la finalité : l'arduino fonctionne, le circuit à L298 fonctionne, le moteur fonctionne : c'est juste du logiciel à faire
Soit le Doc veut un truc autonome à bas cout soit il prend un PC avec une carte + drivers mais pour la mise au point je ne vois pas l’intérêt ou il y a quelque chose que je n'ai pas saisi
 
C

coredump

Compagnon
nopxor a dit:
Bonjour,

Arduino -> 16 Mhz , PC -> ~= 1.6 GHz
Soit une cadence 100 fois plus élevée.
Même en tenant compte de RISC / CISC, la puissance de calcul d'un PC est énorme.
Et le noyau temps réel linux est optimisé pour l'application CNC.

Mais 0 entrée/sortie rapide. Du coup faut passer sur du Mesa qui fait un support matériel des encodeurs et PWM.
 
G

gaston48

Compagnon
il y a quelque chose que je n'ai pas saisi
Je ne pense pas me tromper en disant que la config de prédilection de Doc, c’est Mach3 + la carte YAPSC de Max-Mod + servomoteur DC à balais …
Il se trouve que ma Max-Mod n’assure plus le suivi de sa carte, d’où les tentatives infructueuses de recherche par Doc de driver DC à entrées step/dir lowcost style leadshines ( https://www.usinages.com/posts/590280#p590280 ) par exemple.

J’essaye de convaincre Doc d’utiliser Emc2 non pas comme un Mach3 sur Linux, mais comme une vrais cnc.
Il faut "juste" investir dans une carte à 90 euros. Les drivers en H des moteurs restent ceux à base de L298.
Et pour l’avenir, la possibilité aussi d’exploiter les anciens servodriveDC à entrées +/- 10v.
Ou comme Biduleur, la possibilité de se faire des drivers en H beaucoup plus puissants.
 
Dernière édition par un modérateur:
E

erolhc

Guest
ok mais dans ce cas là ce n'est plus un système autonome (sans PC) ce qui semble être une condition du projet
 
D

Doctor_itchy

Compagnon
lol , coollll ^^

bon alors

oui j'ai des carte yapsci qui gère des gros servo moteur infranor avec les contrôleur servo tach infranor industriel , qui sont sur une CNC ( pas finie non plus ... ) avec un pc dédier (1.6ghz amd , 1go ram , carte ati 9800pro ) et emc2 , mais pas de retour encodeur , la carte est servo le pid est parfait , et yapsci gère la boucle encodeur et les entrée step dir ça fonctionne très bien ça tourne très vite sans la moindre perte de pas en charge on touche pas ^^


le but étant de faire une machine compact et autonome avec le moins de dépense possible ( j'ai tout se qu'il faut , il ne me reste que as coder les drivers servo , et finir la source laser :) ) , avec une carte sur base de DSpic , lcd graphique , qui sorte en step dir , je sais que emc2 est tres bien comme soft , mais je n'ai pas envie de mettre 90€ pour la mesa et je n'ais pas la place pour un pc ( meme un micro ATX ne passe pas j'ai déja essaier :wink: ) ( sinon je n'aurais pas acheter les drivers et arduino , et j'aurais pris du geko ou leadshine tout fait a 80€ le drivers +- ^^

bon je vais plancher sur le code donné , plancher sur un code correcte pour le pont en H

question

il vaut mieux un seul programme bien taper , ou avoir un programme de base et des sous programme (nommer *.h ) genre un pour le pont en H un pour l'encodeur , un pour le pid , ect ???
 
D

Doctor_itchy

Compagnon
mais gaston , je suis d'accord de dire que emc2 serais bcp mieux :) , mais pas pour se projet içi :wink:
 
E

erolhc

Guest
Bonjour

Il y a une librairie pour le PID et même un autotune.

Le code pour pont en H ? euh, il va pas dépasser 2 ou 3 instructions (rapport cyclique et sens déterminé par le PID) et quelques déclarations pour les pin
 
D

Doctor_itchy

Compagnon
pour le pont en H j'ai fait ceci

controle via 2 pin (high pwm et low pwm ) :)


void setMotor(int value) // set PWM of motor, value may range from -255 to 255
{
if (value>=0)
{
digitalWrite(10,LOW);
analogWrite(9,value);
}
if (value<0)
{
digitalWrite(9,LOW);
analogWrite(10,value);
}
}

il ne faut rien de plus spécifique pour le pont en H ?
 
E

erolhc

Guest
Bonjour

:smt017
Ou est ce que tu as récupéré ce code ?

normalement le PWM varie de 0 à 255 (et il n'y a pas de valeur négative) et le sens est donné par 1 ou 0 sur une autre broche, comme un DIR/STEP sauf qu'ici le STEP (basé sur une fréquence) est un signal PWM (basé sur un rapport cyclique)
 
D

Doctor_itchy

Compagnon
en effet je n'ai pas encore modifier ses valeur la ! , sinon le pont en H as deux entrée PWM une pour tourné as droite et une pour tourné a gauche :wink: , donc une doit avoir le pwm et l'autre a la masse et inversement :wink:
 
C

coredump

Compagnon
Doctor_itchy a dit:
pour le pont en H j'ai fait ceci

controle via 2 pin (high pwm et low pwm ) :)


void setMotor(int value) // set PWM of motor, value may range from -255 to 255
{
if (value>=0)
{
digitalWrite(10,LOW);
analogWrite(9,value);
}
if (value<0)
{
digitalWrite(9,LOW);
analogWrite(10,value);
}
}

il ne faut rien de plus spécifique pour le pont en H ?

Idéalement il faut trois états pour le pont en H: les deux polarisations différente et une bande morte (aucun transistor commuté) qui dure un temps très court, afin de prendre en compte la vitesse de commutation des dit transistors.
Normalement c'est pas trop un soucis, mais avec des uP rapides et les transistors un peu lents, on peut avoir un petit moment ou les deux sont conducteurs, ce qui fera grimper la dissipation du pont (ou bien le détruira instantanément).
 
E

erolhc

Guest
Ok. D'après les photo j'avais l'impression que c’était un L298P mais bon tu connais ta carte mieux que moi
Du moment que tu arrives à faire varier la vitesse du moteur dans les deux sens c'est le principal
 
D

Doctor_itchy

Compagnon
non c'est un l6201p :wink:


haaa oui le temps mort je l'avais mis sur l'autre code et pas ici !!! tres juste ! merçi :)
 
G

gaston48

Compagnon
Il me semble que le "dead time" évoqué par Coredump est intégré dans le circuit
(40 ns)
 
D

Doctor_itchy

Compagnon
j'ai pas regarder , je l'ai mis d'office dans le code de toute façon il y as tjrs du jus vu que le moteur est a l'etat "bloquer" quand il est sous tension :)


pas encore regarder , j'ai du faire mon auto , du week je m'y met :)

je mettrais le code une fois fini et parfaitement good , ici pour ceux qui veulent faire des controleur servo façile et peu couteux :)
 
M

moissan

Compagnon
pour utiliser un encodeur sans rater de pas avec un petit microcontroleur , il faut le configurer pour que l'encodeur fasse directement compter un compteur timer du microcontroleur ... ainsi même si le programme prend un peu de retard sur la lecture de ce compteur il n'y a pas de perte de pas

mais je ne sait pas si l'atmel de ton arduino a cette possibilité

si chaque impulsion du codeur doit provoquer une interruption ça va faire une occupation enorme du microcontroleur : ce petit 8bit sera il suffisant ?

autre solution : prendre un micro controleur plus puissant et pas plus cher
https://www.olimex.com/Products/Duino/PIC32/PIC32-PINGUINO-MICRO/open-source-hardware
pour 12euro il y a un pic 32bit a 80MHz donc beaucoup plus de facilité a compter et calculer rapidement

reste a savoir si le language arduino permet d'en utiliser toute la puissance , ou si il faut utiliser le logiciel de programation de microschip

je vais en acheter un pour essayer car il me parait plus interressant que l'arduino de base
 
Dernière édition par un modérateur:
E

erolhc

Guest
Bonjour

Je ne suis pas assez versé dans la chose mais j'ai des doutes concernant l'aptitude des compteurs/timers à gérer les 2 canaux d'un encodeur en quadrature : à chaque changement d'état de l'un des canaux on va voir comment est l'autre pour déterminer le sens de rotation. Et le sens de rotation lors de la mise en maintient de position n'est pas connu à l'avance d’où l'utilité de l'encodeur (réaction à une contrainte pour maintenir la position)
 

Sujets similaires

D
Réponses
6
Affichages
12 632
Doctor_itchy
D
A
Réponses
24
Affichages
2 102
bernard52
B
J
Réponses
265
Affichages
13 856
F
JB
Réponses
11
Affichages
1 789
phil135
P
F
Réponses
6
Affichages
25 595
fraiddy
F
G
Réponses
8
Affichages
13 359
JMe87
J
T
Réponses
28
Affichages
2 912
Tristan l'apprenti
T
D
Réponses
103
Affichages
8 122
Doctor_itchy
D
D
Réponses
9
Affichages
18 044
Doctor_itchy
D
M
Réponses
8
Affichages
3 679
Mandrak
M
Haut