PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit RC5 Fernbedienung und M32



Ingo1988
07.03.2011, 15:51
Hey,
Ich habe ein Problem bei der Verwendung von einer RC5 Fernbedienung in Kombination mit dem M32. Egal welche Taste ich auf der Fernbedienung drücke, das Programm wird immer sofort beendetund startet sich dann manchmal neu und manchmal bleibt es beendet.
Nur mit der Base funktioniert alles.
Auf der Base ist das Slave Programm und die Lib ist ebenfalls die Lib aus den Beispielen!

Weiß zufällig jemand ne Lösung für das Problem?

Mein eigentliches Programm habe ich soweit gekürzt, dass nur die Stellen die für das Problem wichtig sind drin bleiben.


/*
************************************************** ********************
*/

/************************************************** ***************************/
// Includes:

#include "RP6ControlLib.h" // The RP6 Control Library.
// Always needs to be included!

#include "RP6I2CmasterTWI.h" // I2C Master Library


#include "RP6Control_I2CMasterLib.h"// Include our new "RP6 Control I2C Master library":


/************************************************** ***************************/
// Definiton:








/************************************************** ***************************/
// SRF02:

// The I2C slave address of the SRF ranger - default is 0xE0, but you can
// change this when you use the function changeSRFAddr() below.
// Here we changed it to 0xE6 already:
#define SRF_ADR 0xE0



/************************************************** ***************************/
// I2C Event handlers:


// I2C Data request IDs:
#define MEASURE_US_LOW 110
#define MEASURE_US_HIGH 111


/************************************************** ***************************/
/************************************************** ***************************/
// TV- Fernsteuerung!! xx

#define RC_MEINE

// Key Belegung

#ifdef RC_MEINE // RC Type: Phillips RC5 - Bp2
#define RC5_KEY_LINKS_ROT 60
#define RC5_KEY_RECHTS_ROT 42
#define RC5_KEY_VOR 32
#define RC5_KEY_RUECK 33
#define RC5_KEY_STOP 59
#define RC5_KEY_CURVE_LEFT 17
#define RC5_KEY_CURVE_RIGHT 16
#define RC5_KEY_FAHRE_ZUM_LADEN 12
#define RC5_KEY_NORMALER_MOD 1
#define RC5_KEY_IR_MOD 2
#endif



/**
* RC5 Data reception handler - this function is called automatically from the
* RP6lib if new RC5 Data has been received.
*/
void receiveRC5Data(RC5data_t rc5data)
{
// Output the received data:
writeString_P("Toggle Bit:");
writeChar(rc5data.toggle_bit + '0');
writeString_P(" | Device Address:");
writeInteger(rc5data.device, DEC);
writeString_P(" | Key Code:");
writeInteger(rc5data.key_code, DEC);
writeChar('\n');

// Check which key is pressed:
switch(rc5data.key_code)
{
case RC5_KEY_LINKS_ROT: // Turn left:
writeString_P("LEFT\n");
break;
case RC5_KEY_RECHTS_ROT: // Turn right:
writeString_P("RIGHT\n");
break;
case RC5_KEY_VOR: // Move forwards
writeString_P("FORWARDS\n");
break;
case RC5_KEY_RUECK: // Move backwards
writeString_P("BACKWARDS\n");
break;
case RC5_KEY_STOP: // Stop!
writeString_P("STOP\n");
break;
case RC5_KEY_CURVE_LEFT: // Drive curve left - forwards
writeString_P("CURVE LEFT FWD\n");
break;
case RC5_KEY_CURVE_RIGHT: // Drive curve right - forwards
writeString_P("CURVE RIGHT FWD\n");
break;
case RC5_KEY_FAHRE_ZUM_LADEN: // fahre zur Ladestation
writeString_P("fahre zur Ladestation\n");
break;
case RC5_KEY_NORMALER_MOD: // Normaler Modus
writeString_P("Normaler Modus\n");
break;
case RC5_KEY_IR_MOD: // folge den Bewegungsbefehlen der Fernbedienung
writeString_P("folge den Bewegungsbefehlen der Fernbedienung\n");
}
}




/************************************************** ***************************/
// I2C Requests:

/**
* The I2C_requestedDataReady Event Handler
*/
void I2C_requestedDataReady(uint8_t dataRequestID)
{
checkRP6Status(dataRequestID);

uint8_t messageBuf[8];
static uint8_t dist_tmp;
switch(dataRequestID)
{
case MEASURE_US_HIGH: // High data register
// get received data ...
I2CTWI_getReceivedData(messageBuf, 2);
dist_tmp = (messageBuf[0]);
// ... and request low data byte:
I2CTWI_transmitByte(SRF_ADR, 3);
I2CTWI_requestDataFromDevice(SRF_ADR, MEASURE_US_LOW, 1);

break;
case MEASURE_US_LOW: // low data byte:
I2CTWI_getReceivedData(messageBuf, 2);

break;
}
}

/************************************************** ***************************/
// I2C Error handler

/**
* This function gets called automatically if there was an I2C Error like
* the slave sent a "not acknowledge" (NACK, error codes e.g. 0x20 or 0x30).
*/
void I2C_transmissionError(uint8_t errorState)
{
writeString_P("\nI2C ERROR - TWI STATE: 0x");
writeInteger(errorState, HEX);
writeChar('\n');
}



//Hauptprogramm

/************************************************** ***************************/
// Main function - The program starts here:

