Forum: Mikrocontroller und Digitale Elektronik Tasterbetätigung hochzählen u. vergleichen (in C)


von Alfred F. (bluedeep)


Lesenswert?

Hallo,

ich habe einen ATmega16 und möchte als Programmiersprache "C" verwenden.

Ich habe folgendes Problem: Ich möchte durch betätigen eines Tasters am 
Eingang des µC die Tasterbetätigungen hochzählen und somit immer einen 
Wert bzw. eine Zahl einstellen. Wenn diese Zahl eingestellt ist, dann 
soll wiederrum ein anderes Signal, welches ich über eine Lichtschranke 
einspeise hochgezählt werden. Wenn dieses Signal genau so oft gekommen 
ist, wie mein eingestelltes Signal vom Taster, dann soll eine LED 
leuchten.

Den Wert vom Taster möchte ich auch an einem LCD anzeigen lassen, 
ähnlich wie bei einer 7-Segment-Anzeige.

Leider weiß ich einfach nicht wo ich anfangen soll und wie ich das am 
besten realisieren könnte, da ich noch Anfänger bin.

Vielleicht kann mir ja einer etwas helfen oder mich auf den richtigen 
Weg bringen.

von Torsten (Gast)


Lesenswert?

Es ist immer etwas schwierig da Tipps zu geben, wenn "Anfänger" fragen 
und nicht mit allen Infos rausrücken.

Hast du schonmal ein C-Programm geschrieben?
Kennst du dich mit dem Controller aus? Stichwort Interrupt
Liegt der Controller bei dir lose rum und du musst noch eine Platine 
entwerfen oder hast du ein fertiges Board?

von Karl H. (kbuchegg)


Lesenswert?

Pflichte Torsten bei.

Wichtig wäre zu wissen: welche Teile kriegst du alleine hin und wo 
hapert es?
Je nachdem ist deine Aufgabe schon viel zu schwer für dich oder du 
suchst im anderen Extremfall einfach nur nach einer brauchbaren 
Tastenentprellung, die du zb hier >>>Entprellung<<< findest.

von Alfred F. (bluedeep)


Lesenswert?

Danke zuerst für die schnelle Antwort. Ein C-Programm habe ich schon Mal 
geschrieben, allerdings ist das auch schon eine Weile her. Programmieren 
tue ich alles mit AVR Studio und ein Board habe ich auch. Das Board habe 
ich selbst gebaut und ich habe damit auch schon einiges getestet.

Mein Problem liegt eher darin, dass ich nicht genau weiß, wie ich dies 
programmieren kann bzw. wo ich anfangen soll. Muss ich da einen Zähler 
verwenden oder brauch ich eher Arrays? Irgendwie komm ich nicht ganz zum 
Anfang.

von Peter D. (peda)


Lesenswert?

Alfred Flöckchen schrieb:
> Leider weiß ich einfach nicht wo ich anfangen soll

Natürlich mit einem Programmablaufplan. Schreib in Worten hin, was alles 
wann und wie ablaufen soll.

Alfred Flöckchen schrieb:
> möchte als Programmiersprache "C" verwenden.

Das Coden kommt erst viel viel später.
Erst muß der Plan stehen und logisch korrekt (nachvollziehbar) sein.


Peter

von Alfred F. (bluedeep)


Lesenswert?

Hallo Peter,

ich habe ja schon ganz oben beschrieben, wie das ganze ablaufen soll.

von Torsten (Gast)


Lesenswert?

Alfred Flöckchen schrieb:
> Das Board habe
>
> ich selbst gebaut und ich habe damit auch schon einiges getestet.

Alles klaro.
Dann zeig uns mal den Schaltplan. Dann sind wir einen Schritt weiter

von Karl H. (kbuchegg)


Lesenswert?

Alfred Flöckchen schrieb:
> Hallo Peter,
>
> ich habe ja schon ganz oben beschrieben, wie das ganze ablaufen soll.

Gut.
Und jetzt gehst du einen Schritt weiter und formalisierst das ganze 
etwas strenger.
Geh einfach mal davon aus, dass es eine Funktion gibt, die dir sagt, ob 
ein Tastendruck (respektive eine Unterbrechung der Lichtschranke) 
registriert wurde oder nicht (darum kümmern wir uns später).

wie sieht dann dieser Plan aus

  mache endlos
  {

    .... hier kommt deine Logik rein

  }


wie muss der Teil 'deine Logik' aussehen?


Hier nochmal deine Beschreibung
> Ich möchte durch betätigen eines Tasters am Eingang des µC die
> Tasterbetätigungen hochzählen und somit immer einen Wert bzw.
> eine Zahl einstellen. Wenn diese Zahl eingestellt ist, dann
> soll wiederrum ein anderes Signal, welches ich über eine
> Lichtschranke einspeise hochgezählt werden.

Dazu solltest du dir auch noch ein paar zusätzliche Fragen überlegen:
* Im Moment zählst du deine Vergleichszahl immer nur hoch
  Muss diese Vergleichszahl auch wieder verringert werden?
  Was ist wenn sich der Benutzer vertan hat und die Zahl zu
  hoch eingestellt hat? Was tut er dann?

* Unter der Annahme, dass sich an der Lichtschranke ständig und
  regelmässig etwas tut (wie zb Bauteile die auf einem Förderband
  vorbeilaufen), woher weiß der µC eigentlich, wann die ganze
  Zählerei beginnen soll?


> Muss ich da einen Zähler verwenden oder brauch ich eher Arrays?
Logisch überlegen! Worum geht es? Es geht um EINE einzelne Zahl. Die 
wird erhöht oder verringert.
Dazu brauchst du kein Array. Ein Array nimmt man, wenn man eine Anzahl 
gleichartiger Dinge in eine gemeinsame Datenstruktur bringen möchte, 
wobei die Anzahl meistens deutlich größer als 2 ist oder es sonst gute 
Gründe gibt, die Dinge gleich zu behandeln.
Du hast aber keine 'Anzahl gleichartiger Dinge'. Alles was du brauchst 
ist eine Zahl die größer/kleiner werden kann.

von Peter D. (peda)


Lesenswert?

Alfred Flöckchen schrieb:
> ich habe ja schon ganz oben beschrieben, wie das ganze ablaufen soll.

Nö, Du hast nur einige ungenaue Brocken in den Raum geworfen.

Du mußt die Funktion so vollständig beschreiben, daß ein anderer es 
programmieren kann, ohne Dich nochmal fragen zu müssen.

Karl Heinz hat schon einige fehlende Punkte genannt.


Alfred Flöckchen schrieb:
> Wenn dieses Signal genau so oft gekommen
> ist, wie mein eingestelltes Signal vom Taster, dann soll eine LED
> leuchten.

Die sind ja schon beim Einschalten gleich (beide 0), also leuchtet die 
LED sofort?

Bist Du sicher, daß Du mit nur einem Taster auskommst?

Wie gehts weiter, nachdem die LED leuchtet. Leuchtet sie immer weiter 
bis die Erde explodiert?

Usw. usw.


Stell Dir vor, Dein Mathelehrer stellt Dir eine Textaufgabe. Dann sind 
darin ja alle nötigen Informationen enthalten, um sie zu lösen.
Und nun mußt Du eben eine solche Textaufgabe stellen.


Peter

von Alfred F. (bluedeep)


Lesenswert?

Danke Karl Heinz und Peter, ihr habt recht. Ich hab wohl einiges 
vergessen zu schildern, wie ich mir das so geplant habe.

Ich werde es noch mal versuchen, dies genauer zu erklären.

Also:

-Taster T1 für Wert einstellen durch mehrmaliges drücken des Tasters ( 1 
x   drücken = Wert 1 oder in dem Fall Zahl 1)...2 x drücken = Wert 2 
usw.

- (später) möchte ich den Wert auch am Display anzeigen lassen

-T2 um Lichtschrankensignal anfangen zählen zu lassen

-Wenn beide "Null", also Taster T1 und T2 nicht gedrückt wurde, soll 
nichts passieren

- Wenn Lichtschranke so oft gezählt wurde, wie von Taster 1 vorgegeben 
wurde, dann soll ein Ausgang kommen (LED an) und sonst nichts mehr. Das 
heist, dass die Signale der Lichtschranke dann nicht mehr gezählt werden 
müssen

-Taster T4 soll dann für den Reset sein, um den Anfangszustand wieder 
herstellen zu können.

Ich hoffe, dass dies jetzt vielleicht etwas verständlicher ist, als 
zuvor.

von UR-Schmitt (Gast)


Lesenswert?

Alfred Flöckchen schrieb:
> Ich hoffe, dass dies jetzt vielleicht etwas verständlicher ist, als
> zuvor.

Dann fang doch damit mal an, du hast doch einen µC und damit auch schon 
programmiert.
Schliesse einen Taster und ein Display an und bringe ihn datu im Display 
anzuzeigen wie oft du gedrückt hast und dann 'später' beim nächsten 
Tastendruck das Ganze wieder auf 0 zu stellen.

Oder um nach Karl Heinz zu sprechen:
Zerlege dein Problem so lange in kleinere Häppchen bis du die einen nach 
dem anderen lösen kannst.

von Karl H. (kbuchegg)


Lesenswert?

Alfred Flöckchen schrieb:
> Danke Karl Heinz und Peter, ihr habt recht. Ich hab wohl einiges
> vergessen zu schildern, wie ich mir das so geplant habe.

Das ist nicht ungewöhnlich.
Auch das muss man lernen und während man das lernt, merkt man erst, wie 
ungenau und missverständlich wir uns im täglichen Leben ausdrücken. Dass 
es trotzdem nicht zum Chaos kommt, liegt daran, dass dein Gegenüber 
normalerweise ebenfalls ein Mensch ist, der mitdenkt.

Nur: Hier hast du es nicht mit einem Menschen zu tun, sondern mit einer 
Maschine. Und die denkt eben nicht mit. Der musst du jede Kleinigkeit 
exakt und eindeutig beibringen. Und dazu musst du erst mal selber deine 
Gedanken ordnen. Solange du selber nicht exakt beschreiben kannst, was 
in welcher Situation passieren soll, solange kann man auch kein Programm 
dafür schreiben.


> Also:
>
> -Taster T1 für Wert einstellen durch mehrmaliges drücken des Tasters ( 1
> x   drücken = Wert 1 oder in dem Fall Zahl 1)...2 x drücken = Wert 2
> usw.
>
> - (später) möchte ich den Wert auch am Display anzeigen lassen
>
> -T2 um Lichtschrankensignal anfangen zählen zu lassen
>
> -Wenn beide "Null", also Taster T1 und T2 nicht gedrückt wurde, soll
> nichts passieren
>
> - Wenn Lichtschranke so oft gezählt wurde, wie von Taster 1 vorgegeben
> wurde, dann soll ein Ausgang kommen (LED an) und sonst nichts mehr. Das
> heist, dass die Signale der Lichtschranke dann nicht mehr gezählt werden
> müssen
>
> -Taster T4 soll dann für den Reset sein, um den Anfangszustand wieder
> herstellen zu können.
>
> Ich hoffe, dass dies jetzt vielleicht etwas verständlicher ist, als
> zuvor.

Schon besser.
Trotzdem musst DU jetzt erst mal den nächsten Schritt machen. 
Formalisier das ganze etwas strenger.
Wichtig: Kümmere dich nicht um konkrete Details einer 
Programmiersprache. Die sind jetzt noch nicht wichtig. Du kannst das 
ganze ruhig in einer schlampigen Schreibweise schreiben, wichtig ist 
nur, dass du die typischen Elemente deiner Programmiersprache benutzt. 
(Also zb ein if. du weißt was ein if macht und in dieser vorgesehenen 
Verwendung benutzt du das dann auch. Ob du dich mit den Klammern 
verhaust oder nicht ist zum jetzigen Zeitpunkt erst mal zweitrangig)

(Dein Problem ist nämlich: Du versuchst zu früh, viel zu früh, in einer 
realen Programmiersprache zu arbeiten. Dir ist noch nicht klar, wie die 
Logik deiner Problemlösung aussieht. Die muss als allererstes stehen 
und dazu sind syntaktische Details wie Strichpunkte völlig 
uninteressant)


Also

  while( immer )
  {

     Logik

  }

wie muss die Logik aussehen? Ich helfe mal ein wenig:


  VorgabeAnzahl = 0
  Lichtschrankenanzahl = 0

  VorgabeAnzahl auf LCD ausgeben

  while( immer )
  {
    if Taste1 gedrückt
      erhöhe die VorgabeAnzahl um 1
      VorgabeAnzahl auf LCD ausgeben

    ....

  }


wie gehts weiter? Was muss noch im Teil '.....' erfasst werden?

von Alfred F. (bluedeep)


Angehängte Dateien:

Lesenswert?

Hallo Karl Heinz,

ich habe jetzt mal versucht das ganze in einem Programm umzusetzen. Das 
Programm bringt zwar keinen Fehler mehr, allerdings brennt die LED vom 
Ausgang auch nicht.

Vielleicht kannst du oder jemand anderes mal drüberschauen.Liegt es 
eventuell an den Klammern. Irgendwie weiß ich grad nicht mehr weiter.

von MaWin (Gast)


Lesenswert?

> allerdings brennt die LED vom Ausgang auch nicht.

Wie sollte sie auch. Du schreibst selbst:

"PORTD = 0xff; /*PortD alle Ausgänge (LED`s) auf 1 (LED´s leuchten aber 
nicht, da bereits high-Signal über die Pull-ups da ist*/"

Offenbar leuchtet also deine LED nur, wenn du den Ausgang auf 0 (low) 
stellst, was diese Funktion niemals kann:

"PORTD|= (1<<PC1); //PC4 auf 1 setzen"

Besonders elegant in dem Programm ist, daß es zwar eine LED-Funktion zum 
(ein)ausschalten der LED gibt, aber aus (ein)schalten tust du sie auf 
komplett andere Weise

//PORTD = 0xfd;  //PORTD PD1 LED

ist aber uaskommentiert.



Es herrscht ein ziemliches logisches Durcheinander bei dir. Kein Wunder, 
daß der Prozessor nicht tut, was du dir erträumst.

von Karl H. (kbuchegg)


Angehängte Dateien:

Lesenswert?

MaWin schrieb:

> Es herrscht ein ziemliches logisches Durcheinander bei dir. Kein Wunder,
> daß der Prozessor nicht tut, was du dir erträumst.


Kann man wohl sagen.
Ich häng mir das Programm trotzdem als C-File hier ein, damit wenigstens 
das Syntax-Coloring greift.

Alfred, dein Code ist ein Musterbeispiel dafür was rauskommt, wenn man 
sich im Vorfeld die Logik des Programmes nicht überlegt.
Einen Haufen Varialen, die keiner braucht
Tastenabfragen, die so nicht vernünftig sind
Die Logik ist kaum erkennbar, etc. etc.

Ein Compiler erkennt Syntaxfehler! Die Logik des Programmes ist dein 
Bier! Laut Duden ist der Satz

   Das Flugzeug erntete die Essstäbchen.

