- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 9 von 9

Thema: M32 - verhaltensgesteuerter Roboter + TV Fernsteuerung

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2009
    Ort
    NRW
    Beiträge
    23

    M32 - verhaltensgesteuerter Roboter + TV Fernsteuerung

    Anzeige

    Praxistest und DIY Projekte
    Hi Leute,

    ich versuche, das 10. Beispielprogramm des M32 (Example_10_Move2), das einen verhaltensgesteuerten Roboter realisiert, um ein zusätzliches Verhalten zu erweitern. Das Verhalten hab ich erstmal OBEY genannt, der RP6 soll damit auf RC5-Signale hören (dafür hab ich weitgehend das Beispielprogramm der RP6Base - Example_08_TV_REMOTE - übernommen).

    Hintergrund dafür ist einfach nur, dass ich jederzeit die Kontrolle übernehmen können will, und z.B. nach einer Kurskorrektur mit der Promo 8 Fernbedienung wieder in das autonome Verhalten (CRUISE, ESCAPE, AVOID) umschalten will.

    Das Umschalten zwischen den Verhaltensweisen funktioniert auch ohne Probleme. Allerdings funktioniert die Steuerung nicht richtig.
    Der RP6 stoppt beim Aktivieren der Fernsteuerung nur kurz, gibt dann aber wieder Gas. Er wird auf der rechten Seite immer langsamer, auf der linken Seite bleibt die Geschwindigkeit konstant. Und er verringert die Geschwindigkeit nicht, wenn er 0,25 Sekunden lang kein RC5 Signal mehr bekommen hat.

    Nachdem ich mir jetzt die letzten 3 Wochenenden den Kopf darüber zerbrochen hab, wo zum Geier da der Fehler liegen könnte, frag ich lieber mal euch hier, in der Hoffnung, dass ihr mir weiterhelfen könnt

    Ich bin für jeden Tip und Hinweis dankbar! Im Anhang ist der aktuelle Stand des Codes.

    schönes Restwochenende noch,
    V:X

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hi V:X,

    ich habe als Ausgangspunkt für weitere Entwicklungen mal einen Ersatz für die RP6Control_10_Move2.c Datei angehängt. Die I2CMasterLib bleibt unverändert:
    Code:
    // Includes:
    
    #include "RP6ControlLib.h" 		// The RP6 Control Library. 
    								// Always needs to be included!
    
    #include "RP6I2CmasterTWI.h"	// I2C Master Library
    
    
    // Include our new "RP6 Control I2C Master library":
    
    #include "RP6Control_I2CMasterLib.h"
    
    // Behaviour command type:
    
    #define IDLE  0
    
    // The behaviour command data type:
    typedef struct {
    	uint8_t  speed_left;  // left speed (is used for rotation and 
    						  // move distance commands - if these commands are 
    						  // active, speed_right is ignored!)
    	uint8_t  speed_right; // right speed
    	unsigned dir:2;       // direction (FWD, BWD, LEFT, RIGHT)
    	unsigned move:1;      // move flag
    	unsigned rotate:1;    // rotate flag
    	uint16_t move_value;  // move value is used for distance and angle values
    	uint8_t  state;       // state of the behaviour
    } behaviour_command_t;
    
    behaviour_command_t STOP = {0, 0, FWD, false, false, 0, IDLE};
    
    /*****************************************************************************/
    // Cruise Behaviour:
    
    #define CRUISE_SPEED_FWD 80 // Default speed 
    
    #define MOVE_FORWARDS 1
    behaviour_command_t cruise = {CRUISE_SPEED_FWD, CRUISE_SPEED_FWD, FWD, 
    								false, false, 0, MOVE_FORWARDS};
    
    /**
     * Cruise Behaviour
     */
    void behaviour_cruise(void)
    {
    }
    
    /*****************************************************************************/
    // Escape Behaviour:
    
    #define ESCAPE_SPEED_BWD    80
    #define ESCAPE_SPEED_ROTATE 60
    
    #define ESCAPE_FRONT		1
    #define ESCAPE_FRONT_WAIT 	2
    #define ESCAPE_LEFT  		3
    #define ESCAPE_LEFT_WAIT	4
    #define ESCAPE_RIGHT	    5
    #define ESCAPE_RIGHT_WAIT 	6
    #define ESCAPE_WAIT_END		7
    behaviour_command_t escape = {0, 0, FWD, false, false, 0, IDLE}; 
    
    /**
     * This is the Escape behaviour for the Bumpers.
     */
    void behaviour_escape(void)
    {
    	static uint8_t bump_count = 0;
    	
    	switch(escape.state)
    	{
    		case IDLE: 
    		break;
    		case ESCAPE_FRONT:
    			escape.speed_left = ESCAPE_SPEED_BWD;
    			escape.dir = BWD;
    			escape.move = true;
    			if(bump_count > 3)
    				escape.move_value = 200;
    			else
    				escape.move_value = 140;
    			escape.state = ESCAPE_FRONT_WAIT;
    			bump_count+=2;
    		break;
    		case ESCAPE_FRONT_WAIT:			
    			if(!escape.move)
    			{	
    				escape.speed_left = ESCAPE_SPEED_ROTATE;
    				if(bump_count > 3)
    				{
    					escape.move_value = 110;
    					escape.dir = RIGHT;
    					bump_count = 0;
    				}
    				else 
    				{
    					escape.dir = LEFT;
    					escape.move_value = 75;
    				}
    				escape.rotate = true;
    				escape.state = ESCAPE_WAIT_END;
    			}
    		break;
    		case ESCAPE_LEFT:
    			escape.speed_left = ESCAPE_SPEED_BWD;
    			escape.dir 	= BWD;
    			escape.move = true;
    			if(bump_count > 3)
    				escape.move_value = 160;
    			else
    				escape.move_value = 100;
    			escape.state = ESCAPE_LEFT_WAIT;
    			bump_count++;
    		break;
    		case ESCAPE_LEFT_WAIT:
    			if(!escape.move)
    			{
    				escape.speed_left = ESCAPE_SPEED_ROTATE;
    				escape.dir = RIGHT;
    				escape.rotate = true;
    				if(bump_count > 3)
    				{
    					escape.move_value = 100;
    					bump_count = 0;
    				}
    				else
    					escape.move_value = 65;
    				escape.state = ESCAPE_WAIT_END;
    			}
    		break;
    		case ESCAPE_RIGHT:	
    			escape.speed_left = ESCAPE_SPEED_BWD ;
    			escape.dir 	= BWD;
    			escape.move = true;
    			if(bump_count > 3)
    				escape.move_value = 160;
    			else
    				escape.move_value = 100;
    			escape.state = ESCAPE_RIGHT_WAIT;
    			bump_count++;
    		break;
    		case ESCAPE_RIGHT_WAIT:
    			if(!escape.move)
    			{ 
    				escape.speed_left = ESCAPE_SPEED_ROTATE;		
    				escape.dir = LEFT;
    				escape.rotate = true;
    				if(bump_count > 3)
    				{
    					escape.move_value = 100;
    					bump_count = 0;
    				}
    				else
    					escape.move_value = 65;
    				escape.state = ESCAPE_WAIT_END;
    			}
    		break;
    		case ESCAPE_WAIT_END:
    			if(!(escape.move || escape.rotate))
    				escape.state = IDLE;
    		break;
    	}
    }
    
    /**
     * Bumpers Event handler
     */
    void bumpersStateChanged(void)
    {
    	if(bumper_left && bumper_right)
    	{
    		sound(200,100,0);
    		escape.state = ESCAPE_FRONT;
    	}
    	else if(bumper_left) 
    	{
    		sound(200,25,10);
    		sound(150,25,0);
    		if(escape.state != ESCAPE_FRONT_WAIT) 
    			escape.state = ESCAPE_LEFT;
    	}
    	else if(bumper_right)
    	{
    		sound(200,25,10);
    		sound(150,25,0);
    		if(escape.state != ESCAPE_FRONT_WAIT)
    			escape.state = ESCAPE_RIGHT;
    	}
    }
    
    /*****************************************************************************/
    // Avoid Behaviour:
    
    #define AVOID_SPEED_L_ARC_LEFT  20
    #define AVOID_SPEED_L_ARC_RIGHT 80
    #define AVOID_SPEED_R_ARC_LEFT  80
    #define AVOID_SPEED_R_ARC_RIGHT 20
    
    #define AVOID_SPEED_ROTATE 	60
    
    #define AVOID_OBSTACLE_RIGHT 		1
    #define AVOID_OBSTACLE_LEFT 		2
    #define AVOID_OBSTACLE_MIDDLE	    3
    #define AVOID_OBSTACLE_MIDDLE_WAIT 	4
    #define AVOID_END 					5
    behaviour_command_t avoid = {0, 0, FWD, false, false, 0, IDLE};
    
    /**
     * Avoid behaviour with ACS IR Sensors.
     */
    void behaviour_avoid(void)
    {
    	static uint8_t last_obstacle = LEFT;
    	static uint8_t obstacle_counter = 0;
    	switch(avoid.state)
    	{
    		case IDLE: 
    			if(obstacle_right && obstacle_left)
    				avoid.state = AVOID_OBSTACLE_MIDDLE;
    			else if(obstacle_left) 
    				avoid.state = AVOID_OBSTACLE_LEFT;
    			else if(obstacle_right)
    				avoid.state = AVOID_OBSTACLE_RIGHT;
    		break;
    		case AVOID_OBSTACLE_MIDDLE:
    			avoid.dir = last_obstacle;
    			avoid.speed_left = AVOID_SPEED_ROTATE;
    			avoid.speed_right = AVOID_SPEED_ROTATE;
    			if(!(obstacle_left || obstacle_right))
    			{
    				if(obstacle_counter > 3)
    				{
    					obstacle_counter = 0;
    					setStopwatch4(0);
    				}
    				else
    					setStopwatch4(400);
    				startStopwatch4();
    				avoid.state = AVOID_END;
    			}
    		break;
    		case AVOID_OBSTACLE_RIGHT:
    			avoid.dir = FWD;
    			avoid.speed_left = AVOID_SPEED_L_ARC_LEFT;
    			avoid.speed_right = AVOID_SPEED_L_ARC_RIGHT;
    			if(obstacle_right && obstacle_left)
    				avoid.state = AVOID_OBSTACLE_MIDDLE;
    			if(!obstacle_right)
    			{
    				setStopwatch4(500);
    				startStopwatch4();
    				avoid.state = AVOID_END;
    			}
    			last_obstacle = RIGHT;
    			obstacle_counter++;
    		break;
    		case AVOID_OBSTACLE_LEFT:
    			avoid.dir = FWD;
    			avoid.speed_left = AVOID_SPEED_R_ARC_LEFT;
    			avoid.speed_right = AVOID_SPEED_R_ARC_RIGHT;
    			if(obstacle_right && obstacle_left)
    				avoid.state = AVOID_OBSTACLE_MIDDLE;
    			if(!obstacle_left)
    			{
    				setStopwatch4(500);
    				startStopwatch4();
    				avoid.state = AVOID_END;
    			}
    			last_obstacle = LEFT;
    			obstacle_counter++;
    		break;
    		case AVOID_END:
    			if(getStopwatch4() > 1000)
    			{
    				stopStopwatch4();
    				setStopwatch4(0);
    				avoid.state = IDLE;
    			}
    		break;
    	}
    }
    
    /**
     * ACS Event Handler
     */
    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();
    	if(obstacle_left && obstacle_right)
    	{
    		sound(160,20,0);
    	}
    	else
    	{
    		if(obstacle_left)
    			sound(120,10,0);
    		if(obstacle_right)
    			sound(140,10,0);
    	}
    }
    
    /*****************************************************************************/
    // Behaviour RC5 Reception:
    
    #define RC5RECEPTION_MOVE 1
    #define RC5RECEPTION_SHOW 2
    behaviour_command_t rc5Reception = {0, 0, FWD, false, false, 0, IDLE}; 
    
    /**
     * Behaviour with RC5 Reception.
     */
    void behaviour_rc5Reception(void)
    {
    }
    
    /**
     * RC5 Event Handler 
     */
    void receiveRC5Data(RC5data_t rc5data)
    {
    	switch(rc5data.key_code)
    	{
    		case 1 : rc5Reception.state = RC5RECEPTION_MOVE; 
    		break;
    		case 2 : rc5Reception.state = RC5RECEPTION_SHOW;
    		break;
    		case 3 : rc5Reception.state = IDLE;
    		break;
    	}
    
    	if(rc5Reception.state == RC5RECEPTION_SHOW)
    	{
    		if(getStopwatch2() > 500)
    		{
    			clearPosLCD(1, 0, 13);
    			setCursorPosLCD(1, 0); 
    			// Output the received data:
    			writeStringLCD_P("RC5 ");
    			writeCharLCD(rc5data.toggle_bit + '0');
    			writeStringLCD_P(" |");
    			writeIntegerLCD(rc5data.device, DEC);
    			writeStringLCD_P(" |");
    			writeIntegerLCD(rc5data.key_code, DEC);
    			setStopwatch2(0);
    		}
    	}
    }
    
    /*****************************************************************************/
    // Behaviour waitForStart:
    
    #define PREPARE 1
    #define WAIT 2
    behaviour_command_t waitForStart = {0, 0, FWD, 
    									false, false, 0, PREPARE};
    
    /**
     * Wait for start Behaviour. 
     * You need to clap your hands (or make other noise) three times in order
     * to start the Robot!
     */
    void behaviour_waitForStart(void)
    {
    	static uint8_t peak_count = 3;
    	if(waitForStart.state == PREPARE)
    	{
    		if(getStopwatch2() > 250)
    		{
    			setCursorPosLCD(1, 6); 
    			writeIntegerLengthLCD( peak_count, DEC, 1);
    			dischargePeakDetector();
    			waitForStart.state = WAIT;
    			setStopwatch2(0);
    		}
    	}
    	else if(waitForStart.state == WAIT)
    	{
    		uint8_t key = checkReleasedKeyEvent(); 
    		if(key)
    			waitForStart.state = IDLE;
    		if(getStopwatch2() > 50)
    		{
    			uint16_t tmp = getMicrophonePeak();
    			if(tmp > 4)
    			{
    				externalPort.LEDS = 0;
    				uint16_t i;
    				uint8_t j;
    				for(i = 0, j = 2; i < tmp; i+= 40)
    				{
    					if(i < 40)
    					{
    						externalPort.LEDS++;
    					}
    					else
    					{
    						externalPort.LEDS <<=1;
    						externalPort.LEDS++;
    					}
    				}
    				outputExt();
    				if(tmp > 120)
    				{
    					waitForStart.state = PREPARE;
    					peak_count--;
    				}
    				if(peak_count == 0)
    					waitForStart.state = IDLE;
    			}
    			else
    				setLEDs(0b0000);
    			setStopwatch2(0);
    		}
    	}
    }
    
    /*****************************************************************************/
    // Behaviour check low Battery:
    
    #define BATTERY_LOW 1
    behaviour_command_t checkLowBattery = {0, 0, FWD, 
    									false, false, 0, IDLE};
    
    /**
     * In this behaviour routine, we have nothing to do
     */
    void behaviour_checkLowBattery(void)
    {
    }
    
    /**
     * This is a new Event Handler and it gets called when the Battery Voltage
     * is getting low! The Parameter isVoltageLow is true, when the voltage
     * is low and false, when the voltage is OK.
     */
    void batteryVoltageLow(uint8_t isVoltageLow)
    {
    	if(isVoltageLow)
    		checkLowBattery.state = BATTERY_LOW;
    }
    
    /*****************************************************************************/
    // Behaviour control:
    
    /**
     * This function processes the movement commands that the behaviours generate. 
     * Depending on the values in the behaviour_command_t struct, it sets motor
     * speed, moves a given distance or rotates.
     */
    void moveCommand(behaviour_command_t * cmd)
    {
    	if(cmd->move_value > 0)  // move or rotate?
    	{
    		if(cmd->rotate)
    			rotate(cmd->speed_left, cmd->dir, cmd->move_value, false); 
    		else if(cmd->move)
    			move(cmd->speed_left, cmd->dir, DIST_MM(cmd->move_value), false); 
    		cmd->move_value = 0; // clear move value - the move commands are only
    		                     // given once and then runs in background.
    	}
    	else if(!(cmd->move || cmd->rotate)) // just move at speed? 
    	{
    		changeDirection(cmd->dir);
    		moveAtSpeed(cmd->speed_left,cmd->speed_right);
    	}
    	else if(isMovementComplete()) // movement complete? --> clear flags!
    	{
    		cmd->rotate = false;
    		cmd->move = false;
    	}
    }
    
    /**
     * A small helper function to display the current behaviour on the
     * LCD. It only prints out the active behaviour ONCE, otherwise the
     * text would flicker on the LCD!
     */
    void displayBehaviour(uint8_t behave)
    {
    	static uint8_t compare = 0;
    	if(compare != behave)
    	{
    		compare = behave;
    		clearPosLCD(1, 0, 13);
    		setCursorPosLCD(1, 0); 
    		switch(behave)
    		{
    			case 7: writeStringLCD_P("RC5 CONTROL"); setLEDs(0b0000); break;
    			case 6: writeStringLCD_P("LOW BATTERY!"); setLEDs(0b0000); break;
    			case 5: writeStringLCD_P("WAIT"); setLEDs(0b0000); break;
    			case 4: writeStringLCD_P("ESCAPE"); setLEDs(0b0110); break;
    			case 3: writeStringLCD_P("AVOID"); setLEDs(0b1001); break;
    			case 2: writeStringLCD_P("CRUISE"); setLEDs(0b0000); break;
    			case 1: writeStringLCD_P("STOP"); setLEDs(0b0000); break;
    		}
    	}
    	if(behave == 2) // If Cruise behaviour is active, show a running light...
    	{
    		static uint8_t runLEDs = 1;
    		static uint8_t dir = 0;
    		if(getStopwatch2() > 100) 
    		{
    			setLEDs(runLEDs); 
    			if(dir == 0)
    				runLEDs <<= 1; 
    			else
    				runLEDs >>= 1;
    			if(runLEDs > 7 ) 
    				dir = 1;			
    			else if (runLEDs < 2 ) 
    				dir = 0;
    			setStopwatch2(0);
    		}
    	}
    	if(behave == 6) // If Battery is low - beep all 3 seconds!
    	{
    		if(getStopwatch2() > 3000)  // We can use Stopwatch2 here and 
    		{							// for several other things because only
    			sound(200,20,20);		// one of these things can be active at 
    			sound(225,20,60);		// the same time! You could not do this if
    			sound(200,20,20);		// there were things that could be active
    			sound(225,20,0);		// at the same time!
    			setStopwatch2(0);
    		}
    	}
    }
    
    /**
     * The behaviourController task controls the subsumption architechture. 
     * It implements the priority levels of the different behaviours. 
     *
     * Here we also show which behaviour is active on the LC-Display!
     *
     */
    void behaviourController(void)
    {
        // Call all the behaviour tasks:
    	behaviour_checkLowBattery();
    	behaviour_waitForStart();
    	behaviour_cruise();
    	behaviour_avoid();
    	behaviour_escape();
    	behaviour_rc5Reception();
    
        // Execute the commands depending on priority levels:
    	if(checkLowBattery.state != IDLE) // Highest priority - 6
    	{
    		displayBehaviour(6);
    		moveCommand(&checkLowBattery);
    	}
    	else if(rc5Reception.state != IDLE) // Priority - 5a
    	{
    		displayBehaviour(7);
    		moveCommand(&rc5Reception);
    	}
    	else if(waitForStart.state != IDLE) // Priority - 5
    	{
    		displayBehaviour(5);
    		moveCommand(&waitForStart);
    	}
    	else if(escape.state != IDLE) // Priority - 4
    	{
    		displayBehaviour(4);
    		moveCommand(&escape);
    	}
    	else if(avoid.state != IDLE) // Priority - 3
    	{
    		displayBehaviour(3);
    		moveCommand(&avoid);
    	}
    	else if(cruise.state != IDLE) // Priority - 1
    	{
    		displayBehaviour(2);
    		moveCommand(&cruise); 
    	}
    	else                     // Lowest priority - 0
    	{
    		displayBehaviour(1);
    		moveCommand(&STOP);  // Default command - do nothing! 
    							 // In the current implementation this never 
    							 // happens.
    	}
    }
    
    
    /*****************************************************************************/
    
    /**
     * Prints all Sensor Values on the Serial Interface.
     */
    void printAllSensorValues(void)
    {
    	getAllSensors();		
    	writeString_P("\nRead Sensor Values:\n");
    	writeString_P("PL:");writeIntegerLength(mleft_power,DEC,3);
    	writeString_P(" | PR:");writeIntegerLength(mright_power,DEC,3);
    	writeString_P(" | VL:");writeIntegerLength(mleft_speed,DEC,3);
    	writeString_P(" | VR:");writeIntegerLength(mright_speed,DEC,3);
    	writeString_P(" | DL:");writeIntegerLength(mleft_des_speed,DEC,3);
    	writeString_P(" | DR:");writeIntegerLength(mright_des_speed,DEC,3);
    	writeChar('\n');
    	writeString_P("DSTL:");writeIntegerLength(mleft_dist,DEC,5);
    	writeString_P(" | DSTR:");writeIntegerLength(mright_dist,DEC,5);
    	writeChar('\n');
    	writeString_P("LSL:");writeIntegerLength(adcLSL,DEC,4);
    	writeString_P(" | LSR:");writeIntegerLength(adcLSR,DEC,4);
    	writeString_P(" | MCL:");writeIntegerLength(adcMotorCurrentLeft,DEC,4);
    	writeString_P(" | MCR:");writeIntegerLength(adcMotorCurrentRight,DEC,4);
    	writeString_P(" | BAT:");writeIntegerLength(adcBat,DEC,4);
    	writeString_P(" | AD0:");writeIntegerLength(adc0,DEC,4);
    	writeString_P(" | AD1:");writeIntegerLength(adc1,DEC,4);
    	writeChar('\n');
    }
    
    
    /**
     * Heartbeat function
     */
    void task_LCDHeartbeat(void)
    {
    	if(getStopwatch1() > 500)
    	{
    		static uint8_t heartbeat = false;
    		if(heartbeat)
    		{
    			clearPosLCD(1, 15, 1);
    			heartbeat = false;
    		}
    		else
    		{
    			setCursorPosLCD(1, 15);
    			writeStringLCD_P("*"); 
    			heartbeat = true;
    			printAllSensorValues();
    		}
    		setStopwatch1(0);
    	}
    }
    
    
    /**
     * Timed Watchdog display - the other heartbeat function
     * does not work in this example as we use blocked moving functions here.
     */
    void watchDogRequest(void)
    {
    	static uint8_t heartbeat2 = false;
    	if(heartbeat2)
    	{
    		clearPosLCD(1, 14, 1);
    		heartbeat2 = false;
    	}
    	else
    	{
    		setCursorPosLCD(1, 14);
    		writeStringLCD_P("#"); 
    		heartbeat2 = true;
    	}
    }
    
    /*****************************************************************************/
    // I2C Requests: 
    
    /**
     * The I2C_requestedDataReady Event Handler
     */
    void I2C_requestedDataReady(uint8_t dataRequestID)
    {
    	checkRP6Status(dataRequestID);
    }
    
    /*****************************************************************************/
    // 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');
    }
    
    /*****************************************************************************/
    // Main function - The program starts here:
    
    int main(void)
    {
    	initRP6Control();  
    	initLCD();
        
    	writeString_P("\n\nRP6 CONTROL M32 I2C Master Example Program!\n"); 
        writeString_P("\nMoving...\n"); 
    
    	// ---------------------------------------
    	WDT_setRequestHandler(watchDogRequest); 
    	BUMPERS_setStateChangedHandler(bumpersStateChanged);
    	ACS_setStateChangedHandler(acsStateChanged);
    	IRCOMM_setRC5DataReadyHandler(receiveRC5Data);
    	BATTERY_setLowVoltageHandler(batteryVoltageLow);
    
    	// ---------------------------------------
    	I2CTWI_initMaster(100);  
    	I2CTWI_setRequestedDataReadyHandler(I2C_requestedDataReady);
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    
    	sound(180,80,25);
    	sound(220,80,25);
    
    	setLEDs(0b1111);
    
    	showScreenLCD("################", "################");
    	mSleep(500);
    	showScreenLCD("I2C-Master", "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);
    
    	startStopwatch1();
    	startStopwatch2();
    
    	showScreenLCD("Active Behaviour", "");
    
    	while(true) 
    	{ 
    		task_LCDHeartbeat();
    		task_checkINT0();
    	    task_I2CTWI();
    		behaviourController();
    	}
    	return 0;
    }
    Damit kennt der RP6 3 RC5-Befehle:
    a) Taste 1: MOVE, noch ohne Funktion. An die Stelle kommen die weiteren Fahrbefehle.
    b) Taste 2: SHOW, Remote-Modus wird eingeschaltet, jede weitere Taste wird auf dem LCD angezeigt.
    c) Taste 3: IDLE, Ende des Remote-Modus.

    Hilft das?

    Gruß Dirk

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2009
    Ort
    NRW
    Beiträge
    23
    Hi Dirk,

    die Signale der Fernbedienung empfangen und damit in ein anderes Verhalten wechseln hab ich schon selbst hinbekommen.
    Aber in mindestens einem Punkt hast du mir schon geholfen: ich werd mein Programm mal etwas vereinfachen und es dann Schritt für Schritt wieder aufbauen. Dann kann ich hoffentlich den Fehler genauer eingrenzen.

    Und eine Sache ist mir noch aufgefallen: Bei deinem Programm stoppen auch die Motoren des RP6, wenn ich die entsprechende Taste auf der Fernbedienung drücke. Bei meinem Programm war das nicht der Fall, obwohl ich eine stop()-Anweisung drin hatte und zusätzlich speed_left und -right im Behaviour-Struct auf 0 standen.

    Ich hab das Gefühl, dass sich die Beschleunigungs-Anweisungen und die deccelerate-Funktion in meinem Programm gegenseitig stören.
    Ich werds mal am Wochenende mit weniger Code für die RC5-Signale probieren und schauen, ob ich nen Fehler finde.

    Weitere Tips und Anregungen sind aber immernoch erwünscht

    mfg,
    V:X

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hallo V:X,

    Weitere Tips und Anregungen sind aber immernoch erwünscht
    Noch mehr?
    Hier z.B. das Verhalten "RC5 Empfang":
    Code:
    /*****************************************************************************/
    // RC5 Reception Behaviour:
    
    // The TV Remote Control definitions
    
    // ###########################
    // Uncomment __one__ (only one!) of the following definitions:
    //#define RC_EURO_SKY
    //#define RC_PROMO8
    #define RC_TOTAL_CONTROL
    //#define RC_YOUR_OWN
    // ...
    
    // ###########################
    // Change the keymapping here:
    
    #ifdef RC_EUROSKY		// RC Type:  Conrad - EuroSky	
    	#define RC5_KEY_LEFT 				22		
    	#define RC5_KEY_RIGHT 				21		
    	#define RC5_KEY_FORWARDS 			16  	
    	#define RC5_KEY_BACKWARDS 			17		
    	#define RC5_KEY_STOP 				23		
    	#define RC5_KEY_CURVE_LEFT 			1	
    	#define RC5_KEY_CURVE_RIGHT 		3	
    	#define RC5_KEY_CURVE_BACK_LEFT 	7	
    	#define RC5_KEY_CURVE_BACK_RIGHT 	9	
    	#define RC5_KEY_LEFT_MOTOR_FWD 		1
    	#define RC5_KEY_LEFT_MOTOR_BWD 		7
    	#define RC5_KEY_RIGHT_MOTOR_FWD 	3
    	#define RC5_KEY_RIGHT_MOTOR_BWD 	9
    	#define RC5_KEY_CONTROL_START	 	?
    	#define RC5_KEY_CONTROL_END		 	?
    #endif
    
    #ifdef RC_PROMO8		// RC Type:  Conrad - Promo8			
    	#define RC5_KEY_LEFT 				21		
    	#define RC5_KEY_RIGHT 				22		
    	#define RC5_KEY_FORWARDS 			32  	
    	#define RC5_KEY_BACKWARDS 			33		
    	#define RC5_KEY_STOP 				11	
    	#define RC5_KEY_CURVE_LEFT 			29	
    	#define RC5_KEY_CURVE_RIGHT 		13	
    	#define RC5_KEY_CURVE_BACK_LEFT 	10	
    	#define RC5_KEY_CURVE_BACK_RIGHT 	62		
    	#define RC5_KEY_LEFT_MOTOR_FWD 		1
    	#define RC5_KEY_LEFT_MOTOR_BWD 		7
    	#define RC5_KEY_RIGHT_MOTOR_FWD 	3
    	#define RC5_KEY_RIGHT_MOTOR_BWD 	9
    	#define RC5_KEY_CONTROL_START	 	?
    	#define RC5_KEY_CONTROL_END		 	?
    #endif
    
    #ifdef RC_TOTAL_CONTROL	// RC Type:  Conrad - TOTAL control			
    	#define RC5_KEY_LEFT 				4		// 4
    	#define RC5_KEY_RIGHT 				6		// 6
    	#define RC5_KEY_FORWARDS 			2  		// 2
    	#define RC5_KEY_BACKWARDS 			8		// 8
    	#define RC5_KEY_STOP 				5		// 5
    	#define RC5_KEY_CURVE_LEFT 			32		// P+
    	#define RC5_KEY_CURVE_RIGHT 		16		// L+
    	#define RC5_KEY_CURVE_BACK_LEFT 	33		// P-
    	#define RC5_KEY_CURVE_BACK_RIGHT 	17		// L-
    	#define RC5_KEY_LEFT_MOTOR_FWD 		1		// 1
    	#define RC5_KEY_LEFT_MOTOR_BWD 		7		// 7
    	#define RC5_KEY_RIGHT_MOTOR_FWD 	3		// 3
    	#define RC5_KEY_RIGHT_MOTOR_BWD 	9		// 9
    	#define RC5_KEY_CONTROL_START	 	23		// ENTER
    	#define RC5_KEY_CONTROL_END		 	0		// 0
    #endif
    
    #ifdef RC_YOUR_OWN		// Your own RC!
    	#define RC5_KEY_LEFT 				4		
    	#define RC5_KEY_RIGHT 				6		
    	#define RC5_KEY_FORWARDS 			2  	
    	#define RC5_KEY_BACKWARDS 			8		
    	#define RC5_KEY_STOP 				5		
    	#define RC5_KEY_CURVE_LEFT 			1	
    	#define RC5_KEY_CURVE_RIGHT 		3	
    	#define RC5_KEY_CURVE_BACK_LEFT 	7	
    	#define RC5_KEY_CURVE_BACK_RIGHT 	9		
    	#define RC5_KEY_LEFT_MOTOR_FWD		10
    	#define RC5_KEY_LEFT_MOTOR_BWD 		11
    	#define RC5_KEY_RIGHT_MOTOR_FWD 	12
    	#define RC5_KEY_RIGHT_MOTOR_BWD 	13
    	#define RC5_KEY_CONTROL_START	 	?
    	#define RC5_KEY_CONTROL_END		 	?
    #endif
    
    //... you can add more Remote control keymappings or implement something
    // better than this if you like...
    
    
    #define RC5RECEPTION_MOVE 1
    behaviour_command_t rc5Reception = {0, 0, FWD, false, false, 0, IDLE}; 
    
    /**
     * Behaviour with RC5 Reception.
     */
    void behaviour_rc5Reception(void)
    {
    }
    
    #define RC5RECEPTION_SPEED_ROTATE 			60
    #define RC5RECEPTION_SPEED_MAX				80
    #define RC5RECEPTION_SPEED_L_ARC_LEFT 		20
    #define RC5RECEPTION_SPEED_L_ARC_RIGHT 		80
    #define RC5RECEPTION_SPEED_R_ARC_LEFT 		80
    #define RC5RECEPTION_SPEED_R_ARC_RIGHT 		20
    
    /**
     * RC5 Event Handler 
     */
    void receiveRC5Data(RC5data_t rc5data)
    {
    	// Check which key is pressed:
    	switch(rc5data.key_code)
    	{
    		case RC5_KEY_LEFT: 	 		// Turn left:
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_ROTATE;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = LEFT;
    			rc5Reception.move = false;
    			rc5Reception.rotate = true;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_RIGHT: 		// Turn right:
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_ROTATE;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = RIGHT;
    			rc5Reception.move = false;
    			rc5Reception.rotate = true;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_FORWARDS: 		// Move forwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_BACKWARDS: 	// Move backwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.dir = BWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_STOP: 			// Stop!
    			rc5Reception.speed_left = 0;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = false;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 0;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CURVE_LEFT: 	// Drive curve left - forwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_L_ARC_LEFT;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_L_ARC_RIGHT;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CURVE_RIGHT: 	// Drive curve right - forwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_R_ARC_LEFT;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_R_ARC_RIGHT;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CURVE_BACK_LEFT: 	// Drive curve left - backwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_L_ARC_LEFT;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_L_ARC_RIGHT;
    			rc5Reception.dir = BWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CURVE_BACK_RIGHT: 	// Drive curve right - backwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_R_ARC_LEFT;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_R_ARC_RIGHT;
    			rc5Reception.dir = BWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_LEFT_MOTOR_FWD: 	// Only left motor on - forwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_LEFT_MOTOR_BWD: 	// Only left motor on - backwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = BWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_RIGHT_MOTOR_FWD: // Only right motor on - forwards
    			rc5Reception.speed_left = 0;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_RIGHT_MOTOR_BWD: 	// Only right motor on - backwards
    			rc5Reception.speed_left = 0;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.dir = BWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CONTROL_START:		// Start of the RC5 control mode
    			rc5Reception.speed_left = 0;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = false;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 0;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CONTROL_END:		// End of the RC5 control mode
    			rc5Reception.speed_left = 0;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = false;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 0;
    			rc5Reception.state = IDLE;
    		break;
    	}
    
    	if(rc5Reception.state == RC5RECEPTION_MOVE)
    	{
    		if(getStopwatch2() > 500)
    		{
    			clearPosLCD(1, 0, 13);
    			setCursorPosLCD(1, 0); 
    			// Display the received data:
    			writeStringLCD_P("RC5 ");
    			writeCharLCD(rc5data.toggle_bit + '0');
    			writeStringLCD_P(" |");
    			writeIntegerLCD(rc5data.device, DEC);
    			writeStringLCD_P(" |");
    			writeIntegerLCD(rc5data.key_code, DEC);
    			setStopwatch2(0);
    		}
    	}
    }
    
    /*****************************************************************************/
    Gruß Dirk

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    28.10.2009
    Ort
    Ratingen
    Alter
    66
    Beiträge
    60

    Seit langem habe ich mal wieder Zeit für meinen RP6

    Zitat Zitat von Dirk
    Hallo V:X,

    Weitere Tips und Anregungen sind aber immernoch erwünscht
    Noch mehr?
    Hier z.B. das Verhalten "RC5 Empfang":
    Code:
    /*****************************************************************************/
    // RC5 Reception Behaviour:
    
    // The TV Remote Control definitions
    
    // ###########################
    // Uncomment __one__ (only one!) of the following definitions:
    //#define RC_EURO_SKY
    //#define RC_PROMO8
    #define RC_TOTAL_CONTROL
    //#define RC_YOUR_OWN
    // ...
    
    // ###########################
    // Change the keymapping here:
    
    #ifdef RC_EUROSKY		// RC Type:  Conrad - EuroSky	
    	#define RC5_KEY_LEFT 				22		
    	#define RC5_KEY_RIGHT 				21		
    	#define RC5_KEY_FORWARDS 			16  	
    	#define RC5_KEY_BACKWARDS 			17		
    	#define RC5_KEY_STOP 				23		
    	#define RC5_KEY_CURVE_LEFT 			1	
    	#define RC5_KEY_CURVE_RIGHT 		3	
    	#define RC5_KEY_CURVE_BACK_LEFT 	7	
    	#define RC5_KEY_CURVE_BACK_RIGHT 	9	
    	#define RC5_KEY_LEFT_MOTOR_FWD 		1
    	#define RC5_KEY_LEFT_MOTOR_BWD 		7
    	#define RC5_KEY_RIGHT_MOTOR_FWD 	3
    	#define RC5_KEY_RIGHT_MOTOR_BWD 	9
    	#define RC5_KEY_CONTROL_START	 	?
    	#define RC5_KEY_CONTROL_END		 	?
    #endif
    
    #ifdef RC_PROMO8		// RC Type:  Conrad - Promo8			
    	#define RC5_KEY_LEFT 				21		
    	#define RC5_KEY_RIGHT 				22		
    	#define RC5_KEY_FORWARDS 			32  	
    	#define RC5_KEY_BACKWARDS 			33		
    	#define RC5_KEY_STOP 				11	
    	#define RC5_KEY_CURVE_LEFT 			29	
    	#define RC5_KEY_CURVE_RIGHT 		13	
    	#define RC5_KEY_CURVE_BACK_LEFT 	10	
    	#define RC5_KEY_CURVE_BACK_RIGHT 	62		
    	#define RC5_KEY_LEFT_MOTOR_FWD 		1
    	#define RC5_KEY_LEFT_MOTOR_BWD 		7
    	#define RC5_KEY_RIGHT_MOTOR_FWD 	3
    	#define RC5_KEY_RIGHT_MOTOR_BWD 	9
    	#define RC5_KEY_CONTROL_START	 	?
    	#define RC5_KEY_CONTROL_END		 	?
    #endif
    
    #ifdef RC_TOTAL_CONTROL	// RC Type:  Conrad - TOTAL control			
    	#define RC5_KEY_LEFT 				4		// 4
    	#define RC5_KEY_RIGHT 				6		// 6
    	#define RC5_KEY_FORWARDS 			2  		// 2
    	#define RC5_KEY_BACKWARDS 			8		// 8
    	#define RC5_KEY_STOP 				5		// 5
    	#define RC5_KEY_CURVE_LEFT 			32		// P+
    	#define RC5_KEY_CURVE_RIGHT 		16		// L+
    	#define RC5_KEY_CURVE_BACK_LEFT 	33		// P-
    	#define RC5_KEY_CURVE_BACK_RIGHT 	17		// L-
    	#define RC5_KEY_LEFT_MOTOR_FWD 		1		// 1
    	#define RC5_KEY_LEFT_MOTOR_BWD 		7		// 7
    	#define RC5_KEY_RIGHT_MOTOR_FWD 	3		// 3
    	#define RC5_KEY_RIGHT_MOTOR_BWD 	9		// 9
    	#define RC5_KEY_CONTROL_START	 	23		// ENTER
    	#define RC5_KEY_CONTROL_END		 	0		// 0
    #endif
    
    #ifdef RC_YOUR_OWN		// Your own RC!
    	#define RC5_KEY_LEFT 				4		
    	#define RC5_KEY_RIGHT 				6		
    	#define RC5_KEY_FORWARDS 			2  	
    	#define RC5_KEY_BACKWARDS 			8		
    	#define RC5_KEY_STOP 				5		
    	#define RC5_KEY_CURVE_LEFT 			1	
    	#define RC5_KEY_CURVE_RIGHT 		3	
    	#define RC5_KEY_CURVE_BACK_LEFT 	7	
    	#define RC5_KEY_CURVE_BACK_RIGHT 	9		
    	#define RC5_KEY_LEFT_MOTOR_FWD		10
    	#define RC5_KEY_LEFT_MOTOR_BWD 		11
    	#define RC5_KEY_RIGHT_MOTOR_FWD 	12
    	#define RC5_KEY_RIGHT_MOTOR_BWD 	13
    	#define RC5_KEY_CONTROL_START	 	?
    	#define RC5_KEY_CONTROL_END		 	?
    #endif
    
    //... you can add more Remote control keymappings or implement something
    // better than this if you like...
    
    
    #define RC5RECEPTION_MOVE 1
    behaviour_command_t rc5Reception = {0, 0, FWD, false, false, 0, IDLE}; 
    
    /**
     * Behaviour with RC5 Reception.
     */
    void behaviour_rc5Reception(void)
    {
    }
    
    #define RC5RECEPTION_SPEED_ROTATE 			60
    #define RC5RECEPTION_SPEED_MAX				80
    #define RC5RECEPTION_SPEED_L_ARC_LEFT 		20
    #define RC5RECEPTION_SPEED_L_ARC_RIGHT 		80
    #define RC5RECEPTION_SPEED_R_ARC_LEFT 		80
    #define RC5RECEPTION_SPEED_R_ARC_RIGHT 		20
    
    /**
     * RC5 Event Handler 
     */
    void receiveRC5Data(RC5data_t rc5data)
    {
    	// Check which key is pressed:
    	switch(rc5data.key_code)
    	{
    		case RC5_KEY_LEFT: 	 		// Turn left:
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_ROTATE;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = LEFT;
    			rc5Reception.move = false;
    			rc5Reception.rotate = true;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_RIGHT: 		// Turn right:
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_ROTATE;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = RIGHT;
    			rc5Reception.move = false;
    			rc5Reception.rotate = true;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_FORWARDS: 		// Move forwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_BACKWARDS: 	// Move backwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.dir = BWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_STOP: 			// Stop!
    			rc5Reception.speed_left = 0;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = false;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 0;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CURVE_LEFT: 	// Drive curve left - forwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_L_ARC_LEFT;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_L_ARC_RIGHT;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CURVE_RIGHT: 	// Drive curve right - forwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_R_ARC_LEFT;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_R_ARC_RIGHT;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CURVE_BACK_LEFT: 	// Drive curve left - backwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_L_ARC_LEFT;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_L_ARC_RIGHT;
    			rc5Reception.dir = BWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CURVE_BACK_RIGHT: 	// Drive curve right - backwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_R_ARC_LEFT;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_R_ARC_RIGHT;
    			rc5Reception.dir = BWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_LEFT_MOTOR_FWD: 	// Only left motor on - forwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_LEFT_MOTOR_BWD: 	// Only left motor on - backwards
    			rc5Reception.speed_left = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = BWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_RIGHT_MOTOR_FWD: // Only right motor on - forwards
    			rc5Reception.speed_left = 0;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_RIGHT_MOTOR_BWD: 	// Only right motor on - backwards
    			rc5Reception.speed_left = 0;
    			rc5Reception.speed_right = RC5RECEPTION_SPEED_MAX;
    			rc5Reception.dir = BWD;
    			rc5Reception.move = true;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 100;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CONTROL_START:		// Start of the RC5 control mode
    			rc5Reception.speed_left = 0;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = false;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 0;
    			rc5Reception.state = RC5RECEPTION_MOVE;
    		break;
    		case RC5_KEY_CONTROL_END:		// End of the RC5 control mode
    			rc5Reception.speed_left = 0;
    			rc5Reception.speed_right = 0;
    			rc5Reception.dir = FWD;
    			rc5Reception.move = false;
    			rc5Reception.rotate = false;
    			rc5Reception.move_value = 0;
    			rc5Reception.state = IDLE;
    		break;
    	}
    
    	if(rc5Reception.state == RC5RECEPTION_MOVE)
    	{
    		if(getStopwatch2() > 500)
    		{
    			clearPosLCD(1, 0, 13);
    			setCursorPosLCD(1, 0); 
    			// Display the received data:
    			writeStringLCD_P("RC5 ");
    			writeCharLCD(rc5data.toggle_bit + '0');
    			writeStringLCD_P(" |");
    			writeIntegerLCD(rc5data.device, DEC);
    			writeStringLCD_P(" |");
    			writeIntegerLCD(rc5data.key_code, DEC);
    			setStopwatch2(0);
    		}
    	}
    }
    
    /*****************************************************************************/
    Gruß Dirk
    Hallo
    Mir ist nicht klar, wie dieser Code in das weiter oben vorgestellte erweiterte move Programm eingefügt werden muß.

    kann mir hier jemand helfen?

    Gruß Klaus

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    28.10.2009
    Ort
    Ratingen
    Alter
    66
    Beiträge
    60
    Hallo,

    etwas bin ich weiter gekommen. Im Prinzip funktioniert es schon, aber wenn per IR nur der linke oder rechte Motor laufen soll, läuft erst einmal auch der andere mit an

    Gruß Klaus
    Angehängte Dateien Angehängte Dateien

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    @Klaus:
    Was mir auffällt:

    1. In der Funktion behaviourController müßte auch noch die behaviour_rc5Reception(); aufgeführt werden.

    2. In der Main müßte auch der Handler für RC5 eingefügt werden:
    IRCOMM_setRC5DataReadyHandler(receiveRC5Data);

    3. In der displayBehaviour Funktion müßte es den Case 7 noch geben:
    case 7: writeStringLCD_P("RC5 CONTROL"); setLEDs(0b0000); break;

    4. Das komplette Verhalten und der Event Handler für den RC5-Empfang fehlt noch (hatte ich hier gepostet).

    Weiter habe ich noch nicht geguckt.

    Gruß Dirk

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    28.10.2009
    Ort
    Ratingen
    Alter
    66
    Beiträge
    60
    Hallo Dirk,

    Schande über mein Haupt, ich hatte die falsche Datei angehängt

    Gruß

    Klaus
    Angehängte Dateien Angehängte Dateien

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    06.11.2010
    Beiträge
    773
    Ich habe da ein ähnliches Problem, wenn auch kleiner und auf der BASE!
    Ich möchte zunächst nur, dass mein Robot zwar mit TV-Remote rumfährt, aber er soll später auch auf Knopfdruck in eigene Routinen fahren (z.B. Lichtverfolgung etc).
    Da ich noch Anfänger bin, will ichs mal nicht übertreiben und habe einfach einen Bumper_stateChangeHandler eingebaut / einbauen wollen.
    Aber es passiert rein gar nichts, wenn ich diese auslöse.
    Kann sich das mal jemand ansehen, der was davon versteht?

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad