oberallgeier
01.12.2012, 18:02
Hallo Alle,
sorry für den seltsamen Titel. Ich hänge seit Stunden an einem undurchsichtigen Problem und bitte um Hilfe. Irgendwo steckt in einer Subroutine ein Fehler - den ich leider nicht finden kann. Einzig allein der Verzicht auf die (nicht unbedingt nötige) Routine RUNslow1 beseitigt die beschriebene Fehlfunktion - ABER ich würde gerne sehen/wissen/lernen wo ich den Fehler habe.
Stand: Eine waitms-Routine (aus dem C-Code für die RN-Control abgeschrieben und seit Jahren störungsfrei in Betrieb) wird derzeit nach Benutzung in einer bestimmten Subroutine von anderen Routinen nicht mehr benutzbar - zeigt aber in der "Kidnapping"routine weiter saubere Ergebnisse.
Die waitms aus meiner AKTUELLEN Quelle kopiert:
//================================================== ============================ =
//### Programm 1 ms pausieren lassen !! Der Pausenwert ist nur experimentell !
void waitms(uint16_t ms)
{
for(; ms>0; ms--)
{
uint16_t __c = 4000;
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__c)
: "0" (__c)
);
}
}
// ================================================== ============================ =
Auszug aus der Schleife im main:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - Testversion = ...
// - - - - - - - - - - - - - - -
while ( 1 ) //
{ //
TC1TMR_on (); // Vor Servofahrt(en) Servotimer enablen ~tmr~
// RUNi2c_02 (); // Servotest02, Fahre alle Servos mit I2C-Befehlen ~tst~
// RUN_tst2 (); // Servotest, Fahre alle Servos ~tst~
BULid (1); // Servos S2+3 auf mit "1" ~r2n~
waitms ( 5000);
BULid (0); // Servos S2+3 zu mit "0" ~r2n~
waitms ( 5000);
RN2aua90G (); // Servotest, Fahre (alle) Servos 2x auf-ab-90Grad ~r2n~
RUNslow1 () ; // Fahre 10 Servo slow durch Micropositionierung ~r2n~
uart_puts("\r\n\tVor waitms 5000 in main/while(1) \r\n"); //
waitms ( 5000);
uart_puts("\r\n\tEnde main/while(1) \r\n"); //
} //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
return 0; // Ende int main(void)
Die verdächtige Routine "RUNslow1". Wenn die Routine RUNslow1 im obigen Code im main nicht aufgerufen wird, läuft alles bestens. Es werden in der RUNslow1 keine anderen Interrupts initialisiert - es wird dort nur das benutzt, was in den anderen Routinen auch läuft.
//================================================== ============================ =
// ALLE Servoports werden aus unterschiedlichen Startpositionen heraus zwischen
// gleichen Betriebsgrenzen mit gleichen Incrementen gewobbelt
// ##>> Eine Anpassung an unterschiedliche Betriebsgrenzen und Änderungsicremente
// ist durch leichte Änderungen möglich
// KEINE I²C-Funktionalität
// ================================================== ============================ =
void RUNslow1 (void) // Fahre 10 Servo durch Micropositionierung, damit
// geringe Drehgeschwindigkeit
{ // und unabhängig voneinander
uint8_t nservo = 10; //
uint8_t lowbyte, hibyte; //
uint16_t iword = 0; // NUR zum Auslesen
// Word-Variable für Byte 2 (low) + 3 (high)
int16_t mdmmy; // Dummy-Wert
int16_t maxsrv, minsrv; // allgemeine Extrema der Servo
maxsrv = 600; // 28.Nov.2012, 22:59
minsrv = 300; // dto
// - - - - - - - - - - - - - - -
int16_t s[12]; // Vorzeichenbehaftetes Increment für Rampenwert
for (uint8_t i = 0; i <= 12; i++) { s[i] = 2; } // Startwerte
// - - - - - - - - - - - - - - -
// Ausgabe über die serielle Schnittstelle
uart_puts("\tAktiv ist RUNslow1\r\n");
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// und noch quick´n dirty Servos ansteuern
// Startwerte für Servos ##>> IM TESTbetrieb
// ==========
cli();
Srv_tm [1] = 350;
Srv_tm [2] = 400;
Srv_tm [3] = 450;
Srv_tm [4] = 500;
Srv_tm [5] = 550;
Srv_tm [6] = 600;
Srv_tm [7] = 400;
Srv_tm [8] = 500;
Srv_tm [9] = 600;
Srv_tm [10] = 400;
sei();
// - - - - - - - - - - - - - - -
while ( 1 ) // Endlosschleife für Test
{ //
for (uint8_t n = 1; n <= 10; n++)
{ // Servo-Sollwerte wobbeln
cli(); //
mdmmy = Srv_tm [n];
sei(); //
if (mdmmy > maxsrv) s[n] = -2; //
if (mdmmy < minsrv) s[n] = 2; //
cli(); //
Srv_tm [n] = Srv_tm [n] + s[n]; //
sei(); //
} // Ende for (uint8_t n = 0; n =... = EINE 10er Periode !!
waitms ( 21); // Wartezeit für Servozyklus
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Ist die "Abbruchtaste" gedrückt?
if ( IsBitClr (PIND, 2 )) break;
} // Ende while ( 1 )
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uart_puts("\tEnde RUNslow1\r\n");
return; //
} // Ende RUNslow1 (void)
// === Ende RUNslow1 (void)
// ================================================== ============================ =
Die Routine void "BULid (uint8_t auf)" läuft bei den ersten beiden Malen einwandfrei - mit den Parametern 0 und 1, diese Parameter werden (nach der Benutzung der RUNslow1) beim zweiten Durchlauf der BULid gut übergeben, aber die BULid (1) zeigt keine Reaktion, weil die Pause - mit waitms - danach nicht gefahren wird, ebenso nicht die nach dem BULid (0). Dagegen laufen die waitms sowohl in der RUNslow1 als auch in der RN2aua90G.
Sorry für diese Arbeit - aber ich weiß im Moment wirklich nicht weiter.
Danke im Voraus für Hilfe.
sorry für den seltsamen Titel. Ich hänge seit Stunden an einem undurchsichtigen Problem und bitte um Hilfe. Irgendwo steckt in einer Subroutine ein Fehler - den ich leider nicht finden kann. Einzig allein der Verzicht auf die (nicht unbedingt nötige) Routine RUNslow1 beseitigt die beschriebene Fehlfunktion - ABER ich würde gerne sehen/wissen/lernen wo ich den Fehler habe.
Stand: Eine waitms-Routine (aus dem C-Code für die RN-Control abgeschrieben und seit Jahren störungsfrei in Betrieb) wird derzeit nach Benutzung in einer bestimmten Subroutine von anderen Routinen nicht mehr benutzbar - zeigt aber in der "Kidnapping"routine weiter saubere Ergebnisse.
Die waitms aus meiner AKTUELLEN Quelle kopiert:
//================================================== ============================ =
//### Programm 1 ms pausieren lassen !! Der Pausenwert ist nur experimentell !
void waitms(uint16_t ms)
{
for(; ms>0; ms--)
{
uint16_t __c = 4000;
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__c)
: "0" (__c)
);
}
}
// ================================================== ============================ =
Auszug aus der Schleife im main:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - Testversion = ...
// - - - - - - - - - - - - - - -
while ( 1 ) //
{ //
TC1TMR_on (); // Vor Servofahrt(en) Servotimer enablen ~tmr~
// RUNi2c_02 (); // Servotest02, Fahre alle Servos mit I2C-Befehlen ~tst~
// RUN_tst2 (); // Servotest, Fahre alle Servos ~tst~
BULid (1); // Servos S2+3 auf mit "1" ~r2n~
waitms ( 5000);
BULid (0); // Servos S2+3 zu mit "0" ~r2n~
waitms ( 5000);
RN2aua90G (); // Servotest, Fahre (alle) Servos 2x auf-ab-90Grad ~r2n~
RUNslow1 () ; // Fahre 10 Servo slow durch Micropositionierung ~r2n~
uart_puts("\r\n\tVor waitms 5000 in main/while(1) \r\n"); //
waitms ( 5000);
uart_puts("\r\n\tEnde main/while(1) \r\n"); //
} //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
return 0; // Ende int main(void)
Die verdächtige Routine "RUNslow1". Wenn die Routine RUNslow1 im obigen Code im main nicht aufgerufen wird, läuft alles bestens. Es werden in der RUNslow1 keine anderen Interrupts initialisiert - es wird dort nur das benutzt, was in den anderen Routinen auch läuft.
//================================================== ============================ =
// ALLE Servoports werden aus unterschiedlichen Startpositionen heraus zwischen
// gleichen Betriebsgrenzen mit gleichen Incrementen gewobbelt
// ##>> Eine Anpassung an unterschiedliche Betriebsgrenzen und Änderungsicremente
// ist durch leichte Änderungen möglich
// KEINE I²C-Funktionalität
// ================================================== ============================ =
void RUNslow1 (void) // Fahre 10 Servo durch Micropositionierung, damit
// geringe Drehgeschwindigkeit
{ // und unabhängig voneinander
uint8_t nservo = 10; //
uint8_t lowbyte, hibyte; //
uint16_t iword = 0; // NUR zum Auslesen
// Word-Variable für Byte 2 (low) + 3 (high)
int16_t mdmmy; // Dummy-Wert
int16_t maxsrv, minsrv; // allgemeine Extrema der Servo
maxsrv = 600; // 28.Nov.2012, 22:59
minsrv = 300; // dto
// - - - - - - - - - - - - - - -
int16_t s[12]; // Vorzeichenbehaftetes Increment für Rampenwert
for (uint8_t i = 0; i <= 12; i++) { s[i] = 2; } // Startwerte
// - - - - - - - - - - - - - - -
// Ausgabe über die serielle Schnittstelle
uart_puts("\tAktiv ist RUNslow1\r\n");
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// und noch quick´n dirty Servos ansteuern
// Startwerte für Servos ##>> IM TESTbetrieb
// ==========
cli();
Srv_tm [1] = 350;
Srv_tm [2] = 400;
Srv_tm [3] = 450;
Srv_tm [4] = 500;
Srv_tm [5] = 550;
Srv_tm [6] = 600;
Srv_tm [7] = 400;
Srv_tm [8] = 500;
Srv_tm [9] = 600;
Srv_tm [10] = 400;
sei();
// - - - - - - - - - - - - - - -
while ( 1 ) // Endlosschleife für Test
{ //
for (uint8_t n = 1; n <= 10; n++)
{ // Servo-Sollwerte wobbeln
cli(); //
mdmmy = Srv_tm [n];
sei(); //
if (mdmmy > maxsrv) s[n] = -2; //
if (mdmmy < minsrv) s[n] = 2; //
cli(); //
Srv_tm [n] = Srv_tm [n] + s[n]; //
sei(); //
} // Ende for (uint8_t n = 0; n =... = EINE 10er Periode !!
waitms ( 21); // Wartezeit für Servozyklus
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Ist die "Abbruchtaste" gedrückt?
if ( IsBitClr (PIND, 2 )) break;
} // Ende while ( 1 )
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uart_puts("\tEnde RUNslow1\r\n");
return; //
} // Ende RUNslow1 (void)
// === Ende RUNslow1 (void)
// ================================================== ============================ =
Die Routine void "BULid (uint8_t auf)" läuft bei den ersten beiden Malen einwandfrei - mit den Parametern 0 und 1, diese Parameter werden (nach der Benutzung der RUNslow1) beim zweiten Durchlauf der BULid gut übergeben, aber die BULid (1) zeigt keine Reaktion, weil die Pause - mit waitms - danach nicht gefahren wird, ebenso nicht die nach dem BULid (0). Dagegen laufen die waitms sowohl in der RUNslow1 als auch in der RN2aua90G.
Sorry für diese Arbeit - aber ich weiß im Moment wirklich nicht weiter.
Danke im Voraus für Hilfe.