-
        

Seite 1 von 7 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 66

Thema: Programm_Anpassungen

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    09.07.2007
    Beiträge
    42

    Programm_Anpassungen

    Anzeige

    Hi!

    Da unser Robo z.Zt. zwangs-inaktiv ist, habe ich mir ein wenig Eure tollen und sehr gut
    dokumentierten *.h's und *.c's angeschaut; ich kann dabei noch sehr viel in Sachen C,
    Asm und AVR lernen!!!

    Dabei ist mir das eine oder andere aufgefallen. (Bitte nicht als Kritik verstehen, denn
    das soll und will ein Newby wie ich (leider noch bin! gar nicht!

    Bei der IR-Übertragung ist mir aufgefallen, dass der Sender und auch der Empfänger zwar
    immer wieder eingeschaltet wird, jedoch NIE aus! (in print.c und uart.c)

    Anpassungsvorschlag: UCSRB = 0x00; // Sender und Empfaenger ausschalten

    Beim Senden vom Asuro aus gibt es ähnliche Programme:
    void SerWrite (unsigned char *data, unsigned char length)
    void UartPutc (unsigned char zeichen) mit void SerPrint (unsigned char *data)

    Man könnte mit den "Sahnehäubchen" aus beiden ein Programm basteln:
    z.Bsp.
    aus*********

    void UartPutc (unsigned char zeichen)
    {
    UCSRB = 0x08; // enable transmitter
    UCSRA |= 0x40; // clear transmitter flag
    while (!(UCSRA & 0x20)) // wait for empty transmit buffer
    ;
    UDR = zeichen;
    while (!(UCSRA & 0x40)) // Wait for transmit complete flag (TXC)
    ;
    }

    mit+++++++++

    void SerPrint (unsigned char *data)
    {
    unsigned char i = 0;

    while (data [i] != 0x00)
    UartPutc (data [i++]);
    }

    und-------------

    void SerWrite (unsigned char *data, unsigned char length)
    {
    unsigned char i = 0;

    UCSRB = 0x08; // Sender einschalten
    while (length > 0) // so lange noch Daten da sind
    {
    if (UCSRA & 0x20)
    { // warten, bis der Sendebuffer leer ist
    UDR = data[i++];
    length --;
    }
    }
    while (!(UCSRA & 0x40)) // abwarten, bis das letzte Zeichen
    ; // uebertragen wurde.

    for (i = 0; i < 0xFE; i++) // warten auf irgendwas; keiner weiss
    for (length = 0; length < 0xFE; length++); // wofuer =>> na, dann weglassen!)
    }

    Prog_neu------------

    void SerWrite_SerPrint_NEU (unsigned char *data, unsigned char length)
    {
    unsigned char i = 0;

    UCSRB = 0x08; // Sender einschalten
    // enable transmitter
    UCSRA |= 0x40; // 'clear' transmitter flag
    // TXC-flag setzen
    // (TXC = transmit complete flag)

    while (length && data[i]) // so lange noch Daten da sind *)
    {
    if (UCSRA & 0x20) // wait for empty transmit buffer
    { // warten, bis der Sendebuffer leer ist
    UDR = data[i++];
    length --;
    }
    }
    while (!(UCSRA & 0x40)) // abwarten, bis das letzte Zeichen
    ; // uebertragen wurde.
    // Wait for transmit complete flag (TXC)

    UCSRB = 0x00; // Sender ausschalten
    // disable transmitter
    }

    ------------
    *) 2 Fliegen mit einer Klappe schlagen!)

    SerWrite_SerPrint_NEU () funktioniert (besser: SOLLTE!
    - mit Null-terminierten String data[] und/oder
    - mit einer Längenangabe (auch ohne 'End-Null'):
    Im ersten Fall muss man (leider als Schönheitsfehler!) als Länge einfach "0xff"
    oder eine Zahl angeben, die größer/gleich der tatsächlichen Länge ist,
    im zweiten die korrekte Länge des Strings!

    Zum Prg.-Namen machen wir einen Wettbewerb!
    Prog. leider noch nicht getestet!

    ********************

    Beim Prog. IR-Empfangen versuche ich demnächst 'mal, die Fehlererkennung mit einzubauen.

    Bis bald und
    cu Helmut

  2. #2
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Jena
    Alter
    31
    Beiträge
    3.913
    hmm.. klingt gar nicht schlecht, aber wenn man alles getrennt lässt bleibt man abwärtskompatibel. vielleicht sendest du mal ne nachricht an waste, der beschäftigt sich mit der lib, vielleicht gibt das ne neuaufnahme...
    kleinschreibung ist cool!

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo zusammen,
    die Warteschleife am Ende der SerWrite()-Funktion ist tatsächlich sehr merkwürdig.
    Als einzigen Grund für das Ding kann ich mir nur vorstellen, dass eine Syncronisation mit einem Empfänger besser funktioniert.
    Wenn man permanent Daten sendet, dann kann es passieren, dass die Start-Bits in den Daten nicht mehr zum richtigen Zeitpunkt gefunden werden. Macht man ab und zu eine Pause, dann schaffen es die Empfänger wieder das nächste Start-Bit korrekt zu erkennen. Ist mir schon passiert, als ich permanet Daten der Liniensensoren gesendet habe und 'natürlich' auch diese 'Zeitverschwendung' ausgebaut hatte.

    Ist waste tatsächlich der richtige Ansprechpartner? Ich würde eher m.a.r.v.i.n sehen. (Oder ich?, OK ich sehe mir das heute Abend mal in Ruhe an, und werden es dann erst hier zur Begutachtung abgeben.)
    Lieber Asuro programieren als arbeiten gehen.

  4. #4
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Jena
    Alter
    31
    Beiträge
    3.913
    na ich denke ihr seid alle richtig =) nur ich halt nich...
    an sich finde ich die idee nicht schlecht, evtl wirds ja was
    kleinschreibung ist cool!

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    So, an alle die richtig und nicht richtig sind P.S.: damaltor ist immer richtig!

    Ich habe den Vorschlag für SerWrite_SerPrint_NEU() mal so umgeschrieben dass ich in lesen kann. (Entspricht jetzt eher den Original-Codestellen zu Vergleichszwecken)
    Code:
    void SerWrite_SerPrint_NEU (unsigned char *data, unsigned char length)
    {
      unsigned char i = 0;
    
      UCSRB = 0x08; // enable transmitter
      UCSRA |= 0x40; // clear transmitter flag
    
      while (length && data[i]) // so lange noch Daten da sind *)
      {
        while (!(UCSRA & 0x20)) // wait for empty transmit buffer
          ;
    
        UDR = data[i++];
        length --;
      }
    
      while (!(UCSRA & 0x40)) // Wait for transmit complete flag (TXC)
        ;
    
      UCSRB = 0x00; // disable transmitter
    }
    So sieht das ganze ja recht gut aus.

    Es gibt aber folgendes zu bedenken:

    1: Ein einzelnes Char-Zeichen ist nur noch umständlich zu senden.
    --> charVariable [0] = 'x';
    --> SerWrite_SerPrint_NEU (charVariable, 1);
    anstatt:
    --> UartPutc ('x');

    2: gravierender: Ich kann nicht mehr 'alle' Daten einschliesslich 0x00 senden.
    Ein Datenarray mit 0x00 als Inhalt an einer Stelle, würde genau dieses Zeichen zum Abbruch der Funktion führen. Die "while (length && data[i])"-Schleife wird ja genau hier abbrechen, ohne dieses verflixte 0x00 gesendet zu haben.
    - Somit hat SerWrite() seine Daseinsberechtigung.
    - SerPrint() ist fuer die C-String-Sender.
    - Und UartPutc() ist nun mal für LowLevel.

    Ich glaube also, dass es keine so gute Idee wäre einen Wettbewerb für den Funktionsnamen zu beginnen.

    Auf alle Fälle finde ich es klasse, dass du dich so intensiv mit den einzelnen Funktionen und möglichen Sahnehäubchen, äh Optimierungen, beschäftigst. Sonst ist bestimmt nämlich noch niemandem aufgefallen, dass man Energie sparen kann durch das Ausschalten des Senders. Akku und Umwelt werden es danken. -> Wird auf den Weg in die LIB gebracht.

    Was ich aber bestehen lasse, ist diese merkwürdige Warteschleife zum Schluss. Da habe ich ehrlich gesagt ein bisschen Bammel vor die auszubauen. (Beim DLR werden die sich da irgendetwas gedacht haben um so ein Rätsel einzubauen.)
    Lieber Asuro programieren als arbeiten gehen.

  6. #6
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Jena
    Alter
    31
    Beiträge
    3.913
    ... ich seh das mal als kompliment =)

    aber warum zur hölle sollte ich ein 0x00 senden wollen? =)
    kleinschreibung ist cool!

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    12.06.2005
    Ort
    Südwestdeutschland
    Beiträge
    1.062
    Blog-Einträge
    2
    void SerWrite_SerPrint_NEU (unsigned char *data, unsigned char length)
    Hallo Sternthaler,

    könntest Du in der neuen Version den Längenparameter rauswerfen?
    Buchstaben zählen können Prozessoren besser als der Mensch.

    Beste Grüße ,
    stochri

  8. #8
    Erfahrener Benutzer Roboter Genie Avatar von m.a.r.v.i.n
    Registriert seit
    24.07.2005
    Ort
    Berlin
    Beiträge
    1.247
    Hi,
    Zitat Zitat von damaltor
    aber warum zur hölle sollte ich ein 0x00 senden wollen? =)
    Wenn man Binärdaten senden will, kommt 0x00 durchaus vor und die Längenangabe in SerWrite braucht man dann natürlich ebenso.
    Ganz so einfach geht es also nicht.

    Vielleicht vereint man print.c und uart.c auf folgende Weise, indem man SerWrite umschreibt und SerPrint durch ein Define ersetzt:

    Code:
    void SerWrite (unsigned char *data, unsigned char length)
    {
      if (length)
      {
       do {
         uart_putc(*data++);
        }
        while (length--);
      }
      else
      {
        while (*data)
          uart_putc(*data++);
      }
    }
    
    #define SerPrint SerWrite(unsigned char *data, 0);

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    @damaltor
    Klar, ist so gemeint. Allerdings wirft dich die Frage nach der Hölle nun etwas zurück Siehe Antwort von m.a.r.v.i.n

    @stochri
    Da ist noch nichts eingebaut.
    Mit dem Übernehmen in die LIB hatte ich nur im Sinn den Sender auch wieder auszuschalten. In meinem Beitrag hatte ich (wahrscheinlich durch blah, blah, blah verstümmelt) eigendlich für die Daseinsberechtigung aller 3 Funktions-Varianten zum senden plädiert.

    Aber m.a.r.v.i.n hat wohl den Nagel auf den Kopf getroffen, und eine perfekte Lösung gefunden.
    Kleine Änderung beim define:
    #define SerPrint(data) SerWrite(unsigned char *data, 0);
    Oder muss das "data" bei einem define auch mit Typeangabe, *-chen oder sonstigem sein?

    Auch noch eine weitere Frage zu dem Code, bei der ich absolut unsicher bin was da eigendlich passieren wird.
    - Ich mache ne Char-Array-Variable á la "char infos [10];"
    - Daten da rein mit "strcpy (infos, "Wichtig");"
    - Nun der Aufruf über SerPrint (infos) an SerWrite(infos, 0)
    - In SerWrite wird mit "*data++" das zu sendende Zeichen ausgewählt UND der Zeiger auf den übergeben Datenbereich mit ++ erhöht.

    Meine Frage ist:
    Wenn die Funktion beendet wird, ist dann der Zeiger/Adresse in infos immer noch an der Stelle im Speicher an der ich 10 Byte speichern darf, oder wurde dieser Zeiger/Adresse nun durch das ++ auch beim Aufrufer geändert?
    Wenn das der Fall wäre, dann dürfte ich als Aufrufer ja nun nicht mehr davon ausgehen, dass mir der Speicherbereich ab infos mit 10 Byte gehört.

    Im Original-Code ist das Adressieren der Daten in infos mit einer eigenen Variablen gelöst: "data[i++]"
    Lieber Asuro programieren als arbeiten gehen.

  10. #10
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Jena
    Alter
    31
    Beiträge
    3.913
    keine sorge:

    du übergibst ja das array (welches technisch gesehen eingentlich nur ein zeiger auf dass erste element ist). dann wird damit gearbeitet, der zeicher wird etwas hin-und hergeschubst usw.

    sowie du aber wieder mit dem namen des arrays arbeitest, hat sich das problem erledigt: der NAME des arrays zeigt auf das erste element. grundsätzlich. und wenn innerhalb einer funktion die adresse, auf die der zeiger zeigt, verändert wird, ist das in der aufrufenden funktion nicht geändert. sowie die fnktion verlassen wird, zegt der name wieder auf das erste element.
    kleinschreibung ist cool!

Seite 1 von 7 123 ... LetzteLetzte

Berechtigungen

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