Hallo Gerhard, fehlt Dir nur die Auswertung oder hast Du keine(n) Odometriesensor(en)?... wohl ein mech. Problem, anstatt ein elektronisches wegen noch fehlender Odometrieauswertung ...
Hallo Gerhard, fehlt Dir nur die Auswertung oder hast Du keine(n) Odometriesensor(en)?... wohl ein mech. Problem, anstatt ein elektronisches wegen noch fehlender Odometrieauswertung ...
Ciao sagt der JoeamBerg
Hallo JoeAmBerg !
Freu mich Dich wieder mal zu lesen...
Ich denke es liegt erstens am Material der Bereifung, zweitens dann daran fdas nicht die Umdrehungszahl kontrolliert und ausgewertet wird. Ich habe mir jetzt aus zwei Gabellichtschranken einen Sensor für die Lochscheiben auf den Achsen gebastelt(siehe Foto).
Nun muss ich noch sehen wie ich das ganze Softwaremässig einbinde in das Grundprogramm. ich habe dahingehend noch nix selber "gecodet", auch noch nicht so richtig dafür Beispiele/Anregungen gefunden..
Als erstes möchte ich in einer Messschaltung feststellen, ob schon rein elektrisch/mech. von der Umdrehung her schon Unterschiede zwischen den beiden Motoren besteht. Nur fehlt momentan die Zeit um kontinuierlich daran durchweg zu arbeiten.
Gruss Gerhard
Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint
Hallo Gerhard
Na prima, damit kann man ja schon ne ganze Menge anfangen. Hier mal kurz skizziert wie ich meine Geschwindigkeiten und Wege messe.
1. Ein Timer mit 50 µs - bei meinen 20 MHz-Controllern habe ich also satte 1000 Maschinenzyklen zwischen den Timer-Interrupts. Der Timer zählt diese Zeitscheiben (timer units) hoch bis zu - sagen wir 20 000 - danach wird er auf "Eins" gesetzt. Der Timer wird mit dieser Interruptserviceroutine "ausgelesen".
2. Ein Interrupt (hier bei steigender Flanke der Gabellichtschranke) ausgelöst am Eingang EXT_INT1 (und für den anderen Motor auf EXT_INT0. Die Zeitscheiben zwischen zwei Interrupts werden notiert z.B. als Iz_ysec1 => Istzeit_für_mot_1. Ausserdem wird gleich die Zeitdifferenz zwischen zwei Interrupts berechnet, damit kann schnell die Drehzahl berechnet werden. Beachte: die vierflügelige Encoderscheibe wird nur bei jedem zweiten Schlitz ausgewertet => das ist die Zeit für eine halbe Motorumdrehung. Diese Zeitscheiben nenne ich in meinem Programm tupsi (t imer u nits p er s ensor i nterrupt) - das ist also eine inverse Geschwindigkeit. Und die Vorgabe dazu sind die stupsi - Soll-tupsi.Code:// ============================================================================== = // === Nicht unterbrechbare ISR für timer2 ===================================== = // Routine zählt hoch im Takt 20 kHz = 50 µs. Der Zählerwert wird von den ISR für // EXT_INT0 und -INT1 ausgelesen und den Werten Iz_yseci zugewiesen. ISR(TIMER2_COMPA_vect) // Vektor 7 { if (Izeit_1 < Izthrznt) //Interrupt-Timer = 0 ... 19 999 ... (1 sec blink) // Izthrznt ist der Zeithorizont, meist 19 999 // entsprechend einer Sekunde // Izeit_1 ist die "Bordzeit" als Teil einer Sek { // Izeit_1 ++; // ###>>> Izeit_1 ist aktuell int16_t ==>> // Izeit_1 bleibt bis 32000 in der int16-Grenze } // else // { // Izeit_1 = 1; // ansonsten: Rückstellen auf Eins } // Ende if (Izeit_1 < Izthrznt) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - return; } // // ============================================================================== =
Anmerkung: Es gibt alle Sekunden einen Rechenfehler durch den Zeitüberlauf von Izeit_1. Der wird aus Gründen der Rechengeschwindigkeit vernachlässigt, der dadurch entstehende Fehler stört in der Praxis nicht. Fehlerhäufigkeit ist dabei durchschnittlich 0,5% der Encoderzeit-Messungen.
Code:// ============================================================================== = // === Nicht unterbrechbare ISR für EXT_INT1 auf Pin 5/PD3/mega168 ============ = // Routine setzt einfach einen Zähler hoch. // Diese Encoderroutine schreibt die verstrichenen Zeiteinheiten zu 50µs auf, // die seit dem letzten Encoder-Interrupt verstrichen sind. ISR(INT1_vect) // hiess mal: ISR(SIG_INTERRUPT1) { // if (nenc1 < mxnc1) // mxnc1 ist eine Art "Divisor" für die // Encoderscheibe => es wird nur jeder // mxnc1-te (hier 2) Scheibentick gezählt { nenc1 = nenc1 + 1; // Interrupt hochzählen (4-Flügel-Encoder) Lncdrges1 ++; // Gesamte Encoderticks einfach hochzählen } else { // Zähle NUR jeden vierten Interrupt nenc1 = 1; Iencdr1 ++; //zähle Counter/encoder1 hoch Ienc1alt = Iencdr1; Iz_yseci1 = Izeit_1; //Weise Iz_ysec1 dem akt. Timerwert zu Iz_diff1 = Iz_yseci1-Iz_ysecv1; //Neue Zeit-Differenz1 ausrechnen Iz_ysecv1 = Iz_yseci1; //der aktuelle Zeitwert wird "Alter" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Es werden jetzt die aktuellen Daten festgehalten für Messfahrt } } // ============================================================================= =
Nun habe ich manchmal in einem kurzen Testlauf at runtime in der ISR (zu Punkt 2) die Encoderzeiten = Zeitbedarf für eine halbe Motorumdrehung, in einem hundertelementigen Feld festgehalten, dazu die fortlaufende Bordzeit (wegen der späteren Diagramm-Zeitachse) und nach dem Testlauf die Daten über UART ausgegeben. Damit kann ich prächtig die beiden Motoren auf Gleichlauf und sonstige dynamisch interessante Eigenschaften prüfen.
In diesen Messfahrten (klick für Beschreibung und Diagramme) habe ich das simultane Anfahren meiner Motörchen getestet, Fehler festgestellt und behoben *ggg*.
Und hier (klick mal) habe ich beschreiben, wie ich die Reifen für meinen WALL R so griffig mache, das ich Rutschen verhindern kann (seit diesem Postings fahren die Formel1-Piloten mit Soft, Supersoft, Inter etc *ggg*).
Natürlich kann ich mit alle dem NUR die Umfangsgeschwindigkeit der Antriebsräder berechnen/messen. Der Schlupf verhindert, dass diese Geschwindigkeit auch zu 100,000 % die wahre Fahrgeschwindigkeit des zugehörigen Rades ist :-/
Viel Erfolg
Geändert von oberallgeier (12.06.2012 um 17:30 Uhr) Grund: Hinweis auf Schlupf der Antriebsräder
Ciao sagt der JoeamBerg
Hier mein Testlaufprogramm ganz einfach erst mal :
int MLD = 7; //Motor Links Richtung (Low/High)
int MLV = 9; //Motor Links Speed (0...255)
int MRD = 8; //Motor Rechts Richtung (Low/High)
int MRV = 10; // Motor Rechts Speed (0..255)
void setup() {
pinMode(MLD, OUTPUT); // Left direction
pinMode(MLV, OUTPUT); // left speed
pinMode(MRD, OUTPUT); // Right direction
pinMode(MRV, OUTPUT); // right speed
}
void loop () {
digitalWrite(MLD,HIGH); // Dir Vorwärtz
digitalWrite(MRD, HIGH); // Dir Vorwärtz
analogWrite(MLV, 200); //PWM Speed Control
analogWrite(MRV, 200); //PWM Speed Control
}
Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint
Einfache Tests ziehe ich immer den komplizierten vor.
Eins ist mir bei Deinem Programmschnippsel nicht klar - aber ich kenne/kann eben nicht den arduino-Dialekt: die Routine void loop ist ja kein loop sondern ein einfaches Setzen von Geschwindigkeiten und Drehrichtungen !? Ich kann mir eben nix vorstellen unter dem Befehl digitalWrite oder analogWrite. Wird da etwas geschrieben? Ich vermute daß damit nur die eben genannten Werte für den Motortreiber gesetzt werden.
Nur mal so: wenn Du beim Testen aktuelle Daten über UART ausgibst, dann wird das nicht sehr zeitnah sein - weil die serielle Ausgabe eben dauert - im Vergleich zu ner millisekundenlangen (oder eher -kurzen) Motorzeitkonstante.
Ciao sagt der JoeamBerg
wenn wir mal "tellen"... ich richte mich nach Deiner freien Zeit erklär ich dir das mal kurz...bzw wenn mein Listing mit lfd Bemerkungen in den Zeilen fertig ist schicke ich Dir das per mail...das ist dann verständlicher..zunächst werde ich die Segmentscheibenauswertung machen, am Steckbord so als "Steckverkabelung"..
will da mal erst mittels FZä.. die Umdrehungen messen im Leerlauf...möchte dann so stück für stück weiterausbauen um ales zu verstehen was ich da mache und was sich dadurch tut...zumindestens alles was geht(..zu verstehen ;=) )
nochmals zur Erklärung den Codeschnipsel habe ich einfach genommen, um überhaupt erst mal zu erfahren was das Board und der Robo damit macht, erste Funktionskontrolle sozusagen...nur mal eben sehen ob die Motoren Laufen, das Board geht usw., ja auch wegen der Garantie
Gerhard
Edit 14.6.12: Heute ist die GLS auf der Lochraster fertig verdrahtet und getestet. Es stehen folgende Spannungspegel am Ausgang an:
1. Hell = 0,110V
2. Dunkel = 4,7V
Ich hoffe das dies zur Auswertung gehen wird, heute Abend werde ich das am FZ testen, zum Anbau auf das Chassis muss ich noch einen 3x10mm Schlitz in die Lpl. fräsen, mal sehen ob ich das ohne Fräsständer "Drehmeln" kann/schaffe
Edit 2: Die Messung der GLS-Impulse (Die Scheibe hat 6 Lichtschlitze) ergab bei beiden ca. 14,5 HZ , gemessen mit einem Multimeter mit f-messbereich, ich weiss das ist nicht Ideal, aber erst mal akzeptabel um allzugrosse Abweichungen zu erkennen.
Edit 3: ernüchterne Erkenntnis, ich weiss nicht was ich da an Frequenz gemessen habe, als ich nochmals die rein digitalen Werte messen wollte, durch lkangsames Drehen der Räder musste ich feststellen das sich nix ändert und die Segmentscheibe IR- u. Lichtdurchlässig ist....grolll, gräm...grrr
Geändert von oderlachs (14.06.2012 um 14:32 Uhr)
Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint
Stimmt, das hatten schon viele von uns mühselig gelernt - dass IR und sichtbares Licht zwei verschiedene Stiefel sind. Ich hatte das auch mal gerafft und dieses (klick) Torpedorohr aus Schrumpfschlauch durch Messingröhrchen ersetzt (klick). Mit Messing, später auch Alufolie gings dann perfekt.... ernüchterne Erkenntnis ... musste ich feststellen ... Segmentscheibe IR- u. Lichtdurchlässig ...
Ciao sagt der JoeamBerg
Lesezeichen