www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Schleife + Verzögerung (mega8/Bascom)


Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!

Habe ein "kleines programmiertechnisches Problem":

Möchte gerne ein Programm haben, mit folgender "Teilfunktion":

Es soll den Wert von einem ADC einlesen, vergleichen ob sich dieser im
Gegensatz zu vorher geändert hat (ob also am Poti "gedreht" wurde),
wenn nein, dann soll das Programm fortlaufen die Werte 2er anderer ADCs
auslesen + anzeigen, ist dies aber nicht der Fall (und da tritt dann
auch mein "Problem" auf), also wenn am Poti "gedreht" wurde, soll
er eine neue "Anzeige" starten, bei der dann der Poti-Wert angezeigt
wird (soweit im Prinzip auch kein Thema), er soll jedoch wenn das Poti
wieder "losgelassen" wird, erst noch ein bisschen warten, bis er zur
Anzeige der beiden anderen ADCs wieder zurück kehrt.

Hat da jemand eine "Grundidee" für mich?!! Brauche keine konkrete
Syntax für Bascom, das ist kein Problem, eher so eine Idee wie:

"Schleife starten"...

"Schleife beenden"...

etc.

Danke schonmal im Voraus!

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schleifenbeginn
  ADC1 einlesen
  wenn ADC1 sich veränndert hat:
      ADC2 und ADC3 einlesen
      Anzeige aktualisieren
  wenn ADC1 sich nicht verändert hat:
      warte ein gewisse Zeit ([OT] auf den Weihnachtsmann,
                                   die Bahn [/OT]
Schleifenende

Und wo ist das Problem?

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast das glaube ich falsch verstanden:

Schleifenbeginn

ADC1 einlesen

Wenn ADC1 unverändert:
             ADC2 und ADC3 einlesen
             ADC2 und ADC3 ausgeben auf Display

Wenn ADC1 verändert:
           ADC1 einlesen
           ADC1 auf Display ausgeben

Schleifenende

So, wenn ich jetzt vor das Schleifenende die Verzögerung lege, dann
verzögert er das ja bei jedem Durchlauf der Schleife, und ich kann am
Poti drehen, aber es tut sich nichts...

Ich hoffe das Problem ist jetzt klar geworden?!?!

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schleifenbeginn

ADC1 einlesen

Wenn ADC1 unverändert:
             ADC2 und ADC3 einlesen
             ADC2 und ADC3 ausgeben auf Display

Wenn ADC1 verändert:
           ADC1 einlesen
           ADC1 auf Display ausgeben
           Warten

ADC2 und ADC3 ausgeben auf Display

Schleifenende
So vielleicht?

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann habe ich ja auch wieder das Problem: ich drehe am Poti, der
Controller "registriert" eine Veränderung des Werte, springt in den
2. Teil der Abfrage ("ADC1 verändert"), gibt auch den ADC1-Wert aus,
und wartet dann => wenn ich jetzt weiter am Poti drehe, bekomme ich die
Änderung erst nach der Wartezeit wieder... :-/
Aber danke soweit für die Hilfe!

Hat noch jemand eine Idee?!?

Autor: Peter Schwarz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sprich, solange am Poti gedreht wird, soll dieser Wert angezeigt werden.
Wenn dann nicht mehr gedreht wird, soll dieser Wert noch eine gewisse
Zeit angezeigt werden.

Dann sollen wieder die anderen 2 Werte angezeigt werden. Korrekt ?

Schleifenbeginn

ADC1 einlesen

IF ADC1 verändert:
           ADC1 einlesen
           ADC1 auf Display ausgeben
           ADC1-Flag setzen
END IF

IF ADC1 unverändert:
     IF ADC1-Flag gesetzt
             Warten
             ADC1-Flag löschen
     ELSE
             ADC2 und ADC3 einlesen
             ADC2 und ADC3 ausgeben auf Display
     END IF
END IF


ADC2 und ADC3 ausgeben auf Display

Schleifenende

Autor: Peter Schwarz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ADC2 und ADC3 ausgeben auf Display am Ende gehört natürlich weg.

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber so wie ich das sehe, würde er ja dann zuerst (also wenn ADC1
verändert ist) das hier machen:

(IF ADC1 verändert:)
           ADC1 einlesen
           ADC1 auf Display ausgeben
           ADC1-Flag setzen

Aber er macht das dann doch nur ein mal, oder?!? (Ist ja soweit auch
"gewollt" denke ich, ich frage nur wegen des Verständnisses)

Aber er geht ja dann weiter im Programm, fragt ob ob das "Flag"
gesetzt ist, was ja dann der Fall ist, und wartet also...

Aber das soll er ja gerade nicht?!? Weil dann wartet er ja, geht dann
wieder raus, zeigt ADC2 und ADC3 an, und fragt dann erneut ab...

Aber so die "Grundidee" mit dem "Flag" (Ich denke du meinst damit
einfach nur eine Variable, die ich setze?!?!) könnte man ja mal
"weiterdenken"...

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Prinzip brauchst du dann eine Art Entprell-Routine für ADC1: solange
ADC1 sich ändert, ADC1 anzeigen. Danach einen Moment warten und die
beiden anderen anzeigen.
Scheifenbeginn
   Schleifenbeginn
     frage ADC1 ab
     zeige ADC1-Wert an
   Schleifenende, wenn ADC1 sich nicht verändert hat.
   warte einen Moment
   Schleifenbeginn
      Zeige ADC2 und ADC3 an
   beende Schleife, wenn ADC1 sich verändert hat
Schleifenende

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mmmmh...ich hatte mir folgendes gedacht (ist so ähnlich wie da von Peter
Schwarz):

Schleifenanfang

     ADC1-Abfragen
     Wenn ADC1 = Verändert
     ADC1 anzeigen
     ADC1-"Flag" setzen
     Wenn ADC1 = unverändert
        wenn ADC1-Flag = gesetzt
                Warten
                ADC1-"Flag" zurück setzen
       Sonst
         ADC2 und ADC3 anzeigen
       Ende Wenn-Abfrage
Ende schleife

So (oder so ähnlich) sollte es klappen...oder ich versuch einfach mal
in Bascom über die Simulation, aber ob es das bringt?!?!

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, ich hab das jetzt mal versucht, aber irgendwie klappt das alles
nicht, bin momentan auch etwas "unschlüssig", wie ich die Abfrage
"ADC1 verändert oder nicht" hinbekommen soll... :-/

Wenn da vielleicht jemand nen Tip hätte!??!?!

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will ja nicht rumnölen, aber eigentlich solltest du wissen, wie du
das haben willst. Um sich den Ablauf klarzumachen benutzt man auch
gerne solche altmodischen Gerätschaften wie einen Bleistift und ein
Blatt Papier. (oder auch mehrere...).
Auf dieses Blatt kann man solche Sachen wie Ablaufpläne oder
Struktogramme, also Programme ohne Programmiersprachenbezug aufmalen.
Ausserdem solltest du dir darüber im Klaren sein, welche
Funktionsblöcke du hast/brauchst.
Übrigens macht meine Version exakt das Gleiche...nur dass ich mir ein
Flag spare, und im Einschaltmoment die Pause gemacht wird, da die
Variable in der der ADC1-Wert zwecks Vergleich enthält ("Hat ADC1 sich
verändert?") noch nicht den ADC1-Wert enthält.
Das kann man entweder dadurch abstellen, dass man vor Beginn der
Schleife in diese Variable den ADC1-Wert einliest, oder man ignoriert
die Pause, verkauft sie als neues "Feature" (Es ist ja vielleicht
auch interessant zu Beginn des Betriebs den ADC1-Wert zu lesen).
Aber wenn du nicht mal weißt, wie du solche Probleme löst, solltest du
dir vielleicht lieber die Freizeitbeschäftigung "Briefmarken- /
Kronenkorkensammeln" aussuchen.
Merkt man, dass ich etwas angepestet bin?
Schön...

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super, genau den Beitrag habe ich gebraucht, nachdem ich vorhin ungefähr
10 Blatt Papier vollgeschrieben hab, und jetzt immer noch hier sitze,
und es mal "live" probiert habe, also im Simulationsmodus von
Bascom!!

Aber danke für deinen geistreichen Beitrag, hat mich echt aufgebaut,
und ich bin frohen Mutes, da jetzt mit vollem Elan weiter zu machen!!

TOP!!

Ich weiß doch wie ich es haben will! Hab ich doch schon 3 mal gepostet
mindestens!!

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Poste doch mal deinen Code bisher...
Freut mich, dich aufgebaut zu haben...

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, bis lang habe ich das hier:

$regfile = "m8def.dat"
$crystal = 3686400

Dim X As Word
Dim Y As Word
Dim Z As Word
Dim B As Bit


Do
While Y = Y      'Einfach mal "laufen" lassen



If X <> X Then  ' Wenn X sich geändert hat

X = Getadc(0)

Cls
Upperline
Lcd X
B = 1                      '"Flag" setzen

Else

If B = 1 Then

Waitms 500

B = 0

Else

Z = Getadc(1)

Cls
Upperline
Lcd Z

End If
End If
Wend


Loop



So mal "ganz grob" für mich programmiert...

Habe es mal simuliert, aber wie gesagt, da ändert sich nichts, wenn ich
am ADC0 was ändere...

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab mal den ersten Fehler "selber" gefunden:

X ist ja immer gleich X, weil selbst wenn er am Anfang die Variable
"irgendwie" setzt, sind sie ja gleich, also springt er da schonmal
nicht rein... :-/

Aber wie löse ich es dann?

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs mal damit:

$regfile = "m8def.dat"
$crystal = 3686400

Dim X As Word
Dim Y As Word
Dim Z As Word
Dim B As Bit

X = Getadc(0)
Do
While Y = Y      'Einfach mal "laufen" lassen Endlosschleife?
   b=0
   If X <> Getadc(0) Then  '
    X = Getadc(0)
    Cls
    Upperline
    Lcd X          'ADC1-Wert anzeigen
    B = 1          '"Flag" setzen
  End If
  If B = 1 Then
   Waitms 500
   B = 0
  End If
  Z = Getadc(1)
  Cls
  Upperline
  Lcd Z
Wend
Loop  '2 Endlosschleifen?

Meine Variante:

$regfile = "m8def.dat"
$crystal = 3686400

Dim X As Word
Dim Y As Word
Dim Z As Word
Dim B As Bit

X = Getadc(0)

While 1      'Endlosschleife
  do
    Y = Getadc(0)
    Cls
    Upperline
    Lcd X          'ADC1-Wert anzeigen
  loop while X<>Y
  Waitms 500 'ADC1 hat sich nicht mehr verändert
  do
    Z = Getadc(1)
    Y = Getadc(0)
    Cls
    Upperline
    Lcd Z
  loop while X<>Y
Wend

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht fällt dir noch was auf: Grupppiere Anweisungen durch
Einrückungen. Und spare nicht an sinnvollen Kommentaren. Selbst wenn du
nur so für dich was machst, helfen Kommentare meistens zu verstehen, was
man eigentlich mit dem erreichen will, was man da gerade geschrieben
hat, und wenn man später ins Programm guckt, muß man nicht erst wieder
den Code "aufdröseln", um zu verstehen, was da steht...

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, da hast du wohl recht...habe auch leider den Code gelöscht, wo ich
es am laufen hatte, nur halt ohne die Verzögerung...aber ich mach für
heute sowieso erstmal Ende, das bringt nix mehr, hab gar keinen Elan
mehr irgendwie...

Danke soweit für die Hilfe, ich meld mich morgen mal wieder, wenn ich
wieder klar denken kann... ;-)

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gute Idee.

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Code will übrigens nicht so ganz, bzw. Bascom "kennt" die
Anweisung nicht, der macht nur "Loop Until [Bedingung]"

Aber auch wenn ich das "umstricke" klappt dat irgendwie nicht...

Aber der Akku ist bei mir jetzt echt "alle", ich geh mal lieber
pennen, und morgen dann "frisch" ans Werk... ;-)

