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
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...
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
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
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
Moore, Mealy, Medvedev, bald haben wir alle drei durch :)
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
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.
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
1 | #define STATE_START 0
|
2 | #define STATE_CURRENT 1
|
3 | #define STATE_NORMAL 2
|
4 | #define STATE_STARTER 3
|
5 | |
6 | ...
|
7 | |
8 | |
9 | state = STATE_START; |
10 | |
11 | while( 1 ) { |
12 | |
13 | switch( state ) { |
14 | |
15 | case STATE_START: |
16 | if( Key_Detected ) { |
17 | PowerUp_Electronics(); |
18 | state = STATE_CURRENT; |
19 | }
|
20 | break; |
21 | |
22 | case STATE_CURRENT: |
23 | if( !Key_Detected ) { |
24 | PowerDown_Electronics(); |
25 | state = STATE_START; |
26 | }
|
27 | else if( Key_Turned_Right ) { |
28 | PowerUp_Ignition(); |
29 | state = STATE_NORMAL; |
30 | }
|
31 | break; |
32 | |
33 | case STATE_NORMAL: |
34 | if( Key_Turned_Right ) { |
35 | PowerUp_Starter(); |
36 | state = STATE_STARTER; |
37 | }
|
38 | else if( Key_Turned_Left ) { |
39 | PowerDown_Ignition(); |
40 | state = STATE_CURRENT; |
41 | }
|
42 | break; |
43 | |
44 | case STATE_STARTER: |
45 | if( Key_Turned_Left ) { |
46 | PowerDown_Starter(); |
47 | state = STATE_NORMAL; |
48 | }
|
49 | break; |
50 | }
|
51 | }
|
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.
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.
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
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.
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
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 );
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.