guten abend
Ich habe ein undefiniertes Problem, für mich auf jedenfall...
Also, ich aknn mit dem M128 alle LEDs ansprechen ohne Probleme, auch die auf dem Roboter via I2C
Aber
Sobald ich einen Bumper auswerten möchte im M128 geht das nicht, Auch das fahren funktioniert nicht wie gewünscht, denn wenn ich einen befehl gebe zu fahren mit Blockiert... färt er nur die erste Distanz:-(
// edit1: Ich habe gemerkt dass er die Lichtsensoren auslesen kann! aber die Bumpder oder infrarot nicht...
Ich hoffe mir kann jemand helfen
Ich hoffe mir kann jemand helfen
... ohne dein Programm auf der M128 und dem RP6? Nur mit Glaskugel!
Gruß Dirk
naja
es ist das beispielprogramm i2c_slave von der lib des rp6
und es ist das beispiel prgramm movement2 vom c controller
Movement:
/************************************************** *****************************
* RP6 C-Control PRO M128 Erweiterungsmodul
* ----------------------------------------------------------------------------
* I2C Bus - Bewegung & Sensorik - Beispielprogramm
* ----------------------------------------------------------------------------
* Ein weiteres einfaches Bewegungsprogramm, diesmal reagiert der RP6
* allerdings auf die Bumper.
* Zunächst fährt der RP6 vorwärts in einer Kreisbahn.
* Kollidiert er mit einem Hindernis, werden die Motoren gestoppt und
* die LEDs fangen an zu blinken.
* (man könnte natürlich auch anders auf die Kollision reagieren...)
************************************************** ****************************/
#include "../../RP6CCLib/RP6CCLib.cc"
// ###########################
#include "RP6MasterLib.cc"
// ###########################
#include "RP6_Sensorcheck.cc"
/**
* Dieser Thread wird ausgeführt sobald der Roboter mit einem
* Hindernis kollidiert ist.
*/
void blink(void)
{
while(true)
{
setRP6LEDs(LED2 | LED3);
setLEDs(LED3 | LED4 | LED5); // LEDs kurz aufblitzen lassen ...
Thread_Delay(5); // ...
setLEDs(0); // ...
Thread_Delay(30);
setRP6LEDs(LED5 | LED6);
setLEDs(LED3 | LED4 | LED5);
Thread_Delay(5);
setLEDs(0);
Thread_Delay(30);
}
}
void main(void)
{
RP6_CCPRO_Init(); // Auf Startsignal warten!
newline();
println(" ________________________");
println(" \\| RP6 ROBOT SYSTEM |/");
println(" \\_-_-_-_-_-_-_-_-_-_/ ");
newline();
println(" RP6 Movement DEMO 2 ");
newline();
beep(100, 200, 300);
showScreenLCD("Movement", "DEMO Program 2");
AbsDelay(2000);
clearLCD();
// ACS auf mittlere Sendeleistung stellen:
RP6_writeCMD_1param(RP6_BASE_ADR, CMD_SET_ACS_POWER, ACS_PWR_MED);
RP6_writeCMD_1param(RP6_BASE_ADR, CMD_SET_WDT, true);
RP6_writeCMD_1param(RP6_BASE_ADR, CMD_SET_WDT_RQ, true);
// Der Thread zur Überprüfung von Statusänderungen wird gestartet:
Thread_Start(1,thread_checkINT0);
// Vorwärts im Kreis fahren:
changeDirection(FWD);
moveAtSpeed(100,40);
setCursorPosLCD(1,0);
printLCD("Moving... :-)");
setRP6LEDs(LED1 | LED4);
byte stopped;
stopped = false;
while(true)
{
if(!stopped) { // Es sollte nur einmal stop() und Thread_Start aufgerufen
// werden, daher fragen wir hier ab, ob das bereits
// geschehen ist.
// Man muss die Bumper nicht in RP6_Sensorcheck.cc
// auswerten. Man kann auch hier direkt die beiden Variablen
// der Tastsensoren abfragen:
if(bumperLeft || bumperRight)
{
stop(); // Roboter stoppen!
Thread_Start(2,blink); // Blinken!
stopped = true; // Roboter wurde angehalten!
setCursorPosLCD(1,0);
printLCD("Ouch! Crash! :-(");
}
}
Thread_Delay(1); // Muss immer hier rein, sonst werden die anderen
// Threads blockiert.
}
}
sensorcheck:
/************************************************** *****************************
* RP6 C-Control PRO M128 Erweiterungsmodul
* ----------------------------------------------------------------------------
* I2C Bus Beispielprogramm
* ----------------------------------------------------------------------------
* In diese Datei wurde die Sensorauswertung ausgelagert. So bleibt
* das Programm insgesamt übersichtlicher.
*
* Die Ausgaben des ACS wurden in diesem Beispiel entfernt!
************************************************** ****************************/
//------------------------------------------------------------------------------
//
#ifndef __SENSORCHECK__ // Alles nur EINMAL einbinden!
#define __SENSORCHECK__
// Diese zwei Zeilen und die letzte in dieser Datei sind wichtig, sonst
// funktioniert das übersetzen nicht! Auch bei eigenen Erweiterungen MUSS das
// am Anfang stehen!
/**
* Wenn sich der Zustand des ACS verändert hat, wird diese Funktion
* aufgerufen. Was hier genau gemacht wird, hängt dann von der Anwendung ab.
*/
void handle_ACS(void)
{
}
/**
* Genauso wie bei der ACS Funktion, wird handle_Bumpers aufgerufen sobald
* sich der Zustand der Tastsensoren vom RP6 geändert hat.
*/
void handle_Bumpers(void)
{
beep_t(100, 1, 1);
if(bumperRight) { // Rechter Tastsensor
setCursorPosLCD(0,14);
printLCD("BR");
}
else // Links nichts detektiert - also Text vom LCD löschen:
clearPosLCD(0,14,2);
if(bumperLeft) { // Linker Tastsensor
setCursorPosLCD(0,0);
printLCD("BL");
}
else
clearPosLCD(0,0,2);
if(bumperLeft && bumperRight) { // Beide, also in der Mitte
setCursorPosLCD(0,6);
printLCD("MID");
}
else
clearPosLCD(0,6,3);
}
/**
* Bei niedriger Akkuspannung wird diese Funktion aufgerufen
*/
void handle_BatLow(void)
{
print("BAT LOW:");
printInteger(adcBat);
println(" ");
}
/**
* Sobald Bewegungsabläufe abgeschlossen sind, oder bei einer
* Fehlerabschaltung aufgrund blockierter Motoren wird diese Funktion
* aufgerufen.
*/
void handle_DriveSystemChange(void)
{
print(" DRIVE:");
printInteger(movementComplete);
printInteger(motorOvercurrent);
println(" ");
}
/**
* Der RP6 kann mit dem IR Empfänger vom ACS auch RC5 Codes von Fernbedienungen
* empfangen. Sobald ein Tastencode empfangen wurde, wird diese Funktion
* aufgerufen.
*/
void handle_RC5_reception(void)
{
beep_t((RC5_data+5)*15, 2, 2);
print(" RC5: ");
printInteger(RC5_toggle); // Togglebit (Taste gehalten
print(":"); // oder mehrfach gedrückt?)
printInteger(RC5_adr); // Adresse
print(":");
printInteger(RC5_data); // Tastencode
println(" ");
}
/**
* Damit der Roboter nicht ausser Kontrolle gerät, wenn das CCPRO oder andere
* Host Controller abstürzen (oder die Kommunikation aus sonstigen Gründen
* gestört ist), kann ein Watchdog Timer aktiviert werden, der
* alle 250ms eine Anfrage an den Host sendet. Antwortet dieser nicht innerhalb
* von 3 Sekunden auf diese Anfrage, werden die Motoren gestoppt und der Roboter
* muss zurückgesetzt werden bevor er weiterfahren kann.
*
* Man kann diese periodischen Anfragen auch gut verwenden um zu signalisieren
* dass das Programm noch läuft, indem man eine LED blinken lässt, oder wie
* in diesem Beispielprogramm ein Zeichen auf dem LC-Display ("Heartbeat").
*/
byte heartbeat;
void handle_WDT_RQ(void)
{
if(heartbeat)
{
clearPosLCD(0, 11, 1);
heartbeat = false;
}
else
{
setCursorPosLCD(0,11);
printLCD("*");
heartbeat = true;
}
}
/**
* Dies ist die etwas aufgeräumte Interrupt Behandlungsroutine. Die eigentliche
* Auswertung der Daten erfolgt in den einzelnen Funktionen oben. Diese
* werden hier bei Bedarf aufgerufen.
*/
void thread_checkINT0(void)
{
while(true) {
if(Port_ReadBit(PORT_PE5_INT)) { // Hat der Controller auf dem Mainboard neue Daten?
// Die drei Status Register auslesen:
RP6_readRegisters(RP6_BASE_ADR, 0, messageBuf, 3);
// Wir überprüfen, ob die Status Bits sich verändert haben,
// also verknüpfen wir den alten und neuen Wert per Exclusiv Oder
// um nur die geänderten Bits auswerten zu müssen.
byte compare;
compare = messageBuf[0] ^ interrupt_status;
interrupt_status = messageBuf[0];
// ------------------------------------
// Zunächst prüfen wir ob sich die ACS Status Bits verändert haben.
// Falls nicht, hat irgend etwas anderes den Interrupt ausgelöst und
// wir können mit den anderen Abfragen weitermachen.
if(compare & MASK_ACS)
{
// Die ACS Status Variablen setzen:
obstacleLeft = messageBuf[0] & 0x20;
obstacleRight = messageBuf[0] & 0x40;
// ACS in getrennter Funktion weiterbehandeln:
handle_ACS();
}
// ------------------------------------
// Abfragen ob sich der Zustand der Bumper geändert hat, falls
// ja, Text auf der seriellen Schnittstelle ausgeben:
if(compare & MASK_BUMPER)
{
bumperLeft = messageBuf[0] & 0x2;
bumperRight = messageBuf[0] & 0x4;
handle_Bumpers();
}
// ------------------------------------
// Überprüfen ob ein RC5 Datenpaket mit dem IRCOMM empfangen
// worden ist - falls ja auf der seriellen ausgeben:
if(interrupt_status & MASK_RC5)
{
RP6_readRegisters(RP6_BASE_ADR, I2C_REG_RC5_ADR, messageBuf, 2);
RC5_toggle = messageBuf[0] >> 5;
RC5_adr = messageBuf[0] & 0x1F;
RC5_data = messageBuf[1];
handle_RC5_reception();
}
// ------------------------------------
// Überprüfen ob die Batteriespannung zu niedrig ist:
if(compare & MASK_BATLOW)
{
RP6_readRegisters(RP6_BASE_ADR, I2C_REG_ADC_UBAT_L, messageBuf, 2);
adcBat = (messageBuf[1] << 8) | (messageBuf[0]);
handle_BatLow();
}
// ------------------------------------
// Bewegung fertig? Notabschaltung?
if(compare & MASK_DRIVE)
{
movementComplete = messageBuf[2] & 1;
motorOvercurrent = messageBuf[2] & 4;
handle_DriveSystemChange();
}
// ------------------------------------
// Auf Watchdog Requests prüfen:
if(messageBuf[1] & MASK_WDT_RQ)
{
handle_WDT_RQ();
}
}
Thread_Delay(1);
}
}
#endif
und es ist das beispiel prgramm movement2 vom c controller
Nach dem hier:
Auch das fahren funktioniert nicht wie gewünscht, denn wenn ich einen befehl gebe zu fahren mit Blockiert... färt er nur die erste Distanz:-(
... hätte ich eher gedacht, dass du da was selbst programmiert hast.
Egal.
Bei mir funktioniert das RP6_Movement2.cc Programm.
Gruß Dirk
welche lib benutzt du?
auch die neuste »Version 20080915<<
irgenwas ist da nicht in ordnung...
Ja, vom RP6 20080915, von der M128 20090131.
Gruß Dirk
Hallo,
die Interrupt Jumper sind richtig gesteckt?
s. Anleitung standard Jumper Einstellung.
MfG,
SlyD
Hallo,
Vielen Dank für die Hilfe! Des wahr das problem!
Hab die jumper vom Interrupt und sogar noch vom
Memory umgesteckt und jetzt geht es!
Danke
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.