mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit abspeichern von Variablen


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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);
        }

Autor: Gast (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Angang wurde nicht mit hochgelanden

Autor: Ralf W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :-(

Autor: Ralf W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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);

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Ralf W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Ralf W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.