- LiFePO4 Speicher Test         
Seite 1 von 5 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 43

Thema: mal wieder ne Änfängerfrage: Strings

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.02.2005
    Beiträge
    385

    mal wieder ne Änfängerfrage: Strings

    Hi,
    es geht darum, einige Werte ber UART auszugeben. Zur Ausgabe habe ich folgende Methoden:
    Code:
    void uart_out(char c) {
    	loop_until_bit_is_set(UCSRA, UDRE); 
    	UDR = c;
    }
    
    void uart_puts(char *s) {
    	int len = strlen(s);
    	while(len--) {
    		loop_until_bit_is_set(UCSRA, UDRE); 
    		UDR = *s;
    		s++;
    	}
    }
    Ich muss also z.B. einen String wie "<Variable>: <Wert>" ausgeben können, dazu muss ich ja nen String bauen, in den der Wert eingearbeitet ist. Nur wie mache ich das? Oder gibts ne besserer Methode das auszugeben?

    mfg
    jagdfalke

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.06.2004
    Ort
    Bad Schussenried in Oberschwaben
    Alter
    34
    Beiträge
    1.461
    Hi!

    Versuch das mal mit strcpy und strcat oder mit sprintf
    Das sind die C-standard-Funktionen für sowas.

    Ich weis aber nicht, ob das der AVR-GCC unterstützt...

    VLG Tobi
    http://www.tobias-schlegel.de
    "An AVR can solve (almost) every problem" - ts

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.02.2005
    Beiträge
    385
    Hi, ich habe jetzt mal das hier geschrieben:
    Code:
    	char *s_pre = "Shoulder: ";
    	char *str = "   ";
    	sprintf(str, "%d", shoulder_pos);
    	str = strcat(s_pre, strcat(str, "\n\r"));
    	uart_puts(str);
    Es gibt schon einigermaßen das richtige aus, aber irgendwann siehts so aus:
    Shoulder: 128
    Shoulder: 128
    130Shoulder: 128
    130131Shoulder: 128
    130131131Shoulder: 128
    13013113.131Shoulder: 128
    13013113.131131Shoulder: 128
    13013113.131131131Shoulder: 128
    13013113.131131131131Shoulder: 128
    13013113.131131131131131Shoulder: 128
    13013113.131131131131131131Shoulder: 128
    13013113.131131131131131131131Shoulder: 128
    13013113.131131131131131131131131Shoulder: 128
    13013113.131131131131131131131131131Shoulder: 128
    Die Methode, die das macht wird per timer interrupt ausgeführt. Ich habe aber am Anfang der Methode cli() und am Ende ein sei() stehn.

    hier mal die komplette methode:
    Code:
    void keep_moving() {
    	cli();
    
    	//NEUE POSITIONEN AUSRECHNEN UND RUNDEN
    	shoulder_pos = (uint8_t)(shoulder_pos + shoulder_step);
    	elbow_pos = (uint8_t)(elbow_pos + elbow_step);
    
    	//POSITIONEN ÄNDERN
    	//move(1, shoulder_pos);
    	//move(2, shoulder_pos);
    	//move(3, elbow_pos);
    
    	char *s_pre = "Shoulder: ";
    	char *str = "   ";
    	sprintf(str, "%d", shoulder_pos);
    	str = strcat(s_pre, strcat(str, "\n\r"));
    	uart_puts(str);
    
    	//WENN DIE POSITIONEN GERUNDET ÜBEREINSTIMMEN
    	//NEUBERECHNUNG DER STEPS ERLAUBEN UND NEUES ZIEL FÜR ELBOW SETZEN
    	if(shoulder_pos == shoulder_dest && elbow_pos == elbow_dest) {
    		recalc_flag = 1;
    	} else {
    		recalc_flag = 0;
    	}
    
    	servo_flag = 0;
    	sei();
    }
    mfg
    jagdfalke

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Versuch mal so was.

    Code:
    	char s_pre[] = "Shoulder: ";
    	char str[10];
    	sprintf (str, "%d", shoulder_pos);
    	uart_puts(s_pre);
    	uart_puts(str);
    	uart_puts("\n\r");
    und mach dir den Unterschied klar zwischen
    char *s = "foo";
    char s[] = "foo";

    anstatt sprintf ist effizienter itoa

    und guckst du
    https://www.roboternetz.de/phpBB2/ze...=130591#130591
    Disclaimer: none. Sue me.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.02.2005
    Beiträge
    385
    kann du mir erklären was der unterschied ist?

    Was mache ich wenn shoulder_pos ein float ?

    mfg
    jagdfalke

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.01.2005
    Ort
    Obertraun
    Alter
    36
    Beiträge
    194
    wenn schoulder_pos ein float ist kannst es z.B. so schreiben:

    sprintf (str, "%f", shoulder_pos);

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.02.2005
    Beiträge
    385
    dass habe ich schon probiert, es kommt aber
    warning: format '%f' expects type 'double', but argument 3 has type 'float'
    Ich bin mir aber sich, dass shoulder_pos float ist. Wenn ich schreibe
    Code:
    	uint8_t shoulder_to_go = (uint8_t)shoulder_pos;
    	uint8_t elbow_to_go = (uint8_t)elbow_pos;
    bleibt shoulder_pos ja float und wird nocht zum uint8_t oder?

    hier mal das, was evtl. wichtig ist:
    Code:
    volatile uint8_t servo_flag = 0;
    volatile uint8_t recalc_flag = 1;
    
    volatile float shoulder_pos = 127.0;
    volatile uint8_t shoulder_dest = 255;
    volatile float shoulder_step = 0;
    
    volatile float elbow_pos = 127.0;
    volatile uint8_t elbow_dest = 1;
    volatile float elbow_step = 0;
    
    int main (void) {
    
            /* UART AN UND TIMEREINSTELLEN ... */
    
           sei();
    
    
    	while(1)
    	{
    		if(recalc_flag == 1) {
    			calc_steps();
    		}
    		if(servo_flag == 1) {
    			keep_moving();
    		}
    	}
    	return 0;
    }
    
    void keep_moving() {
    	cli();
    
    	//NEUE POSITIONEN AUSRECHNE
    	shoulder_pos = shoulder_pos + shoulder_step;
    	elbow_pos = elbow_pos + elbow_step;
    
    	uint8_t shoulder_to_go = (uint8_t)shoulder_pos;
    	uint8_t elbow_to_go = (uint8_t)elbow_pos;
    
    
            //AUSGABE
    	char s_pre[] = "Shoulder: ";
    	char str[10];
    	sprintf (str, "%f", shoulder_pos);
    	uart_puts(s_pre);
    	uart_puts(str);
    	uart_puts("\n\r");
    
    	//WENN DIE POSITIONEN GERUNDET ÜBEREINSTIMMEN
    	//NEUBERECHNUNG DER STEPS ERLAUBEN UND NEUES ZIEL FÜR ELBOW SETZEN
    	if(shoulder_pos == shoulder_dest && elbow_pos == elbow_dest) {
    		recalc_flag = 1;
    		uart_puts("ERREICHT!!!!!!!!!!!");
    	} else {
    		recalc_flag = 0;
    	}
    
    	servo_flag = 0;
    	sei();
    }
    
    
    void calc_steps(void) {
    	//BERECHNEN WIE VIEL SICH DIE Servos BEWEGEN MÜSSEN*
    	uint16_t shoulder_to_go = shoulder_dest - shoulder_pos;
    	uint16_t elbow_to_go = elbow_dest - elbow_pos;
    
    	//HIER ALS ABSOLUTE WERTE
    	int16_t shoulder_abs = abs(shoulder_to_go);
    	int16_t elbow_abs = abs(elbow_to_go);
    
    	//STEP ERSTMAL AUF +/- 1 SETZEN, JE NACH RICHTUNG
    	elbow_step = signum(elbow_to_go);
    	shoulder_step = signum(shoulder_to_go);
    
    	
    	if(elbow_abs < shoulder_abs) {
    		elbow_step = 1 * signum(elbow_to_go);
    		shoulder_step = (shoulder_abs / elbow_abs) * signum(shoulder_to_go);
    	}
    	if(elbow_abs > shoulder_abs) {
    		shoulder_step = 1 * signum(shoulder_to_go);
    		elbow_step = elbow_abs / shoulder_abs * signum(shoulder_to_go);
    	}
    
    }
    
    SIGNAL (SIG_OVERFLOW0){
    	servo_flag = 1;
    }
    mfg
    jagdfalke

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Den Unterschied sieht man am besten am erzeugten Code:

    Code:
    char *foo1 = "Text1";
    char foo2[] = "Text2";
    
    void bar (char*);
    
    void inc()
    {
    	foo1[1] = 11;
    	bar (foo1);
    
    	foo2[1] = 22;
    	bar (foo2);
    }
    
    -------------------------------------------------------
    
    	.size	foo2, 6
    foo2:
    	.string	"Text2"
    
    .LC0:
    	.string	"Text1"
    
    	.size	foo1, 2
    foo1:
    	.word	.LC0
    
    inc:
    	;; foo1[1] = 11;
    	lds r30,foo1
    	lds r31,(foo1)+1
    	ldi r24,lo8(11)
    	std Z+1,r24
    
    	;; bar (foo1);
    	lds r24,foo1
    	lds r25,(foo1)+1
    	rcall bar
    
    	;; foo2[1] = 22;
    	ldi r24,lo8(22)
    	sts foo2+1,r24
    
    	;; bar (foo2);
    	ldi r24,lo8(foo2)
    	ldi r25,hi8(foo2)
    	rcall bar
    
    	ret
    foo1 enthält nur die Adresse des Strings "Text1"
    foo2 iat der Anfang des Speicherbereichs, der mit "Text2" initialisiert wird.

    Dementsprechend sehen Zugriff und Adressbildung auch anders aus.

    Beide sind vom Typ char*, aber während foo1++ ok ist, gibt foo2++ einen Fehler.
    Disclaimer: none. Sue me.

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.01.2005
    Ort
    Obertraun
    Alter
    36
    Beiträge
    194
    bleibt shoulder_pos ja float und wird nocht zum uint8_t oder?
    Ja shoulder_pos bleibt float


    aber wegen dem Problem format '%f' expects type 'double'...
    ich habe bis jetzt bei printf mit floats immer %f verwendet (allerdings nur am PC und nicht am µC!!!)

    probier vielleicht einmal statt %f, %g oder %e

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.01.2005
    Ort
    Obertraun
    Alter
    36
    Beiträge
    194
    zur Not könntest du es auch so schreiben:
    Code:
    sprintf (str,"%f",(double)shoulder_pos);
    es gibt aber bestimmt noch eine elegantere Methode ...

Seite 1 von 5 123 ... LetzteLetzte

Berechtigungen

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

12V Akku bauen