absolut korrekt. Er hat Subjekt, Prädikat, Objekt. Die Artikel sind 
richtig, das Verb steht in einer korrekten Zeitform.

Trotzdem ist dieser Satz so unsinnig, dass es ärger nicht mehr geht. Die 
'Logik' des Satzes stimmt nicht, auch wenn der Duden keine Einwände 
gegen den Satz hat.

von Jens (Gast)


Lesenswert?

wer nicht hört muss fühlen :-)

Die User haben dir jetzt2 mal vorgeschlagen erstmal die Logik zu machen, 
beim zweiten mal sogar schon angefangen das aufzuzeichnen... was machst 
du, postest ein Programm.

Ich wäre nun so weit dass ich dir weiterhin alles gute wünschen würde.

JJ

von Alfred F. (bluedeep)


Lesenswert?

MaWin schrieb:
> Offenbar leuchtet also deine LED nur, wenn du den Ausgang auf 0 (low)
> stellst, was diese Funktion niemals kann:
>
> "PORTD|= (1<<PC1); //PC4 auf 1 setzen"

So, jetzt habe ich das mal in PORTD&= ~(1<<PC1); geändert, da meine 
LED´s ja schon ein high-Signal zwecks Pull-up besitzen.

Danke :-)  Leider hat dies an der Situation nichts geändert. Die LED 
bleibt trotzdem aus.

Na, dass der Rest auskomentiert war, das hast du aber gut bemerkt. Das 
war ja auch nur für einen Test und hat damit nichts zu tun.

Danke dir trotzdem sehr

von Alfred F. (bluedeep)


Lesenswert?

Ist echt schade, dass man einem Anfänger hier nicht helfen kann und 
diesem stattdessen nur Kritik an den Kopf wirft, wie z.B. diese von 
Jens.
Ich habe es ja versucht, aber leider fehlt mir hier ja die Logik, sonst 
müsste ich ja auch nicht fragen. Man könnte grad denken, hier sind alle 
Meister vom Himmel gefallen.
Es ist ja nicht nur bei mir so. Auch in anderen Beiträgen fällt es immer 
wieder auf, dass Anfänger eher kritisiert werden, als dass man ihnen 
hilft.

von Jens (Gast)


Lesenswert?

hör auf zu heulen und mach das:


  VorgabeAnzahl = 0
  Lichtschrankenanzahl = 0

  VorgabeAnzahl auf LCD ausgeben

  while( immer )
  {
    if Taste1 gedrückt
      erhöhe die VorgabeAnzahl um 1
      VorgabeAnzahl auf LCD ausgeben

    ....

  }



doch mal weiter.

Das ist doch quark, nur weil ich erwähnt habe, dass du kaum auf die 
Ratschläge eingehst?

Dann kann ich auch heulen, dass man hier ständig user betreut, die 
wollen hilfe, wenn man welche gibt, nehmen sie diese aber nicht an.

JJ

von Jens (Gast)


Lesenswert?


von Peter D. (peda)


Lesenswert?

Alfred Flöckchen schrieb:
> ich habe jetzt mal versucht das ganze in einem Programm umzusetzen. Das
> Programm bringt zwar keinen Fehler mehr, allerdings brennt die LED vom
> Ausgang auch nicht.

Warum wundert das hier niemanden?
Weil Du den letzten Schritt vor dem ersten machst.

Es ist ein Unterschied, ob man Kartoffeln zuerst kocht oder die rohen 
Kartoffeln ißt und dann kochendes Wasser hinterher trinkt. Eins davon 
geht richtig schief.


Alfred Flöckchen schrieb:
> Auch in anderen Beiträgen fällt es immer
> wieder auf, dass Anfänger eher kritisiert werden, als dass man ihnen
> hilft.

Was erwartest Du denn:

1. Schlaraffenland:
Hier ist das fertige Programm.

2. Unehrlich sein:
Gut so.
Mach weiter, bis Du selber merkst, daß es ne Sackgasse ist.

3. Ehrlich sein:
Gehe schrittweise heran.
Und nein, ich mache es nicht für Dich.


Wenn gesagt wird, Du mußt zuerst den Ablauf beschreiben, dann nicht, um 
Dich zu ärgern. Und am besten geht dazu Papier und Bleistift.
Du kannst auch gerne Deine Kritzeleien dann zur Begutachtung einscannen. 
Ist auf alle Fälle besser als undurchdachter Code.

Ein erfahrener Programmierer fängt mit einer neuen Entwicklung an, indem 
er den PC ausschaltet (zu neudeutsch: Brainstorming).


Peter

von Karl H. (kbuchegg)


Lesenswert?

Alfred Flöckchen schrieb:

> Ich habe es ja versucht, aber leider fehlt mir hier ja die Logik, sonst
> müsste ich ja auch nicht fragen.

Du hast es doch noch gar nicht versucht!
Genau darum geht es doch. DU musst das machen. Es hilft dir nichts, wenn 
ICH das für dich übernehme. Um die Logik zu erstellen brauchst du keine 
Programmiersprache - du brauchst Papier und Bleistift.
Und ehe du die Logik nicht im Kasten hast, kannst du auch kein Programm 
schreiben. So einfach ist das.


