Erst einmal Hallo
Bin ziemlich neu hier und habe bis jetzt immer direkt meine Antworten zu
meinen Problemen gefunden !
Aber jetzt bin ich am verzweifeln !
Zu Thema:
Ich habe ein Tintenstrahldrucker so weit zerlegt das ich nur noch die
Druckerkopfaufnahme und die Achse auf der der Druckerkopf läuft, mit
dem DC-Motor und den Zahnriemen.
Jetzt möchte ich den Druckerkopf auf der Achse in meine Gewünschte
Position bewegen ( die Position soll sich erst einmal mit einem Poti
verändern lassen)
Um das erst einmal Technisch aufzubauen habe ich einen optischen
Inkrementalgeber aus anderen teilen des Druckers und "Strichrasterband"
mit gröberer Auflösung zur Position Erkennung eingebaut!
Zum Problem:
Ich schaffe es nicht die Position des Druckerkopfs genau auszulesen.
Er verzählt sich immer wieder und das schon nach der ersten links-rechts
fahrt um 10-30 Schritte !
Ein paar Fakten:
-habe ein Arduino UNO Board mit einem ATmega328
-Der Inkrementalgeber liest mit großer Sicherheit jeden Impuls vom
"Strichrasterband"
-Besonders langsame Fahrten 1m/h werden zum teil über Haupt nicht
gezählt!
-Der Inkrementalgeber hat 2 digitale Ausgänge: Wenn ich eine Karte von
links nach rechts durchzieh bleibt er auf A1=HIGH A2=LOW. Ziehe ich die
Karte von rechts nach links bleibt er auf A1=LOW A2=HIGH.
-Ich habe sehr wenig Erfahrung in C/C++ und habe das meiste an
Programmen mir zusammen gefummelt und verändert bis es läuft !
Mein Programm:
Ich weiß das hier vieles nicht gebraucht wird aber gehe jetzt einfach
mal davon aus das Geschwindigkeit nicht mein Problem ist !
Wie gesagt das Programm gibt mir zwar einen Zählerstand wieder und
erkennt auch die Richtung (zählt rauf und runter) aber lässt viele
Schritte aus und das meist bei langsamen !
Fallst jemand darauf stossen sollte !
Inkrementalgeber fuktionieren nur wenn die Scheibe oder das Band mit dem
Strichcode genau auf den Inkrementalgeber abgestimmt ist.
Wird das raster grösser oder kleiner ist verzählt sich der
Inkrementalgeber immer wieder und mann hat so Probleme wie ich oben !
Ansonsten fuktoniert der Code den ich oben geschrieben habe !
>Inkrementalgeber fuktionieren nur wenn die Scheibe oder das Band mit dem>Strichcode genau auf den Inkrementalgeber abgestimmt ist.
Nein. Es liegt am Code.
Lies Dir mal den Artikel
"http://www.mikrocontroller.net/articles/Drehgeber" durch. Dort ist das
Problem beschrieben.
Im Prinzip hast Du 4 Zustände: 00, 01, 11 und 10. Wanderst Du von einem
der 4 Zustände nach rechts, musst Du hochzählen, wanderst Du nach links,
runter.
So lässt sich übrigens einfach prüfen, ob der Code richtig ist:
Jeweils die eine und die andere Leitung trennen. Dreht man jetzt
langsam, muss der Zähler immer eins hoch und dann wieder eins runter
zählen. Also beispielsweise 70,71,70,71,70 ...
Zählt er weiter oder gar nicht, ist der Code falsch.
skink schrieb:> Nein. Es liegt am Code.
In diesem Fall schon, aber ...
> Im Prinzip hast Du 4 Zustände: 00, 01, 11 und 10. Wanderst Du von einem
i,A. muss der Strichcode breiter als der Geberabstand sein, damit
sichergestellt ist, dass beim Bewegen alle vier Zustände der Reihe nach
auftreten.
OK zugegeben ich weiss nicht mehr genau ob das Programm was da oben
stehet noch richtig ist !
Aber ich kann sicher bestätigen das die Inkrementalgeber aus einem
Drucker nur mit dem Strichcode laufen mit dem sie verbaut sind.
Ich habe ein größeren Strichcode gebastelt und er hat sich immer
verzählt !
Das Programm was ich genutzt habe :
1
2
int B=2;
3
int A=3;
4
int Wert;
5
6
void setup (){
7
attachInterrupt(0,CHAInt,CHANGE); // Call Channel A of ENCODER Function while on CH1 Signal Changing
8
pinMode(2,INPUT);
9
pinMode(3,INPUT);
10
digitalWrite(2,HIGH);
11
digitalWrite(3,HIGH);
12
Serial.begin(9600);
13
}
14
15
void loop(){
16
17
// Hier kannst du dann mit der Variabeln Wert machen was du willst
18
Serial.println(Wert);
19
}
20
21
void CHAInt (){
22
23
boolean Aread=false;
24
boolean Bread=false;
25
Aread=digitalRead(A);
26
Bread=digitalRead(B);
27
if (Aread==true && Bread==false||Aread==false && Bread==true){
28
Wert--;
29
}
30
if (Aread==false && Bread==false ||Aread==true&& Bread==true){
Der Stichabstand vom Band muss zum Stichabstand der Maske passen die vor
den Detektoren sitzt. Band und Maske haben eine Differenz im
Stichabstand so das beim übereinanderlegen ein Interferenzmuster mit
hellen und dunklen Stellen entsteht. An diesen Stellen sitzen die
Phototransistoren.
Peter Hunsen schrieb:> Ich habe ein größeren Strichcode gebastelt und er hat sich immer> verzählt !
Das kann auch an anderen Unzulänglichkeiten liegen.
>> Das Programm was ich genutzt habe :>> // Hier kannst du dann mit der Variabeln Wert machen was du willst> Serial.println(Wert);
Es muss aber sichergestellt werden, dass "Wert" nicht während der
Benutzung in der ISR geändert wird (Stichwort ATOMIC).
> if (Aread==true && Bread==false||Aread==false && Bread==true){> Wert--;> }> if (Aread==false && Bread==false ||Aread==true&& Bread==true){> Wert++;> }
Was passiert, wenn die Interrupts so kurz hintereinander auftreten,
dass einer nicht behandelt wird, weil die ISR noch nicht fertig ist
(Stichwort: prellen)? Das Programm kann das so gar nicht feststellen.
Besser wäre es, statt der PinChange-Interrupts einen Timer-Interrupt zu
benutzen und alle vier mögliche Zustände (s. weiter oben) auszuwerten.