hm... wenn es man tun würde!
soll ich euch einfach mal das ganze programm posten=?
mach ich einfach mal!
Code:
/*
* ****************************************************************************
* RP6 ROBOT SYSTEM - ROBOT BASE EXAMPLES
* ****************************************************************************
* Example: RP6 Remote Controlled
* Author(s): Dominik S. Herwald
* ****************************************************************************
* Description:
*
* This demo program shows how to use a RC5 TV Remote Control to control your
* RP6 like a RC-Car.
* It also implements acceleration and deceleration functionality.
* (yes it is intentionally that the robot accelerates and decelerates so
* slow ;) Of course you can change this if you want!)
*
* First you need to get a Remote Control that transmits RC5 Code - like
* Conrad Promo8 or EuroSky Universal remote controls - which are very cheap
* --> about 10 Euro. Then you may need to try out some different codes - look
* at the manual of these remote controls how to change the transmit code!
*
* Attention: The codes listed in this sample program will not match even
* when you use the same remote control - it depends on specific protocol
* that it uses.
*
* You can test if the remote transmits RC5 code when you start this program
* and look at the Terminal output. If it receives a RC5 code, it will display
* the keycode, address and the toggle bit.
*
* MAKE SURE THAT THE RP6 CAN NOT MOVE,
* or uncomment the line #define DO_NOT_MOVE!
*
* As soon as this works, you can change the key mapping - look at your
* remote control and decide yourself which keys are best for move left/right,
* forwards/backwards, drive left/right curve fwd/bwd, only left/right motor
* forwards/backwards and stop.
* Typically there are some keys with ideal layout for this
* (usually intended for cursor movement and stuff like that)!
* Press them and look what their keycode is. Then enter the keyvalues in the
* source code - like in this example:
*
* #ifdef RC_YOUR_OWN // Standard Numbers on every Remote control
* #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
* //...
* #endif
*
* Outcomment the #define RC_PROMO8
* like this: //#define RC_PROMO8
* and Uncomment //#define RC_YOUR_OWN
* like this: #define RC_YOUR_OWN
*
* Then recompile the program, upload it, start it again and test if
* the RP6 reacts when you press those keys on your remote control.
* You need to HOLD DOWN the key - then the RP6 will accelerate slowly to the
* MAX_SPEED values defined in this program. If you release the key again,
* it starts to deccelerate slowly.
* You can control the RP6 also with
* press key - release key - press key - release key - press key - release key
* ....
* This will result in a slower movement than just holding the key down
* continously.
*
* ****************************************************************************
*/
/*****************************************************************************/
// Includes:
#include "RP6RobotBaseLib.h"
/*****************************************************************************/
/*****************************************************************************/
static uint8_t schussAktiv = 0;
static uint8_t stopwatchgestartet = 0;
// If you only want to look at the RC5 Keycodes received from the Remote
// Control, uncomment this line:
//#define DO_NOT_MOVE
// The RP6 will not move then!
/*****************************************************************************/
/*****************************************************************************/
// Key Belegung
// müsste eigt erst weiter unten stehen, aber so kann ich sie bei dieser Switch
// schon mitbenutzen und muss sie nicht doppelt deifineren.
// 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_SCHUSS 12
#define RC5_SERVO_LINKS 1
#define RC5_SERVO_RECHTS 2
//... you can add more Remote control keymappings or implement something
// better than this if you like...
void schuss(void)
{
if(stopwatchgestartet == 1 && PORTA==0) // Hier nochmal genau prüfen
setStopwatch3(0);
if(schussAktiv==1)
{
if(PORTA == 0)
PORTA = 1;
if(getStopwatch3()>30){
PORTA = 0;
schussAktiv = 0;
stopwatchgestartet = 0;
}
}
}
/*****************************************************************************/
// Defines:
// RP6 Base Servo Connection:
#define SERVO_OUT SCL // PINC1 XBUS Pin 12
// Servo movement limits (depending on servo type):
#define LEFT_TOUCH 950 // Left servo touch
#define RIGHT_TOUCH 154 // Right servo touch [max. 255]
#define PULSE_ADJUST 4
#define PULSE_REPETITION 19 // Pulse repetition frequency
static uint8_t pos=100;
/*****************************************************************************/
// Functions:
/**
* INIT SERVO
*
* Call this once before using the servo task.
*
*/
void initSERVO(void)
{
DDRC |= SERVO_OUT; // SERVO_OUT -> OUTPUT
PORTC &= ~SERVO_OUT; // SERVO_OUT -> LO
startStopwatch5(); // Needed for 20ms pulse repetition
}
/**
* PULSE SERVO
*
* This is the servo pulse generation. This function
* must be called every 20ms (pulse repetition).
*
* position = 0 : Left touch
* position = RIGHT_TOUCH : Right touch
*
* ATTENTION: ! This function is BLOCKING all other activities for about 1 !
* ! to 2ms (depending on the value of position)!!! !
* ! If you generate a pulse every 20ms 5-10% of the processor's !
* ! calculating time is wasted by this kind of pulse generation. !
* ! If this is a problem for the rest of your program, you !
* ! cannot use this method. !
* ! You will need an interrupt-based solution instead. !
*
*/
void pulseSERVO(uint8_t position)
{
cli();
PORTC |= SERVO_OUT; // SERVO_OUT -> HI (pulse start)
delayCycles(LEFT_TOUCH);
while (position--) {
delayCycles(PULSE_ADJUST);
}
PORTC &= ~SERVO_OUT; // SERVO_OUT -> LO (pulse end)
sei();
}
/**
* SERVO TASK
*
* This is the servo demo task.
* The positioning demo shows the servo lever rapidly
* moving to the left touch, then slowly moving to
* the right touch and so on ...
*
*/
void task_SERVO(void)
{
if (getStopwatch5() > PULSE_REPETITION) { // Pulse every ~20ms
pulseSERVO(pos); // Servo pulse [1..2ms]
// ---------------------------------------------------------------------
setStopwatch5(0);
}
}
/*****************************************************************************/
// Speed values:
#define MAX_SPEED_MOVE 200
#define MAX_SPEED_TURN 100
#define MAX_SPEED_CURVE 120
#define MAX_SPEED_CURVE2 40
#define ACCELERATE_CURVE 10
#define ACCELERATE_CURVE2 4
#define DECELERATE_CURVE 4
#define DECELERATE_CURVE2 2
#define MAX_SPEED_1_MOTOR 120
#define ACCELERATE_VALUE 8
#define DECELERATE_VALUE 4
uint8_t max_speed_left; // Maximum speed variable left
uint8_t max_speed_right; // Maximum speed variable right
uint8_t acl_left;
uint8_t acl_right;
uint8_t decl_left;
uint8_t decl_right;
/*****************************************************************************/
/**
* Just a small helper function to set speed params.
*/
void setDefaultSpeedParameters(void)
{
max_speed_left = MAX_SPEED_MOVE;
max_speed_right = max_speed_left;
acl_left = ACCELERATE_VALUE;
acl_right = ACCELERATE_VALUE;
decl_left = DECELERATE_VALUE;
decl_right = DECELERATE_VALUE;
uint16_t tmp = (getDesSpeedLeft() + getDesSpeedRight())/2;
moveAtSpeed(tmp , tmp);
}
/**
* 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');
uint8_t movement_command = false; // used to store if we have received
// a movement command.
// Any other key is ignored!
// Check which key is pressed:
switch(rc5data.key_code)
{
case RC5_KEY_LINKS_ROT: // Turn left:
writeString_P("LEFT\n");
setDefaultSpeedParameters();
max_speed_left = MAX_SPEED_TURN;
max_speed_right = max_speed_left;
changeDirection(LEFT);
setLEDs(0b100000);
movement_command = true; // Store that we have received a movement command!
break;
case RC5_KEY_RECHTS_ROT: // Turn right:
writeString_P("RIGHT\n");
setDefaultSpeedParameters();
max_speed_left = MAX_SPEED_TURN;
max_speed_right = max_speed_left;
changeDirection(RIGHT);
setLEDs(0b000100);
movement_command = true;
break;
case RC5_KEY_VOR: // Move forwards
writeString_P("FORWARDS\n");
setDefaultSpeedParameters();
changeDirection(FWD);
setLEDs(0b100100);
movement_command = true;
break;
case RC5_KEY_RUECK: // Move backwards
writeString_P("BACKWARDS\n");
setDefaultSpeedParameters();
changeDirection(BWD);
setLEDs(0b001001);
movement_command = true;
break;
case RC5_KEY_STOP: // Stop!
writeString_P("STOP\n");
max_speed_left = 0;
max_speed_right = max_speed_left;
moveAtSpeed(0,0);
setLEDs(0b011011);
movement_command = true;
break;
case RC5_KEY_CURVE_LEFT: // Drive curve left - forwards
writeString_P("CURVE LEFT FWD\n");
max_speed_left = MAX_SPEED_CURVE2;
max_speed_right = MAX_SPEED_CURVE;
acl_left = ACCELERATE_CURVE2;
acl_right = ACCELERATE_CURVE;
decl_left = DECELERATE_CURVE2;
decl_right = DECELERATE_CURVE;
changeDirection(FWD);
setLEDs(0b110100);
movement_command = true;
break;
case RC5_KEY_CURVE_RIGHT: // Drive curve right - forwards
writeString_P("CURVE RIGHT FWD\n");
max_speed_left = MAX_SPEED_CURVE;
max_speed_right = MAX_SPEED_CURVE2;
acl_left = ACCELERATE_CURVE;
acl_right = ACCELERATE_CURVE2;
decl_left = DECELERATE_CURVE;
decl_right = DECELERATE_CURVE2;
changeDirection(FWD);
setLEDs(0b100110);
movement_command = true;
break;
case RC5_KEY_SCHUSS:
stopwatchgestartet = 1;
schussAktiv = 1;
break;
case RC5_SERVO_LINKS:
pos--;
if (pos < LEFT_TOUCH) {pos = 0;} // pos: 0..RIGHT_TOUCH
break;
case RC5_SERVO_RECHTS:
pos++;
if (pos > RIGHT_TOUCH) {pos = RIGHT_TOUCH;}
break;
}
if(movement_command) // Did we receive a move command?
{
// Accelerate if neccessary:
if(getDesSpeedLeft() < max_speed_left) // If we have not reached the left maximum speed...
{ // ... accelerate!
moveAtSpeed(getDesSpeedLeft()+acl_left, getDesSpeedRight());
if(getDesSpeedLeft() < 10)
moveAtSpeed(10, getDesSpeedRight());
}
if(getDesSpeedRight() < max_speed_right) // If we have not reached the right maximum speed...
{
// ... accelerate!
moveAtSpeed(getDesSpeedLeft(), getDesSpeedRight()+acl_right);
if(getDesSpeedRight() < 10)
moveAtSpeed(getDesSpeedLeft(), 10);
}
// Start Stopwatch 1 - it starts decceleration after 250ms of no RC5 reception! (s. below)
setStopwatch1(0);
startStopwatch1();
}
}
/*****************************************************************************/
/**
* This function is called frequently out of the main loop and checks if
* Stopwatch1 has counted at least 250ms. If this is the case, decceleration is started
* and the Stopwatch is resetted and the progtam waits for next 250ms to pass by.
* Stopwatch1 ist set to 0 and started from the RC5 reception handler after
* each reception of a valid keycode. (s. above)
*/
void deccelerate(void)
{
if(getStopwatch1() > 250) // After 250ms with no reception...
{
if(getDesSpeedLeft() <= 10) // If left speed is less or equal than 10...
moveAtSpeed(0, getDesSpeedRight()); // ... stop the left motor
else // Otherwise continue to deccelerate:
moveAtSpeed(getDesSpeedLeft()-decl_left, getDesSpeedRight());
if(getDesSpeedRight() <= 10) // If right speed is less or equal than 10...
moveAtSpeed(getDesSpeedLeft(), 0); // ... stop the right motor
else // Otherwise continue to deccelerate:
moveAtSpeed(getDesSpeedLeft(), getDesSpeedRight()-decl_right);
if (getDesSpeedRight() == 0 && getDesSpeedLeft() == 0)
stopStopwatch1(); // Decceleration has finished!
max_speed_left = getDesSpeedLeft(); // Update max_speed value
max_speed_right = getDesSpeedRight(); // Update max_speed value
setLEDs(0b000000); // and clear LEDs
setStopwatch1(0);
}
// Make sure we don't move after Direction has changed and key is released too fast.
// This prevents the RP6 from moving when the direction has just changed and temporary saved
// speed value is written back again in the task_motionControl function.
if(getDesSpeedLeft() > max_speed_left)
{
if(getDesSpeedLeft() <= 10) // If left speed is less or equal than 10...
moveAtSpeed(0, getDesSpeedRight()); // ... stop the left motor
else // decelerate:
moveAtSpeed(getDesSpeedLeft()-decl_left, getDesSpeedRight());
}
if(getDesSpeedRight() > max_speed_right)
{
if(getDesSpeedRight() <= 10) // If right speed is less or equal than 10...
moveAtSpeed(getDesSpeedLeft(), 0); // ... stop the right motor
else // decelerate:
moveAtSpeed(getDesSpeedLeft(), getDesSpeedRight()-decl_right);
}
}
/*****************************************************************************/
// Main - The program starts here:
int main(void)
{
initRobotBase();
setLEDs(0b111111);
writeChar('\n');
writeString_P("RP6 controlled by RC5 TV Remote\n");
writeString_P("___________________________\n");
mSleep(500);
setLEDs(0b000000);
powerON();
// Set the RC5 Receive Handler:
IRCOMM_setRC5DataReadyHandler(receiveRC5Data);
startStopwatch2();
// Für Schuss
startStopwatch3();
DDRA = 1; // ADC0 auf Ausgang
// Für Servo
initSERVO();
startStopwatch4(); // Used for the demo task
task_SERVO();
// Main loop
while(true)
{
deccelerate(); // Call the deceleration function.
task_RP6System(); // Motion Control tasks etc.
schuss();
//task_SERVO();
}
return 0;
}
edit:
wenn man dann mit der Fernbedienung eine Taste drückt, dann empfämgt der Roboter nicht immer die Signale im Terminal! Nur manchmal, also ganz sporalisch!
Deswegen gehe ich nämlich davon aus, dass der Cpu ausgelastet ist. Geht das dann denn gar nicht ohne die Erweiterungsplatine?
Mfg Morpheus
Lesezeichen