-
        

Ergebnis 1 bis 10 von 10

Thema: fehlerhafte kommunikation mit Rp6

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    19.08.2007
    Beiträge
    6

    fehlerhafte kommunikation mit Rp6

    Anzeige

    hallo zusammen,
    das ist mein erster Beitrag. ich hoffe, mir geling´s das Fehler gut zu beschreiben.
    folgendes klein programm habe ich geschrieben:

    while(true)
    {
    writeString_P("\n please Target position: ");
    receiveBytesToBuffer(bytesToReceive,&receiveBuffer[0]);
    TargetPosition=(uint8_t)receiveBuffer[0];

    writeString_P("\n Target position is: ");

    writeInteger(TargetPosition,DEC);

    }

    ich nutze den Terminal vom Rp6 loader für die Ein/Ausgabe.
    Wenn ich .n10 als integer eingebe, wird im Terminal TX: -> 10 gezeigt.
    aber irgendwie wird nicht die 10 als dezimalzahl zum rp6 weitergeleitet, sondern, vermute ich, nur die '1' als character. Das merke ich an der Ausgabe meines Programms:
    Target position is: 49

    dh. egal ob ich 10, 11, bis 19 eingebe, bekomme ich immer die 49 raus, weil immer das erste char 1 interpretiert wird.

    mache ich da ein Fehler oder habe ich die funktionsweise vom Terminal nicht verstanden !!!
    danke für eure Hilfe
    ---------------------------
    amin

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo amin

    Nein, du machst eigentlich nicht wirklich einen Fehler und du hast das Problem auch schon selbst erkannt: Der ASCII-Code für "1" ist 49, deshalb wird dein Target auch als 49 erkannt.

    Einfach Lösung wäre vielleicht:
    Code:
    receiveBytesToBuffer(bytesToReceive,&receiveBuffer[0]);
    Temp=(uint8_t)receiveBuffer[0]-48;
    receiveBytesToBuffer(bytesToReceive,&receiveBuffer[0]);
    TargetPosition=(uint8_t)receiveBuffer[0]-48;
    TargetPosition+=temp*10;
    Temp speichert die Zehner, 48 ist der Code für "0" und dient der Umrechnung von ascii zu Wert. Allerdings must du nun führende Nullen mit eingeben.

    Das geht sicher viel eleganter wenn man gleich zwei Zeichen einliest (über bytesToReceive=2 und receiveBuffer[1]?) und einem Timeout für einstellige Zahlen, aber mit der seriellen Kommunikation habe ich mich bisher noch nicht beschäftigt.

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    19.08.2007
    Beiträge
    6
    danke radbruch für deinen Vorschlag,
    daran habe ich auch schon gedacht (eine 2 stellige Zahl über zwei Byte zu schicken). Aber ich will mit solche Lösungen erst anfangen, wenn ich weiss, dass das Terminal so programmiert ist (was ich aber bezweifle).

    in der Hilfe vom Terminal steht das man eine Zahl (1 Byte) in 3 formen schicken kann: hexadecimal, decimal oder octal. Ich habe allen probiert , es kommt immer das gleiche raus, dh. auch mit 0x01 bekomme ich nicht die 1 als Ausgabe sondern die 49.
    hat jemand so ein problem schon gehabt?

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    Hallo amin,

    erstmal arbeitest Du anscheinend noch mit einer alten RP6Lib Version. In der neuen ist der Empfang von Daten über die serielle Schnittstelle etwas anders gelöst. Die neue Version gibts hier: http://www.arexx.com/rp6


    Poste auch mal Dein komplettes Programm. Wenn immer 49 rauskommt, ist irgendwo anders was nicht richtig....
    Ich hab das hier gerade selbst getestet (allerdings mit den neuesten Versionen) und eigentlich keine Probleme gehabt.


    ------------------------------

    Die Auswertung von normalen Text Eingaben ist auch nicht so schwierig - hier ein paar Auszüge aus einem Beispielprogramm (neue Versionen von der RP6 Homepage!):

    Code:
    	char receiveBuffer[charsToReceive+1];  // <<-- da kommt der Text rein
    
    	clearReceptionBuffer();   // Empfangspuffer leeren
    	
    	uint8_t buffer_pos = 0;	
    	while(true) 
    	{ 
    		if(getBufferLength())   // Sind neue Zeichen da? 
    		{		
    			receiveBuffer[buffer_pos] = readChar(); // Ein Zeichen lesen
    			if(receiveBuffer[buffer_pos]=='\n' || buffer_pos >= charsToReceive)  // Ende? 
    			{
    				receiveBuffer[buffer_pos]='\0'; 
    				buffer_pos = 0; 
                          
    				break; // Schleife beenden!   // ***1 s. unten
    			}
    			buffer_pos++; 
    		}										 
    	}
    Dieser Code empfängt eine komplette Eingabezeile (also bis zum Zeilenumbruch) bzw. bricht bei der maximalen Länge ab.


    Danach kann man optional noch überprüfen ob es sich auch um einen Zahlenwert handelt:

    Code:
    uint8_t cnt;
    				uint8_t is_a_number = 1;
    				for(cnt = 0;cnt < 3 && receiveBuffer[cnt] != '\0'; cnt++)
    				{
    					if(!(receiveBuffer[cnt] >= '0' && receiveBuffer[cnt] <= '9'))
    					{
    						is_a_number = 0;
    						break;
    					}
    				}
    Kann man aber komplett weglassen wenn man sicher ist, dass immer eine Zahl eingegeben wird.

    Wenn es eine Zahl ist, dann kann per "atoi" (array-to-integer) Funktion aus der AVR Libc der Zahlenwert in eine Variable geschrieben werden.

    Code:
    if(is_a_number)
    {
            uint16_t value = atoi(receiveBuffer);
            // ... mach was damit ...
    }
    else
         // Keine Zahl...

    So kann man wie z.B. beim Testprogramm einfach die Zahl eingeben ohne .n davor...

    MfG,
    SlyD

    PS:

    Bei
    // ***1
    könnte man auch den empfangenen Text verarbeiten und die Schleife nicht verlassen (Dann muss man hier nochmal clearReceptionBuffer usw. aufrufen)
    So könnte man innerhalb der while(true) Schleife noch andere Sachen nebenbei machen - z.B. die Motoren regeln etc..

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    19.08.2007
    Beiträge
    6
    hallo SlyD,
    es kommt nicht immer nur die 49 raus. Ich wollte nur bei dem Beispiel bleiben. Beim eingeben von 21 oder 22 ...29 kommt die 50 raus. und genaus so für die 3x kommt die 51 raus.
    hier ist das komplete code
    Code:
    #include "RP6RobotBaseLib.h" 	
    #define bytesToReceive 			1
    
    char receiveBuffer[bytesToReceive];
    uint8_t TargetPosition;
    		
    int main(void)
    {
    	initRobotBase(); // Always call this first! The Processor will not work
    					 // correctly otherwise.
    
    	setLEDs(0b111111); // Turn all LEDs on
    	mSleep(500);       // delay 500ms
    	setLEDs(0b000000); // All LEDs off
    
    	while(true)
    	{
    		writeString_P("\n please Target position:   ");
    		receiveBytesToBuffer(bytesToReceive,&receiveBuffer[0]);
    		TargetPosition=(uint8_t)receiveBuffer[0];
    	
    		writeString_P("\n Target position is:   ");
    	
    		writeInteger(TargetPosition,DEC);
    		
    	}
    	
    	return 0;
    }
    ich werde aber die neue Lib runterladen und testen. Danke.

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    Hmm was mir gerade schonmal direkt auffällt:
    char receiveBuffer[bytesToReceive];

    sollte immer _mindestens_ 1 Zeichen größer sein --> also bytesToReceive+1.
    Daran könnte es schon liegen.

    MfG,
    SlyD

    PS:
    Zur neuen Lib brauchst Du auch eine neue Version vom RP6Loader, da die erste noch nicht am Ende jeder Eingabe einen Zeilenumbruch gesendet hat.
    (das kann man jetzt in den Optionen einstellen)

    PPS:
    Habs gerade mit Deinem Code und aktueller RP6Loader Version probiert - damit klappt es problemlos.

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    19.08.2007
    Beiträge
    6
    hallo SlyD,
    ich teste nun mit der neuen Lib und auch die beta version vom RP6Loader 1.4.
    1) der Loader startet sofort das Programm auf Rp6 auch wenn ich nur Upload aktiviere!!!
    2) Ich habe das gleiche problem wie vorher. Die Komm. beim Hinweg ist falch, ich gebe eine 1, es wird aber eine 49 zur rp6 geschickt.

    Es liegt mit sicherheit nicht an das C-Programm, aber auch nicht am Terminal selber, weil du das getestet hast bei dir.
    kann das irgend eine falche Konfiguration bei mir sein??
    hier ist das neue code falls jemand das auch testen möchte um zu sehen ob es wo anders gut klappt:

    Code:
    #include "RP6RobotBaseLib.h" 	
    #define charsToReceive 	 5
    
    uint8_t TargetPosition;
    		
    int main(void)
    {
    	initRobotBase(); // Always call this first! The Processor will not work
    					 // correctly otherwise.
    
    	setLEDs(0b111111); // Turn all LEDs on
    	mSleep(500);       // delay 500ms
    	setLEDs(0b000000); // All LEDs off
    
    	while(true)
    	{
    		
    		char receiveBuffer[charsToReceive+1];  // <<-- da kommt der Text rein 
    		clearReceptionBuffer();   // Empfangspuffer leeren 
    		writeString_P("\n Zielposition eingeben:   \n");
    		uint8_t buffer_pos = 0;    
    		while(true) 
    		{ 
    			if(getBufferLength())   // Sind neue Zeichen da? 
    			{       
    				writeString_P("\n bin im ersten If drin \n");
    				receiveBuffer[buffer_pos] = readChar(); // Ein Zeichen lesen 
    								
    				if(receiveBuffer[buffer_pos]=='\n' || buffer_pos >= charsToReceive)  // Ende? 
    				{ 
    					writeString_P("\n bin im zweiten If drin \n");
    					receiveBuffer[buffer_pos]='\0'; 
    					buffer_pos = 0; 
                          
    					break; // Schleife beenden!   // ***1 s. unten 
    				} 
    				buffer_pos++; 
    			}                               
    		}
    		writeChar('\n');
    		writeStringLength(receiveBuffer,charsToReceive,0);
    		
    		TargetPosition=(uint8_t) receiveBuffer[0];
    		writeString_P("\n Target position is:   \n");
    		writeInteger(TargetPosition,DEC);
    		
    	}
    	
    	return 0;
    }

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    19.08.2007
    Beiträge
    6
    hallo,
    vergisst mal den 2ten punkt von meinem Beitrag, es funktioniert doch jetzt mit der neuen Lib und neue Loader. Danke SlyD für deiner Hilfe.

  9. #9
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    Hallo,

    OK gut - hatte das gerade schon bei mir getestet und hier hats auch funktioniert...

    Noch zu Punkt 1:

    1) der Loader startet sofort das Programm auf Rp6 auch wenn ich nur Upload aktiviere!
    Es gibt nun zwei verschiedene Upload Buttons - einer der nur das Programm in den Roboter lädt und einer der es danach sofort startet.
    Falls man verhindern will das man versehentlich auf "Upload+Start" klickt gibt es in den Einstellungen eine Option "Software Start erlauben".

    Man kann das übrigens auch im Terminal über die Tastatur steuern:
    STRG+Y = "Upload+Start"
    STRG+D = "Upload"
    STRG+S = "Start"
    STRG+R = "Reset / Stop"
    ...


    MfG,
    SlyD

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    19.08.2007
    Beiträge
    6
    hallo SlyD,
    jetzt nachdem ich das Loader neu starte merke ich dass das Button Upload allein das Programm nicht startet. Also es ist alles Ok
    Warum habe ich vorher was anders festgestellt, weisse ich nicht. Villeicht bin ich jetzt einfach müde und brache eine Pause. Also Tschüß und danke.
    --------
    MfG, Amin

Berechtigungen

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