On commence par une vidéo du résultat obtenu :
Voici l'axe de la tête d'impression d'une imprimante classique :
Et d'un capteur optique :
La bande glisse à l'intérieur du capteur optique.
Dans mon cas le capteur utilisé disposait de deux sorties (A et B). Cela permet de trouver le sens du mouvement. Sur la photo ci-dessous nous pouvons voir les 6 pattes du capteur optique. J'ai identifié le câblage qu'ils ont utilisé et fait un petit schéma. Le circuit ci-dessous sert d'illustration, sur la carte de la tête d'impression il n'est pas implanté au même endroit.
Ici, nous pouvons voir le capteur situé sur la carte de la tête d'impression. C'est le même qu'au dessus. Le jeu consiste maintenant à identifier sur la tresse blanche les fils qui nous intéressent. C'est-à-dire l'alimentation, la masse, et les deux sorties du capteur. Cela doit varier en fonction des imprimantes...
Une fois les fils identifiés, nous pouvons les faire ressortir à l'arrière de l'axe :
Une fois cela fait, il faut pouvoir piloter le moteur de l'axe :
Pour cela j'ai réalisé le montage (pont en H) proposé sur ce post : http://arduino.cc/forum/index.php?topic=120408.0
J'ai donc deux fils reliés à mon Arduino pour piloter le moteur et deux pour lire les signaux du capteur.
J'ai écrit deux bibliothèques pour gérer ce projet. La première se nomme HBridge et comme son nom l'indique permet de faciliter le pilotage d'un pont en H à deux fils de commande (comme sur le schéma du lien ci-dessus). La deuxième se nomme PrinterAxis et permet de gérer l'axe de l'imprimante. Pour utiliser les bibliothèques il faut créer un dossier portant le nom de la bibliothèque et y placer le .h et le .cpp. Ce dossier se place dans votre dossier arduino/libraries.
HBridge.h
#ifndef HBRIDGE_h #define HBRIDGE_h #include "Arduino.h" /* * Auteur: Eliott Dumeix * Date: 04/05/2013 * Permet de contrôler un pont en H à 2 fils de commande. */ class HBridge { public: HBridge(int pinT1, int pinT2); void clockwise(byte pwm); // sens horraire void antiClockwise(byte pwm); // sens anti horraire void halt(); // stopper void setSpeed(int speed); // commander en vitesse (pwm) dans les deux sens void setMaxSpeed(int speed); private: const int t1; const int t2; int max_speed; }; #endifHBridge.cpp
#include "HBridge.h" HBridge::HBridge(int pinT1, int pinT2): t1(pinT1), t2(pinT2), max_speed(255){ pinMode(t1, OUTPUT); pinMode(t2, OUTPUT); halt(); } void HBridge::clockwise(byte pwm){ digitalWrite(t2, LOW); analogWrite(t1, pwm); } void HBridge::antiClockwise(byte pwm){ digitalWrite(t1, LOW); analogWrite(t2, pwm); } void HBridge::halt() { digitalWrite(t1, LOW); digitalWrite(t2, LOW); } void HBridge::setMaxSpeed(int speed) { max_speed = speed; } void HBridge::setSpeed(int speed) { if (speed>0) { if (speed>max_speed) analogWrite(t1, max_speed); else analogWrite(t1, speed); } else { if (speed<-max_speed) analogWrite(t2, max_speed); else analogWrite(t2, -speed); } }PrinterAxis.h
#ifndef PRINTERAXIS_h #define PRINTERAXIS_h #include "Arduino.h" #include "HBridge.h" /* * Auteur: Eliott Dumeix * Date: 04/05/2013 * Permet de contrôler un axe d'imprimante à encodeur linéaire. * Encodeur 2 voies. */ class PrinterAxis { public: PrinterAxis(HBridge &motorRef, int pinA, int pinB); void step(int steps, int dir); // bouger de n pas, dir=RIGHT ou LEFT void goTo(int nGoal); void count(); const int RIGHT; const int LEFT; private: const int A, B; // pin de l'encoder, channel A et B HBridge &motor; // Handle pour contrôler le moteur int n; int pos; // sauvegarde position static const int val[2][2]; // attribue une valeur à la combinaison pin A et B static const int right[4]; // permet de retrouver si le chariot se déplace vers la droite // l'ancienne valeur attribuée, permet de déduire le sens du chariot // paramètres pour le correcteur PI int error_sum ; int error_fluc; float kp, ki; }; #endifPrinterAxis.cpp
#include "PrinterAxis.h" const int PrinterAxis::right[4] = {2, 0, 3, 1}; const int PrinterAxis::val[2][2] = {{0, 1}, {2, 3}}; PrinterAxis::PrinterAxis(HBridge &motorRef, int pinA, int pinB) : motor(motorRef), A(pinA), B(pinB), RIGHT(1), LEFT(-1), n(0), kp(2), ki(0.005){ pinMode(A, INPUT); pinMode(B, INPUT); pos = val[digitalRead(A)][digitalRead(B)]; error_sum =0; error_fluc= 0; } void PrinterAxis::step(int steps, int dir) { int goal_n = n + steps*dir; // position désirée int pwm; int error = goal_n - n; while(error != 0) { count(); error = goal_n -n; error_sum += error; count(); pwm = error*kp + ki*error_sum; motor.setSpeed(pwm); } count(); motor.halt(); for(int i=0;i<200;i++) count(); } void PrinterAxis::goTo(int nGoal) { if (nGoal==n) return; step(abs(nGoal-n), nGoal-n>0 ? RIGHT : LEFT); } void PrinterAxis::count() { byte v = val[digitalRead(A)][digitalRead(B)]; if (v != pos) { if (right[v]==pos) n++; else n--; } pos = v; // sauvegarde ancienne position }Maintenant il ne reste plus qu'a utiliser les bibliothèques afin d'avoir un code propre :
#include <PrinterAxis.h> #include <HBridge.h> const int pin_channelA = 2; const int pin_channelB = 3; const int pin_t1 = 10; const int pin_t2 = 9; HBridge motor(pin_t1, pin_t2); PrinterAxis axis(motor, pin_channelA, pin_channelB); void setup() { TCCR1B = TCCR1B & 0b11111000 | 0x03; motor.setMaxSpeed(150); } void loop() { for (int i=0; i<20;i++) { axis.step(i*100, axis.RIGHT); axis.step(i*100, axis.LEFT); } }
++
RépondreSupprimer