mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Servos durch µC ersetzten


Autor: DkS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Ich bin schon ziemlich lange hier auf der Seite unterwegs und habe auch 
schon viele nützliche Informationen bekommen.
Nun steh ich aber vor einem etwas größerem Problem ich hoffe ihr könnt 
mir helfen.
Ich habe vor einen Funksteuerung zu bauen bei der die beiden Servos 
durch einen µC ersetz werden und sollen. Das ganze soll in C 
programmiert werden.
Das Problem ist das ich nicht genau weiß wie ich das Signal welches mir 
der Empfänger schickt auswerten soll.
Der µC soll mir z.B. bei der Raufbewegung an der Fernbedienung die erste 
LED anmachen sobald der Steuerknüppel wieder in der Mittelstellung ist 
soll die LED wieder ausgehen. Das ganze soll dann halt mit den anderen 
Bewegung auch realisiert werden, sodass ich 4 verbrauche ein und wieder 
ausschalten kann.
Ich habe schon ein bisschen mit einem Atmega32 rumprobiert aber ich 
bekomme einfach keine gute Auswertung zustande.
Ein weiters Problem was dann besteht ist, wenn die Funkverbindung 
abbricht muss der µC in ne Sicherheitsstellung gehen so dass alle LED´s 
aus sind.
Hat jemand nen paar hilfreiche Ideen oder schon nen Fertigen code 
irgendwo rumliegen ;-)

MFG DKS

Autor: ARM-Fan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist dir denn klar, was für Signale die Empfänger in der Regel
ausspucken? Wenn ja, dann ist es doch ein leichtes.

Du mißt einfach die Pulsdauer(n) und machst dann mit der gewonnenen
Information, was du magst.

Fertigen code gibts sicher im Netz. Aber die paar Zeilen sollte man
auch so zusammen bekommen.

