PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servos mittels TV-Remote steuern



Biohazardry
14.02.2011, 23:00
Hi, habe erst vor kurzen den RP6 gekauft und das C-Tutorial auf der CD durchgearbeitet (Bin C Neuling jedoch beherrsche ich LabView).

Zum Problem: ich möchte mir mittels 2 Servomotoren eine 2-Achs Platform bauen worauf ich einen Laserpointer befestige (Laser+Servos vorhanden). Das ganze soll mittels TV Fernbedienung gesteuert werden... also ein Druck auf die Links-Taste soll den Servo 1 (X-Achse) nach links drehen; Rechts-Taste nach rechts; Y-Bewegung mit Rauf/Runter...

Ich habe mir das TV-Remote Example zu herzen genommen und eine Servosteuerung von hier (glaube eine von Dirk) versucht zu implementieren...

Nur geht es nicht so wie ich es mir vorgestellt habe. Bei einen Druck auf Links (oder Rechts) fahrt der Servo ganz nach Rechts gegen den Anschlag. Dort verharrt er schließlich. Das passiert immer egal von welcher Position er startet.... Auch die (hoffentlich) unbeschädigte TV Remote-Ansteuerung der Roboterbewegung will nicht mehr...

Kann mal einer vll. ein Blick auf des Programm werfen und den oder die Fehler suchen

Thx


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

#include "RP6RobotBaseLib.h"

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


// 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!



/************************************************** ***************************/
/************************************************** ***************************/
// The TV Remote Control definitions

// ###########################
// Uncomment __one__ (only one!) of the following definitions:
//#define RC_EURO_SKY
//#define RC_PROMO8
#define RC_YOUR_OWN
// ...

#define SERVO_OUT ADC0 //
#define SERVO_OUT2 ADC1 //


// ###########################
// 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
#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
#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_SERVO_1_LEFT 17
#define RC5_KEY_SERVO_1_RIGHT 16
#define RC5_KEY_SERVO_2_LEFT 32
#define RC5_KEY_SERVO_2_RIGHT 33
#endif

//... you can add more Remote control keymappings or implement something
// better than this if you like...



/************************************************** ***************************/
// 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;
uint8_t POS_SERVO = 100;

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