int main(void)
{
initRP6Control();
initLCD();

writeString_P("\n\nRP6 CONTROL M32 I2C Master Example Program!\n");

// ---------------------------------------
I2CTWI_initMaster(100);
I2CTWI_setRequestedDataReadyHandler(I2C_requestedD ataReady);
I2CTWI_setTransmissionErrorHandler(I2C_transmissio nError);
// Set the RC5 Receive Handler:
IRCOMM_setRC5DataReadyHandler(receiveRC5Data);



sound(180,80,25);
sound(220,80,25);

setLEDs(0b1111);

showScreenLCD("################", "################");
mSleep(500);
showScreenLCD("Mein Robot", "Behaviours");
mSleep(1000);
setLEDs(0b0000);

// ---------------------------------------
// Setup ACS power:
I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_ACS_POWER, ACS_PWR_MED);
// Enable Watchdog for Interrupt requests:
I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT, true);
// Enable timed watchdog requests:
I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT_RQ, true);
showScreenLCD("Active Behaviour", "");

while(true)
{
task_checkINT0();
task_I2CTWI();
mSleep(5);
}
return 0;
}



Lieben Gruß

Ingo Hunfeld

SlyD
07.03.2011, 17:21
Könnte dran liegen das Du den Software Watchdog des Slave Programms aktiviert hast. Der muss dann auch ständig zurückgesetzt werden.

Das hier:


// Enable Watchdog for Interrupt requests:
I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT, true);
// Enable timed watchdog requests:
I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT_RQ, true)


muss auf false wenn Du das nicht brauchst.

MfG,
SlyD

Ingo1988
07.03.2011, 17:53
Das setzen auf false bei den beiden Parametern ändert leider nichts.

Desweiteren ist mir noch aufgefallen, dass im Terminal noch
Toggle Bit:0 | Device Address:0 | Key Code:16
angezeigt wird, bevor das Programm beendet wird. Das müsste doch heißen, dass der Empfang ansich funktioniert, jedoch danach einen Fehler provoziert!

Lieben Gruß

SlyD
07.03.2011, 19:17
In so nem Fall kommentierst Du einfach erstmal alles aus bis nur noch ein Minimalprogramm übrig bleibt - also den Ultraschall Code da raus, und in der RC5 routine das komplette switch(rc5data.key_code) ...

Genauso das msleep in der Hauptschleife.
Dann nochmal die Ausgaben des Programms checken.

MfG,
SlyD

PS:
Verwende auch bitte die aktuelle RP6Lib und das aktuelle WinAVR aus dem Netz - nicht die von der CD.

Ingo1988
07.03.2011, 20:02
hi,
vielen Dank für deine Hilfe ich konnte den Fehler jetzt soweit eingrenzen.
Er steckt in dieser Passage:



void I2C_requestedDataReady(uint8_t dataRequestID)
{
checkRP6Status(dataRequestID);

uint8_t messageBuf[8];
static uint8_t dist_tmp;
switch(dataRequestID)
{
case MEASURE_US_HIGH: // High data register
// get received data ...
I2CTWI_getReceivedData(messageBuf, 2);
dist_tmp = (messageBuf[0]);
// ... and request low data byte:
I2CTWI_transmitByte(SRF_ADR, 3);
I2CTWI_requestDataFromDevice(SRF_ADR, MEASURE_US_LOW, 1);

break;
case MEASURE_US_LOW: // low data byte:
I2CTWI_getReceivedData(messageBuf, 2);

break;
}


}

Mein Problem ist jetzt allerdings, dass ich nicht weiß wie ich diese Passage so programmiere, das es nicht zum Absturz des Systems führt.

Vielen Dank für eure Hilfe

Lieben Gruß

SlyD
07.03.2011, 20:10
Hast Du überhaupt einen Ultraschallsensor an Deinem Roboter angeschlossen?
Der Code da ist ja aus der Ultraschalldemo.

Da Du aber nirgendwo eine Messung auslöst vermute ich mal das Du sowieso keine dran hast also lösch das BIS AUF
checkRP6Status(dataRequestID);

alles weg.

MfG,
SlyD

Ingo1988
07.03.2011, 20:21
Hi vielen dank für deine Hilfe.
Doch ich hab einen angeschlossen, ich wollte nur zum Posten das prog nicht komplett reinstellen, sondern nur die Teile die den Fehler verursachen, damit jemadn der das Prog nicht geschrieben hat keine 3 std braucht um sich einzulesen.

Ich habe den Fehler jetzt gefunden. Verstehe aber nicht warum es zu einem komplett Abstuz führt vllt kannst du mir das erklären.

Und zwar darf
uint8_t messageBuf[8];
nicht innerhalb der Funktion stehen. Wenn ich das Array außerhalb der Funktion erzeuge funktioniert es...
ICh weiß nur einfach nicht warum.

Lieben Gruß

Ingo

RolfD
08.03.2011, 14:51
Ich weis nicht ob es daran liegt aber Variablen in einer Funktion sind ansich dynamisch auf dem Stack im Gegensatz zu statischen vars im Ram. Wenn Dein Programm aus irgendwelchen Gründen zum Stack overflow neigt, knallt es natürlich um so schneller, je mehr Du auf den Stack drauf packst. Entsprechend hat die Var auch nur eine Gültigkeit innerhalb der Funktion da nach der Funktion der Stack abgeräumt ist. Demnach müsste es laufen wenn du ein "static" davor setzt, dann bastelt sich der Compiler die Var in einen extra Speicherbereich statt auf den Stack.
LG Rolf