> Man könnte grad denken, hier sind alle
> Meister vom Himmel gefallen.

Das sind wir sicher nicht.
Aber rate mal, wie wir gut geworden sind?
Sicher nicht dadurch, dass wir unsystematisch alle möglichen 
Codeänderungen durchprobiert haben.

Du siehst nur das Ergebnis. Die Jahre, die wir mit genau dieser Methode 
'Erst die Logik auf Papier und Bleistift skizzieren' verbracht haben, 
die siehst du nämlich nicht. Und du siehst auch nicht die Notizen, die 
wir uns heute immer noch, nach 30 Jahren zu Problemen machen. Willst du 
mal meinen Notizblock sehen? Da sind Skizzen drauf (weil ich im Bereich 
CAD arbeite), da sind Zusammenhänge drauf, da sind Berechnungen drauf, 
da sind Formeln drauf, das sind Krizzeleien drauf und Geschmiere. Da 
sind Ablaufdiagramme drauf und Codeskizzen. Und egal was dir wer 
erzählt, wie toll das nicht alles geht mit diversen Hilfsprogrammen die 
Logik zu erfassen .... mit meinem Notizblock und einem Bleistift bin ich 
5 mal so schnell, mir einen Überblick über ein Problem zu verschaffen, 
die Sonderfälle zu identifizieren und mir das ganze so aufzubereiten, 
dass ich eine Logik hinkriege, die ich dann auch implementieren kann. 
Und ehe ich sie implementiere, skizziere ich mir die Logik (damit ich 
sie nicht vergesse), male mir ein paar Beispiele auf und wende genau 
diese skizzierte Logik auf die Probleme an (Ja, ich spiele Computer der 
diese Logik als Programm auffasst und abarbeitet) um zu sehen, ob sie 
das Problem überhaupt lösen oder ob ich etwas übersehen habe.

Ich verbrauch in 2 Jahren ungefähr 3 Stück Din-A4 Collegeblocks.


Und ob da jetzt eine LED durch
   PORTA |= ( 1 << BIT );
eingeschaltet wird oder nicht, spielt in der Codeskizze überhaupt keine 
Rolle. Das ist ein Implementierungsdetail. Auf der Skizze steht nur 
"Fehlerled einschalten".

von Jens (Gast)


Lesenswert?

wenn du es doch lieber in codeform machen willst dann geht auch:

http://de.wikipedia.org/wiki/Pseudocode

ähnlich wie bereits angefangen,....

JJ

von Jens (Gast)


Lesenswert?

>>Ich verbrauch in 2 Jahren ungefähr 3 Stück Din-A4 Collegeblocks.

Also ungefähr 3x80 Blatt in 2x220 Arbeitstagen.

Das ist eine halb Seite am Tag :-)

JJ

von Karl H. (kbuchegg)


Lesenswert?

Jens schrieb:
>>>Ich verbrauch in 2 Jahren ungefähr 3 Stück Din-A4 Collegeblocks.
>
> Also ungefähr 3x80 Blatt in 2x220 Arbeitstagen.
>
> Das ist eine halb Seite am Tag :-)

Könnte hinkommmen, denn natürlich gibt es auch Phasen in denen ich nix 
niederschreibe.

von Karl H. (kbuchegg)


Lesenswert?

Und um das auch mal zu sagen.

Das hier
1
> -Taster T1 für Wert einstellen durch mehrmaliges drücken des Tasters ( 1
2
> x   drücken = Wert 1 oder in dem Fall Zahl 1)...2 x drücken = Wert 2
3
> usw.
4
>
5
> - (später) möchte ich den Wert auch am Display anzeigen lassen
6
>
7
> -T2 um Lichtschrankensignal anfangen zählen zu lassen
8
>
9
> -Wenn beide "Null", also Taster T1 und T2 nicht gedrückt wurde, soll
10
> nichts passieren
11
>
12
> - Wenn Lichtschranke so oft gezählt wurde, wie von Taster 1 vorgegeben
13
> wurde, dann soll ein Ausgang kommen (LED an) und sonst nichts mehr. Das
14
> heist, dass die Signale der Lichtschranke dann nicht mehr gezählt werden
15
> müssen
16
>
17
> -Taster T4 soll dann für den Reset sein, um den Anfangszustand wieder
18
> herstellen zu können.

IST gut!
Du musst es nur noch strenger formalisieren, das ist alles!

zb folgt aus deiner Beschreibung implizit, dass dein Programm 2 
verschiedene Modi haben wird.
In dem einen Modus kann der Benutzer die Vorgabezahl einstellen. Dafür 
werden Puls an der Lichtschranke erst mal ignoriert.
Im anderen Modus, kann der Benutzer an der Zahl nichts mehr ändern, 
dafür zählen aber Lichschrankenpulse einen Zähler (der mit der 
Vorgabezahl gestartet ist) um 1 herunter.

Nennen wir das eine mal Editiermodus und das andere Zählmodus, damit die 
Dinge einen Namen haben.