/**
* 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');

#ifndef DO_NOT_MOVE // used to disable movement if you want to
// look at the received RC5 codes only (s. above).

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_LEFT: // 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_RIGHT: // 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_FORWARDS: // Move forwards
writeString_P("FORWARDS\n");
setDefaultSpeedParameters();
changeDirection(FWD);
setLEDs(0b100100);
movement_command = true;
break;
case RC5_KEY_BACKWARDS: // 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_CURVE_BACK_LEFT: // Drive curve left - backwards
writeString_P("CURVE LEFT BWD\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(BWD);
setLEDs(0b011001);
movement_command = true;
break;
case RC5_KEY_CURVE_BACK_RIGHT: // Drive curve right - backwards
writeString_P("CURVE RIGHT BWD\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(BWD);
setLEDs(0b001011);
movement_command = true;
break;
case RC5_KEY_LEFT_MOTOR_FWD: // Only left motor on - forwards
writeString_P("MOTOR LEFT FWD\n");
max_speed_left = 0;
max_speed_right = MAX_SPEED_1_MOTOR;
acl_left = 4;
acl_right = 4;
decl_left = 4;
decl_right = 4;
changeDirection(FWD);
setLEDs(0b110000);
movement_command = true;
break;
case RC5_KEY_LEFT_MOTOR_BWD: // Only left motor on - backwards
writeString_P("MOTOR LEFT BWD\n");
max_speed_left = 0;
max_speed_right = MAX_SPEED_1_MOTOR;
acl_left = 4;
acl_right = 4;
decl_left = 4;
decl_right = 4;
changeDirection(BWD);
setLEDs(0b101000);
movement_command = true;
break;
case RC5_KEY_RIGHT_MOTOR_FWD: // Only right motor on - forwards
writeString_P("MOTOR RIGHT FWD\n");
max_speed_left = MAX_SPEED_1_MOTOR;
max_speed_right = 0;
acl_left = 4;
acl_right = 4;
decl_left = 4;
decl_right = 4;
changeDirection(FWD);
setLEDs(0b000110);
movement_command = true;
break;
case RC5_KEY_RIGHT_MOTOR_BWD: // Only right motor on - backwards
writeString_P("MOTOR RIGHT BWD\n");
max_speed_left = MAX_SPEED_1_MOTOR;
max_speed_right = 0;
acl_left = 4;
acl_right = 4;
decl_left = 4;
decl_right = 4;
changeDirection(BWD);
setLEDs(0b000101);
movement_command = true;
break;
case RC5_KEY_SERVO_1_LEFT: // SERVO LEFT
writeString_P("SERVO 1 LEFT\n");
POS_SERVO += 1;
setLEDs(0b000101);
movement_command = true;
break;
case RC5_KEY_SERVO_1_RIGHT: // SERVO LEFT
writeString_P("SERVO 2 RIGHT\n");
POS_SERVO -= 1;
setLEDs(0b000101);
movement_command = true;
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();
}
#endif

}

void initSERVO(void)
{
DDRA |= SERVO_OUT; // SERVO_OUT -> OUTPUT
PORTA &= ~SERVO_OUT; // SERVO_OUT -> LO
DDRA |= SERVO_OUT2; // SERVO_OUT -> OUTPUT
PORTA &= ~SERVO_OUT2; // SERVO_OUT -> LO
startStopwatch3(); // Needed for 20ms pulse repetition
}


void pulseSERVO(uint8_t position)
{
cli();
PORTA |= SERVO_OUT; // SERVO_OUT -> HI (pulse start)


delayCycles(800);
while (position--) {
delayCycles(4);
}
PORTA &= ~SERVO_OUT; // SERVO_OUT -> LO (pulse end)
sei();
}



void task_SERVO(void)
{
if (getStopwatch1() > 19) { // Pulse every ~20ms
pulseSERVO(POS_SERVO); // Servo pulse [1..2ms]

// ---------------------------------------------------------------------
/// ---------------------------------------------------------------------
setStopwatch3(0);
}
}



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

/**
* This function is called frequently out of the main loop and checks if
* Stopwatch1 has counted 250ms. If this is the case, decceleration is started
* and the Stopwatch is resetted and 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();
initSERVO();


// Set the RC5 Receive Handler:
IRCOMM_setRC5DataReadyHandler(receiveRC5Data);

//Output small usage instructions and the RC5 Codes:
writeString_P("\nYou can control your RP6 with the following RC5 Keycodes:");
writeString_P("\n-----------------------");
writeString_P("\n * Turn Left: "); writeInteger(RC5_KEY_LEFT, DEC);
writeString_P("\n * Turn Right: "); writeInteger(RC5_KEY_RIGHT, DEC);
writeString_P("\n * Move Forwards: "); writeInteger(RC5_KEY_FORWARDS, DEC);
writeString_P("\n * Move Backwards: "); writeInteger(RC5_KEY_BACKWARDS, DEC);
writeString_P("\n * Stop: "); writeInteger(RC5_KEY_STOP, DEC);
writeString_P("\n * Move curve left forwards: "); writeInteger(RC5_KEY_CURVE_LEFT, DEC);
writeString_P("\n * Move curve right forwards: "); writeInteger(RC5_KEY_CURVE_RIGHT, DEC);
writeString_P("\n * Move curve left backwards: "); writeInteger(RC5_KEY_CURVE_BACK_LEFT, DEC);
writeString_P("\n * Move curve right backwards: "); writeInteger(RC5_KEY_CURVE_BACK_RIGHT, DEC);
writeString_P("\n * Motor left forwards: "); writeInteger(RC5_KEY_LEFT_MOTOR_FWD, DEC);
writeString_P("\n * Motor left backwards: "); writeInteger(RC5_KEY_LEFT_MOTOR_BWD, DEC);
writeString_P("\n * Motor right forwards: "); writeInteger(RC5_KEY_RIGHT_MOTOR_FWD, DEC);
writeString_P("\n * Motor right backwards: "); writeInteger(RC5_KEY_RIGHT_MOTOR_BWD, DEC);
writeString_P("\n-----------------------\n");
writeString_P("To change the key mapping, read the comments in the program source code!\n");
writeString_P("_________\nPlease make sure that your IR Remote Control really transmits RC5 code!\n");

startStopwatch2();

// Main loop
while(true)
{
deccelerate(); // Call the deceleration function.
task_RP6System(); // Motion Control tasks etc.
task_SERVO();
}
return 0;
}

Biohazardry
15.02.2011, 18:28
HI,
nach ein bisschen durchforsten des Forums habe ich den Beitrag
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=40216&highlight=tv+remote
gefunden.

Jetzt habe ich das Programm verkleinert.

// Includes:

#include "RP6RobotBaseLib.h" // The RP6 Robot Base Library.
// Always needs to be included!

/************************************************** ***************************/
// Defines:

