PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ACS funktioniert bei modifikation von Move_05 nicht mehr



WarChild
03.02.2008, 12:31
Hi,

ich wollte meinen RP6 etwas erweitern und in das Beispielpogramm Move_05 meine funktionen implementieren.

Er soll eigentlich nur während er "cruised" mit dem SRF02 Messungen durchführen und dann auf den LEDs SL1 bis 6 darstellen. Das funktioniert auch genau so wie ich mir das gewünscht habe. Allerdings ragiert dann das ACS nicht mehr auf Gegenstände. ](*,)

Ich habe auch schon versucht nur Teilfunktionen auszuführen. Also ohne zu messen eine Zahl auf den LEDs ausgeben, aber dennoch funzt das ACS nicht. Und auch wenn ich nur messe ohne es darzustellen geht es nicht. GRGR ich habe keine Ahnung woran es liegt.

hier der Code, allerdings nur mein modifizierten Teil, den Rest hat wohl jeder.



#define SRF02 0xE0
#define attachdistance 8

/************************************************** *************************************\
| Diese FUnktion stellt einen Messwert der Distanz vor dem Roboter bereit. |
| Bitter nicht vergessen vorher die I2C Master Library einzufügen. |
| Und außerdem noch die Definitionen. |
| |
| #include "RP6I2CmasterTWI.h" |
| #define SRF02 0xE0 // dies ist die Standardadresse des SRF02 |
| #define attachdistance 8 // hiermit lässt sich die Montagedistanz korregieren |
\************************************************* **************************************/

uint16_t distanceSRF02(void)
{

static uint8_t measureactive = false; //Messungsstatus
uint8_t srfbuffer[2]; //Speicher für die übertragenen Bytes
uint16_t distance = 0; //Gemessene Strecke

if (measureactive == false)
{
I2CTWI_transmit2Bytes(SRF02, 0, 81); // SRF02 bekommt im Register 0 den Befehl in cm zu messen
measureactive = true;
startStopwatch6();
}

if (getStopwatch6() >= 65 && measureactive == true)
{
I2CTWI_transmitByte(SRF02, 2); // Ab dem zweiten Reigster Daten anfordern
I2CTWI_readBytes(SRF02, srfbuffer, 2); // und in dem Array speichern
distance = (srfbuffer[0] * 256) + srfbuffer[1]-attachdistance;
stopStopwatch6();
measureactive = false;
}
// hiermit werden Messfehler korregiert, da negative Werte sonst bei anderen funktionen zu Problemen führen
if (distance == -attachdistance)
distance = 0;

return distance;
}

/* stellt die gemessene Strecke auf den Status LEDs dar*/

void LEDmeter(uint16_t distance)
{

statusLEDs.LED1=0;
statusLEDs.LED2=0;
statusLEDs.LED3=0;
statusLEDs.LED4=0;
statusLEDs.LED5=0;
statusLEDs.LED6=0;

if ((distance % 100)/25 >= 1) // cm werden auf der einen Seite dargestellt. Jede LED=25cm
statusLEDs.LED1=1;
if ((distance % 100)/25 >= 2)
statusLEDs.LED2=1;
if ((distance % 100)/25 >= 3)
statusLEDs.LED3=1; // m auf der anderen. Jede LED=1m
if (distance / 100 >= 1)
statusLEDs.LED4=1;
if (distance / 100 >= 2)
statusLEDs.LED5=1;
if (distance / 100 >= 3)
statusLEDs.LED6=1;

updateStatusLEDs();
}



/**
* We don't have anything to do here - this behaviour has only
* a constant value for moving forwards - s. above!
* Of course you can change this and add some random or timed movements
* in here...
*/

void behaviour_cruise(void)
{
uint16_t distance = distanceSRF02();

if (distance != 0)
{
LEDmeter(distance); // Anzeige der Distanz auf SL1 bis SL6

writeString_P("\n Dist.= ");
writeInteger(distance,DEC);
writeString_P("cm");
writeString_P("\t");
writeInteger(distance / 100,DEC);
writeString_P("\t");
writeInteger((distance % 100)/25,DEC);
}
}


