Archiv verlassen und diese Seite im Standarddesign anzeigen : Fragen zur ASUROLib
trapperjohn
12.07.2008, 13:20
Hi,
ich hab mal eine Frage zur Odometrie.
Sehe ich das richtig, dass der A/D-Wandler, nachdem er einmal per EncoderInit() gestartet wurde, nicht mehr über die Lib deaktiviert werden kann? EncoderStop() schaltet ja nur das Auswerten der Messung aus, aber der A/D-Wandler wandelt trotzdem fröhlich weiter und löst Interrupts aus. Ist das so gewollt oder hab ich den Code in der Lib nur falsch verstanden? O:)
Gruß,
Florian
m.a.r.v.i.n
14.07.2008, 10:30
Hallo Florian,
sieht so aus, als hast du Recht. Ist wohl ein Fehler seit Anbeginn, oder war wirklich so gedacht.
Wobei mir das schon länger ein Dorn im Auge ist. Besser wäre es alle Wandler im IRQ Mode auszulesen oder alle zu pollen, aber nicht gemischt.
Hab nur noch keine Zeit und Muse gefunden, das zu ändern.
Gruß Peter
trapperjohn
14.07.2008, 16:43
Okay, dann hab ich die Einstellungen des AD-Wandlers ja doch richtig verstanden ;)
Solltest du mal Zeit finden, könntest du auch noch bei GoTurn() zuschlagen ... mir ist beim Testen meiner Software mehrmals aufgefallen, dass GoTurn() Probleme machen kann, weil es nie beendet. Meist passiert das zwar aus eigener Schuld, aber schöner wäre es, wenn es gar nicht dazu kommen kann.
Ein Beispiel ist, wenn GoTurn mit einem zu kleinen Wert für Speed aufgerufen wird, sodass der Roboter gar nicht losfährt und GoTurn auf ewig in der Schleife festhängt. Ein anderes Beispiel ist, falls vorher (bspw. durch EncoderStop()) die Variable autoencode auf false gesetzt wurde - auch dann kehrt GoTurn nie zum Aufrufer zurück.
Ich habe bei mir lokal in GoTurn dafür noch ein explizites EncoderStart() hinzugefügt und mit GetTime() ein Timeout von 15 Sekunden eingebaut. Das ist sicher keine perfekte Lösung, aber so wird jedenfalls sichergestellt, dass GoTurn zurückkehrt, falls man Mist gebaut hat ... ;)
Bei mir ist außerdem noch das Problem aufgetreten, dass ab und zu bei LineData() und OdometryData() für rechts und links exakt gleiche Werte zurückgeliefert werden, obwohl das in den jeweiligen Fällen eigentlich nicht sein konnte. Ich hab jetzt beim Aufruf von ReadADC() in der jeweiligen Funktion den Sleep-Parameter von 0 auf 10 geändert (wie bei Battery()) und seitdem diesen Effekt nicht mehr beobachten können. Ich bin mir allerdings nicht sicher, ob das wirklich zusammenhängt oder eher Zufall ist ...
Gruß,
Florian
Sternthaler
18.07.2008, 21:24
Hallo trapperjohn,
ja, die Probleme mit dem "Hängenbleiben" in den Funktionen sind sehr lästig.
Und alle Sensoren per Interrupt zu bearbeiten ist nicht unbedingt übersichtlich und einfach.
Unter ASURO ermittelt Werte für Lib V2.70 myasuro.h selber (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=31073) findest du in dem ASURO-Programm-Teil alle Funktionen (bis auf IR-Empfang) in Interrupts verpackt.
Die Steuerung, welche Sensoren aktiv sein sollen, erfolgt über die in deinem Hauptprogramm zu setzenden Werte in der Variablen: asuro.strg.dat
// Muster aus dem dort vorhandenen test.c main()-Programm zum einschalten
// der RAD-(ODO)-Sensoren und der LINIEN-Sensoren
asuro.strg.dat |= STRG_RAD;
asuro.strg.dat |= STRG_LINIE;
// Wichtig, um sicherzustellen, dass die Sensoren einen Interrupt-
// Zyklus durch haben und nun kontinuierlich Daten liefern.
// Aber NICHT zwingend notwendig. NICHTS bleibt hängen!
while (asuro.sens.dat [SENS_RAD_RD] == 0)
;
// Zum Ausschalten dann bei Bedarf:
asuro.strg.dat &= ~STRG_RAD;
asuro.strg.dat &= ~STRG_LINIE;
Das Messen der Batteriespannung und die Erkennung von gedrückten Tasten lässt sich NICHT abschalten. Macht meiner Meinung nach keine Sinn. Tasten werden i.d.R. immer benötigt, und das Messen der Batterie ist ein Abfallprodukt.
Folgende Interrupts / Funktionen sind beteiligt:
- IR-Senden mit: SIGNAL (SIG_UART_DATA)
- Auswahl des nächsten ADC: SIGNAL (SIG_OVERFLOW2)
- ADC-Daten ausgewertet in: SIGNAL (SIG_ADC)
- Der Wahnsinn beginnt hier: Init()
- Angepasst auf gepuffertes, interruptbetriebenes IR-Senden: SerWrite()
- Angepasst auf interruptbetriebene Tasten: PollSwitch()
- Angepasst auf interruptbetriebene Linien-Sensoren: LineData()
- Linien verfolgen bzw. GoTurn-Ersatz: MotorPID()
- Aktuell nicht funktionsfähig: BackLED()
Alle ermittelten Messwerte sind in der Datenstruktur asuro.sens.dat [xxx] vorhanden.
Für xxx gelten:
- SENS_TASTER ==> Tastenwert wie von PollSwitch()
- SENS_BATTERIE ==> geglätteter Batteriespannungswert
- SENS_LINIE_LH ==> Linker Liniensensor bei EINgeschalteter LED
- SENS_LINIE_RH ==> Rechter Liniensensor bei EINgeschalteter LED
- SENS_LINIE_LD ==> Linker Liniensensor bei AUSgeschalteter LED
- SENS_LINIE_RD ==> Rechter Liniensensor bei AUSgeschalteter LED
- SENS_RAD_LH ==> Linker Radsensor bei EINgeschalteter LED
- SENS_RAD_RH ==> Rechter Radsensor bei EINgeschalteter LED
- SENS_RAD_LD ==> Linker Radsensor bei AUSgeschalteter LED (ja, es geht ! )
- SENS_RAD_RD ==> Rechter Radsensor bei AUSgeschalteter LED
- SENS_TIK_L ==> Gezählte Tik’s vom linken Rad
- SENS_TIK_R ==> Gezählte Tik’s vom rechten Rad
- SENS_TASTER_ADC ==> purer ADC-Wert der Tasten
Am besten schaust du dir die Datei asuro_st.h mal an.
Dort sind die Datentypen definiert und beschrieben.
Unter anderem gibt es noch die asuro.my.yyyy-Variablen. Diese sind für die einstellbaren Werte zuständig, um die Tik-Zählerei und GoTurn() zu betreiben. Die werden in Init() vorbelegt.
Dann gibt es noch die von waste entwickelte PID-Funktion.
Ich habe sie MotorPID() genannt und so umgebaut, dass sie sowohl die (waste-)Linienverfolgung, als auch ein Fahren mit Tik-Vorgaben machen kann. (Geradeausfahren (Go()) Drehen auf der Stelle (Turn()) UND Bogenfahrt sind damit möglich.)
Damit ist es NICHT mehr möglich, dass man hängen bleibt. Die Funktion muss allerdings im Hauptprogramm alle 2ms (Zeit hatte waste ermittelt) aufgerufen werden.
Ein Muster ist auch in test.c zu finden. (Aber durch Sparmaßnahmen deaktiviert.)
Warnung:
Sowohl ausro_st.c als auch test.c sind durch ein paar Defines auf Sparmaßnahmen getrimmt. Somit ist es teilweise unübersichtlich.
Ach und noch etwas:
Das Problem mit den Werten der ADC's liegt tatsächlich am Timing. Du hast schon an der richtigen Stelle (Sleepzeit anpassen) eingegriffen.
Im Source von mir wird dies in asuro_st.c mit den Defines ADC_DELAY_.... gelöst. Der Timerinterrupt schaltet auf den nächsten ADC um, und wartet dann aber erst die in den Delay-Defines angegeben Timer-Interrupt-Anzahl, bis der ADC tatsächlich gestartet wird. Dadurch werden alle möglichen Kondensator-Ladezeiten und Einschaltzeiten (z.B. der LED's) überbrückt. Ist hier aber alles per Interrupt gelöst, so das dieses Warten keine CPU-Zeit vergeudet.
Bei Fragen zum Source: Nur zu ;-)
Gruß Sterntahler
P.S.: Auch die Entfernungsmessung per IR-Hardware kann im Interrupt betrieben werden: https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=371678#371678
Dieser Source passt auch zur hier im Forum verwendeten Asuro-LIB, da die Interruptfunktion dank m.a.r.v.i.n's Umbau nur in den Timer 'eingehängt' werden muss.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.