// RP6 Base Servo Connection:
#define SERVO_OUT ADC0 // PINC0 XBUS Pin 10
#define SERVO_OUT2 ADC1 // PINC0 XBUS Pin 10


// Servo movement limits (depending on servo type):
#define LEFT_TOUCH 800 // Left servo touch
#define RIGHT_TOUCH 254 // Right servo touch [max. 255]
#define PULSE_ADJUST 4
#define PULSE_REPETITION 19 // Pulse repetition frequency


#define RC5_KEY_LEFT 4
#define RC5_KEY_RIGHT 6


#define DIR_LEFT -1
#define DIR_RIGHT 1
#define DIR_NONE 0

int8_t direction = DIR_NONE;



/************************************************** ***************************/
// Functions:

/**
* INIT SERVO
*
* Call this once before using the servo task.
*
*/
void initSERVO(void)
{
DDRA |= SERVO_OUT; // SERVO_OUT -> OUTPUT
PORTA &= ~SERVO_OUT; // SERVO_OUT -> LO
DDRA |= SERVO_OUT2; // SERVO_OUT -> OUTPUT
PORTA &= ~SERVO_OUT2; // SERVO_OUT -> LO
startStopwatch1(); // 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();
PORTA |= SERVO_OUT; // SERVO_OUT -> HI (pulse start)
PORTA |= SERVO_OUT2; // SERVO_OUT -> HI (pulse start)

delayCycles(LEFT_TOUCH);
while (position--) {
delayCycles(PULSE_ADJUST);
}
PORTA &= ~SERVO_OUT; // SERVO_OUT -> LO (pulse end)
PORTA &= ~SERVO_OUT2; // SERVO_OUT -> LO (pulse end)
sei();
}


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');

if (rc5data.key_code == RC5_KEY_LEFT)
{
direction = DIR_LEFT;
}
else if (rc5data.key_code == RC5_KEY_RIGHT)
{
direction = DIR_RIGHT;
}
else
{
direction = DIR_NONE;
}
}