mfg WarChild

Dirk
03.02.2008, 16:00
Hallo WarChild,

die SRF02-Funktion hält die Hauptschleife schon etwas auf (mind. 65 ms), das ist aber wohl nicht so schlimm. Auf jeden Fall solltest du aber vor jeder Messung die Stopwatch(6) nicht nur starten, sondern auch vorher auf 0 zurücksetzen.

Aber wenn du auch schon die SRF02-Funktion weggelassen hast, ist da wohl noch was anderes im Busch, wobei ich nicht genau weiss, was es ist.
Hast du die Defines der Funktion behaviour_cruise auch drin gelassen (CRUISE_SPEED_FWD, MOVE_FORWARDS)?

Gruß Dirk

WarChild
03.02.2008, 17:44
jap

also ich kommentiere nur meine beiden Funktionen und die erweiterung des cruise behaviors aus und schon funktioniert das ACS.

mfg WarChild

WarChild
03.02.2008, 17:56
Irgendwie kann ich nicht einmal eine simple writeInteger() Funktion im Cruise Behavior einfügen, ohne dass das ACS nicht mehr funzt.

Kann ja jeder mal testen. Diese Funktion dauert ja nicht allzulange, als dass es die anderen aufhalten könnte.

mfg WarChild

sechsrad
03.02.2008, 19:15
....Irgendwie kann ich nicht einmal eine simple writeInteger() Funktion im Cruise Behavior einfügen, ohne dass das ACS nicht mehr funzt......

also mit copy/paste kommste nicht weiter.
ohne sich mit winavr-c auseinander zu setzen ist bald schluss mit dem spielen oder der rp6 fährt nur im keis.

WarChild
04.02.2008, 08:50
@ Sechsrad
danke für deine qualifizierte Antwort!

Kannst du mir dann vlt auch sagen, weshalb das Avoid behavior durch jeden smplen befehl im Cruise behavior aussetzt?
Wenn nicht, dann bist du nicht viel schlauer als ich...

mfg WarChild

SlyD
04.02.2008, 11:56
Hallo,

Hallo WarChild,

hmm also da musst Du aber noch irgendwas anderes verändert haben am Programm - denn wenn ich hier im Cruise Behaviour einfach mal



static uint16_t test = 0;
writeString_P("\nTest:");
writeInteger(test++,DEC);


reinschreibe funktioniert dennoch alles andere wie erwartet.
(Das sollte man aber besser von einer Stopwatch regeln lassen.)


Damit das mit den LEDs richtig funktioniert, musst Du natürlich diese Funktion hier:


/**
* ACS Event Handler - ONLY used for LED display!
* This does not affect the behaviour at all!
* The sensor checks are completely done in the Avoid behaviour
* statemachine.
*/
void acsStateChanged(void)
{
if(obstacle_left && obstacle_right)
statusLEDs.byte = 0b100100;
else
statusLEDs.byte = 0b000000;
statusLEDs.LED5 = obstacle_left;
statusLEDs.LED4 = (!obstacle_left);
statusLEDs.LED2 = obstacle_right;
statusLEDs.LED1 = (!obstacle_right);
updateStatusLEDs();
}


anpassen ODER diese Zeile in der Main Funktion auskommentieren:
ACS_setStateChangedHandler(acsStateChanged);
Sonst kommt sich das in die quere.
Du kannst aber z.B. auch nur zwei LEDs für das ACS verwenden und den rest für was anderes - musst nur die entsprechenden Zeilen da in der obigen Funktion auskommentieren.
(vor allem die ersten vier Zeilen der Funktion müssen weg)


MfG,
SlyD

WarChild
04.02.2008, 15:18
Vielen Dank, für die wirklich mal hilfeiche, Antwort.

mfg WarChild

Mal sehen, ob ich den Fehler finde.