Hallo,
ich habe mir 2 Servos(HS-311) besorgt und will diese mit einem
Atmega328p ansteuern, um eine Kamera damit zu schwenken.
Leider klappt dies überhaupt nicht. Der Servo dreht bzw. zuckt sich
immer nur in eine Richtung. Wenn er seine "Grenze" erreicht hat dann
zuckt er einfach weiter. Habe schon viel gegoogelt und mit den Zahlen
wie "Reload" herumgespielt. An den Bauteilen liegt es auch nicht ,weil
ich alle ausgewechselt habe. Vielleicht hilft das bisschen:Ich habe an
dem Port ,an dem auch der Servo hängt, eine LED dazugegeben und diese
blinkt ca jede Sekunde rägelmäßig.
Hier der code:
Danke für die schnelle Antwort,
Aber leider hat es mit "Enable Interrupts" auch nicht geklappt. Könntest
du mir bitte noch schnell erklären was "Stackwerte" sind?Ich habe
darüber im Internet keine Erklärung gefunden.Weil ich mir alles selber
beigebracht habe ,hab ich leider so "Wissenslücken"
Mfg Lukas
Stack-Werte sind Angaben für einen für den Programmablauf wichtigen
Speicherplatz im ram. Darin werden zB. Rücksprungadressen gespeichert
und ähnliches.Bei bascom kannst du im editor mit F1 eine Hilfe aufrufen,
da findest du auch was über hwstack, swstack und framesize. Blöderweise
sind im editor auch Voreinstellungen enthalten, die beim compilieren
verwedet werden. Nur die passen nicht für alle Fälle und für alle
Kontroller. So ist es besser, die händisch ins Programm zu schreiben,
weil man dann sieht, welche Werte auch verwendet wurden.
In der Hilfe sind auch Beispielprogramme, auch für Servos, aber leider
auch ohne stack-Werte.
Verwende mal
$hwstack=32
$swstack=8
$framesize=24
edit
Hab' das $framesize erhöht
Schau in der bascom Hilfe unter
BASCOM Language Reference
->Compiler Directives
-->$HWSTACK
Danke,
habe alles ausprobiert was ging. Nur leider habe ich keine Fortschritte
gemacht. Das mit den Stck-werten habe ich gut verstanden ;-) nur leider
wird das bei mir nicht gehen, weil ich den MC nicht über "Bascom"
sondern über "myAVRProgrammTool" brenne. Und wie ich im Internet
nachgelesen habe werden die Stack-werte in einem flüchtigen Speicher
gespeichert, also kann ich die nicht auslesen.
Ich habe auch den Example-code von Bascomn für Servos angeschaut, aber
da ändert sich leider auch nix.
Mfg Lukas
Lukas S. schrieb:> Ich habe auch den Example-code von Bascomn für Servos angeschaut, aber> da ändert sich leider auch nix.
Probiere es doch mal direkt, etwa so:
1
$regfile="m328pdef.dat"
2
$crystal=8000000
3
4
DimXxAsByte
5
6
ConfigPortb.1=Output
7
8
Do
9
ForXx=1To40
10
Portb.1=1
11
Waitus1000
12
Portb.1=0
13
Waitms19
14
Next
15
16
ForXx=1To40
17
Portb.1=1
18
Waitus2000
19
Portb.1=0
20
Waitms19
21
Next
22
23
ForXx=1To40
24
Portb.1=1
25
Waitus1500
26
Portb.1=0
27
Waitms19
28
Next
29
Loop
Wenn das nicht funktioniert, ist dein Servo hinüber.
Ist das ein neuer Atmega ? Wenn ja hast du die Clockdiv8 Fuse geändert ?
Ein Fabrikneuer Atmega läuft nur mit 1 MHz. Dann würden die Timings
nicht mehr stimmen und der Servo macht nicht das was er soll
Gruß JackFrost
Dann müsste man das aber am Blinken erkennen.
Zeig' doch mal den code mit dem Blinketeil drin. Wenn vor jedem waitms
1000 die Led ein, bzw beim nächsten waitms wieder ausgeschaltet wird,
sollte sich alle Sekunde der Zustand ändern, also ein eher langsames
Blinken.
Solltest du vielleicht einen Arduino verwenden, läuft der mit 16000000
Hz und du hättest eine Blinkfrequenz von 1 Hz, 1/2 Sec an, 1/2 Sec aus.
Lukas S. schrieb:> Das mit den Stck-werten habe ich gut verstanden ;-) nur leider> wird das bei mir nicht gehen, weil ich den MC nicht über "Bascom"> sondern über "myAVRProgrammTool" brenne.
Wenn du die in deinem Programmlisting rein schreibst und mit bascom
compilierst, dann sind die auch im .bin - file drin, das du dann mit
wasweißich auf den Kontroller flashst. Schreibst du die nicht rein,
verwendet bascom voreingestellte Werte, die total falsch sein könnten,
nur, wie du schon schriebst; nicht mehr kontrolliert werden können.
Marc V. schrieb:> Probiere es doch mal direkt, etwa so:> ......> Wenn das nicht funktioniert, ist dein Servo hinüber.
Leider hat der code auch nichts geändert. Dass der Servo kaputt ist
glaube ich kaum, weil ich 2 neue Servos vom Conrad gekauft habe und ich
nehme nicht an, dass beide kaputt sind. Sonst würde es ja einer tun ;-)
Bastian W. schrieb:> Ist das ein neuer Atmega ? Wenn ja hast du die Clockdiv8 Fuse geändert ?
Ja er ist neu. Und wenn diese "Clockdiv8 Fuse" der Tackt ist, habe ich
ihn geändert(im Internet habe ich darüber nichts gefunden).
Michael K. schrieb:> Solltest du vielleicht einen Arduino verwenden, ....
Nein ich verwende auch kein Board. Also daran liegt es auch nicht.
Ich glaube generell nicht, dass es an der Hardware liegt, weil ich alles
doppelt zuhause habe, ausgenommen das Netztgerät. Vermute eher einen
Programmfehler.
Mfg Lukas
Lukas S. schrieb:>> Wenn das nicht funktioniert, ist dein Servo hinüber.>> Leider hat der code auch nichts geändert. Dass der Servo kaputt ist
Probiere das mal:
Oh Super,
der Servo macht jetzt genau das, was im code steht. Gut zu wissen, dass
der Servo nicht kaputt ist ;-) Wie ich das jetzt aus dem code herauslese
wird der Servo einfach nur als normaler Moter verwendet. Könnte mir
vielleicht noch jemand verraten wie ich jetzt den Winkel programmieren
kann? Ich meine mit dem Servo Befehl von Bascom.
Mfg Lukas
Eigentlich schon,
ich habe immer darauf geachtet 8Mhz zu haben.
Möglicher weiße habe ich eine Null vergessen aber das glaube ich
eigentlich nicht.
Mfg Lukas
Lukas S. schrieb:> Und wenn diese "Clockdiv8 Fuse" der Tackt ist, habe ich> ihn geändert(im Internet habe ich darüber nichts gefunden).
Das ist nicht der Takt, sondern ein Teiler des Taktes. Ist diese fuse
'enable', wird die Taktfrequenz intern durch 8 dividiert.
Wenn du 8MHz als Takt haben willst, musst du die fuse auf 'int RC 8 MHz'
(oder so ähnlich) stellen und 'clockdiv8' auf 'disable' stellen.
Lukas S. schrieb:> Eigentlich schon,>> ich habe immer darauf geachtet 8Mhz zu haben.> Möglicher weiße habe ich eine Null vergessen aber das glaube ich> eigentlich nicht.>> Mfg Lukas
Was meinst Du mit - eine Null vergessen - ?
Die Zeile - $crystal = 1000000 - teilt Bascom nur mit, mit welchem Takt
der Prozessor läuft. Damit wird der Takt des Prozessors nicht verändert.
Das must Du mit Programmierung der FUSES direkt am µC machen. In diesem
Fall
die - clkdiv8 fuse - löschen, die den 8 MHz durch 8 teilt.
Aber vermutlich reichen 1 MHz sowieso aus.
Lukas S. schrieb:> Eigentlich schon
Schreib doch bitte mal - aus Deinem Wissen heraus - wie ein
Standard-Servo angesteuert werden muss. Wie bekommt man ihn ganz nach
Links (maximal), in die Mitte, ganz nach Rechts (minimal). Kein
Programm, nur die Grundlagen.
Ich möchte einfach nur wissen ob Du weißt, was Du da versuchst.
Weiß nicht genau wie ich es erklärenm soll aber ich probiere es
einmal....
Der servo wird mithilfe PWM (pulsweitenmoduliertes Signal) angesteuert.
Dieses Signal hat "Perioden", in denen kein Strom fließt, die länge der
Signale variert je nach Servo. Dann gibt es die sogenannten "Impulse",
das ist einfach wenn Strom fließt. Je nach Länge der Impulse, richtet
sich der Servo aus. Ich glaube 1,5 ms sind die Mitte.
Mfg Lukas
Lukas S. schrieb:> Der servo wird mithilfe PWM (pulsweitenmoduliertes Signal) angesteuert.
Alle Achtung - das hätte ich nicht erwartet. Nein, nicht PWM etc.
sondern das Du eine Erklärung versuchst. Finde ich gut :-) - obwohl ich
oft meine, Du veralberst hier alle :-)
Egal - Du liegst schon richtig. Es geht immer um 20 mS-Perioden (mit
Start-Puls), in welchen ein Impuls an der richtigen Stelle die Stellung
des Servos bestimmt.
Hier finde ich das ganz anschaulich dargestellt:
http://rn-wissen.de/wiki/index.php/Servos
Da ist auch ein hübsches Bascom-Beispiel dabei.
Oh - und das gibt jetzt Haue für mich - warum fängst Du nicht mit
Arduino an? Du musst ja nicht stumpf alles zusammenklicken, aber da sind
die Librarys "transparent" und Du musst Dir erstmal keine Gedanken drum
machen. Wenn Du neugierig genug bist schaust Du Dir den Hintergrund
irgendwann an.
http://funduino.de/nr-12-servo-ansteuern
Du kannst natürlich auch mit Assembler einsteigen (ideal Hardware-nah)
oder mit C (was ich aktuell bevorzuge) aber da musst Du Dich schon
intensiver mit der Hardware beschäftigen.
Dieter F. schrieb:> 20 mS-Perioden
Erinnert mich an den 600Ω-Impuls ...
s = Sekunden ; S = Siemens (Leitwert, 1/Ω)
Zeitabhängige Einheiten sind meist klein!
Dieter F. schrieb:> mit Start-Puls
Das könnte man nun in den falschen Hals bekommen.
Es kommt einfach eine Folge von Pulsen, keiner ist der Start-Puls.
Ich weiß, dass Du die Zeit einfach inkl. der Zeit für den Puls, welcher
sich am Anfang jeder Periode befindet, meinst.
Also: Zeit von positiver Flanke bis zur nächsten positiven Flanke sind
ungefähr 20ms. So genau muss das aber nicht eingehalten werden, wichtig
für die Position des Servos ist die Länge des Pulses.
Gruß
Jobst
Danke für die Antworten,
habe jetzt alles ziemlich gut verstanden. Den code von "Marc Vesely
(Firma: Vescomp) (logarithmus) Datum: 29.11.2016 19:25" habe ich jetzt
auch endlich gerafft :-).Nur die Befehle von Bascom funktionieren immer
noch nicht, obwohl ich keine Fehlermeldungen habe und ich auch keinen
Fehler finde. Könnte es am Tackt liegen?Ich habe zwar schon jetzt fast
alle gängigen durchprobiert, aber nichts hat geklappt.
Dieter F. schrieb:> warum fängst Du nicht mit Arduino an?
Dies liegt vermutlich daran, dass wenn ich etwas gebaut habe, es nicht
mehr "zerstören" will und außerdem baue ich normal auch halbwegs
nützliche Sachen. Die verwende ich dann meistens auch und deswegen wäre
für jede Sache ein neuer Arduino bisschen teuer ;-)
Mfg Lukas
3€ für einen chinesischen Arduino sind dir zu teuer? Wenn man die Dinger
im 10er Pack kauft wirds sogar noch billiger. Dafür hat man gleich ein
betriebsfertiges Board mit USB dran. Das musst du ohne Arduino erstmal
unterbieten.
Lukas S. schrieb:> Nur die Befehle von Bascom funktionieren immer> noch nicht, obwohl ich keine Fehlermeldungen habe und ich auch keinen> Fehler finde.
Hast du jetzt die fusea umgestellt? Wenn nicht, dann schreib in deinen
bacom-Programm auch rein, das du mit 1 MHz Kontrollertakt arbeitest,
also
$crystal=1000000
und enable interrupts
nicht vergessen
Ich weiß jetzt wirklich nicht was falsch sein könnte.
Stefan U. schrieb:> Die Ardunino Entwicklungsumgebung ist auch mit "nackten" Chips nutzbar.> Du brauchst kein komplettes Arduino Board.
Ich weiß schon aber mir gefällt Bascom irgendwie besser und ich bin zu
faul noch meher Programmiersprachen zu lernen.Aber ich kann mir ja einen
besorgen und mal ausprobieren ;-)
Mfg Lukas
Lukas S. schrieb:> Servo(1) = 60> Waitms 1000> Servo(1) = 140> Waitms 1000
Die Zeiten stimmen nicht. Es gilt x 10µs. Das hieße: 60x10µs=0,6ms und
140x10µs = 1,4ms.
Setze mal:
Servo(1)= 100 für ganz links
Servo(1)= 150 für die Mitte
Servo(1)= 250 für ganz rechts
ein.
MfG Paul
Leider ändert das überhaupt nichts. Der Servo zuckt immer noch nach
rechts(von dem Pickerl aus rechts) und bleibt dort dann hängen, bzw. er
versucht sich nach dem Anschlag noch weiter zudrehen.
Mfg Lukas
Lukas S. schrieb:> Der Servo zuckt immer noch nach> rechts(von dem Pickerl aus rechts) und bleibt dort dann hängen, bzw. er> versucht sich nach dem Anschlag noch weiter zudrehen.
Wie versorgst Du denn den Servo? Welche Spannung Anschluss welche
maximale Leistung?
Dieter F. schrieb:> Wie versorgst Du denn den Servo? Welche Spannung Anschluss welche> maximale Leistung?
Ich habe Mc und Servo parallel an mein Netztgerät geschlossen Dieses
geht bis zu 3A und ich habe eine Spannung von 5V Dc eingestellt. Im
Datenblatt vom Servo sind 4.8V-6V tolleriert und beim Mc 4.5V-5.5V.Dies
sollte demnach kein Problem sein.
Mfg Lukas
Gewöhnlich dokumentiert man zu einem Programm auch die Schaltung
der Hardware. Ansonsten kann man unendlich im Nebel stochern ohne
der Lösung näher zu kommen.
Lukas S. schrieb:> Ich habe Mc und Servo parallel an mein Netztgerät geschlossen
Da gibts aber eigentlich nicht meher zu sagen. Vielleicht noch, dass das
Seuerungskabel vom Servo auf Pin 15 (PINB.1) liegt. Dass ich einen
Atmega328p verwende, sieht jeder hoffentlich schon am Tietel.
Und ehrlich gesagt finde ich da einen Schaltplan bisschen überflüssig,
bei einer so "koplizierten" Schaltung ;-)
Mfg Lukas
Was erwartest du denn, dass wir glauben, was ein Dreizehnjähriger
alles richtig oder falsch machen könnte?
Dein Servo-Steuereingang könnte ja ein Pegel-, Stromaufnahme- oder
Timmingproblem haben.
Also mal nicht so dick auftragen, wenn du Hilfe suchst.
Geht leider auch nicht.
Aber was mir auffällt ist: Wenn ich den Mc einschalte bzw. ihn mit Strom
versorge dreht sich der Servo kurz nach liks und dann aber sofort nach
rechts. Leider zuckt er noch und dreht sich auch nicht flüssig.Ich kann
mir schwer vorstellen, dass das Problem an der Harware liegt, weil der
Code von "Marc Vesely (Firma: Vescomp) (logarithmus)Datum: 29.11.2016
19:25" nach wie vor gut funktioniert.
Mfg Lukas
Lukas S. schrieb:> Geht leider auch nicht.>> Aber was mir auffällt ist: Wenn ich den Mc einschalte bzw. ihn mit Strom> versorge dreht sich der Servo kurz nach liks und dann aber sofort nach> rechts. Leider zuckt er noch und dreht sich auch nicht flüssig.Ich kann
Ich kenne mich mit Bascom nicht aus aber es gibt auch Help.
Kurz:
Reload ist die Zeit zwischen 2 Impulsen.
Fange doch einfach mit Reload = 4 und wenn es nicht geht, erhöhe
den Wert bis 20, meinetwegen.
Falls die Sache ruhiger wird, ändere den Wert für Servo(1) von
etwa 50 bis 250.
P.S.
So sieht der LA die Sache.
Marc V. schrieb:> Fange doch einfach mit Reload = 4 und wenn es nicht geht, erhöhe> den Wert bis 20, meinetwegen.
Habe ich gemacht, aber leider hat sich nichts geändert.
Michael K. schrieb:> Nano, nicht mikro, wird wohl nur ein Schreibfehler sein :-)
Oh, stimmt habe ich übersehen. Habe bis jetzt aber immer Kondensatoren
mit bisschen mehr nF verwendet, ich hoffe da ist nichts kaputtgegangen.
Mfg Lukas
Lukas S. schrieb:> Oh, stimmt habe ich übersehen. Habe bis jetzt aber immer Kondensatoren> mit bisschen mehr nF verwendet, ich hoffe da ist nichts kaputtgegangen.
Kaputtgegangen wohl nicht.
Aber Kondensatoren mit mehreren µF sind meistens Elkos, und die sind
hier nicht geeignet (Induktivität!). Du brauchst einen
Keramik-Kondensator, und der muss möglichst nahe am µC sein.
Redit schrieb:> Vielleicht hilft dir das auch weiter:>http://www.electronicsplanet.ch/mikrocontroller/sourcecode/ATmega8/ATmega8Servo.htm
Danke, bin mit der Erklärung aber leider auch nicht weitergekommen.
Dieter F. schrieb:> So wie es aussieht war der Servo schon defekt. Schon mal mit einem> anderen Servo probiert?
Ja und gleichzeitig Nein. Habe es mit einem 2ten Servo ausprobiert und
es hat alles auch nicht funktioniert aber es war genau das selbe
Modell(HS-311).Könnte es sein,dass es am Modell liegt?
Mfg Lukas
Hallo,
ich glaube, dass ich einen Fehler gefunden habe. Zur info ich verwende
zum Brennen"myAVR ProgrammTool V.139".
Kann es sein, dass ich die Fuse nie mitgebrannt habe? Bis jetzt hatte
ich nämlich immer das "Fuses brennen:" aus (siehe Foto 1). Wenn das ein
Fehler war, wie soll ich dann die Einstellungen konfigurieren(siehe Foto
2)? Ich nehme an, dass ich die nnicht neinfach alle so lassen kann.
Mfg Lukas
Moin,
Nein, lass die Fuses so wie sie sind. Dann ist der Code mit 1MHz
richtig.
Lassen wir mal die Fuses weg, das ist erstmal ok so.
In der Hilfe von Bascom ist das etwas dürftig dokumentiert aber ich
denke das ist noch falsch konfiguriert.
Grundsätzlich: Bei vielen dieser höheren Befehlen ist es nicht besonders
gut sie in Bascom zu benutzen, vor allem wenn sie einen Timer nutzen.
Damit hast Du nämlich das Timing aus der Hand gegeben.
Timer sind fast das Wichtigste und deshalb mach das mit dem Timer0
selbst, alleine schon um was zu lernen.
Wie das Signal aussehen muss weisst Du ja.
Ich erkläre mal einen recht einfachen Weg, wie man das zu Fuß macht.
Den Overflow muß man sowieso anspringen, rein mit Hardware-PWM geht das
nur ganz schlecht mit Timer0.
Du wirst das alles im Datenblatt nachvollziehen müssen aber das ist
nicht zu kompliziert.
Wir lassen den Timer0 mit dem Vorteiler 8 bei laufen und zwar im Modus
PWM, Phase correct mit Top als 255. Dabei zählt er immer rauf und
runter. 0...255...0...usw..
Mit Teiler 8 dauert das jeweils 4,096ms.
Wir wollen eine Periode von 20 ms, also muss das 5x passieren.
Das zählen wir nachher in der ISR mit.
Nun nehmen wir den PWM-Ausgang OCR0A für das Signal.
Achtung, das ist Portd.6, das musst Du ändern!
Wenn der Wert erreicht wird, geht der Ausgang auf 1 beim Runterzählen
und wieder 0 beim Hochzählen.
Dementsprechen ist der Wert von OCR0A jeweils 16µs.
62 ist ca. 1ms, 125 ist ca. 2ms.
Die ISR wird angesprungen, wenn der Timer auf 0 kommt.
Wenn man dann den Wert für das Servo schreibt, passiert nichts denn das
Register wird erst wirklich beschrieben wenn der Timer 255 erreicht, der
alte Wert wird also immer noch fertig ausgeführt.
Der Code würde dann so aussehen:
1
$regfile="m328pdef.dat"
2
$crystal=1000000
3
$hwstack=32
4
$swstack=8
5
$framesize=24
6
7
DimPeriodcounterAsByte
8
DimServovalueAsByte
9
10
'PhasecorrectPWM,Top&HFF:
11
TCCR0A.WGM00=1
12
'ClearOC0AonCompareMatchwhenup-counting.SetOC0Aon
13
'CompareMatchwhendown-counting.
14
TCCR0A.COM0A1=1
15
'OCR0AisD6
16
DDRD.6=1
17
18
'Starttimer0withdivider8
19
TCCR0B.CS01=1
20
21
EnableTimer0
22
EnableInterrupts
23
OnTimer0T0_isr
24
25
Do
26
Servovalue=62
27
wait2
28
Servovalue=96
29
wait2
30
Servovalue=125
31
wait2
32
Loop
33
34
T0_isr:
35
IncrPeriodcounter
36
IfPeriodcounter=5Then
37
Periodcounter=0
38
OCR0A=Servovalue
39
Else
40
OCR0A=0
41
EndIf
42
Return
Hmmm, ungetestet aber müsste so passen.
OCR0B für das zweite Servo kannst Du genauso einfügen.
In C würde das vom Prinzip her übrigens auch nicht viel anders aussehen.
Wenn Du dran bleibst, wirst Du irgendwann auf C umsteigen und wenn Du
Dich nicht so von den höheren Funktionen von Bascom einlullen lässt, ist
der Umstieg nicht so schwer. Für den Anfang ist die Syntax von Bascom
aber nunmal viel einfacher.
Wenn Du Fragen hast - nur zu.
Aber Du wirst Dich durch das Datenblatt Timer0 durchkämpfen müssen, das
ist die absolute Grundlage, wenn Du damit etwas weitermachen willst.
Wenn Du da was nicht verstehst kannst Du gerne fragen aber bitte
möglichst gezielt.
Wenn das mit den 13 Jahren stimmt, hat sich das Geschreibsel hoffentlich
gelohnt.
Gruß,
Norbert
Moin,
Da fehlt noch:
'Clear OC0B on Compare Match when up-counting. Set OC0B on
'Compare Match when down-counting.
Tccr0a.com0b1 = 1
Rest sieht gut aus.
Gruß,
Norbert
Moin,
Nachtrag:
Lass das mit Single. Das macht man nur wenn man ohne Ende Zeit und Platz
hat. Hat man meist nicht, also gar nicht erst angewöhnen.
Deine Adcin / 10.24 sind Quatsch wenn das Integer ist. Meckert Bascom da
nicht?
Ausserdem kommt bei der Rechnung 50-150 raus, büschn viel (sollte aber
gehen).
Die Mitte ist 96, 100% wäre 62 - 125, also ca +/- 32.
Flexibler macht man das besser so:
1
ConstServomid=96
2
ConstPotimid=512
3
4
DimServovalue1AsInteger
5
DimAdcin1AsInteger
6
7
.
8
.
9
.
10
11
'CalculationofServovalues:
12
Servovalue1=Adcin1-Potimid
13
ShiftServovalue1,Right,4,Signed'/16
14
Servovalue1=Servovalue1+Servomid
Division kostet immer viel Zeit und Speicher, deswegen "Shift".
Willst Du einen anderen Faktor als 2^n, dann multiplizierst Du erst und
dann wird geshiftet. Multiplikation quält den µC nicht ganz so, wenn er
das nicht sogar in Hardware kann.
Also immer ein Bruch in der Form * X / 2^n.
125% Weg wäre also z.B.
Servovalue1 = Servovalue * 5
Shift Servovalue1, Right, 6, Signed '/64
Beim Multiplizieren musst Du immer drauf achten, daß der Wert nicht
überlaufen kann. Test: Servovalue könnte -512 bis 511 sein.
* 5 macht -2560 -> passt.
Gruß,
Norbert
Norbert S. schrieb:> Division kostet immer viel Zeit und Speicher, deswegen "Shift"> ...
Dann ist aber auch der Compiler mist wenn er aus einer Division, die
eigentlich nur ein Shift ist, kein Shift macht. Sowas erkennen Compiler
schon seit Jahren eigentlich von alleine.
Danke,
Der 2te Servo funktioniert jetzt auch gut.
Nur mit der neuen Rchnungsformel geht es leider nicht mehr:
Norbert S. schrieb:> Const Servomid = 96> Const Potimid = 512>> Dim Servovalue1 As Integer> Dim Adcin1 As Integer> .> .> .> 'Calculation of Servovalues:> Servovalue1 = Adcin1 - Potimid> Shift Servovalue1, Right, 4, Signed '/16> Servovalue1 = Servovalue1 + Servomid
Der Servo zuckt (über 90°) jetzt nur noch. Man merkt, dass er sich schon
noch über den Poti leicht beeinflussen lässt. Mit "meiner alten Formel"
funktioniert es noch. --> es liegt an der Formel. Oder fehlt einfach nur
ein wait?
Mfg Lukas
Lukas S. schrieb:> Mit "meiner alten Formel"> funktioniert es noch. --> es liegt an der Formel.
Welcher ?
Von Norbert S. ?
Von dir habe ich weder alte noch neue Formeln gesehen.
Hallo,
Mit der "alten" Rechnungsart meinte ich:
Lukas S. schrieb:> Adcin1 = Adcin1 / 10.24 'Wert für Servo umrechnen> Adcin1 = Adcin1 + 50> Servovalue1 = Adcin1
....und mit der "neuen" Rechnungsart:
Norbert S. schrieb:> Const Servomid = 96> Const Potimid = 512>> Dim Servovalue1 As Integer> Dim Adcin1 As Integer>> .> .> .>> 'Calculation of Servovalues:> Servovalue1 = Adcin1 - Potimid> Shift Servovalue1, Right, 4, Signed '/16> Servovalue1 = Servovalue1 + ServomidNorbert S. schrieb:> Die Mitte ist 96, 100% wäre 62 - 125, also ca +/- 32.
Demnach ist die von Norbert S. richtig und meine falsch, nur wie ich
oben schon geschrieben habe zuckt der Servo extrem.Ich hoffe das lässt
sich noch beheben :-)
Mfg Lukas
Moin,
M. K. schrieb:> Dann ist aber auch der Compiler mist wenn er aus einer Division, die> eigentlich nur ein Shift ist, kein Shift macht. Sowas erkennen Compiler> schon seit Jahren eigentlich von alleine.
Jaaa, das kann Bascom nicht.
/ 2^n wird ne Division.
Mehrere Operationen in einer Formel gehen auch nicht.
Aber etwas mitdenken ist erlaubt, dafür kommt man schnell rein.
Bei meinem Beispiel mit den 125% wird das aber kein Compiler in eine
Multiplikation und Shift zerlegen sondern eben die krumme Division
basteln.
Gruß,
Norbert
Lukas S. schrieb:> Demnach ist die von Norbert S. richtig und meine falsch
Moin,
Deine Rechnung liegt nur leicht daneben, das Servo geht damit aber
sicher auch.
Ich vermute, Du hast aus meiner Vorlage das nicht richtig umgesetzt,
deswegen solltest Du wirklich das zuckende Programm komplett zeigen.
Meine Version sollte ziemlich sicher auch funktionieren.
Vergiss aber mal die Fummelei mit dem Shift, vielleicht war das
übertrieben.
Single geht aber echt nicht für sowas und brauchst Du nicht.
Also erste Maßnahme: Integer statt Single (für die C-Leute: Single ist
Float).
Ausserdem würde ich das auf die Mittelposition beziehen, so kannst Du
den Schwenkbereich einfacher ändern (also nicht 1500µs +/- 500µs sondern
z.B +/-700µs).
Du hast das mit dem Offset von der einen Endposition und dem
Gesamtausschlag von links nach rechts gemacht, das ist nicht so schön.
Also mit Division aber den Mittelstellungen:
Norbert S. schrieb:> Jaaa, das kann Bascom nicht.> / 2^n wird ne Division.> Mehrere Operationen in einer Formel gehen auch nicht.> Aber etwas mitdenken ist erlaubt, dafür kommt man schnell rein.
Ich kenne Bascom leider nicht aber ehrlich gesagt überrascht mich das
schon sehr, dass das eine Division bzw. Multiplikation mit 2^n nicht
erkennt und in eine Shift-Operation umsetzt. Das ist ja nicht erst seit
gestern Stand der Technik. OK, wieder was gelernt.
Mitdenken kann immer hilfreich sein, ist also immer erlaubt ;)
M. K. schrieb:> dass das eine Division bzw. Multiplikation mit 2^n nicht> erkennt und in eine Shift-Operation umsetzt.
Das geht natürlich nur, wenn man mit Literalen arbeitet - sonst kann der
Compiler dass natürlich nicht "wissen".
Danke,
es funktioniert jetzt alles.
Hätte da nur noch 2 Fragen:
1) Kann ich die ganze Reihe "C" als output configurieren? Ich frage weil
ich an PORT.0,1,2 LEDs habe und an 5 und 6 die adc's. Würde das die
adc's stören?
Lukas S. schrieb:> Config Adc = Single , Prescaler = Auto , Reference = Avcc> Config Portb = Output> Config Portc.0 = Output> Config Portc.1 = Output> Config Portc.2 = Output
2) Die Servos drehen sich jetzt nur noch um ca. 130°. Davor haben sie
sich um volle 180° gedreht und mit der Hand geht es auch noch. Ich nehme
mal an das liegt am programm. Weiß da vielleicht jemand woran es liegen
könnte?
Mfg Lukas
Lukas S. schrieb:> Ich nehme mal an das liegt am programm. Weiß da vielleicht jemand> woran es liegen könnte?
Das wird an den Programmänderungen liegen, die du zwischen der
180°-fähigen und der nur 130°-drehenden Version gemacht hast. Zeig mal,
was du zwischen diesen beiden Versionen geändert hast.
1.) Nein, wenn die Pins mit den ADCs als Output deklariert werden,
funktionieren die ADCs dort nicht mehr.
2.) Das werden eher +/- 60° sein und so soll es sein.
Das entspricht den +/- 32 die aus den Adcin berechnet werden.
Bei Deiner vorherigen Berechnung waren es +/- 50, was eigentlich zuviel
ist.
Wenn Du jetzt mehr Ausschlag haben willst, wirst Du selbst drauf kommen,
wie Du die Rechnung änderst. Hat Norbert oben doch sogar schon
beschrieben (125%).
Danke,
habe mich jetzt bisschen mit den werten gespielt. Bei mir war am besten
"14", als Divisor.
Habe noch eine Frage:Ich hätte es gerne, dass der Servo so lange dreht,
bis der Potentometer anschlägt. Ist das möglich, oder ist irgendwann der
Spannungsunterschied zu gering?
Mfg Lukas
Thomas W. schrieb:> Zeig mal,> was du zwischen diesen beiden Versionen geändert hast.
Nicht viel, habe noch eine Constante gemacht "Divisor", und diese
bisschen geändert.Auch die Kommentare habe ich angepasst und neue
gemacht.
Das wäre mein code derzeit:
1
$regfile = "m328pdef.dat"
2
$crystal = 1000000
3
$hwstack = 32
4
$swstack = 8
5
$framesize = 24
6
7
Config Adc = Single , Prescaler = Auto , Reference = Avcc 'adc's
8
Config Portb = Output 'LED's
9
Config Portc.0 = Output 'LED's
10
Config Portc.1 = Output 'LED's
11
Config Portc.2 = Output 'LED's
12
13
Dim Adcin1 As Integer 'Poti1
14
Dim Adcin2 As Integer 'Poti2
15
Dim Periodcounter As Byte
16
Dim Servovalue1 As Integer 'Servo1
17
Dim Servovalue2 As Integer 'Servo2
18
19
Const Servomid = 96
20
Const Potimid = 511
21
Const Divisor = 14
22
23
'Phase correct PWM, Top &HFF:
24
Tccr0a.wgm00 = 1
25
'Clear OC0A on Compare Match when up-counting. Set OC0A on
26
'Compare Match when down-counting.
27
Tccr0a.com0a1 = 1
28
Tccr0a.com0b1 = 1
29
'OCR0A is D6
30
Ddrd.6 = 1
31
'Ocr0b Is D5
32
Ddrd.5 = 1
33
34
'Start timer0 with divider 8
35
Tccr0b.cs01 = 1
36
37
Enable Timer0 'Timer0 an
38
Enable Interrupts 'erlaubt Interrupts
39
Portc.0 = 0
40
Portc.1 = 1
41
On Timer0 T0_isr 'Interrupt von Timer0
42
Start Adc 'Startet ADC's
43
44
Do
45
46
Do
47
Loop Until Periodcounter = 1
48
49
Adcin1 = Getadc(5) 'wert von Poti 1
50
If Adcin1 < 40 Then 'LED's je nach Potistellung ein/aus
51
Portb.2 = 1
52
Portb.3 = 0
53
Portb.4 = 0
54
Elseif Adcin1 < 984 Then
55
Portb.2 = 0
56
Portb.3 = 1
57
Portb.4 = 0
58
Else
59
Portb.2 = 0
60
Portb.3 = 0
61
Portb.4 = 1
62
End If
63
64
Adcin1 = Adcin1 - Potimid '-512...512
65
Adcin1 = Adcin1 / Divisor 'Divisor in Probephase ;-)
66
Servovalue1 = Adcin1 + Servomid
67
68
Adcin2 = Getadc(4) 'wert von poti 2
69
If Adcin2 < 40 Then 'LED's je nach Potistellung ein/aus
70
Portc.0 = 1
71
Portc.1 = 0
72
Portc.2 = 0
73
Elseif Adcin2 < 984 Then
74
Portc.2 = 0
75
Else
76
Portc.0 = 0
77
Portc.1 = 0
78
Portc.2 = 1
79
End If
80
81
Adcin2 = Adcin2 - Potimid '-512...512
82
Adcin2 = Adcin2 / Divisor 'Divisor in Probephase ;-)
Moin,
Ich verstehe die Frage nicht ganz.
Lukas S. schrieb:> dass der Servo so lange dreht,> bis der Potentometer anschlägt. Ist das möglich, oder ist irgendwann der> Spannungsunterschied zu gering?
Das Poti mit dem Du das einstellst? (DAS Potentiometer, DAS Servo!).
Am Ende ist da ev. ein toter Weg im Poti.
D.h. Du drehst noch die letzten paar Grad aber am Wert ändert sich
nichts mehr.
Das kannst Du aber auch messen.
Gruß,
Norbert
Lukas S. schrieb:> Nicht viel, habe noch eine Constante gemacht "Divisor", und diese> bisschen geändert.
Dann überlege mal, was bei einer Integer-Divisionen von kleinen Zahlen
nach Art
1
Adcin1 = Adcin1 / Divisor 'Divisor in Probephase ;-)
Thomas W. schrieb:> Dann überlege mal, was bei einer Integer-Divisionen von kleinen Zahlen> nach ArtAdcin1 = Adcin1 / Divisor 'Divisor in Probephase> ;-)> so passiert (Stichwort "Abrunden")
Hä?
Das wird doch sofort um 512 nach unten verschoben.
Du bist komplett auf dem Holzweg.
Gruß,
Norbert
Das hat mich jetzt bisschen verwirrt!
Psst das nicht wenn ich den Divisor ändere? Dadurch ertweitere ich doch
den Schwenkbereich, oder irre ich mich da komplett?
Mfg Lukas
Moin,
Nee, ist schon genau richtig.
Mit Divisor beeinflusst Du den Servoweg.
Divisor darf nur nicht zu klein werden, sonst mag das Servo die Signale
ev. nicht mehr.
Keine Ahnung was Thomas W. uns sagen wollte.
Gruß,
Norbert