PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : while() aber nichts passiert...?



Rabenauge
22.05.2010, 01:41
Hallöle.


servo=servoMitte; // funktioniert (servoMitte ist eine Konstante, Wert 120)


while (servo != servo_maxRechts) // nichts passiert, servo_maxRechts ist ebenfalls eine Konstante, Wert 65
{
servo= servo-1;
}
while(servo<servo_maxLinks) // nichts passiert, auch servo_maxLinks ist eine Konstante mit Wert 155
{
servo=servo+1;
}

Ich kann das Servo später (das hier ist gewissermassen nur ein Selbsttest vor der eigentlichen Programmschleife) problemlos durch erhöhen oder verringern von servo richtig steuern.
Probeweise habe ich schon Wartezeiten eingebaut, aber ohne Ergebnis.
Der Codeauszug steckt _nicht_ in irgendeiner übergeordneten Schleife oder so!

Was ist _da_ wieder für ein Wurm drin?

Chaosmann
22.05.2010, 03:42
Was soll denn deiner Meinung nach passieren?
Du hast in dem Code ja keine Ausgabe oder sonstiges drin.
servo müsste nach dem Schnipsel servo_maxLinks entsprechen.

Gruß
Daniel

Rabenauge
22.05.2010, 11:36
servo ist der Sollwert des Servos. Heisst, es fährt diese Position an.
Da es zu Anfang zentriert wird (servo_maxRechts und servo_maxLinks sind die beiden festgelegten Endlagen, weiter darf es nicht fahren) mit servo=servoMitte, sollte es anschliessend einmal nach rechts, dann ganz nach links fahren.
Tuts aber nicht, es fährt nur die Mittelposition an.

Im Programm ändere ich später einfach den Wert Servo so:



int8_t status_R = sens_getRight(); // Rechter Fühler
if(status_R < 0) // nach hinten
{
servo=servo - 5; // Servo nach rechts
delay(50);
if (servo < servo_maxRechts) // Überlauf verhindern
{
servo=servo_maxRechts;
}
}
if(status_R > 0) // nach vorne
{
servo = servo + 5; // Servo nach links
delay(50);
if (servo > servo_maxLinks) // Überlauf verhindern
{
servo = servo_maxLinks;
}
}

..und kann damit das Servo mittels der beiden Taster in beliebige Positionen fahren.
Auch das funktioniert ganz problemlos, ein paar Zeilen später.

sternst
22.05.2010, 13:19
Diese Schleifen verändern den Wert servo viel schneller, als der Servo überhaupt folgen kann. Die Schleifen sind schon komplett durch bevor der Servo überhaupt mal anfängt sich zu bewegen.

SprinterSB
22.05.2010, 14:06
Und durch welche Magie gelange der Inhalt der Variablen "servo" zum Servo?

Rabenauge
22.05.2010, 14:08
Danke, genau das war es.
So:


while(servo<servo_maxLinks)
{
servo=servo+1;
delay(100);
}

funktioniert es.
Nun werd ich mal testen, wieviel Verzögerung da wirklich nötig ist, die 100 nicht.

@SprinterSB das wird im Rest des Programmes erledigt, neben diversen anderen Sachen.
Aktuell (das Programm ist für meinen NiboBee) kann es folgendes:
Servoposition auf dem Display ausgeben, Tooltips (mit welchem Fühler man was bewegt) ausgeben, alle 10s die Akkuspannung messen (brauche ich, da LiPo-Akku), nach rund einer Minute die Displaybeleuchtung ausschalten (das baue ich inzwischen gewohnheitsmässig ein, wo es Sinn macht), inklusive Wiedereinschalt- Funktion.
Beim Start wird zuerst die Akkuspannung geprüft und ausgegeben, das Display aufgebaut, danach fährt das Servo zuerst in die Mitte (um Eventualitäten auszuschliessen), dann einmal voll rechts, einmal voll links, wieder zur Mitte, und dann kann man es mittels dem Rechten Fühler beliebig bewegen. Mit dem Linken Fühler lässt es sich jederzeit wieder in Mittelstellung fahren, ausserdem kann der in der zweiten Stellung die Display-Beleuchtung wieder aktivieren.
Da der Sensor noch immer auf dem Wege zu mir ist, beschäftige ich mich eben damit, wie man später beim fahren am effentivsten die Umbebung nach Hindernissen absucht, und ich glaube, mit diesem Ansatz wird das ganz gut klappen.

Die Servosteuerung selber sieht so aus:



TCCR2 = (1 << WGM21) | (1 << CS20); // CTC-Mode, no prescaling, no OC2-PIN!
OCR2 = 208; // 36kHz @15MHz
TIMSK |= (1 << OCIE2);

In der ISR dann:



ISR (TIMER2_COMP_vect)
{
if(count_serv>servo) PORTC &= ~(1<<PC3); else PORTC |= (1<<PC3);
if(count_serv<1440) count_serv++; else {count_serv=1; if(p) p--;};
}

Ich glaube, der Code stammt im wesentlichen von Radbruch, ich hab ihn halt eingebaut und, wo nötig, etwas modifiziert.
Nun kann man das Servo bequem über die Variable servo in beliebige Positionen fahren, 100 ist ca. Mitte.
Da ich den vollen Weg nicht brauchen kann, habe ich mir die drei Konstanten

servoMitte //für die tatsächliche Mittelstellung
servo_maxLinks // für den maximal erlaubten Ausschlag nach links
servo_maxRechts //für den Maximalausschlag Rechts

definiert, da mein Servo später einen IR-Sensor bewegen soll.
Durch die bei mir nötig gewordene Umlenkung (das Servo bewegt den Sensor über Gestänge und Umlenkhebel) komme ich halt auf _meine_ individuellen Wege, die man in dem Programm bequem mit den drei konstanten anpassen kann.