- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 4 von 7 ErsteErste ... 23456 ... LetzteLetzte
Ergebnis 31 bis 40 von 67

Thema: Probleme mit if-Bedingungen????????????????

  1. #31
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Anzeige

    Powerstation Test
    Hallo

    Kurz und knapp. Das versteht jeder, der logische Verknüpfungen und Programmieren mit der Muttermilch verabreicht bekam. Didaktisch zwar völlig wertlos, aber für mich ein Ansporn, endlich in die Low-Level-Programmierung einzusteigen. So ein "blöder" RISC-Prozessor kann doch nicht soooo kompliziert sein, dass ich ihn nicht beherschen kann.

    Bitte nicht falsch verstehen. Ich bin immer noch auf der Suche nach meinem "Weg", ob Mechanik oder Software, ich weis einfach nicht, was mich mehr begeistert. Auf jeden Fall war der asuro für mich ein "Glücksgriff", genauso wie dieses Forum hier. Und bevor ich hier noch mehr ins offtopic abdrifte, beende ich besser mein sentimentales Gesülze. Schönes We noch.

    Gruß

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

  2. #32
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Milda
    Alter
    37
    Beiträge
    4.063
    Didaktisch wertlos, da hast du wohl recht... machs besser -.- sprüche klopfen kann ja jeder...
    Read... or die.
    ff.mud.de:7600
    Bild hier  

  3. #33
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    machs besser
    Würde ich ja gerne, wenn ich's könnte. Da ich aber AVR und c Neuling bin, verwirrt mich dieses Bitgeschiebe etwas. Ich würde das ganz traditionell durch binäre Schreibweise ersetzen, dann würde auch der Zusammenhang zwischen Bitnummer und Port erkennbar sein. Du machst das ja auch so in deinem ersten Beispiel:

    DDRD =DDRD | (1<<6);

    würde ich dann so schreiben:

    DDRD =DDRD | 0b01000000;

    was als Einstieg aber immer noch viel zu kompliziert ist.

    Erstmal muss man wissen, dass DDRD für das Datenrichtungsregister des Port D steht und irgendwo (in der io.h?) per #define definiert wurde. Nach dem Reset sind alle Ports auf Eingang gesetzt (offenbar sind sie es nicht, siehe unten) und müssen, je nach Bedarf, als Ausgang geschaltet werden. Um den 7. Pin als Ausgang zu definieren, genügt ein

    DDRD=0b01000000; // binaere Schreibweise

    wobei man beachten muss, dass die Zählung der Bits bei 0 beginnt. Allerdings werden mit diesem Befehl auch die anderen Richtungsbits beeinflust, dies ist aber meist nicht gewünscht. Um gezielt ein bestimmtes Bit zu setzen (ein 1 reinschreiben), muss man eine oder-Verküpfung anwenden, die nur das gewünschte Bit verändert und den Rest unbeeinflusst läst:

    DDRD=DDRD | 0b01000000;

    Das Setzen eines Ausgangs funktioniert dann nach dem selben Schema, nur das man dabei auf das Datenregister zugreift, das als PORTD definiert wurde. Wiederum mit einer oder-Verknüpfung, um die anderen Ports nicht zu beeinflussen, sieht das Setzen die 7. Ports (Portbit6!) dann so aus:

    PORTD=PORTD | 0b01000000;

    Das Rücksetzen des Ausgangs funktioniert nun ähnlich, mit dem Unterschied, dass wir eine und-Verknüpfung anwenden müssen, um die anderen Portbits nicht zu beeinflussen. Das würde dann so aussehen:

    PORTD=PORTD & 0b10111111;

    und läst sich mit dem ~-Operator noch wunderbar vereinfachen, weil dieser einen Wert bitweise negiert, also aus einer 0 eine 1 macht und aus einer 1 eine 0. Man kann also einfach auch

    PORTD=PORTD & ~0b01000000;

    schreiben. So wird beim Lesen gleich klar, welches Bit eigentlich gemeint ist, dem AVR ist es aber egal, er setzt beidesmal das Portbit auf 0.

    Na wunderbar, scheinbar habe wenigstens ich es jetzt kapiert. Hier mein allererstes selbstgeschriebenes Programm, das OHNE die asuro-Lib direkt auf die Ports zugreift. Weil meine umgebaute FrontLED unsichtbares IR-Licht aussendet, setze ich völlig unspektakulär die StatusLED auf rot:

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    int main(void)
    {
    	DDRB=0; // nicht benoetigte Ports auf Eingang setzen
    	DDRC=0;
    	DDRD=0b00000100; //rote StatusLED haengt an PD2(= Port D, Bit2)
    	PORTD=0b00000100; // Ausgang setzen
    	while(1);
    	return(0);
    }
    Mit #include <avr/io.h> werden, je nach Compilerdirektive, die #defines für den entsprechenden Mikrokontroller eingebunden. In unserem Fall eben die Definitionen für den ATMega8.
    Mit #include <avr/interrupt.h> werden noch die Default-Interruptroutinen eingebunden, ohne verabschiedet sich der Prozessor nach dem Programmstarts ins Nirwana.

    Da ich mir das nun selbst erarbeitet habe, bin ich ziemlich stolz auf das Ergebniss. Natürlich werden die AVR-Profis unter euch darüber schmunzeln, aber jeder fängt eben mal klein an. Die "Bitschiebereien" habe ich natürlich kapiert, aber für den Einstieg finde ich es so verständlicher.

    Gruß

    mic

    [Edit]
    Abschließend noch zum Thema Tastenabfrage:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    int main(void)
    {
    	DDRB=0; // nicht benoetigte Ports auf Eingang setzen
    	DDRC=0;
    	DDRD=0b00000100; //rote StatusLED haengt an PD2(= Port D, Bit2)
    	while(1)
    	{
    /*
    Die Tasten haengen an PortC Bit4. Wenn keine Taste gedrueckt ist,
    wird ueber R23 VCC an diesen Pin gelegt. Das ergibt eine 1 beim Einlesen.
    
    Wenn man dann eine Taste drueckt, ergibt sich ein Spannungsteiler,
    bei dem der Pin dann deutlich, bei K6 1000K zu 68K, nach 0V gezogen wird.
    Das ergibt eine 0 am Eingang.
    
    Den C7 kann man ignorieren, R24 ebenfalls, weil PD3 als Eingang (ohne Pullup?)
    geschaltet ist.
    */
    
    		if (PINC & 0b00010000) // PortC Bit4 ist der Tasteneingang
    		{
    			PORTD=0b00000100; // StatusLED rot setzen
    		}
    		else
    		{
    			PORTD=0b00000000; // StatusLED ausschalten
    		}
    
    /*
    Spätestens jetzt wird auch mir klar, dass die Bitschieberei effektiver ist:
    
       PORTD=((PINC & (1<<PC4))  >> 2);
    
    */
    	}
    	return(0);
    }
    Wenn man eine Taste drückt, geht die StatusLED aus.
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #34
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Milda
    Alter
    37
    Beiträge
    4.063
    find ich gut, das problem ist dass der avr-gcc (zumindest bei mir) keine binärzahlen erkennt. da kommt nur expected ; before string constant oder sowas. er denkt also das ist ein string.

    an sich ist das programm sonst das gleiche.. alternative: für jedes linksschieben kann man auch mit 2 multiplizieren.

    1<<4 ist dann 1*2*2*2*2.

    funktioniert gut, ist allerdings prozessortechnisch eine absolute katastrophe, weil man eine verschiebung manuell in eine multiplikation umschreibt, die dann im prozessor wieder in eine schiebung umgewandelt wird. das erzeugt relativ viel unnützen code, weil der prozessor für jede 2 zwei register reserviert (integer brauchen 2), dann verschiebungen über beide register mit ständigen carry-check macht usw.

    funktioniert bei euch 0b00100000 im quelltext?
    Read... or die.
    ff.mud.de:7600
    Bild hier  

  5. #35
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.06.2007
    Alter
    31
    Beiträge
    104
    Im Buch vom Asuro steht es so, wie damaltor es geschrieben hat. Das hat mich bisher auch überzeugt und ich habs verstanden.

    @radbuch Du hast geschrieben das du dich nicht entscheiden kannst. Nehm doch Michatronik! Das ist ne Mischung aus Mechanik und Informatik.

    @damaltor: Das was du da oben geschrieben hast hab ich verstanden. Aber woher weiß ich jetzt welches Register zu welchem Pin gehört.

    Auch nicht verstanden hab ich die Geschichte vom Motor. Da gibt es ja so ne Pulsweitende-Funktion oder so ähnlich. Außerdem gibt es da ja 3 Pins pro Motor (z.B. für den linken Motor: PD4(XCK/T0) PD5(T1) PB1(OC1A)). Und was soll das jetzt??

    Gruß Roboaktiv
    Gruß Roboaktiv


    It is öde to be blöde

  6. #36
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.06.2007
    Alter
    31
    Beiträge
    104
    Hallo Radbuch,
    ich hab's heute endlich geschaft, dass der ASURO z.B. 4 Umdrehungen vorfährt!!! Hier das Programm:
    Code:
    /*Asuro fährt geradeaus und misst die Helligkeit der Readsensoren*/
    #include <asuro.h>
    #include <string.h>
    int main(void)
    {
    unsigned int umdrehung=0;											//Ist wichtig zu zaehlen der Umdrehungen
    unsigned int zaehler=0;											//Ist wichtig zu zaehlen der verschiedenen Felder
    unsigned int zeit;													//Ist wichtig fuer die Pausen
    unsigned int data[2],data_min[2],data_max[2],data_mit[2];
    char AusgabeTxt[80], Text[80], Textaa[80];							//Ist wichtig für die SerWrite ausgaben
    Init();
    data_max[0] = 0;
    data_max[1] = 0;
    data_min[0] = 65000;
    data_min[1] = 65000;
    
    	MotorDir(FWD,FWD);												//Asuro fäht sehr langsam fuer genaue Messungen
    	MotorSpeed(150,160);
    	
    	OdometrieData(data);											//Das aktuelle Feld wird erfasst
    	if (data[0] < data_min[0])										//Hier werden die Daten vom OdometrieData  ausgewertet und der höchste
    		{
    		   data_min[0] = data[0];									//und niedrigste Wert beider Seiten wird gespeichert
    		}
    	if (data[1] < data_min[1])
    		{
    		   data_min[1] = data[1];
    		}
    	if (data[0] > data_max[0])
    		{
    		   data_max[0] = data[0];
    		}
    	if (data[1] > data_max[1])
    		{
    		   data_max[1] = data[1];
    		}
    	
    	sprintf (AusgabeTxt, "Min 1: %d Min 2: %d Max 1: %d Max 2: %d  \n\r",
    	data_min[0],data_min[1],data_max[0],data_max[1]);				//Die gespeicherten Werte werden hier über einen Striing ausgegeben
    	SerWrite(AusgabeTxt,80);
    	data_mit[0]=((data_max[0]-data_min[0])/2)+data_min[0];		//Hier wird der Mittelwert vom linkenm Rad berechnet
    	sprintf (Text,"Mittelwert links: %d  \n\r",data_mit[0]);		//Dieser wird dann ausgegeben
    	SerWrite(Text,80);
    	data_mit[1]=((data_max[1]-data_min[1])/2)+data_min[1];		//Das ganze mit der anderen Seite
    	sprintf (Textaa,"Mittelwert rechts: %d  \n\r",data_mit[1]);
    	SerWrite(Textaa,80);											//Bishierhin wurde nur kaliebriert und erfasst
    	while(1)														//Folgendes wird immer wiederholt und ist das eigendliche Programm
    	{
    	OdometrieData(data);											//Das aktuelle Feld wird erfasst
    	if(data[1]>data_mit[1])										//und mit dem Mittelwert verglichen
    		{															//wenn es dunkeler war wird das zu der Anzahl der dunkelen Felder addiert
    		zaehler++;
    		SerWrite("zeahler++\n\r",11);								//Dieses TOPEREIGNISS wird natürlich weitererzählt
    		}
    	if(zaehler>=6)													//Wenn 6 dunkle Felder erfasst wurden
    		{
    		umdrehung++;												//Haben sich die Räder einmal gedreht
    		SerWrite("Umdrehung++\n\r",14);								//Auch dieses TOPEREIGNISS wird natürlich weitererzählt
    		zaehler	= 0;												
    		}
    	if(umdrehung>=4)												//wenn sie sich denn 4 mal gedreht haben 
    		{
    		MotorSpeed(0,0);
    		for(zeit=0;zeit<4000;zeit++)								//Vier Sekunden stillstand
    			{
    			Sleep(36);
    			}
    		umdrehung = 0;
    		SerWrite ("Das waren 4 Umdrehungen!\n\r",26);
    		}
    	}
    while(1)
    return 0;
    }
    Und was sagst du dazu.
    Natürlich will ich besteh ich nicht darauf, dass du was dazu schreibst. Programmieren und CO soll ja Spaß machen. Aber ich würde mich schon mal über ne kurze Stellungsnahme von dir freuen. Allerdings ist es jetzt kein MEGAerfolg. Aber dennoch ein Erfolg.

    Gruß Roboaktiv
    Gruß Roboaktiv


    It is öde to be blöde

  7. #37
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo Roboaktiv

    Na, dann wollen wir mal:

    Zuerst eine Anmerkung zu den Zeilennummern: Ich habe dein Programm mit einem Klick auf Bild hier   markiert, dann kopiert und dann in meinen Editor eingefügt. Möglicherweise stimmen deshalb die von mir angegebenen Zeilennummern nicht mit deinen überein. Ursache dafür wären dann Leerzeilen oder ein Zeilenvorschub(=Enter) zwischen dem code-Tag und der ersten Progammzeile in deinem Posting.

    Zeile 15/16: Ein integer ist beim ATMega8 zwar maximal 65535 groß, aber die Odometrie verwendet nur 10 Bits, also ist der Maxwert 1023.
    Zeile 20: Hier sollte vielleicht eine Pause sein, damit der Motor hochdrehen kann.
    Zeile 22-37: Das solltest du in einer Schleife mehrmals tun damit die Ritzel Zeit haben sich zu bewegen! So liest du genau einmal einen Wert ein! Und if kleiner else if größer wäre eleganter
    Zeile 41/44: Den Mittelwert bildet man mit dieser Formel: (max+min)/2

    Zeile 50-54:Bei jedem Schleifendurchgang mit data[1] > datamit[1] wird der Zähler hochgezählt, auch wenn das Rad stehen würde! Deshalb prüft man auf die helle Kante, merkt sich, dass zuletzt hell war, prüft dann auf die dunkle Kante, merkt sich, dass zuletzt dunkel war usw,usw...

    Ab Zeile 50: Ich vermute, du willst das mal anschauen und zählst deshalb die Umdrehungen und die Impulse pro Umdrehung. Und hast auch deshalb die SerWrite()s drin. Im echten Leben würde das nicht funktionieren. 4 Umdrehungen mit der 6er Codescheibe sind 24 Segmente. Also fährt man auch auf 24 (besser auf 22, der Bremsweg zählt ja weiter), und sendet dann den Wert, denn während SerWrite() kann der asuro nichts anderes tun und würde vielleicht Impulse übersehen.

    Möglichweise ist das noch nicht alles. Ich konnte dein Programm aber leider nicht compilieren und testen, weil ich einen "implicit declaration of function `sprintf' "-Fehler gemeldet bekomme. Und da ich string.h bei meinen Programmen nicht anwende, war ich zu faul die Ursache dafür zu suchen.

    Ich mache das so:
    Ich teile den Bereich zwischen max und min in drei Teile, oberes Drittel ist high, unteres Drittel ist low und prüfe dann, in welchem Drittel der eingelesene Wert liegt und merke mir das als Bit. Wenn das bit nicht gesetzt ist, prüfe ich auf high, wenn erkannt setzte ich das bit und prüfe auf low und lösche, wenn erkannt das bit wieder usw,usw..

    Jeder Bitwechsel wird gezählt und dabei die StatusLED umgeschaltet. Die 6er Scheibe hat dann 12 Impulse pro Umdrehung und ein Stoppen auf den Kante zählt keinen Unsinn:

    Code:
    void Count(){
        OdometrieData(data);
        if (!odo_bit_l & (data[0] > odo_high_l)) {
            odo_bit_l=1; count_l ++; StatusLED(YELLOW);
        }
        if (odo_bit_l & (data[0] < odo_low_l)) {
            odo_bit_l=0; count_l ++; StatusLED(OFF);
        }
        if (!odo_bit_r & (data[1] > odo_high_r)) {
            odo_bit_r=1; count_r ++; StatusLED(RED);
        }
        if (odo_bit_r & (data[1] < odo_low_r)) {
            odo_bit_r=0; count_r ++; StatusLED(OFF);
        }
    }
    Übrigens heißen meine Variablen hinten alle _l bzw. _r. Ich teste dann nur den Code für eine Seite, kopiere den Code und suche&ersetze dann in der Kopie das _l durch ein _r.

    Ich würde string.h nicht einbinden und alle Ausgaben mit SerWrite()/PrintInt() erledigen. Jedes #include bläht möglicherweise den Code auf. Aber das ist in erster Linie Geschmackssache.

    Ich hoffe, dass hilft dir etwas auf die Sprünge.

    Gruß

    mic

    Falls es jemanden interessieren sollte:
    Das ist das Programm, aus dem der Zählcode stammt. Das waren meine c-Anfänge, mit Datum vom 8.1.07, da hatte ich den asuro grad 2 Wochen. Und das sieht man auch, es stecken noch einige Fehler drin. Die Funktion: Der asuro wird auf dem Boden stehend eingeschaltet. Er fährt dann ein Stüch vorwärts und misst die Min-/Maxwerte, wenn er fertig ist, blickt er. Man muss ihn dann hochheben und wieder auf den Boden setzen. Wieder auf dem Boden beschleunigt er auf eine vorgegebene Geschwindigkeit, verzögert wieder auf 0 und sendet die Zählerstände. Dann das selbe rückwärts. Endlos bis der Akku leer ist:
    Code:
    #include <asuro.h>
    
    unsigned char sw_data, i, tmp_char, step, speed_min, speed_max, rampe_v, rampe_r;
    unsigned int data[2], j, tmp_int;
    unsigned long loop_count, rampe_delay;
    unsigned char odo_bit_l, odo_bit_r;
    unsigned int odo_min_l, odo_max_l, odo_low_l, odo_high_l;
    unsigned int odo_min_r, odo_max_r, odo_low_r, odo_high_r;
    unsigned int count_l, count_r, count_soll_l, count_soll_r;
    unsigned int speed_l, speed_r, speed_max_l, speed_max_r, speed_soll_l, speed_soll_r;
    
    void hochheben() { // blinken: gelb=hochheben green=hinsetzen  dauergreen=los
        LineData(data); tmp_char=data[0]+data[1]+20; // Schwelle für aufheben vom Boden
        do {
            LineData(data); StatusLED(OFF);Msleep(300); StatusLED(YELLOW); Msleep(150);
        } while ((data[0]+data[1]) < tmp_char);
        do {
            LineData(data); StatusLED(OFF);Msleep(300); StatusLED(GREEN); Msleep(150);
        } while ((data[0]+data[1]) > tmp_char);
        StatusLED(GREEN); Msleep(2000);
    }
    
    int init_odo() {
    
        StatusLED(YELLOW); MotorDir(RWD,FWD);
        odo_min_l=odo_max_l=odo_low_l=odo_high_l=count_l=0;
        odo_min_r=odo_max_r=odo_low_r=odo_high_r=count_r=0;
    
        MotorSpeed(150,150);
        for (j==0; j<5000; j++) {
            OdometrieData(data);
            if (data[0] < odo_min_l) odo_min_l=data[0];
            if (data[0] > odo_max_l) odo_max_l=data[0];
            if (data[1] < odo_min_r) odo_min_r=data[1];
            if (data[1] > odo_max_r) odo_max_r=data[1];
            for (i=0; i<200; i++);
        }
        MotorSpeed(0,0);Msleep(100);
        OdometrieData(data);
    
        odo_low_l=((odo_min_l + odo_max_l)/3);  //  je ein drittel high-nix-low
        odo_high_l=((odo_min_l + odo_max_l)/3)*2;
        if (data[0] >= ((odo_min_l + odo_max_l)/2)) odo_bit_l=1; else odo_bit_l=0;
    
        odo_low_r=((odo_min_r + odo_max_r)/3);  //  je ein drittel high-nix-low
        odo_high_r=((odo_min_r + odo_max_r)/3)*2;
        if (data[1] >= ((odo_min_r + odo_max_r)/2)) odo_bit_r=1; else odo_bit_r=0;
        MotorDir(BREAK,BREAK);
    }
    
    void Count(){
        OdometrieData(data);
        if (!odo_bit_l & (data[0] > odo_high_l)) {
            odo_bit_l=1; count_l ++; StatusLED(YELLOW);
        }
        if (odo_bit_l & (data[0] < odo_low_l)) {
            odo_bit_l=0; count_l ++; StatusLED(OFF);
        }
        if (!odo_bit_r & (data[1] > odo_high_r)) {
            odo_bit_r=1; count_r ++; StatusLED(RED);
        }
        if (odo_bit_r & (data[1] < odo_low_r)) {
            odo_bit_r=0; count_r ++; StatusLED(OFF);
        }
    }
    
    int MotorRampe(unsigned char sp_l, unsigned char sp_r, unsigned int r) {
    
        if (loop_count > rampe_delay) {
            if (sp_l != speed_l) {
                if (sp_l > speed_l) speed_l ++;
                if (sp_l < speed_l) speed_l --;
                rampe_delay=loop_count+r;
            }
            if (sp_r != speed_r) {
                if (sp_r > speed_r) speed_r ++;
                if (sp_r < speed_r) speed_r --;
                rampe_delay=loop_count+r;
            }
        MotorSpeed(speed_l,speed_r);
        }
        return ((sp_l == speed_l) && (sp_r == speed_r));
    }
    
    void run(void) {
    }
    
    int main(void) {
    Init();
    SerWrite("\nHallo\nBatterie: ",17);
    PrintInt(Batterie());
    
    init_odo();// hochheben();
    step=loop_count=rampe_delay=speed_l=speed_r=count_l=count_r=0;
    speed_min=0; speed_max=250; rampe_v=15; rampe_r=15;
    
    do {
        loop_count ++;
        switch (step) {
            case (0): MotorDir(FWD,FWD); FrontLED(ON); BackLED(OFF,OFF);
                count_l=count_r=0; step++; break;
            case (1): if (MotorRampe(speed_max,speed_max,rampe_v)) step++; break;
            case (2): if (MotorRampe(speed_min,speed_min,rampe_r)) step++; break;
            case (3): MotorDir(RWD,RWD); FrontLED(OFF); BackLED(ON,ON);
                SerWrite("\n",1);PrintInt(count_l); SerWrite("\n",1); PrintInt(count_r);
                step++; break;
            case (4): if (MotorRampe(speed_max,speed_max,rampe_v)) step++; break;
            case (5): if (MotorRampe(speed_min,speed_min,rampe_r)) step=0; break;
            case (98): MotorDir(BREAK,BREAK); step++; break;
            case (99): FrontLED(OFF); BackLED(OFF,OFF); step=99; break;
        }
        Count();
    } while (1);
    return 0;
    }
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  8. #38
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.06.2007
    Alter
    31
    Beiträge
    104
    Hi Mic,
    erstmal danke für deine Meinung und deine Tipps!

    Da ich die Geschichte mit der Bitprogrammierung und den Registern hab ich noch nicht richtig verstanden. Dehalb probiere ich jetzt erstmal mit den vorprogrammierten Libaries rum. Außerdem wollte ich dieses Programm als Übergangsprogramm für diese Tastergeschichte nehmen.

    Der Integerwert (65000) wird doch sowieso bei dem erstendurchlauf der Schleife runtergesetzt.

    Das mit der Hochdrehpause ist doch dann so ne Sleep-Geschichte oder?

    Eigendlich könnte man diese sprintf- und SerWritefunktionen auch weglassen.

    Im Grunde hab ich doch das ganze Programm zu kompliziert gemacht. Es reicht doch, wenn man es so schreibt:
    Code:
    /*Asuro fährt geradeaus und misst die Helligkeit der Readsensoren*/
    #include <asuro.h>
    int main(void)
    {
    unsigned int durchlauf;
    unsigned int umdrehung=0; //Ist wichtig zu zaehlen der Umdrehungen
    unsigned int zaehler=0;	//Ist wichtig zu zaehlen der verschiedenen Felder
    unsigned int zeit; //Ist wichtig fuer die Pausen
    unsigned int data[2],data_neu[2];
    Init();
    while(1)													
    {
    MotorDir(FWD,FWD); //Asuro fäht sehr langsam fuer genaue Messungen
    MotorSpeed(150,160);
    OdometrieData(data); //Das aktuelle Feld wird erfasst
    for(durchlauf=0;durchlauf>=1000;durchlauf++)
    {
    sleep(36);
    }
    OdometrieData(data_neu); //Das aktuellere Feld wird erfasst
    if(data[1]!=data_neu[1]) //und mit dem aktuellem Feld verglichen
    { //wenn es anders war wird das zu der Anzahl der veränderten Felder addiert
    zaehler++;
    SerWrite("zeahler++\n\r",11); //Dieses TOPEREIGNISS wird natürlich weitererzählt
    }
    if(zaehler>=24)	//Wenn 24 Änderungen erfasst wurden
    {
    umdrehung++; //Haben sich die Räder einmal gedreht
    SerWrite("Umdrehung++\n\r",14);	//Auch dieses TOPEREIGNISS wird natürlich weitererzählt
    zaehler	= 0;												}
    if(umdrehung>=4) //wenn sie sich denn 4 mal gedreht haben 
    {
    MotorSpeed(0,0);
    for(zeit=0;zeit<4000;zeit++) //Vier Sekunden stillstand
    {
    Sleep(36);
    }
    umdrehung = 0;
    SerWrite ("Das waren 4 Umdrehungen!\n\r",26);
    }
    }
    while(1)
    return 0;
    }
    Eigendlich funktioniert da jetzt auch gut.
    Falls du Verbesserungvorschläge, Zeit und auch noch Lust hast bitte ich dich mir von diese zu berichten.
    Gruß Roboaktiv


    It is öde to be blöde

  9. #39
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.06.2007
    Alter
    31
    Beiträge
    104
    Ich hab grade ma die länge der zurückgelegten Strecke gemessen und mir ist aufgefallen, dass diese viel zu lang ist. Und auch, wenn ich die Räder festhalt hält der trotzdem irgendwann an. Liegt das vielleicht auch daran, das die Fototransistoren zu genau messen? Wie kann man die Messungen ungenauer machen? Diese Fragen müssen nicht unbedingt von Radbruch beantwortet werden, sondern auch von Usern, die auch davon Ahnung haben und hier mal vorbei surfen.

    Gruß Roboaktiv
    Gruß Roboaktiv


    It is öde to be blöde

  10. #40
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Das liegt schlicht daran, dass dein Programm nicht funktioniert. Du solltest einfach auch lesen, was man dir schreibt. Das auch im Stillstand gezählt wird, habe ich dir oben schon geschrieben. Wenn du durch Einrückungen deinen Code etwas struckturierst wird dir vielleicht auch klar, dass du nur eine einzige Schleife hast:

    Code:
    /*Asuro fährt geradeaus und misst die Helligkeit der Readsensoren*/
    //#include <asuro.h>
    int main(void)
    {
    unsigned int durchlauf;
    unsigned int umdrehung=0; //Ist wichtig zu zaehlen der Umdrehungen
    unsigned int zaehler=0;   //Ist wichtig zu zaehlen der verschiedenen Felder
    unsigned int zeit; //Ist wichtig fuer die Pausen
    unsigned int data[2],data_neu[2];
    Init();
    while(1)
    {
    	MotorDir(FWD,FWD); //Asuro fäht sehr langsam fuer genaue Messungen
    	MotorSpeed(150,160);
    	OdometrieData(data); //Das aktuelle Feld wird erfasst
    	for(durchlauf=0;durchlauf>=1000;durchlauf++)
    	{
    		sleep(36);
    	}
    	OdometrieData(data_neu); //Das aktuellere Feld wird erfasst
    	if(data[1]!=data_neu[1]) //und mit dem aktuellem Feld verglichen
    	{ //wenn es anders war wird das zu der Anzahl der veränderten Felder addiert
    		zaehler++;
    		SerWrite("zeahler++\n\r",11); //Dieses TOPEREIGNISS wird natürlich weitererzählt
    	}
    	if(zaehler>=24)   //Wenn 24 Änderungen erfasst wurden
    	{
    		umdrehung++; //Haben sich die Räder einmal gedreht
    		SerWrite("Umdrehung++\n\r",14);   //Auch dieses TOPEREIGNISS wird natürlich weitererzählt
    		zaehler   = 0;                                    }
    	if(umdrehung>=4) //wenn sie sich denn 4 mal gedreht haben
    	{
    		MotorSpeed(0,0);
    		for(zeit=0;zeit<4000;zeit++) //Vier Sekunden stillstand
    		{
    			Sleep(36);
    		}
    		umdrehung = 0;
    		SerWrite ("Das waren 4 Umdrehungen!\n\r",26);
    	}
    }
    while(1)
    return 0;
    }
    Nur ein paar Fehler:

    -Zwischen dem Einlesen der alten und neuen Werte funktioniert die Zeitschleife nicht, weil du auf "durchlauf>=1000" prüfst. Wenn die Verzögerung funktionieren sollte, was sollte sie bewirken? Alter Wert einlesen-eine Sekunde warten während das Rad lustig weiterdreht-Überprüfen, ob sich der Wert geändert hat? Wenn er sich nicht geändert hätte, würde mich das sehr wundern!

    -Du sendest immer noch während der Fahrt.

    -Du kümmerst dich nicht um Hell oder Dunkel, du zählst einfach nur die Unterschiede.

    Das sind auf den ersten Blick die gröbsten Dinge. Lies dir mal diesen Codescheiben-Thread durch und führe das Messprogramm (den Datenlogger) aus, dass in diesem Thread angeboten wird. Dann bekommst du vielleicht ein Gefühl für die Odometrie und ihre Tücken.

    Gruß

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

Seite 4 von 7 ErsteErste ... 23456 ... LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test