Stimmt, da hab ich mich wohl vertippt...
atoi: string to integer
itoa: integer to string
Druckbare Version
Stimmt, da hab ich mich wohl vertippt...
atoi: string to integer
itoa: integer to string
Hi noch mal,
habe nun den ersten Teil mal soweit zusammen.
Würde sich jemand mit mehr Sachverstand den bisherigen Code mal ansehen? Es ist im Prinzip das Beispiel 12 der M256. Ich habe in der Main.c nur die beiden Funktion "void behaviour_wifiControl(void)" verändert und eine Funktion "int cmdsplit(void)" hinzugefügt.
Keine Fehler beim Kompilieren, nur die Warnung "RP6M256_12_WIFI_REMOTE_2.c:487: warning: 'x' may be used uninitialized in this function".
Meine Fragen:
Klappt das so?? :D
und in der Funktion "int cmdsplit(void)" habe ich anstelle der "normalen" str_fill einfach eine for-Schleife gelegt. Klappt das so???
Und wenn ich den atoi-Aufruf mache, ist mein Array "tmp" mit einigen Ziffern besetzt, der Rest wurde vorher mit "x" aufgefüllt. Sieht also z.B. so aus (für 10 Einträge) : |#|3| : |2| : |5|0|*|x|x|, wenn der gesendete String dieser war: #3:2:50*
Wird das dann richtig übernommen? Das resultierende Array params sollte danach so aussehen: |3|2|50|.
Danke schon einmal! Möchte erst einen Sachkundigen Rat hören, bevor ich daran weiterbastle. Sonst wird das debugging später etwas schwer für mich.
In die untere Funktion kommt dann noch ein Funktionsaufruf für das Bearbeiten dieses gesplitteten Strings.
Hier der Code:
EDIT: Nun, was ich möchte, ist eine Remote wie die von FabianE., gepaart mit den Cruise- und Avoid-Funktionen des Beispiels 12. Nur zur Info ;)Code://This Funktion splits the incoming String. This String looks like: #1:30:50:0:13*.
// "#" = Begin of Command
// "*" = End of Command
// "1" is for "driving"
// "30" ist for left engine, "50" ist for right engine -> driving a curve
// "0" is for "driving forwards"
// "13" is just an increasing number, increased after every command
#define MAX_PARAMS 6
int params[MAX_PARAMS];
int cmdsplit(void)
{
int cursor;
cursor=0;
int param_nr;
param_nr =0;
// Parameterarray initialisieren
int i;
for (i=0;i<MAX_PARAMS;i++)
params[i] = -1;
/* Prüfen ob der command-string gültig beginnt */
if ((receiveBuffer_WIFI[cursor] != '#'))
return -1;
while (receiveBuffer_WIFI[cursor] != '\0' && receiveBuffer_WIFI[cursor] != '*') // prüfen ob das ende erreicht wurde
{
char tmp[10];
char x;
for (i=0;i<10;i++)
tmp[i] = x;
//Str_Fill(tmp,'x',10);//!!!!!!!!!!!!!!!!!!!
cursor++;
int j;
j= 0;
while(receiveBuffer_WIFI[cursor] != ':' && receiveBuffer_WIFI[cursor] != '*')
{
tmp[j] = receiveBuffer_WIFI[cursor];
cursor++;
j++;
}
params[param_nr] = atoi(tmp); // wert auslesen
if (param_nr >= MAX_PARAMS) // sind mehr parameter verfügbar als erwartet? Stimmt was mit dem Commando nicht...
return -1;
param_nr++;
// Überspingen der ausgelesen Zeichen und ermitteln des nächsten "interessanten" Teils im string.
while((receiveBuffer_WIFI[cursor] != ':') && (receiveBuffer_WIFI[cursor] != '*') && (receiveBuffer_WIFI[cursor] != '\0'))
cursor++;
}
return param_nr;
}
/**
* This behaviour allows to remotely control the Robot with Text commands that
* are sent over a WIFI connection (with a small modification also via standard serial interface).
*
* It basically receives a text line (with \r or \n or both at the end) and checks if
* it is a command or a number. If it is a number it sets the speed of the motors.
*
* This behaviour first waits to be activated, then it surpresses all other behaviours
* (except for the low battery behaviour).
*
*/
void behaviour_wifiControl(void)
{
static uint8_t speedl = 0;
static uint8_t speedr = 0;
switch(wifiControl.state)
{
case IDLE:
if(getInputLine_WIFI())
{
if(strcmp(receiveBuffer_WIFI,"cmd")==0 || strcmp(receiveBuffer_WIFI,"command")==0)
{
writeString_P_WIFI("\nWIFI COMMAND MODE ACTIVE\n");
wifiControl.state = WIFI_ACTIVE;
break;
}
else if(!behaviour_command_interpreter()) // Call behaviour control interpreter code
writeString_P_WIFI("\nYou must enter cmd or command to enable command mode!\n");
}
break;
case WIFI_ACTIVE:
if(getInputLine_WIFI())
{
if(strcmp(receiveBuffer_WIFI,"z")==0 || strcmp(receiveBuffer_WIFI,"quit")==0)
{
writeString_P_WIFI("\nWIFI COMMAND MODE EXIT!\n");
wifiControl.state = IDLE;
}
else if( strcmp(receiveBuffer_WIFI,"fwd")==0 || strcmp(receiveBuffer_WIFI,"f")==0 || strcmp(receiveBuffer_WIFI,"w")==0)
{
wifiControl.speed_left = speedl;
wifiControl.speed_right = speedr;
writeString_P_WIFI("\nFWD!\n");
wifiControl.dir = FWD;
}
else if(strcmp(receiveBuffer_WIFI,"bwd")==0 || strcmp(receiveBuffer_WIFI,"b")==0 || strcmp(receiveBuffer_WIFI,"s")==0)
{
wifiControl.speed_left = speedl;
wifiControl.speed_right = speedr;
writeString_P_WIFI("\nBWD!\n");
wifiControl.dir = BWD;
}
else if(strcmp(receiveBuffer_WIFI,"left")==0 || strcmp(receiveBuffer_WIFI,"l")==0 || strcmp(receiveBuffer_WIFI,"a")==0)
{
if(speedl/2 >= 30)
{
wifiControl.speed_left = speedl / 2;
wifiControl.speed_right = speedr / 2;
}
else if(speedl > 10)
{
wifiControl.speed_left = 30;
wifiControl.speed_right = 30;
}
writeString_P_WIFI("\nLEFT!\n");
wifiControl.dir = LEFT;
}
else if(strcmp(receiveBuffer_WIFI,"right")==0 || strcmp(receiveBuffer_WIFI,"r")==0 || strcmp(receiveBuffer_WIFI,"d")==0)
{
if(speedl/2 >= 30)
{
wifiControl.speed_left = speedl / 2;
wifiControl.speed_right = speedr / 2;
}
else if(speedl > 10)
{
wifiControl.speed_left = 30;
wifiControl.speed_right = 30;
}
writeString_P_WIFI("\nRIGHT!\n");
wifiControl.dir = RIGHT;
}
else if(strcmp(receiveBuffer_WIFI,"fl")==0 || strcmp(receiveBuffer_WIFI,"q")==0)
{
if(speedl/2 >= 30)
{
wifiControl.speed_left = speedl / 2;
wifiControl.speed_right = speedr;
}
else if(speedl > 10)
{
wifiControl.speed_left = 20;
wifiControl.speed_right = 40;
}
writeString_P_WIFI("\nCURVE FWD LEFT!\n");
wifiControl.dir = FWD;
}
else if(strcmp(receiveBuffer_WIFI,"fr")==0 || strcmp(receiveBuffer_WIFI,"e")==0)
{
if(speedr/2 >= 30)
{
wifiControl.speed_left = speedl;
wifiControl.speed_right = speedr / 2;
}
else if(speedr > 10)
{
wifiControl.speed_left = 40;
wifiControl.speed_right = 20;
}
writeString_P_WIFI("\nCURVE FWD LEFT!\n");
wifiControl.dir = FWD;
}
else if(strcmp(receiveBuffer_WIFI,"stp")==0 || strcmp(receiveBuffer_WIFI,"x")==0)
{
writeString_P_WIFI("\nSTOP!\n");
wifiControl.dir = FWD;
wifiControl.speed_left = 0;
wifiControl.speed_right = 0;
}
else if(!behaviour_command_interpreter()) // Call behaviour control interpreter code
{
cmdsplit();
/*uint8_t pwm_tmp = atoi(receiveBuffer_WIFI);
if(pwm_tmp == 0)
{
uint8_t not_a_number = 0;
int8_t i;
for(i = strlen(receiveBuffer_WIFI)-1; i >= 0 ; i--)
if((receiveBuffer_WIFI[i] < '0') || (receiveBuffer_WIFI[i] > '9'))
{
not_a_number = 1;
writeString_P_WIFI("\n### NOT A NUMBER! ###\n");
}
if(not_a_number) {
pwm_tmp = speedl;
break;
}
}
else if(pwm_tmp > 160){pwm_tmp = 160; writeString_P("\n--> Power limited to 160!");}
else if(pwm_tmp < 0) {pwm_tmp = 0;}
writeString_P_WIFI("\n--> Change speed to:");
writeInteger_WIFI(pwm_tmp,DEC);
writeChar_WIFI('\n');
wifiControl.speed_left = pwm_tmp;
wifiControl.speed_right = pwm_tmp;
speedl = pwm_tmp;
speedr = pwm_tmp;*/
}
}
break;
case WIFI_EXECUTE_CMD:
wifiControl.state = WIFI_ACTIVE;
break;
default:
wifiControl.state = IDLE;
break;
}
}
Hmmm... Ich lasse mir nun das fertige Array zusenden und versuche es auch gleich zu verarbeiten.
Das Zurücksenden klappt super, aber der Befehl wird nicht ausgeführt... ???
Hier die Ausgabe, wenn ich die zwei momentan möglichen Befehle 1 (fahren) und 7 (stoppen) sende:
("1" erwartet dann natürlich noch die Geschwindigkeiten der rechten und linken Kette und die Fahrtrichtung)
Der Code, den ich zu der Funktion aus dem letzten Beitrag hinzugefügt habe:Code:WIFI COMMAND MODE ACTIVE
#7:2*
Params:7|2|-1|-1|-1|-1
#1:20:20:0:4*
Params:1|20|20|0|4|-1
Code:#define CMD_SET_SPEED 1
#define CMD_SET_STOP 7
...
else if(!behaviour_command_interpreter()) // Call behaviour control interpreter code
{
cmdsplit();
switch(params[0])
{
case CMD_SET_SPEED:
moveAtSpeed(params[1],params[2]);
changeDirection(params[3]);
break;
case CMD_SET_STOP:
stop();
break;
}
//Hier wird mal getestet, ob auch alles richtig im params-Array drinnen steht:
writeString_P_WIFI("\nParams:");writeInteger_WIFI(params[0],DEC);
writeString_P_WIFI("|");writeInteger_WIFI(params[1],DEC);
writeString_P_WIFI("|");writeInteger_WIFI(params[2],DEC);
writeString_P_WIFI("|");writeInteger_WIFI(params[3],DEC);
writeString_P_WIFI("|");writeInteger_WIFI(params[4],DEC);
writeString_P_WIFI("|");writeInteger_WIFI(params[5],DEC);
writeString_P_WIFI("\n");
}
Scheinbar lag der Befehl "moveAtSpeed" mit den anderen in diesem Example verwendeten Befehlen "wifiControl.dir", "wifiControl.speed_left" und "wifiControl.speed_right" im Streit... Habe das nun geändert und es funktioniert :D
Ich hoffe, ich habe bis zum Wochenende eine halbwegs akzeptable Fernbedienung auf die Beine gestellt.
Grüße
Mein Projekt nimmt langsam Gestalt an!
Ich habs mal in meinen alten Thread rein.
Grüße
@Max Web und fabqu:
Eure Bedienoberflächen sehen wirklich schon sehr sehr schick aus!
Weiter so! :)
MfG,
SlyD
Danke dir, wird schon!
Das neue LabVIEW 2011 und auch 2012 sind nicht mehr ganz so eckig und kantig und Windows-98-mäßig :D
Jetzt kann sich das auch mal sehen lassen.
Hallo zusammen,
ich habe heute versucht, die M32 Platine von der M256 aus er I2C anzusprechen. Dabei habe ich gemerkt, dass es dazu noch gar keine Bibliotheken-Funktionen gibt.
Also habe ich versucht, selber etwas zu erstellen. Ich habe ganz einfach mit den Leds auf der M32 angefangen. Wie schon früher hier erwähnt, habe ich dabei das meiste bei der Kommunikation zur Base abgeschaut.
Grundsätzlich scheint es zu funktionieren, aber irgendwie will es doch noch nicht so, wie es sollte. Die Leds sollten genau denselben Status haben, wie die der M256.
Eventuell kann jemand von euch den Fehler finden. Hier könnt Ihr die Firmware mit allen nötigen c und h Dateien runterladen.
Grüsse Filou
Ich wollte fragen, ob es eigentlich (ohne große Umstände) möglich ist, auf die M256 OHNE Router zuzugreifen? Also direkt vom PC (Wlan-Karte) auf den RP6??
Grüße
Ja per ADHOC Modus
(Im Konfigurationsdialog aktivieren)
MfG,
SlyD
Ah, danke. Schon mal jemand gemacht? Wird ja im Manual "nicht weiter beschrieben..."
Ja natürlich (sogar in diesem Thread) ;) .
Das funktioniert mit jedem Betriebssystem etwas anders daher wird das da nicht beschrieben.
Hallo
Da sich die RP6-Spezialisten um die Einbindung des M256 in die RP6-Familie kümmern versuche ich ein "Waisenkind" zu adoptieren:
http://youtu.be/EC_VEmwQgjM
(Noch ein Vorkucker: http://www.youtube.com/watch?v=_XI_xrk95H8)
Mechanisch bin ich fertig, jetzt starte ich mit der Software. Wenn SlyD es erlaubt werde ich die RP6-Lib auf die bee übertragen...
Gruß
mic
Die RP6Lib ist GPL... http://de.wikipedia.org/wiki/GNU_General_Public_License
Da gibts nicht viel zu fragen. Und für Uri et Orbi ist jemand anderes zuständig.
Siehe insbesondere auch http://de.wikipedia.org/wiki/GNU_Gen...pyleft-Prinzip
Aber ne andere Frage... hat sich schon mal jemand mit Ethersex auf der M256 beschäftigt?
Nein kein Schweinkram.... http://www.ethersex.de/index.php/Main_Page
Auf ATMega32 und 644 soll das sehr gut laufen - incl ENC28J60 also z.B. dem NETIO-Board von Polin.
Müsste dann auf der M256 ja auch gehen wenn man den WLAN Chip da statt dem LAN chip aktiviert.
Das wär zumindest mal vernünftige Software für die M256 ...
LG Rolf
@Radbruch: Du darfst damit wie Rolf schon sagt alles machen was Du willst, die Quellen sind ja komplett Opensource, GPLv2.
Das M256 ist auch gut geeignet auf anderen Robotern eingesetzt zu werden, also mach ruhig :-)
@Rolf: Die Lib ist nett, aber vieles davon wird mit dem RP6 WLAN Modul nicht benötigt, im WLAN Modul steckt ein 32 Bit Prozessor der vieles davon schon übernimmt (inkl. UDP, TCP, FTP, NTP... )
Man könnte aber natürlich Teile davon portieren für bestimmte Anwendungen die da noch fehlen.
MfG,
SlyD
Hi,
eine Frage an die Fachmänner.
Hardware:
RP6
RP6v2 Control M256 WiFi
M32 (nicht installiert)
Software:
Ordner RP6_M256......
RP6M256_10_Move2.hex
Ordner RP6BASE....
RP6Base_I2C_Slave
Programm RP6Base_I2C_Slave und RP6M256_10_Move2 erkennt nach WiFi Loader Start nur noch die Bumber?
Motoren laufen.
Wenn ich die START Taste am Baseboard drücke, funktioniert alles. USB Start mit Serial Loader funktioniert auch.
Gruß
Kurt
Hallo Kurt,
ja, da scheint irgendwas beim Start nicht zu passen ich schaus mir später diese Woche mal an.
Es funktioniert übrigens auch mit UPLOAD+Start im WIFI Loader normal.
Bis dahin: Upload+Start benutzen oder im WIFI Terminal "start_program" eintippen.
Damit gehts auch.
MfG,
SlyD
Hallo Dirk,
danke für die schnelle Info. Upload+Start funktioniert.
Gruß
Kurt
Hallo SlyD,
gib es noch mehr Befehle wie 'start_program' etc.
Die cmd Palette ist bekannt (.$$$) - get wlan etc.
Danke
Kurt
Meinst Du jetzt Befehle für den Bootloader oder Befehle für das WLAN-Modul?
Die Befehle für das WLAN-Modul sind auch alle noch einmal hier zu finden: http://www.rovingnetworks.com/resour...ly_User_Manual
Was den Bootloader angeht: Schau Dir auch mal die Sourcen des RP6 Flash Writers an - dort ist auch einiges zu finden: https://www.roboternetz.de/community...rce-RP6-Loader .
Allerdings ist der neue Bootloader ein wenig anders als der des RP6.
Hi und Danke.
Ich meine die Bootloader - Anweisungen.
Mit dem Programm RobotLoader Option WiFiLoader aufrufen. Verbindung über Wlan hat funkioniert.
Jetzt klick auf WiFi Terminal.
Hier können wir den Befehl start_program zum Roboter RP6 senden.
Leider funktioniert der direkte Klick WiFi Loader 'Start' noch nicht optimal.
BaseBoard wird nicht richtig initialisiert.
Welche Funktionen gibt es noch?
Gruß
Kurt
Hallo,
ich komm einfach nicht weiter. Ich bin stolzer Besitzer eines RP6, M32 und WiFi-Modul.
Ich habe an einem Servo ein SRF08 Ultraschallmodul befestigt, an der M32 habe ich es zum laufen gebracht, dass der Servo
den SRF geschwenkt hat und er somit "Hindernisse" gut erkannt hat. Das habe ich dank der ServoLib hinbekommen.
Ich will die M32 durch die WiFi ersetzen, aber ich schaffe es nicht das Servo anzusteuern.
Kann mir jemand einen Loesungsansatz geben? Am besten waere PWM, aber ich weiss nicht wie ich einen 2ten Timer programmiere.
Ich habe auch versucht die ServoLib auf die WiFI zu Uebertragen, leider ohne erfolg.