PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : initialisierung, servo & SRF02



inka
01.12.2014, 16:15
hallo allerseits,

seit drei tagen hocke ich schon an diesem code und glaube sehe den wald vor lauter bäumen nicht :-(

das programm (der servo soll schrittweise drehen und der SRF die entfernung messen) läuft bis auf kleinigkeiten, darum geht es hier also nicht, das sind offensichtlich noch laufzeitprobleme...

Das problem ist folgendes:

bei einschalten und starten läuft der SRF an und misst, der servo dreht aber nicht. Beim erneuten drücken des startbuttons - ohne vorher abzuschalten - läuft beides, der SRF und der servo. Wäre für mich ein initialisierungsproblem, aber wo? ich finds einfach nicht - könnte mich bitte jemand anschubsen?....

danke...


#include "RP6ControlLib.h"
#include "RP6I2CmasterTWI.h"
#include "RP6Control_MultiIOLib.h"
#include "RP6Control_I2CMasterLib.h"
#include "RP6Control_MultiIO.h"
#include "RP6Control_LFSBumperLib.h"
#include "RP6ControlServoLib.h"
#include "RP6Control_OrientationLib.h"
#include "standard.h"


#define I2C_RP6_BASE_ADR 10


uint16_t servopos;
uint8_t i;


double distsrf02_1;



/*************** hauptprogramm ***********/

int main(void)
{


initRP6Control();
initLCD();
writeString_P("\n\n SRF02_plus_servo_test_3\n\n");
writeChar('\n');

setLEDs(0b1111);
mSleep(500);
setLEDs(0b0000);

I2CTWI_initMaster(100);
I2CTWI_setTransmissionErrorHandler(I2C_transmissio nError); //aktiviert I2C fehlermeldungen

showScreenLCD(" RP6Control M32", " SRF02_plus_servo","_test_3","");
mSleep(1500);
clearLCD();


setServoPower(0);
multiio_init();



servopos = SERVO1_LT;


while(true)
{

setServoPower(1); //doppelaufruf entfernt
initSERVO(SERVO1 | SERVO2 | SERVO3 ); //doppelaufruf entfernt

distsrf02_1 = SRF02_calculate(SRF02_measure(CH_SRF02_1, MODE_US));

writeString("servopos: ");
writeInteger(servopos, DEC);
writeString(" distanz: ");
writeDouble(distsrf02_1, 4, 2);
writeString(" mm ");
writeString("\n");

setServo(1, servopos);
mSleep(600);

servopos += 5;
if (servopos > SERVO1_RT) servopos = SERVO1_LT;

task_SERVO();


}

return 0;
}


EDIT: doppelaufrufe im code entfernt

Dirk
01.12.2014, 16:43
Befehle, die nur zur Initialisierung dienen, sind:
setServoPower(1);
initSERVO(SERVO1 | SERVO2 | SERVO3 );

Die müssen VOR der while(true)-Schleife stehen.
Man braucht sie auch nicht 2x hintereinander aufzurufen.

inka
01.12.2014, 18:03
ok, das mit dem 2x aufrufen war ein typischer guttenberg...

ich habe nun die variante mit den initialisierungsbefehlen vor der while-schleife ausprobiert, wie schon einiges andere davor - keine besserung, bzw. es ist egal, ob davor oder drinn. Ich denke der unterschied besteht "nur" darin, dass wenn sie in der schleife drinn sind, werden die servos bei jedem durchlauf initialisiert...

Was anderes ich mir aber aufgefallen:

sobald diese zeile:

distsrf02_1 = SRF02_calculate(SRF02_measure(CH_SRF02_1, MODE_US));

im code auftaucht, funktioniert die initialisierung der servos erst beim dritten drücken des startbuttons (das zweite drücken ist der programmabbruch zwischen den zwei starts)...

ich weiss echt nicht weiter...

TrainMen
02.12.2014, 15:08
Hi Inka,
ich versteh das nicht mit dem Startbutton, Start ist Start. Noch mal Drücken ist Programmabbruch. Startest Du jetzt gleich wieder mit dem Startbutton passiert das gleiche wie beim ersten mal. Es kann also kein Unterschied geben. Das einzigste was sich verändert ist die Temperatur Deines Equipments.
Das was Dirk schon sagte hast Du ja schon gemacht und es war unnötig sie bei jedem Durchlauf zu initialisieren. Aber ich kenn das, man versucht da alles mögliche.
Was soll eigentlich die Pause da drin ? Gemessen wird dann auch nicht. Wenn es um die Schritte geht würde ich eine Stopwatch nehmen. Dann Pausiert Dein Programm nicht.
Ich habe auch mal sowas gemacht allerdings mit Sharps. Ich hatte 3 Positionen. (Uhr 11,12,13). Ich habe erst gemessen wenn die Position erreicht war.
Glaube nicht das es was mit Deinem Problem zu tun hat. Aber warum nutzt Du nicht die Servo Routine der MultiIO ?

inka
02.12.2014, 16:39
hi TrainMen,

ich versteh das nicht mit dem Startbutton, Start ist Start. Noch mal Drücken ist Programmabbruch. Startest Du jetzt gleich wieder mit dem Startbutton passiert das gleiche wie beim ersten mal. Es kann also kein Unterschied geben. Das einzigste was sich verändert ist die Temperatur Deines Equipments.

hast Du einen SRF02? Vielleicht kanns Du ja mir helfen es zu verstehen...

folgendes szenario:

der code - so wie er ist (den doppelaufruf habe ich entfernt, die initialisierung des/der servos ist innerhalb der while-schleife). SRF02 ist an der multiIO angeschlossen, an den pins, die am nächsten an dem trapezförmigen ausschnitt sind.

1) nach dem flaschen ausschalten
2) einschalten mit S1, startbutton drücken - das programm läuft, im terminal wird die servopos hochgezählt, die vom SRF02 gemessene entfernung angezeigt, der servo dreht aber nicht...
3) starbutton drücken, also das programm stoppen...
4) ohne mit dem S1 aus- und einzuschalten den startbutton drücken - das programm läuft, im terminal wird die servopos hochgezählt, die vom SRF02 gemessene entfernung angezeigt, der servo dreht... Allerdings dreht er bei der rückstellung nicht nur bis zur festgelegten SERVO1_LT =230, sondern bis 50 (warum weiss ich auch nicht)...