Wie kommt man von einem Modus in den anderen Modus?
Na zb mit der Taste T2. Die macht genau das, wenn man im Editiermodus 
ist. Wie kommt man wieder in diesen Editormodus zurück? Macht das T4 
oder wie? Oder startet T4 einfach nur das Runterzählen wieder neu? Ich 
postuliere mal, dass das so sei

d.h. meine erste Version könnte so aussehen


  Modus = Editiermodus
  VorgabeAnzahl = 0

  while( immer ) {

    if Editiermodus {

      if Taste1 gedrückt {
        erhöhe die VorgabeAnzahl um 1
        VorgabeAnzahl auf LCD ausgeben
      }

      if Taste 2 gedrückt {
        Modus = Zählmodus
        Pulszähler = VorgabeAnzahl
        Led aus
      }
    }

    else if Modus == Zählmodus {
      if Puls an Lichtschranke?
        Pulszähler --

      if Pulszähler gleich 0
        LED an
    }
  }

so, das ist jetzt immer noch nicht vollständig, aber es geht schon mal 
in die richtige Richtung. Wenn DU als Computer das durchspielst und 
deine Intelligenz dazu einsetzt mit der Anweisung 'Puls an 
Lichtschranke?' etwas vernünftiges anzufangen, dann funktioniert die 
Logik bereits in Ansätzen!
Wie dann konkret ausprogrammiert wird, dass der Puls erkannt wird, 
interessiert mich zum jetzigen Zeitpunkt nicht die Bohne. Darum kümmere 
ich mich später! Jetzt will ich einfach nur einen Ablauf haben, der 
zumindest in groben Zügen das möglich macht, was deine Punkteauflistung 
vorgegeben hat. Und wenn das dann funktioniert und ich davon überzeugt 
bin, dass der grobe Plan funktioniert, dann seh ich mir den Plan an und 
überlege mir die Punkte, die ich so lakonisch da jetzt einfach 
hingeschrieben habe, wie zb 'Puls an Lichtschranke feststellen'. Ich 
verfeinere den Plan.

Und jetzt sag nicht, dass sowas für dich zu schwer ist.
Wenn das für dich zu schwer ist, dann bedeutet das, dass du dir eine für 
deine Verhältnisse zu schwere Aufgabe gewählt hast und dass du erst mal 
mit etwas Einfacherem weitermachen solltest.

Edit:
Und ehe du dich jetzt freust: Der grobe Plan ist noch lange nicht 
fertig. Geh deinen erwarteten Arbeitsablauf durch und spiele Computer 
und 'arbeite dein Programm' ab. Erfinde Dinge, die der Benutzer machen 
will und sieh nach, ob das mit deiner Logik möglich ist. Leg einen 
Bleistift neben die 'aktuelle Zeile' und arbeite deine Logik durch. Wenn 
dich deine Logik zb fragt ob die Taste1 gedrückt ist, dann nimm halt 
einfach an, dass die Taste gedrückt wurde oder dass sie nicht gedrückt 
wurd, je nachdem was dein simulierter erfundener Benutzer macht.

von Alfred F. (bluedeep)


Angehängte Dateien:

Lesenswert?

Vielen Dank euch allen,
vielen Dank Karl Heinz,

ihr habt ja schon recht mit dem was ihr schreibt. Vielleicht versuche 
ich auch einfach viel zu viele Schritte auf einmal zu machen und dies 
führt wohl nicht ganz zum Erfolg.
Karl Heinz, ich habe jetzt mal deine Anweisungen befolgt und habe mir 
das ganze erst mal auf dem Papier angeschaut und durchgetestet. Im 
Anhang habe ich mal das ganze angehängt, um Platz zu sparen.

Den Taster3 habe ich gewählt für´s runterzählen, wenn zuweit gedrückt 
wurde.

Den Taster4 nehme ich als Reset. Dabei bin ich mir aber nicht sicher, ob 
das so richtig ist.

Ps.: Ich will doch hier niemanden verärgern und ich habe auch von keinem 
verlangt, dass er mir ein fertiges Programm serviert.

von Karl H. (kbuchegg)


Lesenswert?

Alfred Flöckchen schrieb:

> Den Taster4 nehme ich als Reset. Dabei bin ich mir aber nicht sicher, ob
> das so richtig ist.

Na ja.
Spiels einfach durch.
Fang oben an, leg einen Bleistift neben die "aktuelle Zeile", lies was 
in der Zeile steht und führe die Aktion aus. Wenn dich das Programm 
befragt, ob irgendwelche Dinge eingetreten sind, dann erfinde sie 
einfach (aber denk drann: dein µC arbeitet Tausendfach schneller als 
dein Benutzer reagieren kann. D.h. dein Programm wird eine gedrückte 
Taste ein paar 100 mal als gedrückt sehen, selbst dann wenn dein 
Benutzer so schnell er nur kann niederdrückt und wieder loslässt)

Aber Tastenerkennung und Entprellung ist ein Thema, über das sowieso 
noch zu reden sein wird. Es gibt einen Unterschied zwischen:
  Feststellen ob eine Taste gedrückt IST
  Feststellen ob eine Taste niedergedrückt WURDE