/**
* 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)
{static uint8_t pos;
if (getStopwatch1() > PULSE_REPETITION) { // Pulse every ~20ms
pulseSERVO(pos); // Servo pulse [1..2ms]
// ---------------------------------------------------------------------
// Your test code for positioning the servo here:
if (direction == DIR_LEFT){
setLEDs(0b111000);
pos+=5;
}
else if (direction == DIR_RIGHT){
setLEDs(0b000111);
pos-=5;
}
else{
pos = pos;
}
// ---------------------------------------------------------------------
setStopwatch1(0);
}
}

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

int main(void)
{
initRobotBase(); // Always call this first! The Processor will not work
// correctly otherwise.

// ---------------------------------------
// Write messages to the Serial Interface:
writeString_P("\n\n _______________________\n");
writeString_P(" \\| RP6 ROBOT SYSTEM |/\n");
writeString_P(" \\_-_-_-_-_-_-_-_-_-_/\n\n");

writeString_P("################\n");
writeString_P("<<RP6 Base>>\n");
writeString_P(" Servo - Test 1 \n");
writeString_P(" Version 1.00 \n");
writeString_P("################\n\n");
mSleep(2500);

setLEDs(0b111111); // Turn all LEDs on
mSleep(500); // delay 500ms
setLEDs(0b000000); // All LEDs off

powerON();
// Set the RC5 Receive Handler:
IRCOMM_setRC5DataReadyHandler(receiveRC5Data);

initSERVO();
startStopwatch2(); // Used for the demo task

while(true)
{
task_SERVO();
task_RP6System();



}
return 0;
}


So jetzt zum Problem:
Meines wissens sollte im Terminal doch wenigstens angezeigt werden welche Taste gedrückt worden ist.... tut es aber nicht...

Liegt es vll. daran, dass das task_Servo den Ablauf zu lange blockiert und somit keine Signale ausgewertet werden können??

Gruß Biohazard

Dirk
15.02.2011, 18:41
Liegt es vll. daran, dass das task_Servo den Ablauf zu lange blockiert und somit keine Signale ausgewertet werden können??
Ja, speziell ist es die blockierende Impulserzeugung in pulseSERVO().

Da die alle 20ms erfolgt, gelingt der IR-Empfang fast gar nicht mehr.
In der Original-Lib gibt es daher startSERVO() und stopSERVO(), um die Impulse eine Zeitlang unterbrechen zu können (z.B. für IR Empfang).

Gruß Dirk

Biohazardry
15.02.2011, 19:18
Hi danke für die schnelle Antwort wie setzte ich startSERVO() und stopSERVO() ein?

So?


void receiveRC5Data(RC5data_t rc5data){
stopSERVO()

.....
startSERVO()
}

oder



pulseSERVO(){
startSERVO()
....
stopSERVO()
}


Beide natürlich hier stark verienfacht beschrieben...

Gruß Biohazard

Dirk
15.02.2011, 22:04
Leider geht es so nicht.
Da der RC5-Empfang im Hintergrund erfolgt, kann man nur die Servofunktion mit stopSERVO ausschalten, wenn keine IR-Befehle für die Servos empfangen werden. Sobald ein Befehl für Servobewegungen empfangen wird, müßte man die Servofunktion mit startSERVO einschalten. Danach müßte sie wieder gestoppt werden, am besten zeitgesteuert (z.B. nach 200ms).

Gruß Dirk

Biohazardry
18.02.2011, 13:21
Hi so habe jetzt hinbekommen das ich RC5 empfangen kann und die Servos ansteuern.

(Noch laufen beide Servos synchron... aber das ist der kleinste Teil der Arbeit)

Gut jedoch läuft alles seeehr ruckelig... Außerdem erkennt er nicht einen jeden Tastendruck und manchmal bleiben die Servos einige Sekunden lang stehen ohne sich zu bewegen ....
Code:



#include "RP6BaseServoLib.h"


uint16_t pos = 0;



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');

switch(rc5data.key_code){
case 17:pos = pos-5;
break;
case 16:pos = pos+5;
break;
}

}


int main(void)
{
initRobotBase();

writeString_P("\n\n _______________________\n");
writeString_P(" \\| RP6 ROBOT SYSTEM |/\n");
writeString_P(" \\_-_-_-_-_-_-_-_-_-_/\n\n");

writeString_P("################\n");
writeString_P("<<RP6 Base>>\n");
writeString_P(" Servo - Test 1 \n");
writeString_P(" Version 1.20 \n");
writeString_P("################\n\n");
mSleep(2500);

setLEDs(0b111111);
mSleep(500);
powerON();
// Set the RC5 Receive Handler:
IRCOMM_setRC5DataReadyHandler(receiveRC5Data);

initSERVO(SERVO1 | SERVO2);

startStopwatch2();


while(true)
{

if (getStopwatch2() > 20) {
startSERVO();
servo1_position = pos;
servo2_position = pos;
setStopwatch2(0);

}


task_SERVO();
task_RP6System();stopSERVO();
}
return 0;
}
// THX 2 Dirk
// ------------------------------------------------------------------------------------------


Ideen? Verbesserungsvorschläge?

Gruß Biohazard

Biohazardry
23.02.2011, 18:13
So hab jetzt die Ansteuerung fertig und die Plattform gebaut....

Hier ist ein Video dazu:
http://www.youtube.com/watch?v=L-tGMaAt0vA

Btw: der Laser ist ziehmlich schwach---> Katzenungefährlich :-)

Xenergy
23.02.2011, 20:53
Cool :)
Sag mal: ist es ne Holzplatte im RP6 Design? :)

Biohazardry
23.02.2011, 21:17
Ja wieso nicht??

Ich bin Holztechniker, mein Vater ist Tischler und ich habe Zugriff auf eine komplett eingerichtete Tischlerei....

Die Sperrholzplatten sind sehr stabil und leicht zu bearbeiten... und sind nur 3mm stark.

Nur eine bemerkung am Rande: Fast jeder Schüler sitzt in der Schule auf so ner Sperrholzsitzfläche ;-)

Xenergy
23.02.2011, 22:21
Du, ich hab doch nichst dagegen gesagt:) Hab das sogar "Cool" gefunden:)

radbruch
23.02.2011, 23:17
Hallo

Sehr hübsch. Auch das Holz gefällt mir. Es liegt ja nahe genau das Material zu verwenden, das man auch bearbeiten kann.

ABER, das ist meiner Meinung nach nicht als Katzenspielzeug geeignet. Neben der Gefahr für die Augen, die ein für Menschen wohl ungefährlicher roter Laserpointer für die Augen eines Dämmerungsjägers wohl doch bestehen kann, wird die Katze mit zunehmender Spielzeit immer frustierter, weil sie den Laserpunkt nie fangen kann. Wenn schon mit ferngesteuertem Roboter, dann lieber mit einer "Katzenangel" anstelle des Lasers.

http://www.google.de/search?q=laserpointer+katzen+gefährlich

Gruß

mic

Biohazardry
24.02.2011, 12:30
Hmm werde mir in zukunft überlegen ob die Katzte in die nähe meiner Laser kommt...

Der Laser sollte die Augen (weder Katze noch Mensch) schädigen da seine Leistung unter 0,5mW liegt und keine gute Fokusierung vorhanden ist...
Aber trotzdem, der Katze zuliebe, werde ich wieder meine Rauleder-Handschuhe benutzen ;-)

Der Laser ist zurzeit nur eine Übungslösung ich möchte nämlich später dann mein Monsterlaser benutzen (>300mW) um Figuren in den Himmel zu malen.

fabqu
24.02.2011, 19:06
Nette Sache, deine Servosteuerung.
Aber mit Lasern in den Himmel... Wär ich vorsichtig, ist glaube ich verboten!?

Fabian

oberallgeier
24.02.2011, 19:19
... nur eine Übungslösung ... später ... Monsterlaser ... >300mW ... in den Himmel zu malen ...Aha - wann es so weit ist, erfahren wir ja dann auf alle Fälle aus dem Polizeibericht.

Biohazardry
24.02.2011, 22:00
Naja es ist nicht unbedingt verboten...
das Gesetz bestraft nur wenn der Laser ohne geschultes Personal und den geltenden Sicherheitsrichtlinien in betrieb genommen worden ist.
Außerdem Strafbar ist das blenden von Flugzeugen während Start/Landung...

So siehts rechtlich aus... sonst währen ja die schönen Lasershows verboten...

Morpheus1997
27.03.2011, 20:34
hm... woher kommt
#include "RP6BaseServoLib.h"
??

Biohazardry
28.03.2011, 16:22
hm... woher kommt
#include "RP6BaseServoLib.h"
??
ist von Dirks steuerung von https://www.roboternetz.de/community/showthread.php?40052-RP6Base-Library-f%FCr-8-Servos&highlight=servo
Gruß Biohazard