Autor: Peter Schwarz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube den Ansatz mit dem wait würde ich schon gar nicht machen. In
der Zeit, tut das Program nämlich gar nix, auch wenn man am Poti dreht
und ich würde schon gerne eine Echtzeitanzeige haben wollen.

Vielleicht würde ich es so machen:

Zaehler = 0
NeuADC1 = <ADC1 einlesen>
While 1=1 'um bei dem Beispiel oben zu bleiben mit der Endlosschleife
  AltADC1 = NeuADC1
  NeuADC1 = <ADC1 einlesen>
  ADC2 = <ADC2 einlesen>
  ADC3 = <ADC3 einlesen>
  If Zaehler > 0
     Display NeuADC1
     Zaehler = Zaehler - 1
  Else
    If NeuADC1 <> AltADC1
       Display NeuADC1 'könnte man hier aber auch weglassen
       Zaehler = <StartWert wieder> 'ausprobieren was passt
    Else
       Display ADC2
       Display ADC3
    End If
Wend

Nach dem Start passiert erst mal nix und ADC2+3 werden ausgegeben. Wenn
sich dann was am Poti ändert (ADC1) gehts los in der Schleife.
Der Zaehler wird runtergezählt und der aktuelle Wert ausgegeben.
Passiert in dieser Zeit dann irgenwann nix mehr, läuft der Zähler
komplett runter bis auf 0 und dann werden wieder ADC2+3 ausgegeben.