Zurück zur Logik: d.h. 'ackere' dein Programm von oben nach unten durch. 
Dein gedachter Benutzer drückt irgendwann auf die Taste 4. D.h. 
irgendwann muss dein Bleistift bei der Zeile mit 'Ist Taste 4 gedrückt' 
vorbeikommen und dann lautet deine Antwort darauf 'Jup, ist der Fall' 
und der abhängige Teil wird genommen. Danach lässt du den Bleistift 
weiter kreisen und schaust dir an, was dann weiter passiert. Auch für 
den Fall, wenn der gedachte Benutzer 'auf der Taste eingeschlafen ist'.

Simulier auch weiter was eigentlich passiert, wenn du zb 3 Pulse 
einstellst, dann zählen lässt und 300 Pulse von der Lichtschranke 
kommen. Was passiert dann mit dem Zähler? Ist das ok? (Jetzt gehts ein 
bischen in die Programmierung rein) In der Mathematik kannst du bis 
unendlich zählen. Sowohl positiv als auch negativ. In einem Computer 
aber nicht. Irgendwann gibt es einen Über-/Unterlauf. Kann bei deinen 
Zählern so etwas passieren? zb. dann wenn der µC die Nacht durch 
unbeaufsichtigt Lichtschrankenpulse zählt?

Denk auch ein wenig an den Benutzer. Der kommt zu deiner 'Anlage' hin, 
sieht aufs Display. WOher weiß er, dass deine Schaltugn momentan gerade 
Pulse zählt oder ob sie auf die Freigabe zum Zählen wartet (Editormodus 
versus Zählmodus). Wenn ich in einer Produktionshalle mehrere Maschinen 
zu betreuen habe, dann ist das schon für den Maschinenbetreuer 
interessant das beim Vorbeigehen an 20 derartigen Schaltungen zu wissen. 
Die LED hilft ihm nichts. Denn 'LED aus' ist nicht eindeutig. Nur weil 
die LED aus ist, weiß er deswegen noch lange nicht, ob die Schaltung 
zählt oder nicht.

Und das hier ...
> wie von Taster 1 vorgegeben
> wurde, dann soll ein Ausgang kommen (LED an) und sonst nichts mehr.
... der letzte Teil - 'und sonst nichts mehr', den vergisst du gleich 
wieder. Du musst etwas vorsehen, wie es dann weiter geht. Was soll 
passieren, wenn die Anzahl abgezählt wurde? Wie geht es weiter? Kann der 
Benutzer den ganzen Prozess erneut starten, kann er die Anzahl 
verändern? Was macht die LED?
Ein µC macht nicht 'nichts mehr'. Ein µC macht immer irgendwas. Du musst 
definieren was.

von oldmax (Gast)


Lesenswert?

Hi
Das Internet und seine Privatlehrer.... leider ist "C" für mich wie eine 
Fremdsprache... ich kann die zwar einem Land zuordnen, das ist's aber 
auch schon.
Ok, aber vielleicht kann ich trotzdem helfen. Du möchtest 
Tastenbetätigungen zählen. Dann denk mal kurz nach, was da entscheidend 
ist: Richtig, die Flanke, denn der Controller wird dir was husten, wenn 
du meinst, einfach nur drücken und dann geht's um eins nach oben oder 
unten.
Das bedeutet: Signal einlesen und nachsehen, ob der alte gemerkte Status 
gleich ist: keine Änderung. Nicht gleich, dann schauen, ob neuer Status 
"1", dann zählen und neuen Status in alten Status kopieren.
In Assembler sieht's dann so aus:
[avrasm]
read_IO:
   In  R16, PortD
   COM R16          ; drehen, weil Taster oft gegen GND schalten
   Sts New_In, R16
   LDS R17, Old_In
   EOR R16, R17     ; veränderte Bits in R16, EOR = Exclusiv-Oder
   MOV R3, R16      ; merken !
   AND R16, R17     ; Bit geänder ="1", Alt war "1", also Änderung nach 
"0"
   STS In_To_0, R16
   Mov R16, R3      ; geänderte Bits zurückholen
   LDS R17, New_In  ; den letzten Status holen
   AND R16, R17     ; Bit geändert ="1", Neu = "1", also Änderung nach 
"1"
   STS IN_To_1, R16
   STS Old_In, R17  ; Neuen Status merken
RET
{/avrasm]
Nun brauchst du diesen Teil nur noch in "C" übersetzen und du hast eine 
"1" wenn ein Taster gedrückt wurde in der Variablen In_To_1
Im Programm fragst du das entsprechende Bit passend zum Taster ab und 
wenn gesetzt, zählst du hoch oder runter und, ganz wichtig,  löscht das 
Bit. Nun kannst du deinen Taster halten, bis du vor altersschwäche 
umfällst, es wird nix weitergezählt. Erst loslassen und neu drücken 
liefert ein neues Flankenbit.
Gruß oldmax

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

oldmax schrieb:
> leider ist "C" für mich wie eine Fremdsprache...
> ich kann die zwar einem Land zuordnen, das ist's aber auch schon.
> Ok, aber vielleicht kann ich trotzdem helfen.