Kannst Du den ablauf so bestätigen?

übrigens, wenn ich die zwei zeilen:

setServoPower(1); //doppelaufruf entfernt
initSERVO(SERVO1 | SERVO2 | SERVO3 ); //doppelaufruf entfernt

vor die while-schleife setze, ist der ablauf formal korrekt, am vorne beschriebenem szenario ändert sich aber nichts...


Das was Dirk schon sagte hast Du ja schon gemacht und es war unnötig sie bei jedem Durchlauf zu initialisieren. Aber ich kenn das, man versucht da alles mögliche. In beiden punkten gebe ich Dir uneingeschränkt recht...



Was soll eigentlich die Pause da drin ? Gemessen wird dann auch nicht. Wenn es um die Schritte geht würde ich eine Stopwatch nehmen. Dann Pausiert Dein Programm nicht. Meines wissens nach stoppt die pause nach dem abschicken des messaufrufs an den SRF02 den weiteren ablauf des programms und lässt den ablauf nach der pause wieder zu - dann ist (hoffentlich) auch das messergebnis schon da... Mit stopwatches (mit der abfrage > xyz) habe ich so meine probleme - die kann bei xyz +1 und auch bei xyz + 10000 ms stattfinden...


Glaube nicht das es was mit Deinem Problem zu tun hat. Aber warum nutzt Du nicht die Servo Routine der MultiIO ? tu ich doch...

TrainMen
02.12.2014, 17:33
nur ganz kurz zu Servo Routine
Du schreibst Du nutzt schon die von der MultiIO, warum includierst Du dann die RP6ControlServoLib.h ? und ist der Befehl
initSERVO(SERVO1 | SERVO2 | SERVO3 ) nicht auch aus der RP6ControlServoLib.c ?