Wahrscheinlich kommt jetzt wieder einer mit 'Ja, aber geht doch viel
einfacher'. Mag sein, aber so auf die schnelle würde ich erst mal
machen. Sollte jetzt noch ein Fehler drin sein, dann selbst debuggen,
Fehler ausmerzen und freuen.

Autor: Peter Schwarz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da fehlt noch ein End If vor dem Wend, aber das meckert Bascom schon an
;)

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter!!

Dein Ansatz klingt echt vernünftig und verständlich, werde ich direkt
zu Hause mal versuchen!!

Mit den "Feinheiten" von Bascom etc. komme ich schon klar (habe heute
wieder einen wesentlich klareren Kopf als gestern. ;-)), das
Grundprinzip von dir scheint "auf dem Papier" auch zu laufen, ich
denke das wird am Controller selber auch laufen...

Melde mich dann später mal, wie es so "läuft"... ;-)

Autor: GMB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, hab's ausprobiert, es funktioniert!

Danke dir vielmals! Ärgere mich zwar, das ich nicht selber drauf
gekommen bin, aber gestern war echt der Akku "leer"...

Autor: Peter Schwarz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Freut mich :) Diese simplen Funktionen sind manchmal doch mit etwas
'Hirnschmalz' zu lösen, vor allem weil man sowas ja wirklich
tagtäglich bei allen möglichen Geräten sieht z.B. Lautstärkeanzeige bei
einem Radio.

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.