Hm, der Alfred möchte etwas in C programmieren, und du gibst ihm 
Informationen über ein Implementierungs-Detail (Tastenentprellung) in 
ASM. Möglicherweise ist für Alfred ASM genau so eine Fremdsprache wie 
für dich "C" ???

Tastenentprellungen in C gibts ja "zuhauf", insbesondere die hier gerne 
referenzierte PeDa Routine ...

Genauso gut hättest du anstelle ASM die Tastenentprellung jetzt als 
Kehlkopf-Gesang vortragen können, die hätte Alfred wahrscheinlich 
ebensoviel genutzt im Voranschreiten seines Projektes.

Darüber hinaus: was nutzt das Implementierungsdetail, wenn die 
allgemeine Logik nicht stimmt bzw. nicht vorhanden ist? Brauchst du die 
nicht auch in ASM, und klimperst du auch erst mal drauf los und belegst 
erst mal alle Register mit allen möglichen Variablen?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Alfred Flöckchen schrieb:
> Angehängte Dateien:
>         Tasten_zaehlen_Test.txt
Meine C-Programme enden auf *.c, nicht auf *.txt
Und wenn deine Datei auch so enden würde, dann hätte die Forensoftware 
auch mal den Farbkasten fürs Syntaxhighlighting auspacken können...

von Alfred F. (bluedeep)


Lesenswert?

Lothar Miller schrieb:
> Meine C-Programme enden auf *.c, nicht auf *.txt

Super Lothar, hauptsache mal seinen Senf abgegeben :-)

Wäre es schon ein fertiges C-Programm und nicht nur eine Ausarbeitung, 
welche noch in Planung ist, dann hätte ich die Datei auch auf *.C enden 
lassen. Ich machte dies ja nur um Platz zu sparen, aber das schrieb ich 
ja schon.

von Peter D. (peda)


Lesenswert?

Manche machen wohl Top-down, aber ich halte davon nichts.

Ich fange immer unten an bei den kleinsten Modulen und klebe sie zum 
Schluß zusammen.

In Deinem Fall z.B.:
1. Taste entprellen (Drücken-LED an, nochmal Drücken-LED aus).
2. Anzeige (braucht man immer, ist gut zum Debuggen).
3. Eingabefunktion (benutzt 1. und 2.)
usw.

Kann sein, daß ich es überlesen habe:
Wieviel 1000 Impulse werden denn gezählt, d.h. welchen Wertebereich mußt 
Du eingeben?
Wie schnell kommen die Impulse (minimale Dauer, Abstand).


Peter

von oldmax (Gast)


Lesenswert?

Hi
Na, Herr Wegstabenverbuchsler.... mal wieder nicht gelesen, sondern 
einfach mal so drauflosgeschrieben.

>Hm, der Alfred möchte etwas in C programmieren, und du gibst ihm
>Informationen über ein Implementierungs-Detail (Tastenentprellung) in
>ASM. Möglicherweise ist für Alfred ASM genau so eine Fremdsprache wie
>für dich "C" ???
Geschrieben hab ich über Flankenerfassung und ich war der Meinung, es 
auch ausreichend kommentiert zu haben:
>Dann denk mal kurz nach, was da entscheidend
>ist: Richtig, die Flanke, denn ....
Von einer Tastenentprellung hab ich da nix geschrieben, das hättest du 
anmeckern können. Aber mit Ratschlägen ist's ja nicht so dolle.... dafür 
aber mit in diesem Fall sinnlosen Antworten.
Assembler, da geb ich dir ja recht, ist nicht 1:1 nach C zu übersetzen, 
aber genauso wenig funktioniert das mit einem PAP oder einer Skizze auf 
einem Blatt Papier. Was aber funktioniert, ist die Erkenntniss, wie eine 
komplexe Aufgabe in kleine Teile zerlegt und in der richtigen 
Reihenfolge wieder zusammengesetzt wird. Die Programmiersprache selbst 
ist doch nicht entscheidend, sondern das "Gewußt wie". Ob da nun 
Variablen verwendet werden oder Register spielt doch gar keine Rolle. 
Jeder hat da seine eigene Vorstellung von "Übersichtlich", 
"Verständlich", "Grausig"....
Ach ja und allen anderen, die auch heute morgen mit den Beinen auf der 
falschen Seite lagen... Einen schönen Tag noch
Gruß oldmax

von Alfred F. (bluedeep)


Lesenswert?

Danke Peter für deine Mithilfe

Peter Dannegger schrieb:
> Wieviel 1000 Impulse werden denn gezählt, d.h. welchen Wertebereich mußt
> Du eingeben?

Mir reichen eigentlich schon 100 Impulse die gezählt werden

Peter Dannegger schrieb:
> Wie schnell kommen die Impulse (minimale Dauer, Abstand)?

Die Zeitabstände der Impulse liegen bei ca. 200-500 Millisekunden.


Danke auch an Oldmax. Ich weiß, es war gut gemeint und dient zumindest 
als Denkansatz, wenn sich der Assemblercode für mich auch so chinesisch 
anhört, wie für dich der C-code.

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
Noch kein Account? Hier anmelden.