Hi, folgender Sachverhalt. Habe eine Solarzelle die auf einem Drehteller montiert ist welcher von einem Motor angetrieben wird. Während des Drehvorgangs soll die Momentanspannung mit der abgespeicherten Spanung verglichen werden, und wenn diese größert ist als der wert in der Variablen soll der neue Wert in die Variable abgespeichert werden! Der Vergleich soll 8 mal gemacht werden. Jede Sekunde ein mal. Den wert der Variablen habe ich am anfang = 0 gesetzt. Letztendlich soll die Solarzelle selbstständig auf die Position fahren wo die größte Lichtintensität ist. Das Problem: Mein Programm Speichert nur ein mal den wert der Spannung (immer beim ersten Vergleich)danach bleibt der Wert Konstant. Vollständigheits halber habe ich den ganzen code als Angang beigefügt. Ich arbeite mit einem ATmega32 und programmiere in C Bin noch recht unerfahren in der Programmierung (erstes etwas größeres Projekt) hoffe jeband von euch hat nen guten Tip. Schon mal danke im vorraus. C-Code: for(i=1;i<=8;i++) { lcd_clear(); set_cursor(2,2); lcd_string("Bitte warten...."); MOTOR_Links(); DELAY(DELAY_LS_1s); if(Spannung1>Spannung2) { Spannung2 = adcval; Time =i; } } uint8_t j =(8-Time); for(i=1;i<=j;i++) { lcd_clear(); set_cursor(2,2); lcd_string("Bitte warten...."); MOTOR_Links(); DELAY(DELAY_LS_1s); }
Hallo, du deklarierst und initialisierst Spannung1 einmal so: > uint16_t Spannung1 = adcval; und Spannung2 deklarierst und initialisierst du so: > uint16_t Spannung2 = 0; dann hast du in deiner For Schleife folgenden Vergleich: > if(Spannung1>Spannung2) > { > Spannung2 = adcval; > Time =i; > } Das heist, die erste Prüfung dieser Bedingung wird mit grosser Warscheinlickeit immer klappen. Ausser der ADC liefert rein zufällig 0. Im Prinzip vergleichst du momentaner ADC Wert > 0(zB. 128 > 0). So. Jetzt befindet sich dein Programm in dem Codeblock der zur If Bedingung gehört. Dort weisst du Spannung2 einen neuen ADC Wert zu. Sollte dieser allerdings zufällig höher als Spannung1 sein (zB. 256), wird beim erneuten durchlaufen der For Schleife die If Bedingung nie mehr war. Der Vergleich würde jetzt lauten 128 > 256. Besser wäre zb. folgender Code: uint16_t MaximalWert = 0; for(....{ ... ... Momentanwert = AdcValue(); if(MomentanWert > MaximalWert){ ... ... MaximalWert = MomentanWert; } ... ... } gruss ralf
Hi erst einmal danke für die Antwort. hatte das wie folgt umgesetzt: for(i=1;i<=8;i++) { Spannung_mom = adcval; if(Spannung_mom>Spannung_max) { Spannung_max = Spannung_mom; Time =i; } } hat aber leider nicht funktioniert :-(
Ja. Ist klar. Du machst folgendes: > uint16_t adcval; > uint16_t Spannung1 = adcval; > uint16_t Spannung2 = 0; und dann später > Spannung_mom = adcval; Wo kommt aber adcval her? gruss Ralf besser wäre sicher > uint16_t Spannung1 = ReadChannel(1); > Spannung_mom = ReadChannel(1);
also du meinst dass das ganze so aussehen soll: uint16_t Spannung_mom ; uint16_t Spannung_max = 0; uint16_t Time = 0; uint8_t i; ... for(i=1;i<=8;i++) { Spannung_mom = ReadChannel(1); if(Spannung_mom>Spannung_max) { Spannung_max = Spannung_mom; Time =i; } } Ich hoffe das ich das richtig umgesetzt habe wenn ja funktioniert das wiklich nicht!
Ja. So sollte es aussehen. Spannung_mom bekommt vor der if Bedingung den neuen ADC Wert. Ist Spannung_mom grösser als der alte Maximalwert (Spannung_max) wird anschliessend in Spannung_max der neue Wert gespeichert. Ich denke dieser Codeteil ist jetzt so ok. Du hast ja ein LCD angeschlossen bzw benutzt auch den UART. Versuch doch mal Debugausgaben zu machen. nach der Zuweisung Spannung_mom = ReadChannel(1); zeigst du dir folgende Werte an: # Spannung_mom # Spannung_max und nach der If Bedingung nochmal Spannung_max. Zum Beispiel so: Spannung_mom = ReadChannel(1); send_int(Spannung_mom); send_int(Spannung_max); if(Spannung_mom>Spannung_max) { Spannung_max = Spannung_mom; Time =i; } send_int(Spannung_max); Dies sollte zeigen das diese Codestelle funktioniert. Vielleicht funktionert ReadChannel nicht richtig. Darauf würde man mit diesen Ausgaben auch schliessen können. Oder deine Hardware ist nicht richtig angeschlossen. Hast du schon überprüft, ob der ADC vernünftige Werte vom Solarpanel wandelt und diese auch mal mit einem Multimeter nachgemessen? gruss ralf Offtopic Fühl dich nicht angegriffen. Ich wollte halt nur kurz und so präzise wie möglich zeigen wo ich Probleme sehe und wie ich sie gelöst hätte.
Ach quatsch fühl mich überhaubt nicht angegriffen, eher verzweifelt. Readchannel ADU usw funktioniert einwandfrei hab das Ding so programmiert das ich es auch manuell steuern kann und mir auf dem Display die Spannung ausgegeben wird. Es liegt definitiv an dem Teil in der for schleife! Desweiteren lasse ich mir während des Drehvorgangs den werd der Variablen Spannung_max auf dem Display ausgeben und sehe das die Variable nur beim ersten vergleich überschrieben wird. Danke für die Mühe.
Zeige dir zusätzlich noch Spannung_mom an. Nur so kannst du sehen ob der Code wirklich nicht funktioniert. Vielleicht liefert der ADC beim ersten Durchlauf wirklich immer den höchsten Wert. Eine Lampe in der Nähe? Folgende Änderungen hätte ich noch gemacht. for(i=1;i<=8;i++){ lcd_clear(); set_cursor(2,2); lcd_string("Bitte warten...."); Spannung_mom = ReadChannel(1); if(Spannung_mom>Spannung_max){ Spannung_max = Spannung_mom; Time =i; } MOTOR_Links(); DELAY(DELAY_LS_1s); } // Das Panel steht zB auf Stelle 1 und dieser Wert wird getestet. // Erst dann die nächste Stelle anfahren. Dies für die restliche // 7 Stellen wiederholen. // Angenommen auf Stelle 5 ist der höchste Wert, so hat Time jetzt // den Wert 5. // Dies hier ( uint8_t j =(8-Time); ) ist ungünstig. Das Panel steht auf // Stelle 8 und soll auf Stelle 5. Mit dieser Anweisung fährt es aber // auf Stelle 3. Also weg damit. //Damit wird: for(i=1;i<=Time;i++) { lcd_clear(); set_cursor(2,2); lcd_string("Bitte warten...."); MOTOR_Links(); DELAY(DELAY_LS_1s); } Ich hoffe das der Motor auch in festen Schritten fährt. Sonst wär der Ansatz nicht gut gewählt. gruß ralf
hier mit hats funktioniert! for(i=1;i<=8;i++){ lcd_clear(); set_cursor(2,2); lcd_string("Bitte warten...."); Spannung_mom = ReadChannel(1); if(Spannung_mom>Spannung_max){ Spannung_max = Spannung_mom; Time =i; } MOTOR_Links(); DELAY(DELAY_LS_1s); } vielen vielen DANK :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.