- Labornetzteil AliExpress         
Seite 3 von 3 ErsteErste 123
Ergebnis 21 bis 29 von 29

Thema: readChar richtig verwenden

  1. #21
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Anzeige

    Praxistest und DIY Projekte
    Hallo,

    die Funktionen haben einen Rückgabewert (Variable)! Der wird direkt in der if Bedingung ausgewertet. Ist in C egal ob ich nun schreibe
    int x = funktion();
    if(x) {}

    oder
    if(funktion()) {}

    ... aber nur sofern x später nicht mehr gebraucht wird natürlich.


    Und warum braucht man bei if(strcmp(receiveBuffer, "Ein")==0) das "==0", was soll denn da 0 sein?
    siehe Link weiter oben

    http://www.cplusplus.com/reference/c...string/strcmp/

    Returns an integral value indicating the relationship between the strings:
    A zero value indicates that both strings are equal.
    A value greater than zero indicates that the first character that does not match has a greater value in str1 than in str2; And a value less than zero indicates the opposite.
    0 heisst gleich. Alles andere nicht.

    MfG,
    SlyD

  2. #22
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    28.04.2009
    Ort
    Wörgl
    Alter
    28
    Beiträge
    175
    Ok, jetzt hab ich das auch verstanden.
    Danke nochmal für eure Hilfe.

    lg
    Michi

  3. #23
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Da es das gleiche Thema ist klinke ich ich hier auch mal ein. Zuerst danke SlyD für den HInweis auf dieses Thema.
    Nun mal ne Frage.

    Code:
    char receiveBuffer[UART_RECEIVE_BUFFER_SIZE+1];
    
    uint8_t getInputLine(void)
    {
       static uint8_t buffer_pos = 0;
       if(getBufferLength())
       {                     
          receiveBuffer[buffer_pos] = readChar();
          if(receiveBuffer[buffer_pos]=='\n')
          {
             receiveBuffer[buffer_pos]='\0';
             buffer_pos = 0;
             return 1;
          }
          else if(buffer_pos >= 32)
          {                           
             receiveBuffer[32]='\0';   
             buffer_pos = 0;
             return 2;
          }
          buffer_pos++;
       }
       return 0;
    }
    Was macht dieser Code denn genau? Ich weiß gern was ich da in einem Programm verwende.
    Ist die Variable UART_RECEIVE_BUFFER_SIZE denn schon definiert? Oder muss ich die selber definieren aufgrund der Menge an Zeichen die ich definiere?
    Die Funktion oben geht ja den kompletten receiveBuffer Zeichen für Zeichen durch und jagt readChar() darüber. Was macht readChar() den mit den Zeichen?
    Dann, ein Abbruchkriterium ist ja wenn als Zeichen '\n' gefunden wird. Ich vermute das kann ich auch einfach durch andere "Zeilenendzeichen" ersetzen? Also z.B. mit '\r'.
    Was bringt es eigentlich wenn man ein Zeichen mit '\0' überschreibt?

    Meine letzte aber wohl komischste Frage überhaupt, wo befinden sich denn nach der Funktion überhaupt die eingelesenen Zeichen?
    Wenn ich die Funktion ja aufrufe liefert die mir nur je nach Zustand ein 0, eine 1 oder eine 2 zurück. Oder seh ich das grad richtig das am Ende alle Zeichen der Reihe nach in receiveBuffer[0..Ende] stehen?

    EDIT: Nachdem ich das ganze geschrieben hab un noch ein paar mal drüber nachgedacht hab glaub ich das ich das doch verstanden hab. Narf immer das gleiche ^^


    EDIT2: Aber eine Frage habe ich immernoch, wie kann ich es denn realisieren dass ich in einer Zeile z.B. "050 050" übertragen kann und dann im RP6 das in zwei Variable mit jeweils 50 umsetze?
    Ich will da nämlich Geschwindigkeitswerte übertragen und eben auf für Kurven z.B. "075 125" oder sowas
    Kann ich denn von dieser Variable vom Typ Char einfach die ersten drei Zeichen irgendwie rausnehmen und in eine integer schreiben? Weiß da einer wie man sowas macht?


    EDIT3: Habe nun rausgefunden das sich das ein char mittels
    int i = atoi (char) in etwa umwandeln lässt.
    Werde das daheim dann mal testen.

  4. #24
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Hmm nun probier ich da schon eine Weile rum, aber irgendwie funktioniert da irgendwas nicht so wie es soll.
    Mein Quelltext sieht derzeit so aus.

    Code:
    #include "RP6ControlLib.h"
    #include "RP6I2CmasterTWI.h"
    #include "RP6Control_I2CMasterLib.h"
    
    void I2C_transmissionError(uint8_t errorState)
    {
    	writeString_P("\nI2C ERROR - TWI STATE: 0x");
    	writeInteger(errorState, HEX);
    	writeChar('\n');
    }
    
    char receiveBuffer[8];
    char dir_char[1], speed_1_char[3], speed_2_char[3];
    
    void getInputLine(void)
    {
        clearLCD();
        writeStringLCD("getinputline");
        static uint8_t buffer_pos = 0;
        if(getBufferLength())
        {
          receiveBuffer[buffer_pos] = readChar();
          if((receiveBuffer[buffer_pos]=='\n')||(receiveBuffer[buffer_pos]=='\r'))
          {
             receiveBuffer[buffer_pos]='\0';
             buffer_pos = 0;
          }
          else if(buffer_pos >= 8)
          {
             receiveBuffer[7]='\0';
             buffer_pos = 0;
          }
          buffer_pos++;
        }
    }
    
    
    uint8_t speed_1=0;
    uint8_t speed_2=0;
    uint8_t direction=0;
    uint8_t speed_max=200;
    
    
    int main(void)
    {
        initRP6Control();
        initLCD();
        mSleep(500);
    
    	I2CTWI_initMaster(100);
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    
    	
        setLEDs(0);
        mSleep(500);
    
        sound(180,80,25);
    	sound(220,80,0);
    
    
        while(1)
        {
            task_checkINT0();
            task_I2CTWI();
    
            clearLCD();
            writeStringLCD("fertig");
            mSleep(500);
            clearLCD();
            //uerbtragung in der form 1050080
            //1. erste stelle richtung
            //richtung vorwaerts -> 1
            //richtung rueckwaerts -> 2
            //drehen links -> 3
            //drehen rechts -> 4
            //2.-4. stelle speed_1 (linke kette)
            //5.-7. stelle speed_2 (rechte kette)
            
    getInputLine();
    
            direction=atoi(dir_char);
            speed_1=atoi(speed_1_char);
            speed_2=atoi(speed_2_char);
    
            writeStringLCD("d:");
            writeIntegerLCD(direction, 10);
            writeStringLCD("s1:");
            writeIntegerLCD(speed_1, 10);
            writeStringLCD("s2:");
            writeIntegerLCD(speed_2, 10);
    
    
            
        }
        return 0;
    }
    Aber aus einem mir unerfindlichen Grund kommt er immer nur bis zur LCD Anzeige "fertig".

    Anfangs hatte ich das getInputLine(); mal vor der LCD-Ausgabe für "Fertig", da ist er erst in diese funktion gegangen und hat mir den text "getinputline" angezeigt und danach "fertig". Doch jetzt wo ich die Reihenfolge der zwei getauscht habe macht er das auch nicht mehr.


    Ich wär für jeden Hinweis dankbar.
    Grüße vogel

  5. #25
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hallo vogel0815,

    schau dir noch mal genau das Beispiel von RobotMichi vom 9.8.09 an! Da wird gezeigt, wie getInputLine() verwendet wird.

    Zu einer deiner früheren Fragen:
    Was bringt es eigentlich wenn man ein Zeichen mit '\0' überschreibt?
    Ein bestimmtes "Zeichen" überschreibt man häufiger mit 0, und zwar das Stringende. Wenn man Zeichen in receiveBuffer schreibt, dann kann man den ganzen Buffer als String auslesen, wenn im letzten Byte eine 0 ist, also der String Null-terminiert ist.

    Gruß Dirk

  6. #26
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Also ich hab das nun mal ein bissl umgeändert und probier das wie folgt:

    Code:
    #include "RP6ControlLib.h"
    #include "RP6I2CmasterTWI.h"
    #include "RP6Control_I2CMasterLib.h"
    
    void I2C_transmissionError(uint8_t errorState)
    {
    	writeString_P("\nI2C ERROR - TWI STATE: 0x");
    	writeInteger(errorState, HEX);
    	writeChar('\n');
    }
    
    
    char receiveBuffer[UART_RECEIVE_BUFFER_SIZE+1];
    uint8_t getInputLine(void)
    {
        clearLCD();
            writeStringLCD("getinput");
            mSleep(500);
       static uint8_t buffer_pos = 0;
       if(getBufferLength())
       {
          receiveBuffer[buffer_pos] = readChar();
          if(receiveBuffer[buffer_pos]=='\r')
          {
             receiveBuffer[buffer_pos]='\0';
             buffer_pos = 0;
             return 1;
          }
          else if(buffer_pos >= 32)
          {
             receiveBuffer[32]='\0';
             buffer_pos = 0;
             return 2;
          }
          buffer_pos++;
       }
       return 0;
    }
    
    uint8_t setonce2=false, setonce3=false;
    /*
    LCD Texte einmalig setzen bei betreten des Zustandes
    LCD-Display 2*16 Zeichen
    */
    void LCDText(uint8_t nmbr)
    {
        switch (nmbr)
        {
            case 1:
                showScreenLCD("Starting up! One", "moment please.");
                break;
            case 2:
                setonce3=false;
                if (!setonce2)
                {
                    setonce2=true;
                    showScreenLCD("################","################");
                }
                break;
            case 3:
                setonce2=false;
                if (!setonce3)
                {
                    setonce3=true;
                    showScreenLCD("################","################");
                }
                break;
        }
    }
    
    
    uint8_t speed_max=200;
    
    
    int main(void)
    {
        initRP6Control();
        initLCD();
        mSleep(500);
    
    	I2CTWI_initMaster(100);
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    
    	LCDText(1);
        setLEDs(0);
        mSleep(500);
    
        sound(180,80,25);
    	sound(220,80,0);
    
    
        while(1)
        {
            task_checkINT0();
            task_I2CTWI();
    
            clearLCD();
            writeStringLCD("fertig");
            mSleep(500);
    
            
            if(getInputLine())
            {
                if(strcmp(receiveBuffer, "Ein")==0)
                {
                    clearLCD();
                    writeStringLCD("ein");
                    mSleep(500);
                }
                if(strcmp(receiveBuffer, "Aus")==0)
                {
                    clearLCD();
                    writeStringLCD("aus");
                    mSleep(500);
                }
            }
        }
        return 0;
    }
    aber irgendwie klappt da gar nix.
    Der RP6 rennt zwar sein Programm durch und zeigt mir auch die Textausgaben "fertig" und "getinputline" an so wie er soll, aber die ankommenden daten wertet er irgendwie nicht aus.

    Die Daten schicke ich mittels eines bluetooth moduls das ich auch schon mal als schleife ans notebook gehängt hab, das klappt so wie es soll.
    Hab auch die baudrate im rp6 auf 19200 geändert wie das modul derzeit eingestellt ist.
    Aber selbst wenn ich das eigene UART interface benutze, und das dann auch mit der normalen baudrate im RP6 funktioniert das nicht.
    ich hab das gefühl der hat irgendein problem mit dem datenempfang.

  7. #27
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Ein writeString(receiveBuffer) als Debug Ausgabe könnte schon helfen um zu sehen WAS denn genau ankommt. Oder noch besser in einer Schleife die ASCII Codes ausgeben lassen (writeInteger(receiveBuffer[i],DEC))

    Immer wenn irgendwas nicht funktioniert solltest Du versuchen die Variablen Inhalte auszugeben. Dafür ist die serielle Schnittstelle ja auch da


    Der Grund warum es nicht funktioniert liegt wohl hier:
    mSleep(500);
    (kommt an zwei Stellen vor!)

    Damit funktioniert das task System nicht mehr!
    mSleep darfst Du nur für kurze Pausen <20ms verwenden wenn Du task_ABCD Funktionen in der Hauptschleife aufrufst.
    getInputline ist im prinzip auch so eine Art von Task Funktion und muss MEHRFACH aufgerufen werden damit es funktioniert.
    Die Funktion verarbeitet jedes ankommende Zeichen EINZELN damit das nebenläufig verwendet werden kann und nichts anderes blockiert.

    Wenn man das anders haben möchte muss man das if gegen while austauschen...

    Die bessere Lösung ist aber von mSleep komplett auf die Stopwatches (Software Timer) umzusteigen.

    MfG,
    SlyD

  8. #28
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Also ich hab da heute mal weiter gemacht, und nu funktioniert das so wie es soll

    Mein Code sieht nun so aus.
    Code:
    #include "RP6ControlLib.h"
    #include "RP6I2CmasterTWI.h"
    #include "RP6Control_I2CMasterLib.h"
    
    void I2C_transmissionError(uint8_t errorState)
    {
    	writeString_P("\nI2C ERROR - TWI STATE: 0x");
    	writeInteger(errorState, HEX);
    	writeChar('\n');
    }
    
    
    char receiveBuffer[8];  // our reception buffer is one byte larger
                            // than the data we want to receive, because
    						// we also need to receive the "Newline" character!
    void getInputLine(void)
    {
        clearReceptionBuffer(); // Make sure reception Buffer is empty and no junk data
    							// is left in it.
    
    	uint8_t buffer_pos = 0;
    	while(true)             // Loop until we received one line of Data!
    	{
    		if(getBufferLength())    // Check if we still have data (means getBufferLength()
    		{						 // is not zero)
    			receiveBuffer[buffer_pos] = readChar(); // get next character from reception buffer
    			if(receiveBuffer[buffer_pos]=='\n')     // End of line detected!
    			{
    				receiveBuffer[buffer_pos]='\0'; // Terminate String with a 0, so other routines.
    				buffer_pos = 0;                 // can determine where it ends!
    												// We also overwrite the Newline character here.
    				break; // We are done and can leave reception loop!
    			}
    			else if(buffer_pos >= 7)    // IMPORTANT: We can not receive more
    			{							// characters than "charsToReceive" because
    										// our buffer wouldn't be large enough!
    				receiveBuffer[7]='\0';	// So if we receive more characters, we just
    										// stop reception and terminate the String.
    				writeString_P("\n\nZu viele Zeichen eingegeben FEHLER!\n");
    				break; // We are done and can leave reception loop!
    			}
    			buffer_pos++;
    
    		}
    	}
    }
    
    /*
    char-array von receivebuffer in seine einzelteile zerlegen und ebenfalls in einem char-array
    sowie diese neuen char-arrays umwandeln in integerzahlen
    */
    static int speed_1=0;
    static int speed_2=0;
    static int direction=0;
    char dir_char[2];
    char speed_1_char[4];
    char speed_2_char[4];
    
    void splitbuffer(void)
    {
        dir_char[0]=0;
        dir_char[0]=receiveBuffer[0];
        direction=atoi(dir_char);
        int i=0;
        while (i<3)
        {
            speed_1_char[i]=receiveBuffer[i+1];
            speed_2_char[i]=receiveBuffer[i+4];
            i++;
        }
    
        speed_1=atoi(speed_1_char);
        speed_2=atoi(speed_2_char);
    
    }
    
    
    int speed_max=200;
    
    int main(void)
    {
        initRP6Control();
        initLCD();
    
    	I2CTWI_initMaster(100);
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    
        setLEDs(0);
    
        sound(180,80,25);
    	sound(220,80,0);
    
    
        while(1)
        {
            task_checkINT0();
            task_I2CTWI();
            writeString_P("\nget input\n");
            getInputLine();
            splitbuffer();
    
            if(speed_1>200)
            {
                speed_1=speed_max;
            }
            if(speed_2>200)
            {
                speed_2=speed_max;
            }
            switch (direction)
            {
                case 1: //vorwaerts fahren
                writeInteger(1,DEC);
                writeChar('\n');
                changeDirection(FWD);   //richtung wechseln nach forward
                moveAtSpeed(speed_1, speed_2);
                break;
    
                case 2: //rueckwaerts fahren
                writeInteger(2,DEC);
                writeChar('\n');
                changeDirection(BWD);   //richtung wechseln nach backward
                moveAtSpeed(speed_1, speed_2);
                break;
    
                case 3: //links drehen
                writeInteger(3,DEC);
                writeChar('\n');
                changeDirection(FWD); //forward sonst leichte verwirrung
                moveAtSpeed(speed_1, speed_2);
                break;
    
                case 4: //rechts drehen
                writeInteger(4,DEC);
                writeChar('\n');
                changeDirection(FWD);
                moveAtSpeed(speed_1, speed_2);
                break;
    
                default:
                writeInteger(5,DEC);
                writeChar('\n');
                moveAtSpeed(0,0);
            }
        }
        return 0;
    }
    Die Steuerung vom RP6 über Bluetooth und Labview, wie es später auch geschehen soll funktioniert nun auch einwandfrei.

    Nun muss ich nur noch am RP6 mal die Encoder richtig einstellen, aber da macht mir derzeit der RP6Loader zicken. Irgendwie ist der grad verdammt lahm was die Textausgabe dort angeht. Der hängt ewig hinterher. Aber deswegen hab ich mal im Arexx forum die frage gestellt.


    Nur eine Sache kapier ich nicht. In meinem Quellcode oben teile ich den 7-stelligen Inhalt des receivebuffers auf auf 3 einzelne char-arrays.
    das erste zeichen in das erste array, und dann je 3 zeichen in die anderen arrays. Im Code oben habe ich diese neuen Arrays aber jeweils ein zeichen größer machen müssen als das was da rein kommt. Also statt einem Zeichen hab ich das 2 Zeichen groß machen müssen, und anstelle von 3 Zeichen 4 Zeichen. Sonst hat das einfach nicht funktioniert. Hat irgendjemand eine idee warum das so ist? ist ja schließlich schon etwas komisch.

    Ansonste Grüße und danke für eure Hilfe.

  9. #29
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    > Nur eine Sache kapier ich nicht.

    receiveBuffer[buffer_pos]='\0';
    // Terminate String with a 0, so other routines.
    // can determine where it ends!




    Und wenn Du atoi verwendest musst Du die Arrays auch 0 terminieren!

Seite 3 von 3 ErsteErste 123

Berechtigungen

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

LiFePO4 Speicher Test