Hallo, Ich hab da nen kleines Problem. Mein Ziel ist es über einen Atmega8 8 Servos an zu Steuern, dass heißt ich habe 5 Servo Eingänge, wovon 4 jeweils auf 4 Servoausgänge geschaltet werden. Die Umschaltung erfolgt über den 5. Eingang. Die Servos die nicht angesteuert werden sollen dann in eine Defaultposition fahren. Diese Defaultpositionen sollen dann über 3 Taster (INC,DEC,SERVO) eingestellt werden. Momentan bin ich erstmal dabei das Programm für die Defaultpositionierung zu scheiben. Dazu lege ich über einen Timer den 20ms Puls für alle Servos fest und über einen Counter für jedes Servos die entsprechende Länge des Puls. Das Funktioniert soweit. Wenn ich jetzt allerdings eine der Tasten drücke macht der ganze Atmel einen Neustart, dies habe ich nur herausfinden können weil das Servo Kurz zuckt und wieder in die Ausgangsposition fährt. Testweise hatte ich nach dem Incrementieren oder Decrementieren die Werte in den EEPROM übernommen, dann hatte das Servo die Position auch nach dem Neustart gehalten, nur leider ist das erstens unschön, und zweitens macht das Servo beim Starten des Atmels natürlich erstmal Sprünge bis die Werte aus dem EEPROM wieder geladen sind. Jetzt meine Frage, kann es was mit der Doppelbelegung der Ports zu tun haben, oder wie ich die Tasten angeschlossen habe? Ich bin ziemlich ratlos.
Sven Fabricius schrieb: > Wenn ich jetzt allerdings eine der Tasten drücke macht der ganze Atmel > einen Neustart, dies habe ich nur herausfinden können weil das Servo > Kurz zuckt und wieder in die Ausgangsposition fährt. Wenn ein Servo anfährt und dein µC in diesem Moment abstürzt, dann liegt das Problem in der Versorgungsspannung. Servos können ziemliche Schweine sein, bei dem was sie auf der Versorungsspannung an Schmutz einkoppeln. Den musst du loswerden. Am besten wäre es, wenn die Servos ihre eigene Versorgungsspannung komplett getrennt von der µC-Versorgungsspannung hätten. Wenn das nicht geht, musst du Spulen und oder Kondensatoren einbauen, die dir den Schmutz vom µC fernhalten. Das du dem Mega8 nicht mal die üblichen 100nF an den Versorgungspins spendiert hast, ist eigentlich nur mit einem Wort zu beschreiben: leichtsinnig
Gast
#1369464
>Das du dem Mega8 nicht mal die üblichen 100nF an den Versorgungspins >spendiert hast, ist eigentlich nur mit einem Wort zu beschreiben: >leichtsinnig Noch leichtsinniger ist es die 330nF zu schalten. Wenn die leer sind ziehen sie beim schalten kurzfristig sehr viel Strom. Die 330nF gehören parallel zum Schalter und nicht zum Pullup/down.
Den 100nF hatte ich jetzt in der Zeichnung nicht berücksichtigt, ist aber drinne. Hatte das ganze auf nem Streifenraster aufgebaut. Habe zur Spannungsversorung mal 5V 1,5A angeschlossen und gehofft das würde helfen. Das komische ist, dass der Atmel auch resettet auch wenn ich die Servo Wechsel Taste drücke die garkeine Positionsveränderung auslößt.
Das mit dem Taster hatte ich einfach blanco von nem Eval Board übernommen, aber werd die mal parallel drauf schalten.
Sven Fabricius schrieb: > Das mit dem Taster hatte ich einfach blanco von nem Eval Board > übernommen, aber werd die mal parallel drauf schalten. Lass sie weg. Tastenentprellen kann man prima in Software. http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29 Da kriegst du dann als Zugabe auch noch gratis, dass du auf dem Taster draufbleiben kannst, und die Entprellroutine liefert dir ständig Tastendruck-Impulse. Ideal für dich, oder willst du die Defaultposition von links nach rechts ändern, indem du 200 mal auf die Taste drückst? Und Tasten baut man bei AVR's so ein, dass sie nach Masse schalten. Dann kann man den im µC eingebauten Pullup Widerstand benutzen.
Ok, war mir mit den Tasten immer nicht so sicher, im bezug auf Fehlerquellen. Wenn ich die Tasten gegen Masse schalte, dann muss ich die Abfrage der Tasten dann aber invertiern, oder?
Ach ne, sorry hab mich verguckt
Sven Fabricius schrieb:
> Ach ne, sorry hab mich verguckt
Nein, stimmt schon.
Aber wenn du die verlinkten Source Code Quelle benutzt, brauchst du dich
nicht mehr um die Details kümmern. Einfach ein paar #define richtig
stellen und so wie in der Demo gezeigt abfragen. Fertig.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
danke, werde das heute Abend testen, das mit dem array ist ne super idee, hatte daran noch garnicht gedacht.
Gast
#1369548
Hallo, ich habe genau dasselbe Problem mit Atmega32 auf Pollin-Atmel-Evaluationsboard-V201. Die Beschaltung der Taster 33k/330n scheint vom Pollin-Board zu sein. Getrennte Versorgung des Servo bringt bei mir keinen Unterschied. Tastendrücke führen gelegentlich/häufig zu Reset. Kann das jemand bestätigen, dass die Ladestromspitzen bei der Beschaltung einen Reset auslösen können? Ist das bei dem Pollin-Atmel-Evaluationsboard-V201 so? Danke Josh
Bestätigen kann ich das nicht, aber es ist möglich, da ich die Schaltung der Taster auch übernommen habe.
Josh schrieb: > Getrennte Versorgung des Servo bringt bei mir keinen Unterschied. > Tastendrücke führen gelegentlich/häufig zu Reset. Teste es doch einfach mal indem du den Servo abklemmst. Drückst du dann einen Taster und er resetet immer noch, lag es am Servo. Aus meiner Erfahrung kann ich sagen, dass die Servos unheimlich die Versorgung versauen. Daher auf jeden Fall entkoppeln. Am einfachsten ein zweites Netzteil dazu hängen und GNDs verbinden. Oder ein zweiter 7805. 1,5A erscheint mir für 8 Servos, die gleichzeitig bewegt werden zu knapp. Kommt natürlich auf die Größe und die Last an.
Später soll das ganze über eine entsprechende Versorgung ermöglicht werden, aber momentahn ist 1 maximal 2 Servos dran zum testen.
Gast
#1369758
Ich habe jetzt auch nochmal gesucht und in [[http://www.mikrocontroller.net/articles/Pollin_ATMEL_Evaluations-Board]] wird die Problematik mit den Tastern angesprochen. Ich werde testen ob es bei mir ohne Benutzung der Taster keine Resets mehr gibt.
Hatte gestern leider keine Zeit um das zu testen, hoffe heute Abend.
Also, habe gestern das alles nochmal getestet, und ich muss sagen es geht. Die Pollin Tasterschaltung löst definitiv einen Reset aus auch bei 1,5 A Stromversorgung und ohne Servo. Jetzt komme ich natürlich so langsam an die Grenzen des Atmegas. Habe den Code jetzt soweit optimiert dass ich gerade mal eine Auflösung von 50 Positionen habe. Dabei habe ich noch nicht mal die Eingänge programmiert. Ich könnte den Atmel zwar noch auf 16MHz takten aber, das bringt mir gerade mal 100 Positionen und eigentlich wollte ich ne auflösung von 200 haben, vieleich sollte ich auf nen anderen Atmel wechseln oder das irgentwie aufteilen.
Gast
#1372360
> Jetzt komme ich natürlich so langsam an die Grenzen des Atmegas.
Das glaube ich kaum, meist liegt die Grenze an der Software. Wenn man
mit C schreibt kann es sehr schnell passieren das man etwas
ungeschicktes macht und damit sehr viel rechenzeit verbraucht ohne das
zu wissen.
z.b. ein binary Shift mit Variablen.
Wenn der Code nicht zu geheim ist, dann lass ihn mal sehen. Es finden
sich bestimmt genug stellen um entwas zu optimiern.
Ja, also er Code is natürlich nicht geheim, hab ihn aber gerade nicht zur hand, aber ich denke ich kann einiges aus dem Kopf was wichtig ist
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
Gast
#1372515
was soll denn das cli(); und das sei(); dafür ist der Compiler da, das
sollte man nur in der main verwenden um kurzeitig zu verhindern das ein
interupt aufgerufen wird.
Dann könnte man das ganze sehr stark optimieren, was aber ein größere
Umbau ist.
du müssten intern die Daten so ablegen das du in der ISR sie direkt
verwenden kannst.
> if ( ServoUp == ServoCnt[0] ) SERVOPORT &= ~( 1<<Servo0 );
SERVOPORT = Daten[ ServoUp ]
das ganze braucht aber recht viel speicher 1000 * 8 byte. Da müsste man
sich noch etwas einfallen lassen und es sinnvoller zu speichern.
Mit dem cli und sei wollte ich nur verhindern das der Interupt ncht durch den für die tasten unterbrochen wird.
Peter schrieb: > du müssten intern die Daten so ablegen das du in der ISR sie direkt > verwenden kannst. > >> if ( ServoUp == ServoCnt[0] ) SERVOPORT &= ~( 1<<Servo0 ); > SERVOPORT = Daten[ ServoUp ] Äh. Nein ServoUp ist bei ihm der PWM Zähler
Sven Fabricius schrieb: > Mit dem cli und sei wollte ich nur verhindern das der Interupt ncht > durch den für die tasten unterbrochen wird. Das wird er sowieso nicht. In einer ISR sind Interrupts automatisch gesperrt und sie werden auch automatisch wieder freigegeben. Und nein, es ist nicht egal ob du selbst das sei() in der ISR machst. Machst du das selbst, dann erfolgt das sei() einen Tick zu früh.
Gast
#1372538
dann lies dir erstmal die Doku von den Atmels durch. Ein Iterrupt kann nicht durch einen anderen Interupt unterbrochen werden. Durch dein sei(); hast du aber genau das erreicht und schlimmsten fall der Stack überläuft.
Gast
#1372546
> ServoUp ist bei ihm der PWM Zähler
und warum sollte das dageben sprechen? Damit kann du mit einer zuweisung
alles erledigen. Braucht aber leider viel speicher.
Was noch was bringen würde: wenn es dir gelingt die unsigned int auf unsigned char runterzuholen. Die Arithmetik bzw. die Vergleiche brauchen dann nur noch die halbe Taktanzahl
Die Idee mit
> SERVOPORT = Daten[ ServoUp ]
ist garnicht so blöd weil ich ja wenn dann nur ne auflösung von 200
Schritten haben will, dass heist ich müsste dann nur 200 * 1 Byte in dem
Array haben.
if ( ServoUp >= 200 && ServoUp < 400 )
SERVOPORT = Daten[ ServoUp - 200 ];
schwieriger ist dann nur die INC und DEC geschichten zu realisieren,
allerdings sind diese dann nicht Zeitkritisch.
Sowas is mir gerade durch den Kopf gegangen.
DEC
{
Daten[ServoCnt[ServoId]] &= ~(1<<ServoId);
ServoCnt[ServoId]--;
}
INC
{
ServoCnt[ServoId]++;
Daten[ServoCnt[ServoId]] |= (1<<ServoId);
}
Peter schrieb: >> ServoUp ist bei ihm der PWM Zähler > und warum sollte das dageben sprechen? Damit kann du mit einer zuweisung > alles erledigen. Braucht aber leider viel speicher. Ja. Ich habe nicht behirnt, worauf du hinaus willst. Ein grosses Daten Array in dem die einzelnen Indizes die Zeitachse repräsentieren.
Genau, so in etwa:
Daten:
1111000 ....
1100000
1111000
1100000
1111110
1100000
1111110
1100000
| 1ms |
._________
| |______ Servo 0
._______
| |________ Servo 1
._________
| |______ Servo 2
._______
| |________ Servo 3
.___________
| |____ Servo 4
._______
| |________ Servo 5
.___________
| |____ Servo 6
._______
| |________ Servo 7
Man könnte darüber nachdenken, da so etwas wie ein Run-Length Encoding einzubauen, wenn die Größe des Datenarrays ein Problem ist. Der Update einer Servoposition ist dann zwar besch...eiden, aber die Auswertung in der ISR wäre immer noch kein Problem.
Hab jetzt leider kein WinAVR zur Verfügung, kann denn jemand mal nach checken wie viele Schritte das sind:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
Nur compiliert. Die ISR ist exakt 100 Bytes lang (43 Assembler Tokens). 11 Assembler Tokens bilden den Teil if ( ServoUp >= 200U && ServoUp < 400U ) SERVOPORT = Daten[ ServoUp - 200U ]; Wobei der then Zweig aus c6: ee 59 subi r30, 0x9E ; 158 c8: ff 4f sbci r31, 0xFF ; 255 ca: 80 81 ld r24, Z cc: 8b bb out 0x1b, r24 ; 27 besteht.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
Compiliert mit -Os
43, na das ist doch ne hausnummer, dann kann ich den comperator noch halbieren auf 10, dann habe ich 80 inclusive puffer und dann mach ich noch nen 16er Quarz drann und habe meine 200 Schitte auflösung
Gast
#1372943
Ich habe mir jetzt nicht alles durchgelesen, aber ich glaube, du machst einen Denkefehler. Du brauchst nicht alle Servoimpulse sozusagen gleichzeitig erzeugen, sondern kannst das ganz gemütlich Stück für Stück machen. |-|__________ Servo1 ___|-|________ Servo2 usw. Beim Einlesen ebenfalls, die kommen nacheinander.
Grundsätzlich hast du recht, so kommen sie ja auch aus dem Empfänger, für das Servo ist es wurscht. Der Empfänger macht ja nix anderes als das Sendersignal auf die Kanäle zu demuxen. Ich weiß nur nicht inwiefern es die sache vereinfachen würde
Gast
#1373028
>Ich habe mir jetzt nicht alles durchgelesen, aber ich glaube, du machst >einen Denkefehler. Du brauchst nicht alle Servoimpulse sozusagen >gleichzeitig erzeugen, sondern kannst das ganz gemütlich Stück für Stück >machen. >|-|__________ Servo1 >___|-|________ Servo2 >usw. >Beim Einlesen ebenfalls, die kommen nacheinander. Du hast leider nur teilweise recht. Nur die guten, alten PPM Sendeanlagen arbeiten so. Wie es bei den PCM Anlagen ausschaut weis ich nicht aber bei den 2G4 Anlagen kommen immer mehrere Signale gleichzeitig beim Empfänger raus. Die meißten neuen Graupner Empfänger geben sogar alle Signale (fast) gleichzeitig aus.
Ich bin gerade am überlegen ob ich den Atmel als reinen default signalgeber verwende und die Umschaltung der 4 Input Kanäle auf die Outputs über ne Art von Latch mit Output Enable mache. Denn jetzt noch die Abfrage der Inputs da rein zu bringen, könnte kompliziert werden. Mit zwei von denen (74HCT573) dahinter sollte man das doch recht einfach hin bekommen oder, ich weiß nur nicht ob die Ausgänge das verkraften wenn ich die einfach auf ein ander lege?
Das ist jetzt meine Idee dazu. Ich habe nur Bauchschmerzen dabei die Ausgänge der Latches einfach so auf einander zu legen. Oder sollte ich lieber noch 2 74HCT32 integrieren?
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.