Autor: Beno (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da verwendest du einfach die externen interrrupts! bei steigender flanke 
loest du die interrrupt routine aus und laesst sogleich einen timer 
laufen der dir dann zaehlt bis die flanke wieder sinkt. somit weisst du 
dann wie lange dein puls dauert und kannst ihn auswerten!

Autor: Beno (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch zu den signalen: die sind meistens zwischen 1ms und 2ms lang! 
kannst ja mit oszilloskop nachschauen!

Autor: DkS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Ich habe das Signal an den INT0 angelegt und dann mit einem timer dann 
die zeit zwischen steigender und fallender flanke gemssen aber da kam es 
zu zu vielen fehlen. Und da Habe ich gedacht es gibt noch andere 
möglichkeiten den auszulesen. Ich kann nachher gerne mal meinen code 
Posten aber so richtig funktionieren tut der net warum auch immer.

MFG DkS

Autor: ARM-Fan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>..aber da kam es zu zu vielen fehlen.

Und was für Fehler?

>..aber so richtig funktionieren tut der net

Was heißt "nicht so richtig"?

Laßt euch doch nicht immer alles so aus der Nase ziehen.

Autor: Beno (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
etwas ist an deinem code noch falsch! so gehts!

Autor: DkS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Also im groben Funktioniert meine Auswertung.
Hab das ganze aber erstmal mit der Rauf Runter Bewegung realisiert am 
INT0.
Wenn ich jetzt den µC einschalte und dann die Fernbedienung dann kann 
ich nach oben drücken und die LED geht an lass ich jetzt los dann bleibt 
die LED manchmal an und manchmal geht sie aus drück ich den Hebel nach 
unten dann sind manchmal beide an oder nur die 1 LED geht wieder aus.
Und wenn ich jetzt die Fernbedienung ausschalte dann leuchten die LED´s 
so wie sie wollen, also keine Sicherheitsstellung.

MFG DkS

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du keine Scheu vor ASM hast, hannst Du Dich hier mal umsehen:
http://www.hanneslux.de/avr/mobau/index.html
Hat allerdings schon ein paar Jährchen auf dem Buckel.

...

Autor: DkS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Naja das Probelm ich ich arbeite erst seit 3Monaten mit µC also habe ich 
noch nicht so viel erfahrung.
Leider habe ich überhaupt keine ahnung von ASM.
Aber trozdem Danke

MFG DkS

Autor: M. Kriegel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab da auch schon viel rumexperementiert und die externen Interrupts 
gehen schon, aber leider hat man dann immer einen leichten Jitter drin, 
da wenn die Ausgangskanäle vom Empfänger direkt nebeneinander liegen. 
Unterschiede gibts auch bei PPM und PCM Empfängern. Schreib mal welchen 
Empfänger Du hast und zeig mal Deinen Code, dann kann Dir vllt. geholfen 
werden ....
Grüße,
Michael

Autor: DkS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Ok ich werde nachher mal alles Posten was ich habe. Leider komm ich an 
die Daten grade nicht ran.
MFG DkS

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DkS wrote:
> Hi
> Naja das Probelm ich ich arbeite erst seit 3Monaten mit µC also habe ich
> noch nicht so viel erfahrung.

Dann solltest Du wohl erstmal mit kleineren Projekten etwas üben.

> Leider habe ich überhaupt keine ahnung von ASM.

Nunja, auch ASM-Programme haben Kommentare, in denen man erkennen kann, 
was damit erreicht werden soll. An diesen Kommentaren kann man schon 
diesen oder jenen Algorithmus erkennen.

Und ganz ohne ASM-Kenntnisse wirst Du auf einem kleinen AVR auch in C 
keine zeitkritischen Programme schreiben können. Du solltest zumindest 
in der Lage sein, das Ergebnis des Compilers beurteilen zu können.

> Aber trozdem Danke
>
> MFG DkS


...

Autor: sniper (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

die meisten Empfänger liefern bei Mittelstellung der Steuerknüppel
einen 1,5ms breiten Impuls.
Steuerknüppel ganz unten: 1ms
Steuerknüppel ganz oben: 2ms

Das ganze kann relativ problemlos mit einem Timer gelöst werden.
Bei der Impuls-Startflanke wird der Timer gestartet, und bei der 
Imuls-Stop-Flanke wieder gestoppt.

Wichtig:
1.
Impuls-Startflanke muss den Timer muss so schnell wie möglich starten
Impuls-Stopflanke muss den Timer muss so schnell wie möglich anhalten
Also mal die Interrupt Prios überprüfen

2.
Die Timer-Auflösung muss so hoch wie möglich sein.

3.
Du solltest einen gleitenden Mittelwert über die Impulsdauer bilden, 
sodass
Ausreißer die Erkennung nicht zu sehr beeinflussen.

4.
Es muss einen Mittenabgleich geben

PS:
Warum eigentlich nur 2 LEDs pro Kanal???

Autor: mehrfacher STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Das ganze kann relativ problemlos mit einem Timer gelöst werden.
>Bei der Impuls-Startflanke wird der Timer gestartet, und bei der
>Imuls-Stop-Flanke wieder gestoppt.
Noch einfacher geht es mit der ICP-Einheit, sofern vorhanden.

>1.
>Impuls-Startflanke muss den Timer muss so schnell wie möglich starten
>Impuls-Stopflanke muss den Timer muss so schnell wie möglich anhalten
>Also mal die Interrupt Prios überprüfen

Wenn man den Timer konstant laufen lässt, muß man ihn nur auslesen.
>2.
>Die Timer-Auflösung muss so hoch wie möglich sein.

Nö, warum?

>3.
>Du solltest einen gleitenden Mittelwert über die Impulsdauer bilden,
>sodass Ausreißer die Erkennung nicht zu sehr beeinflussen.

Nice to have. Aber nicht wichtig.
Besser wäre ein Vergleich zwischen dem letzten und dem aktuellen Wert. 
Damit kann man dann einen Sender-Ausfall oder andere Störungen erkennen.

>4.
>Es muss einen Mittenabgleich geben

Nö. Auch das nicht.
Wenn man davon ausgeht, dass 1,5ms die Mitte beschreiben, muß man die 
Schaltgrenzen z.B. bei 1,2ms und 1,8ms setzen.

> Naja das Probelm ich ich arbeite erst seit 3Monaten mit µC also habe ich
> noch nicht so viel erfahrung.
Andere Leute schaffen in 3 Monaten das, wofür andere Jahre brauchen...

Autor: DkS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ICP ist am Atmega32 nur einmal vorhanden leider brauche ich das ganze ja 
in 2 facher ausführung hoch/runter und rechts/links.

Das mit den Empfängersignalen stimmt, da hatte ich mal die gelgenheit 
mit ein Oszilloskop nachzumessen. Leider habe ich keines zuhause 
rumstehen da diese viel zu teuer sind.

Steuerknüppel in der mitte: 1,5ms
Steuerknüppel ganz unten: 1ms
Steuerknüppel ganz oben: 2ms

@Hannes Lux
Da hast du sicherlich recht das man erst mit kleinen Projekten anfangen 
soll.
Aber das habe ich schon lange hintermir (LCD, Tasten, LED, DCF77, 
Temperaturmessung mit KTY).
Ich denke darbei sollte man schon nen bisschen grundwissen gesammelt 
haben um sich an soetwas heran zu trauen.

MFG DkS

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

Bewertung
0 lesenswert
nicht lesenswert
Hi
Wie versprochen der code.
Mal gucken was alles falsch ist :-)
Ich hoffe ihr könnt mir ein paar tips geben was ich besser machen kann.

MFG DkS

Autor: Roland Praml (pram)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, hab mir den Code mal an gesehen:

> impuls = stop - start;

hier passiert Mist, wenn der Timer überläuft

> if (flanke == 1)

mach hier ein "if (PINx & (1 << y))" damit du den PIN einliest und fest 
stellen kannst ob du eine steigende Flanke (PIN ist anschließend high) 
oder eine fallende Flanke hattest:

> int start;
> int stop;

TCNT1 ist unsigned, deshalb liefert ein "start = TCNT1" einen 
Typkonflikt und u.U. ein falsches Ergebnis:

besser wäre "unsigned start, stop". anschließend überprüfst du, ob
stop > start ist und rechnest impuls = stop - start. Andernfalls (wenn
stop < start ist) ist höchstwahrscheinlich der Zähler übergelaufen. Ich 
weiß nicht ob man die Werte dann so einfach subtrahieren kann. müsstest 
mal im AVRstudio simulieren was raus kommt wenn du z.B. 20 - 65000 
rechnest.
(erwarten würde ich jetzt 20 + (65536 - 65000) = 20 + 536 = 546)

int32_t impuls; sollte mit volatile deklariert sein -> warum siehe 
AVR-Tut

weiterhin würd ich eine Tiefpassfilterung vornehmen: das geht z.B. so:

impuls_lpf -= impuls_lpf / 4; // 1/4 abziehen = 3/4 bleibt übrig
impuls_lpf += impuls / 4; // 1/4 von Impuls hinzuaddieren. (3/4 sind ja 
noch von früher)

Die Teilung durch 4 (oder anderes 2^x) deshalb, weil dies der Compiler 
gut optimieren kann.
Die Teilung impuls / 4 kannst dir auch sparen, musst aber beachten, dass 
sich die Auflösung von impuls_lpf dann vervierfacht.

Weiterhin würde ich noch einen Interruptcounter in die ISR einfügen und 
diesen von Zeit zu Zeit (z.B. wenn der Timerint überläuft) auslesen. 
Wenn keine Interrupts zwischen einem Überlauf aufgetreten sind ist 
höchstwahrscheinlich die Fernsteuerung ausgefallen.

Gruß
Roland

Autor: Peter E. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Ich wollte das auch mal machen. Aber ich habe keinerlei ansätze 
gefunden.
Kann mir jemand helfen ich hab das nochnicht ganz verstanden was Roland 
geschrieben hat.
Könntest du DKS deinen fertigen code bitte mal hochladen.
Gruß Peter

Autor: Mark Struberg (struberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Ich hab so etwas vor einiger Zeit programmiert und in die Codebeispiele 
reingestellt.

Guxxdu hier: Beitrag "RC-Fernsteuerung 4-fach switch"

Hoffe es ist halbwegs verständlich. Falls nicht, einfach fragen oder PM.

Es gäbe natürlich noch einiges zu verbessern, zB eine Hysterese für 
höhere Schaltsicherheit, etc. Würde mich freuen wenn Du was damit 
anfangen kannst.

LieGrü,
strub

Autor: Peter E. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Wie sicher ist dein Porgramm also wenn fernbedinung aus geht usw.
Gruß Peter

Autor: Mark Struberg (struberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kannst relativ einfach selbst einstellen. Als Default stellt er alle 
ports auf 0 zurück:
void performActionOnInvalidPulse() {
  // switch out all ports
  PORTB = 0;
}

Autor: Peter E. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Danke für die hilfe ich werde mal versuchen dein programm auseinander zu 
klamüsern.
Wenn noch jemand anregungen hat immer her damit.
Gruß Peter

Autor: Peter E. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Ich habe da nochmal ne frage.
Mein Problem ist, das ich das gerne mit einem anderem µC aufbauen 
möchte. Wenn ich das richtig sehe wird hier der PCINT genommen den habe 
ich bei meinem anderem µC nicht kann ich da auch den normalen INT nehmen 
oder muss ich da großartig was ändern?
Gruß Peter

Autor: Mark Struberg (struberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den einzigen interrupt den ich verwende ist der Timerüberlauf. Und den 
brauch ich auch nur, da der ATtiny13 nur einen einzelnen 8 bit counter 
hat, ich daher jeden timer overflow einen Zähler hochdrehe und somit 
quasi einen 16 bit counter simuliere.

LieGrü,
strub

Autor: Peter E. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Ohh jee
Jetzt wirds mir zu kompliziert.
Ich versuch mal ob ich das auf meinem Atmega32 zum laufen bekomme.
THX für die info.
Gruß Peter

Autor: Mark Struberg (struberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schick mir mal ne PM, dann geb ich Dir meine icq

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.