www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMEGA8 in C: 1 Tastendruck --> 2 verschiedene Funktionen -->Hilfe!


Autor: Chillxx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo allerseits

Ich häng schon eine Weile an dem Problem...und ich bin ein Neuling:

Ich will mit dem Mikrocontroller einen Motor ansteuern, welcher über 
eine Zahnstange einen Deckel auf und ab fährt...das nur zur Info.

Um die Position des Deckels zu detektieren, benutze ich einfach oben 
einen Endschalter (S1) und einen für unten (S2).

Dann hab ich noch einen Haupttaster S3.
Wenn der Deckel geschlossen ist und ich den S3 betätige, soll der Deckel 
den oberen Endschalter S1 anfahren und der Motor soll stoppen.

Wenn der Deckel offen ist, soll sich der Deckel bei erneuter Betätigung 
des S3 schließen bis Endschalter unten schaltet und der Motor stoppen.

Hat jemand eine Idee für ein Programmieransatz in C?
Danke!
MFG

Autor: freche Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hört sich im ersten Moment recht einfach an. Wenn du da selbst 
keinen Ansatz hast, dann solltest du dir erst mal ein paar Tutorials 
durchlesen. Vielleicht sogar hier auf mikrocontroller.net die Hinweise 
zur Programmierung des AVR. Einarbeiten eben...

Autor: Chris L. (kingkernel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kontrolliere einfach in einer if-Abfrage, welcher der endschalter 
betätigt ist und reagiere dann entsprechend, indem du den motor einmal 
links oder rechts rum drehen lässt.
vorher vielleicht noch prüfen, ob der motor grad aktiv ist und den 
tastendruck dann verwerfen.
die endschalter fragst du auf die selbe weise ab, wenn er betätigt wird, 
stoppst du den motor

Autor: Joachim K. (minifloat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach das doch als Statemachine mit 4 States.
1 = Deckel ist offen, Warten auf S3
2 = Deckel wird geschlossen, Motor vorwärts, Warten auf S2
3 = Deckel ist geschlossen, Warten auf S3
4 = Deckel wird geöffnet, Motor rückwärts, Warten auf S1

Ach ja, states als variablentyp macht man sich mit enum, du könntest das 
aber genausogut mit 4 defines machen und ein uint8_t nehmen.

mfg mf

Autor: Reinhard Schopf (schopfi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Startvariable, Zählervariable
z.B.: Start = S1 gedrückt und Motor aus, Zählervariable 0
Beim Drücken von S3, Motor an und auf S2 warten , dann Motor aus und 
Zählervariable 1
Dann bei druck auf S3 vergleichen , ist Zähler 1, dann nur Abwärts und 
Zähler wieder 0 oder ist unten dann nur aufwärts und Zähler wieder 
1.....usw.

na? hilfts ?

lg

Autor: Joachim K. (minifloat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moore, Mealy, Medvedev, bald haben wir alle drei durch :)

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

Bewertung
0 lesenswert
nicht lesenswert
hey,

lso ich habs mal so ähnlich versucht, wahrscheinlich denk ich aber zu 
kompliziert bzw die Logik funktioniert garnicht.

Sicher braucht ihr dafür nur 8 Zeilen :D !!
Aber würde das, was ich da programmiert habe, funktionieren?

^^und ja...war sehr hifreich :)

mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Punkt 1:
Sieh dir das File an.
Wenn du ernsthaft programmieren willst, dann darf sowas wie das was du 
da am Anfang produziert hast nicht passieren (ich meine die äussere 
Form). Der untere Teil ist so einigermassen ok.

Punkt 2:
Du hast dich für eine Zustandsmaschine entschieden.
Das ist ok

So eine Zustandsmaschine sieht in Code im Grundgerüst so aus


   zustand = 1;

   while( 1 ) {

     switch( zustand ) {

       case 1:     // wenn im Zustand 1

         if( Bedingung um den Zustand zu verlassen ) {

           Aktionen die ausgeführt werden, wenn der Zustand
           verlassen wird.

           zustand = neuer Zustand;
         }
         break;


       case 2:     // wenn im Zustand 2

         if( Bedingung um den Zustand zu verlassen ) {

           Aktionen die ausgeführt werden, wenn der Zustand
           verlassen wird.

           zustand = neuer Zustand;
         }
         break;

       usw. usw.
     }
   }


Das kannst du natürlich noch nicht wissen, daher ist das schon ok.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Zustandsmaschinen haben einen enormen Vorteil.
Man kann die Logik, die sie verkörpern, ganz einfach grafisch 
anschaulich machen.

Sieh dir beiliegendes Bild an.
Das Runde sind die Zustände. Jeder Zustand hat einen Namen. Das ist der 
schwarze Text im Oval.
Von jedem Zustand gehen ein (oder mehrere) Pfeile aus. Das sind die 
Zustandsübergänge, wann also die Maschine in einen anderen Zustand 
wechselt. An jedem Pfeil steht dabei, unter welcher Bedingung dieser 
Pfeil genommen werden kann (der blaue Text). Und an jedem Pfeil steht 
dabei, welche Aktion dabei auszuführen ist (der rote Text).

Sieh dir das Diagramm an, du kommst sicher drauf, welcher Vorgang hier 
beschrieben wird ( :-) zumindest in Ansätzen )

In Code würde dasselbe dann so aussehen

#define STATE_START    0
#define STATE_CURRENT  1
#define STATE_NORMAL   2
#define STATE_STARTER  3

...


    state = STATE_START;

    while( 1 ) {

      switch( state ) {

        case STATE_START:
          if( Key_Detected ) {
            PowerUp_Electronics();
            state = STATE_CURRENT;
          }
          break;

        case STATE_CURRENT:
          if( !Key_Detected ) {
            PowerDown_Electronics();
            state = STATE_START;
          }
          else if( Key_Turned_Right ) {
            PowerUp_Ignition();
            state = STATE_NORMAL;
          }
          break;

        case STATE_NORMAL:
          if( Key_Turned_Right ) {
            PowerUp_Starter();
            state = STATE_STARTER;
          }
          else if( Key_Turned_Left ) {
            PowerDown_Ignition();
            state = STATE_CURRENT;
          }
          break;

        case STATE_STARTER:
          if( Key_Turned_Left ) {
            PowerDown_Starter();
            state = STATE_NORMAL;
          }
          break;
      }
    }

wie man sieht übersetzt sich das Schaubild fast kochrezeptartig in eine 
erste Programmversion. Aber: Auf dem Schaubild ist es viel leichter die 
Logik zu verfolgen und auf Sinnhaftigkeit bzw. Fehler abzuklappern. Im 
schlimmsten Fall fährt man einfach mir dem Finger die Pfeile entlang, 
fragt sich was im jeweiligen Kreis alles passieren kann und sieht nach 
wo man landet, wenn man einfach mal annimmt, dass diese Bedingung 
vorliegt.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Eine erste Version des Zustandsautomaten, der deine Schaltlogik 
repräsentiert könnte zb so aussehen (Siehe Bild)

Darauf kann man jetzt weiter aufbauen.
Was soll zb passieren, wenn der Haupttaster gedrückt wird, während der 
Motor fährt, die Maschine sich also entweder im Zustand 'öffnend' bzw 
'schliessend' befindet. Im Moment passiert nichts, aber das muss ja 
nicht so sein.
(zb sollte man sich auch überlegen, was passieren soll, wenn der Deckel 
nach dem Einschalten der Steuerung weder komplett offen noch komplett zu 
ist. Man könnte zb vereinbaren, das der erste Zustand nach dem 
Einschalten der Zustand öffnen ist. Dann fährt der Deckel erst mal auf. 
Man könnte aber auch neue Zustände einführen, die auf 
Benutzerinteraktion mit dem Hauptschalter warten oder man könnte ....)

Je mehr und je besser du dir die Logik im Vorfeld aufbereitest, umso 
weniger Ärger wirst du dann bei der tatsächlichen Programmierung haben. 
Dabei geht es nicht darum, sich an irgendwelche formalen Zwänge zu 
halten. Du kannst im Schaubild rummalen wie du lustig bist und Begriffe 
erfinden wie du lustig bist. Es muss nur gewährleistet sein, dass sich 
Pfeile nicht widersprechen (also 2 Pfeile mit derselben Bedingung aus 
einem Oval rausführen) und dass die Abfolge der Pfeile deiner Logik 
entspricht. Aber ansonsten interessiert sich auf dieser Ebene keiner für 
Klammern oder Strichpunkte oder .... Auf dieser Ebene darfst du kreativ 
sein.

Autor: Chillxx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich glaub ich habs verstanden :)...diese Zustandsmaschine verkürzt mein 
erstes Programm um einiges und es wird viel übersichtlicher....

