Hallo Zusammen,
ich habe das am Ende des Posts angehängte Programm zur Ansteuerung eines
Servos sowie 7 Leeds (die die Position des Servos anzeigen) durch einen
ATMega8.
Zusätzlich soll dieses Programm auch noch ein weiteres LED (das so
genannte Kabinenlicht) ansteuern, dass aber durchgehend brennt, während
der Servo seine Bewegungsroutine abläuft.
Diese "Bewegungsroutine" wird durch einen Button gestartet und besteht
aus einer Anzahl festgelegter Positionen und zugehöriger Waittimes -
beides in je einem Array abgelegt und per For-Schleife mit Zähler
durchlaufen.
Die 7 LEDs sind an PD0-6,
der Servo hängt an PB1,
die Kabinen-LED an PB5
und der Button an PC3
ATMega un Servo haben getrennte Stromversorguzngen und geteilte Masse
und sowohl die VCC als auch AVCC sind mit einem 100nF Papa abgesichert.
Die Mainline hat dazu noch einen eigenen Kapa. Auf dem Board ist
ausserdem eine Kontrolleuchte, die einfach (mit Widerstand) zwischen
Main und GND eingehängt ist, um anzuzeigen, dass das Board Saft hat.
Nun zu meinen 3 Problemen:
1. Nachdem der Servo die vorgegebene Bewegungsroutine durchgeführt hat,
fängt er an scheinbar willkürliche (in Wahrheit aber immer die gleichen)
zusätzlichen Bewegungen auszuführen. Diese gehen mit dem Anschalten von
mehreren LEDs einher.
2. Ganz zum Schluss soll der Servo wieder in die Mitte fahren und die
mittlere LED blinkt drei mal. Tatsächlich aber blinkt erst die mittlere
LED 3 mal un dann fährt der Servo in Mitteposition - obwohl der Code das
so gar nicht herzugeben scheint.
3. Während Servo und die 7 Positions-LEDs zumindest angehen, leuchtet
das Kabinenlicht am PB5 nicht - ich hab hier auch schon PD7 oder PC1
ausprobiert, ohne Erfolg. Manchmal gab es auch den völlig komischen
Effekt dass, wenn der Servo über den maximalen Anstellpunkt hinausgehen
wollte (was eigentlich auch schon nicht sein kann, da ich diese Position
gar nicht in meinem Array habe) dann das Kabinenlicht für diesen
Zeitraum anging.
Ich bin echt komplett ratlos. Kann da bitte einmal jemand mit mehr
Ahnung als ich draufschauen und mir sagen, welchen Anfängerfehler ich
nun wieder verbockt habe?
So hier noch der Code - Achtung nicht erschrecken ich arbeite mit
Compiletime-Makros um bestimmte Funktionen ein und Auszuschalten, daher
die ganzen #ifdef Statements:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
4
#define BUTTON DDC3 // if active PORT for the button to start the action
5
//#define COUNTER 3 // if active one press of the button initiates number of cycles
6
7
8
#define RUNLED 1 // if active, the 7 lights are used to indicate turret position
9
#define CABINLED DDB5 // if active, PORT for the cabinlight - it is turned on while turret moves
10
11
// positions of the 7 lights in the light pattern array
12
#define LIGHT_OFF 0 // all lights off
13
#define LIGHT_LEFT 1 // the left most led
14
#define LIGHT_CENTER 4 // the center led
15
#define LIGHT_RIGHT 7 // the right most led
16
17
18
// do we use the servo and do we have 2 servos?
19
#define SERVO 1
20
#define SERVO_UP DDB1
21
//#define SERVO_DOWN DDB2
22
// Servo Frame-Time:
23
#define FRAME_TIME 800 // msec
24
25
// servo positions
26
#define ABS_CENTER 1500 // center or 0 position
27
#define SERVO_LEFT 750 // roughly -90° - was 675
28
#define SERVO_RIGHT 2250 // roughly +90°
29
#define SERVO_STEP 240 // 3 Schritte von Mitte zu Max Left und Max Right
30
31
32
// wait times in cycle
33
#define START_CYCLE_SLEEP 1000
34
#define AFTER_CYCLE_SLEEP 2000
35
36
#define RAPID_MOVE_SLEEP 350
37
#define FOLLOW_FIGHTER_SLEEP 500
38
#define QUICK_FIRE_SLEEP 750
39
#define FINAL_FIRE_SLEEP 1250
40
41
42
unsignedcharledPattern[]={0b0000000,// 0 - all off
Ich habe beim Lesen des Quelltextes nach dem oberen viertel aufgehört,
weil er voller irreführender Kommentare ist, die nicht mit dem C-Code
überein stimmen. Korrigiere das zuerst.
Beispiel:
1
// configure pins PC3, PC4 and PC5 on Port C as input
2
// and enable internal pull-up resistors
3
4
DDRC=0b1110111;// PC3 as input
Was du da wirklich machen wolltest, kann ich nicht erkennen.
Was heißt "geteilte Masse" .. du hast die GND schon an einem Punkt
verbunden und nicht nur die Signalleitung.
Und was sind Mainline, Papa, Kapa?
Und trotzdem gib dem Servo mal 1000-2200µF parallel. Die sind darauf
ausgelegt, an einem Akku zu hängen der ev. generatorisch erzeugte
Leistung aufnimmt. Außerdem sind Stromspitzen von einigen A durchaus
drin.
Das ist im normalen RC-Betrieb schon häufig nötig, besonders wenn eine
einfache Dioden-Akkuweiche verwendet wird.
Gruß,
Christian
>> Der Ausdruck in den Klammern ergibt 0, also wird da gar kein Pin> getoggelt.
Ich bin da einfach echt noch Noob - was exakt heisst denn dieses
Statement genau? Switch den Port an CABINLED (also DDB5) hin und her?
Ich hab immer gedacht, dass die 0 for dem Port ein explizites
ausschalten ist. Und das Statement
Christian E. schrieb:> Was heißt "geteilte Masse" .. du hast die GND schon an einem Punkt> verbunden und nicht nur die Signalleitung.>> Und was sind Mainline, Papa, Kapa?>> Und trotzdem gib dem Servo mal 1000-2200µF parallel. Die sind darauf> ausgelegt, an einem Akku zu hängen der ev. generatorisch erzeugte> Leistung aufnimmt. Außerdem sind Stromspitzen von einigen A durchaus> drin.>> Das ist im normalen RC-Betrieb schon häufig nötig, besonders wenn eine> einfache Dioden-Akkuweiche verwendet wird.>> Gruß,> Christian
Geteilte Masse heißt, dass der Servo (gespeist von einer 9v Block über
den im Bild gezeigten Aufbau reduziert auf 4,5V) zusätzlich auf die
Messeleitung des Boards mit dem Mikrocontroller gezogen ist.
Die Mainline sollte die VCC Leitung des Bords mit Mikrocontroller sein.
und der Kapa ist ein 100nF - so ein 104er
Christian G. schrieb:> Das soll natürlich später nicht so sein
Das soll auch jetzt nicht so sein, denn damit überlastest du das IC oder
dessen Stromversorgung. Dadurch wird die interne Spannungsversorgung
instabil, was beliebige Fehlfunktionen auslösen kann.
Stefan ⛄ F. schrieb:> Ich habe beim Lesen des Quelltextes nach dem oberen viertel aufgehört,> weil er voller irreführender Kommentare ist, die nicht mit dem C-Code> überein stimmen. Korrigiere das zuerst.>> Beispiel:>
1
>// configure pins PC3, PC4 and PC5 on Port C as input
2
>// and enable internal pull-up resistors
3
>
4
>DDRC=0b1110111;// PC3 as input
5
>
>> Was du da wirklich machen wolltest, kann ich nicht erkennen.
Hab den Quelltext etwas aufgeräumt. Die irreführenden Kommentare waren
nur Merkhilfen für mich, woher das Zeug kam und wie die dortige
Erklärung war.
1
DDRC=0b1110111;
soll den PC3 Port als Input Port für den Button nutzen. Wenn der auf GND
zieht (internal pullups) startet der Zyklus - Funktioniert auch im
Prinzip.
Stefan ⛄ F. schrieb:> Christian G. schrieb:>> Das soll natürlich später nicht so sein>> Das soll auch jetzt nicht so sein, denn damit überlastest du das IC oder> dessen Stromversorgung. Dadurch wird die interne Spannungsversorgung> instabil, was beliebige Fehlfunktionen auslösen kann.
Ok. Dann muss ich das mal ändern. Kann das der denn auch der Grund für
diese irrationalen, aber reproduzierbaren Servobewegungen sein. Ich
meine, die sind zwar nicht mit dem Array der geplanten Bewegung
übereinzubringen, aber auch nicht völlig willkürlich, sondern schon
immer recht gleich.
Christian G. schrieb:> Ich bin da einfach echt noch Noob - was exakt heisst denn dieses> Statement genau?
Ich empfehle dir, die Grundlagen der Programmiersprache zu lernen. Zieh
dir das mal rein: http://stefanfrings.de/mikrocontroller_buch/index.html
In diesem Fall konkret Band1 Kapitel 4.2.20.4, 4.2.20.6 und 6.7.4
PORTC ^= irgendwas ist eine Kurzform von PORTC = PORTC ^ irgendwas.
CABINLED ist DDB5, was wiederum 5 ist.
(1<<5) ist eine 1 fünf mal nach links geschoben, also 32.
PORTC ^= 32 ändert den Wert von Bit 5 im Register PORTC, schaltet also
dem Pin PC5 um.
Aber (0<<irgendwas) ergibt 0 und bewirkt daher nichts.
> Ich hab immer gedacht, dass die 0 for dem Port ein> explizites ausschalten ist.
Siehe Kapitel 6.7
Christian G. schrieb:> H. H. schrieb:>> Christian G. schrieb:>>> Die 7 LEDs sind an PD0-6,>>>> Ohne Vorwiderstand?>> Ja stimmt. Das soll natürlich später nicht so sein :-)
Das sollte auch jetzt nicht so sein.
Christian G. schrieb:> Geteilte Masse heißt, dass der Servo (gespeist von einer 9v Block
Möööööööp!
9V Block Batterien sind nur für ganz geringe Stromstärken geeignet und
außerdem die mit dem schlechtesten Preis-/Leistungs-Verhältnis.
Für Modellbau Servos empfehle ich dringend mindestens 4-5 Rundzellen in
Größe AA.
> DDRC = 0b1110111;> soll den PC3 Port als Input Port
Estmal sind standardmäßig alle I/O Pins als Input konfiguriert. Was du
hier in Wirklichkeit machst ist, alle Pins außer PC3 als Ausgang zu
konfigurieren.
Wenn du nur dieses eine Bit auf LOW setzen willst, dann so:
DDRC &= ~(1<<PC3)
Der Vollständigkeit halber: Wenn du z.B. das Bit für PC2 auf HIGH setzen
willst, dann so:
DDRC |= (1<<PC2)
Anstelle von PC3 und PC2 kannst du auch einfach 3 und 2 schreiben.
Christian G. schrieb:> Kann das der denn auch der Grund für> diese irrationalen, aber reproduzierbaren Servobewegungen sein.
Wie ich bereits schrieb:
Stefan ⛄ F. schrieb:> Dadurch wird die interne Spannungsversorgung> instabil, was beliebige Fehlfunktionen auslösen kann.
Stefan ⛄ F. schrieb:> Anstelle von PC3 und PC2 kannst du auch einfach 3 und 2 schreiben.
Oder auch DDB3 und DDB2. Spielt keine Rolle, denn diese Konstanten haben
alle den Wert 3 bzw. 2.