Adleo
28.12.2009, 13:15
Hallo,
ich habe zu Weihnachten einen RP6 bekommen und bis jetzt bin ich dank des Forums und der tollen Bedienungsanleitung immer weitergekommen (alle vor mir hatten die Probleme auch schon). Nun muss ich selbst eine Frage stellen:
Ich will meine M32 als Master und die Base als Slave verwenden, allerdings soll der Master nur ab und zu eingreifen, sonst soll die Base eine State Machine ausführen! Ich habe es probiert, aber es hat nicht geklappt.
Mein Master-Code:
#include "RP6ControlLib.h"
#include "RP6I2CmasterTWI.h"
#define status_start 0
#define status_fahren 1 // Vorwärtsfahrt mit Überprüfung...
#define status_BWD 2
#define status_bemerkt_links 3
#define status_bemerkt_rechts 4
#define status_bemerkt_beide 5
#define status_KurveR 6
#define status_KurveL 7
#define status_STOP 8
#define state_master 2
void BaseMotorStart(void)
{
if (!I2CTWI_isBusy())
{
I2CTWI_transmit2Bytes(10, 1, 0); //status_start in 1 an 10
I2CTWI_transmit2Bytes(10, 0, 2); //state_master in 0 an 10
}
}
void BaseMotorStop(void)
{
if (!I2CTWI_isBusy())
{
I2CTWI_transmit2Bytes(10, 1, status_STOP);
I2CTWI_transmit2Bytes(10, 0, 2);
}
}
int main(void)
{
initRP6Control();
initLCD();
I2CTWI_initMaster(100); // TWI initialisieren und Frequenz 100 einstellen
uint8_t anzeige=1;
uint8_t Batterie;
uint8_t key_abfrage=0;
uint8_t movestate;
uint8_t AusA;
while(true){
if(anzeige){
clearLCD();
showScreenLCD("Drucke einen","Taster!!!!!!!!!!");
anzeige=0;
}
key_abfrage=0;
key_abfrage=getPressedKeyNumber();
if (key_abfrage != 0){
anzeige=1;
sound(180,80,25);
sound(220,80,0);
switch(key_abfrage){
case 1:
if(!I2CTWI_isBusy()){
I2CTWI_transmitByte(10,2);
movestate=I2CTWI_readByte(10);
}
clearLCD;
showScreenLCD("move_state:","");
setCursorPosLCD(1,1);
writeIntegerLengthLCD(movestate, DEC, 1);
mSleep(2000);
break;
case 2:
if(!I2CTWI_isBusy()){
I2CTWI_transmitByte(10,3);
AusA=I2CTWI_readByte(10);
}
clearLCD;
showScreenLCD("Aus:","");
setCursorPosLCD(1,1);
writeIntegerLengthLCD(AusA, DEC, 1);
mSleep(2000);
break;
case 3:
clearLCD();
showScreenLCD("Batterie: ","ist das OK?");
setCursorPosLCD(0, 10);
if (!I2CTWI_isBusy())
{
I2CTWI_transmitByte(10, 1);
Batterie = I2CTWI_readByte(10); //Batterie auslesen
}
writeIntegerLengthLCD(Batterie, DEC, 4);
mSleep(2000);
break;
case 4:
clearLCD();
showScreenLCD("Warnung! Der","Motor ist an!");
BaseMotorStart(); //Motor starten
clearLCD();
showScreenLCD("Motor lauft!","!!!!!!!!!!!!!!!!");
mSleep(2000);
break;
case 5:
BaseMotorStop();
clearLCD();
showScreenLCD("Motor wird","angehalten!!!!!!");
mSleep(2000);
break;
}
} }
return 0;
}
Mein Slave:
#include "RP6RobotBaseLib.h"
#include "RP6I2CslaveTWI.h"
#define status_start 0
#define status_fahren 1 // Vorwärtsfahrt mit Überprüfung...
#define status_BWD 2
#define status_bemerkt_links 3
#define status_bemerkt_rechts 4
#define status_bemerkt_beide 5
#define status_KurveR 6
#define status_KurveL 7
#define status_STOP 8
#define status_master 9
#define RC5_links 21 //Fernbeninungssteuerung...
#define RC5_rechts 22
#define RC5_FWD 32
#define RC5_BWD 33
#define RC5_STOP 13
#define RC5_speed_plus 14
#define RC5_speed_minus 35
#define RC5_winkel_plus 16
#define RC5_winkel_minus 17
#define RC5_90grad 55
#define RC5_180grad 54
#define RC5_150speed 50
#define RC5_80speed 52
#define RC5_Aus 12
#define RC5_ACS_Aus 63
#define RC5_ACS_An 56
#define RC5_korrigieren_R 18
#define RC5_korrigieren_L 48
#define RC5_drehenR 34
#define RC5_drehenL 0
#define master_status 2
uint8_t move_state; // Speicher für die aktuelle Fahrsituation
uint8_t RC5_state; //Speicher für RC5Kommandos
uint16_t Spann;
uint8_t speed=150;
uint8_t winkel=90;
uint8_t Aus=1;
uint8_t AC_System=0;
uint8_t param1;
void masterabfrage(void)
{
task_RP6System();
if(I2CTWI_writeRegisters[0] && !I2CTWI_writeBusy){
uint8_t cmd = I2CTWI_writeRegisters[0];
I2CTWI_writeRegisters[0] = 0;
switch(cmd){
case master_status:
param1=I2CTWI_writeRegisters[1];
move_state=param1;
break;
}
}
I2CTWI_readRegisters[1]=readADC(ADC_BAT);
I2CTWI_readRegisters[2]=move_state;
I2CTWI_readRegisters[3]=Aus;
}
void receiveRC5Data(RC5data_t rc5data)
{
switch (rc5data.key_code)
{
case RC5_rechts:
setLEDs(0b000111);
move_state=status_bemerkt_rechts;
break;
case RC5_links:
setLEDs(0b111000);
move_state=status_bemerkt_links;
break;
case RC5_BWD:
setLEDs(0b100001);
move_state=status_BWD;
break;
case RC5_FWD:
setMotorDir(FWD, FWD);
moveAtSpeed(speed,speed);
move_state=status_fahren;
break;
case RC5_STOP:
setLEDs(0b111111);
moveAtSpeed(0,0);
break;
case RC5_speed_plus:
setLEDs(0b100000);
speed=speed+10;
break;
case RC5_speed_minus:
setLEDs(0b000001);
speed=speed-10;
break;
case RC5_winkel_plus:
setLEDs(0b010000);
winkel=winkel+10;
break;
case RC5_winkel_minus:
setLEDs(0b000010);
winkel=winkel-10;
break;
case RC5_90grad:
winkel=90;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_180grad:
winkel=180;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_150speed:
speed=150;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_80speed:
speed=80;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_Aus: //AN/AUS gedrück!
if (Aus) {moveAtSpeed(0,0);Aus=0;} else {Aus=1;}
break;
case RC5_ACS_Aus:
AC_System=0;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_ACS_An:
AC_System=1;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_korrigieren_R:
move_state=status_KurveL;
break;
case RC5_korrigieren_L:
move_state=status_KurveR;
break;
case RC5_drehenR:
setMotorDir(FWD,BWD);
move_state=status_fahren;
break;
case RC5_drehenL:
setMotorDir(BWD,FWD);
move_state=status_fahren;
break;
}
}
void acsStateChanged(void)
{
if (AC_System) {
if(obstacle_left)
move_state=status_bemerkt_rechts;
if(obstacle_right)
move_state=status_bemerkt_links;
if(obstacle_right && obstacle_left)
move_state=status_bemerkt_beide;
// -----------------------------------------------------------
// Set LEDs
if(obstacle_left && obstacle_right) // Obstacle in the middle?
statusLEDs.byte = 0b100100;
else
statusLEDs.byte = 0b000000;
statusLEDs.LED5 = obstacle_left;
statusLEDs.LED4 = (!obstacle_left); // Inverted LED5!
statusLEDs.LED2 = obstacle_right;
statusLEDs.LED1 = (!obstacle_right); // Inverted LED2!
// Update the LED values:
updateStatusLEDs(); // The LEDs are turned on/off here! __Not__ in the lines above!
}
}
void bumpersStateChanged(void)
{
if(bumper_left)
move_state=status_bemerkt_rechts;
if(bumper_right)
move_state=status_bemerkt_links;
if(bumper_left && bumper_right)
move_state=status_bemerkt_beide;
}
/*void blink(void)
{
while(true) {
setLEDs(0b111111);
mSleep(500);
setLEDs(0);
mSleep(500);
}
}*/
/************************************************** ***************************/
// Main - The program starts here:
int main(void)
{
initRobotBase(); //roboter einbinden
I2CTWI_initSlave(10); //als Slave10 registrieren!
setLEDs(0b111111);
mSleep(1000);
setLEDs(0b001001);
move_state=status_master;
powerON(); //Verletzungsgefahr!
speed=150;
// Register Event Handlers:
ACS_setStateChangedHandler(acsStateChanged); //ACS HAndler
BUMPERS_setStateChangedHandler(bumpersStateChanged ); //Bumper HAndler
IRCOMM_setRC5DataReadyHandler(receiveRC5Data); //RC5 Handler
setACSPwrMed(); // Aktivieren des ACS in Medium
Spann=readADC(ADC_BAT);
while(true) //Wiederholen bis Akku leer
{
task_motionControl();
switch (move_state) // ist move_state...
{
case status_start:
setLEDs(0b011011);
if(Aus){setMotorDir(FWD, FWD); moveAtSpeed(speed,speed);}
move_state=status_fahren;
break;
case status_fahren:
task_motionControl();
setLEDs(0b001001);
Spann=readADC(ADC_BAT);
if (Spann<6.5) {
moveAtSpeed(0,0);
//blink();
}
do
masterabfrage();
//Nach ACS und Bumpern und RC5 suchen... (in Master-Abfrage)
while (move_state==status_fahren);// ...bis sich etwas geändert hat! (das gleiche wie: solange status_fahren)
break;
case status_bemerkt_links:
mSleep(500);
setLEDs(0b100000);
if(Aus){rotate(speed,LEFT,winkel,1);} // ...nicht wenn AN/AUS gedrückt
move_state=status_start;
break;
case status_bemerkt_rechts:
setLEDs(0b000010);
if(Aus){rotate(speed,RIGHT,winkel,1);} // ...nicht wenn AN/AUS gedrückt
move_state=status_start;
break;
case status_bemerkt_beide:
setLEDs(0b010010);
if(Aus){rotate(speed,RIGHT,winkel,1);} // ...nicht wenn AN/AUS gedrückt
move_state=status_start;
break;
case status_BWD:
setLEDs(0b011011);
if(Aus){setMotorDir(BWD, BWD); moveAtSpeed(speed,speed);}
move_state=status_fahren;
break;
case status_KurveR:
setLEDs(0b000111);
moveAtSpeed(speed-50, speed);
do
//Nach ACS und Bumpern und RC5 suchen...
masterabfrage();
while (move_state==status_KurveR);
break;
case status_KurveL:
setLEDs(0b000111);
moveAtSpeed(speed, speed-50);
do
//Nach ACS und Bumpern und RC5 suchen...
masterabfrage();
while (move_state==status_KurveL);
break;
case status_STOP:
moveAtSpeed(0,0);
move_state=status_fahren;
break;
case status_master:
setLEDs(0b111000);
do
masterabfrage();
while(move_state==status_master);
break;
}
}
return 0;
}
Ich verzweifle! Wieso funktioniert das nicht! ](*,)
Das Auslesen der Register funktioniert prima. Aber wenn ich der State-Maschine auf dem Slave durch den Master den Befehl gebe ihren Status zu ändern, reagiert sie nicht.
Meine RC5-Fernbedienung funktioniert leider auch nicht mehr, sobald die Base als Slave initiiert wurde...
Ich hoffe mir kann jemand helfen.
Viele Grüsse an Alle
Adleo
ich habe zu Weihnachten einen RP6 bekommen und bis jetzt bin ich dank des Forums und der tollen Bedienungsanleitung immer weitergekommen (alle vor mir hatten die Probleme auch schon). Nun muss ich selbst eine Frage stellen:
Ich will meine M32 als Master und die Base als Slave verwenden, allerdings soll der Master nur ab und zu eingreifen, sonst soll die Base eine State Machine ausführen! Ich habe es probiert, aber es hat nicht geklappt.
Mein Master-Code:
#include "RP6ControlLib.h"
#include "RP6I2CmasterTWI.h"
#define status_start 0
#define status_fahren 1 // Vorwärtsfahrt mit Überprüfung...
#define status_BWD 2
#define status_bemerkt_links 3
#define status_bemerkt_rechts 4
#define status_bemerkt_beide 5
#define status_KurveR 6
#define status_KurveL 7
#define status_STOP 8
#define state_master 2
void BaseMotorStart(void)
{
if (!I2CTWI_isBusy())
{
I2CTWI_transmit2Bytes(10, 1, 0); //status_start in 1 an 10
I2CTWI_transmit2Bytes(10, 0, 2); //state_master in 0 an 10
}
}
void BaseMotorStop(void)
{
if (!I2CTWI_isBusy())
{
I2CTWI_transmit2Bytes(10, 1, status_STOP);
I2CTWI_transmit2Bytes(10, 0, 2);
}
}
int main(void)
{
initRP6Control();
initLCD();
I2CTWI_initMaster(100); // TWI initialisieren und Frequenz 100 einstellen
uint8_t anzeige=1;
uint8_t Batterie;
uint8_t key_abfrage=0;
uint8_t movestate;
uint8_t AusA;
while(true){
if(anzeige){
clearLCD();
showScreenLCD("Drucke einen","Taster!!!!!!!!!!");
anzeige=0;
}
key_abfrage=0;
key_abfrage=getPressedKeyNumber();
if (key_abfrage != 0){
anzeige=1;
sound(180,80,25);
sound(220,80,0);
switch(key_abfrage){
case 1:
if(!I2CTWI_isBusy()){
I2CTWI_transmitByte(10,2);
movestate=I2CTWI_readByte(10);
}
clearLCD;
showScreenLCD("move_state:","");
setCursorPosLCD(1,1);
writeIntegerLengthLCD(movestate, DEC, 1);
mSleep(2000);
break;
case 2:
if(!I2CTWI_isBusy()){
I2CTWI_transmitByte(10,3);
AusA=I2CTWI_readByte(10);
}
clearLCD;
showScreenLCD("Aus:","");
setCursorPosLCD(1,1);
writeIntegerLengthLCD(AusA, DEC, 1);
mSleep(2000);
break;
case 3:
clearLCD();
showScreenLCD("Batterie: ","ist das OK?");
setCursorPosLCD(0, 10);
if (!I2CTWI_isBusy())
{
I2CTWI_transmitByte(10, 1);
Batterie = I2CTWI_readByte(10); //Batterie auslesen
}
writeIntegerLengthLCD(Batterie, DEC, 4);
mSleep(2000);
break;
case 4:
clearLCD();
showScreenLCD("Warnung! Der","Motor ist an!");
BaseMotorStart(); //Motor starten
clearLCD();
showScreenLCD("Motor lauft!","!!!!!!!!!!!!!!!!");
mSleep(2000);
break;
case 5:
BaseMotorStop();
clearLCD();
showScreenLCD("Motor wird","angehalten!!!!!!");
mSleep(2000);
break;
}
} }
return 0;
}
Mein Slave:
#include "RP6RobotBaseLib.h"
#include "RP6I2CslaveTWI.h"
#define status_start 0
#define status_fahren 1 // Vorwärtsfahrt mit Überprüfung...
#define status_BWD 2
#define status_bemerkt_links 3
#define status_bemerkt_rechts 4
#define status_bemerkt_beide 5
#define status_KurveR 6
#define status_KurveL 7
#define status_STOP 8
#define status_master 9
#define RC5_links 21 //Fernbeninungssteuerung...
#define RC5_rechts 22
#define RC5_FWD 32
#define RC5_BWD 33
#define RC5_STOP 13
#define RC5_speed_plus 14
#define RC5_speed_minus 35
#define RC5_winkel_plus 16
#define RC5_winkel_minus 17
#define RC5_90grad 55
#define RC5_180grad 54
#define RC5_150speed 50
#define RC5_80speed 52
#define RC5_Aus 12
#define RC5_ACS_Aus 63
#define RC5_ACS_An 56
#define RC5_korrigieren_R 18
#define RC5_korrigieren_L 48
#define RC5_drehenR 34
#define RC5_drehenL 0
#define master_status 2
uint8_t move_state; // Speicher für die aktuelle Fahrsituation
uint8_t RC5_state; //Speicher für RC5Kommandos
uint16_t Spann;
uint8_t speed=150;
uint8_t winkel=90;
uint8_t Aus=1;
uint8_t AC_System=0;
uint8_t param1;
void masterabfrage(void)
{
task_RP6System();
if(I2CTWI_writeRegisters[0] && !I2CTWI_writeBusy){
uint8_t cmd = I2CTWI_writeRegisters[0];
I2CTWI_writeRegisters[0] = 0;
switch(cmd){
case master_status:
param1=I2CTWI_writeRegisters[1];
move_state=param1;
break;
}
}
I2CTWI_readRegisters[1]=readADC(ADC_BAT);
I2CTWI_readRegisters[2]=move_state;
I2CTWI_readRegisters[3]=Aus;
}
void receiveRC5Data(RC5data_t rc5data)
{
switch (rc5data.key_code)
{
case RC5_rechts:
setLEDs(0b000111);
move_state=status_bemerkt_rechts;
break;
case RC5_links:
setLEDs(0b111000);
move_state=status_bemerkt_links;
break;
case RC5_BWD:
setLEDs(0b100001);
move_state=status_BWD;
break;
case RC5_FWD:
setMotorDir(FWD, FWD);
moveAtSpeed(speed,speed);
move_state=status_fahren;
break;
case RC5_STOP:
setLEDs(0b111111);
moveAtSpeed(0,0);
break;
case RC5_speed_plus:
setLEDs(0b100000);
speed=speed+10;
break;
case RC5_speed_minus:
setLEDs(0b000001);
speed=speed-10;
break;
case RC5_winkel_plus:
setLEDs(0b010000);
winkel=winkel+10;
break;
case RC5_winkel_minus:
setLEDs(0b000010);
winkel=winkel-10;
break;
case RC5_90grad:
winkel=90;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_180grad:
winkel=180;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_150speed:
speed=150;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_80speed:
speed=80;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_Aus: //AN/AUS gedrück!
if (Aus) {moveAtSpeed(0,0);Aus=0;} else {Aus=1;}
break;
case RC5_ACS_Aus:
AC_System=0;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_ACS_An:
AC_System=1;
setLEDs(0b111111);
mSleep(1000);
setLEDs(0);
break;
case RC5_korrigieren_R:
move_state=status_KurveL;
break;
case RC5_korrigieren_L:
move_state=status_KurveR;
break;
case RC5_drehenR:
setMotorDir(FWD,BWD);
move_state=status_fahren;
break;
case RC5_drehenL:
setMotorDir(BWD,FWD);
move_state=status_fahren;
break;
}
}
void acsStateChanged(void)
{
if (AC_System) {
if(obstacle_left)
move_state=status_bemerkt_rechts;
if(obstacle_right)
move_state=status_bemerkt_links;
if(obstacle_right && obstacle_left)
move_state=status_bemerkt_beide;
// -----------------------------------------------------------
// Set LEDs
if(obstacle_left && obstacle_right) // Obstacle in the middle?
statusLEDs.byte = 0b100100;
else
statusLEDs.byte = 0b000000;
statusLEDs.LED5 = obstacle_left;
statusLEDs.LED4 = (!obstacle_left); // Inverted LED5!
statusLEDs.LED2 = obstacle_right;
statusLEDs.LED1 = (!obstacle_right); // Inverted LED2!
// Update the LED values:
updateStatusLEDs(); // The LEDs are turned on/off here! __Not__ in the lines above!
}
}
void bumpersStateChanged(void)
{
if(bumper_left)
move_state=status_bemerkt_rechts;
if(bumper_right)
move_state=status_bemerkt_links;
if(bumper_left && bumper_right)
move_state=status_bemerkt_beide;
}
/*void blink(void)
{
while(true) {
setLEDs(0b111111);
mSleep(500);
setLEDs(0);
mSleep(500);
}
}*/
/************************************************** ***************************/
// Main - The program starts here:
int main(void)
{
initRobotBase(); //roboter einbinden
I2CTWI_initSlave(10); //als Slave10 registrieren!
setLEDs(0b111111);
mSleep(1000);
setLEDs(0b001001);
move_state=status_master;
powerON(); //Verletzungsgefahr!
speed=150;
// Register Event Handlers:
ACS_setStateChangedHandler(acsStateChanged); //ACS HAndler
BUMPERS_setStateChangedHandler(bumpersStateChanged ); //Bumper HAndler
IRCOMM_setRC5DataReadyHandler(receiveRC5Data); //RC5 Handler
setACSPwrMed(); // Aktivieren des ACS in Medium
Spann=readADC(ADC_BAT);
while(true) //Wiederholen bis Akku leer
{
task_motionControl();
switch (move_state) // ist move_state...
{
case status_start:
setLEDs(0b011011);
if(Aus){setMotorDir(FWD, FWD); moveAtSpeed(speed,speed);}
move_state=status_fahren;
break;
case status_fahren:
task_motionControl();
setLEDs(0b001001);
Spann=readADC(ADC_BAT);
if (Spann<6.5) {
moveAtSpeed(0,0);
//blink();
}
do
masterabfrage();
//Nach ACS und Bumpern und RC5 suchen... (in Master-Abfrage)
while (move_state==status_fahren);// ...bis sich etwas geändert hat! (das gleiche wie: solange status_fahren)
break;
case status_bemerkt_links:
mSleep(500);
setLEDs(0b100000);
if(Aus){rotate(speed,LEFT,winkel,1);} // ...nicht wenn AN/AUS gedrückt
move_state=status_start;
break;
case status_bemerkt_rechts:
setLEDs(0b000010);
if(Aus){rotate(speed,RIGHT,winkel,1);} // ...nicht wenn AN/AUS gedrückt
move_state=status_start;
break;
case status_bemerkt_beide:
setLEDs(0b010010);
if(Aus){rotate(speed,RIGHT,winkel,1);} // ...nicht wenn AN/AUS gedrückt
move_state=status_start;
break;
case status_BWD:
setLEDs(0b011011);
if(Aus){setMotorDir(BWD, BWD); moveAtSpeed(speed,speed);}
move_state=status_fahren;
break;
case status_KurveR:
setLEDs(0b000111);
moveAtSpeed(speed-50, speed);
do
//Nach ACS und Bumpern und RC5 suchen...
masterabfrage();
while (move_state==status_KurveR);
break;
case status_KurveL:
setLEDs(0b000111);
moveAtSpeed(speed, speed-50);
do
//Nach ACS und Bumpern und RC5 suchen...
masterabfrage();
while (move_state==status_KurveL);
break;
case status_STOP:
moveAtSpeed(0,0);
move_state=status_fahren;
break;
case status_master:
setLEDs(0b111000);
do
masterabfrage();
while(move_state==status_master);
break;
}
}
return 0;
}
Ich verzweifle! Wieso funktioniert das nicht! ](*,)
Das Auslesen der Register funktioniert prima. Aber wenn ich der State-Maschine auf dem Slave durch den Master den Befehl gebe ihren Status zu ändern, reagiert sie nicht.
Meine RC5-Fernbedienung funktioniert leider auch nicht mehr, sobald die Base als Slave initiiert wurde...
Ich hoffe mir kann jemand helfen.
Viele Grüsse an Alle
Adleo