also ich werd mein Program mal auf diese art schreiben...kann etwas 
dauern ;)

Die Bilder und die Erklärungen haben mir sehr geholfen
danke vorerst
mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chillxx schrieb:
> ich glaub ich habs verstanden :)...diese Zustandsmaschine verkürzt mein
> erstes Programm um einiges

Ich denke kürzer wirds nicht werden, ...

> und es wird viel übersichtlicher....

... ganz genau.

Vor allen Dingen, wenn du dir dann noch Makros machst, die die Dinge 
beim Namen nennen, anstelle von PB1, PB2 etc.


            TURN_ON_MOTOR( OPEN );
            TURN_OFF_MOTOR;
            TURN_ON_MOTOR( CLOSE );

liest sich nun mal schon viel besser und aussagekräftiger als

            PORTC |= ( 1 << PC0 );
            PORTC &= ~( ( 1 << PC0 ) | ( 1 << PC1 ) );
            PORTC |= ( 1 << PC1 );

obwohl es genau dasselbe in anderer Verpackung ist.

Autor: Chillxx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Vor allen Dingen, wenn du dir dann noch Makros machst, die die Dinge
>
> beim Namen nennen, anstelle von PB1, PB2 etc.

dann sag ich einfach am Anfang zB:
PC0=MotorAUF
...oder Funktioniert es bei der "PIN Zuweisung" anders
...ihr wisst eh-->Anfänger ;)

Karl heinz Buchegger schrieb:
> liest sich nun mal schon viel besser und aussagekräftiger als
>             PORTC |= ( 1 << PC0 );
>
>             PORTC &= ~( ( 1 << PC0 ) | ( 1 << PC1 ) );
>
>             PORTC |= ( 1 << PC1 );

das stimmt, allerdings - muss selber ständig nachschaun!
mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chillxx schrieb:

> PC0=MotorAUF
> ...oder Funktioniert es bei der "PIN Zuweisung" anders
> ...ihr wisst eh-->Anfänger ;)

An dieser Stelle kommt der von Insidern lange erwartete Hinweis:
Du brauchst ein C Buch!

[C]
#define MOTOR_PORT   PORTC
#define OPEN         PC0
#define CLOSE        PC1

#define SET_BIT(p,b)         (p) |= (1<<(b))
#define TURN_ON_MOTOR(bit)   MOTOR_PORT |= (1<<(bit) )
#define TURN_OFF_MOTOR       MOTOR_PORT &= ~( (1<<OPEN) | (1<<CLOSE) )

....

            TURN_ON_MOTOR( OPEN );

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.