Forum: Compiler & IDEs AVR Mega8 Servosteuerung über Uart


von Jens W. (jens_w)


Angehängte Dateien:

Lesenswert?

Hallo,
ich bin gerade dabei für ein Projekt eine Servosteuerung zu basteln. Ich 
möchte dazu den Timer1 von meinem Atmel Mega8 über den Uart ansprechen. 
Der soll mir dann entsprechend des gesendeten Werts ein PWM Signal an 
den Servo schicken. Bis jetzt hab ich mir ein kleines C Programm 
geschrieben. Leider funktioniert das ganze nicht so wie ich mir das 
vorstelle, denn der Servo fängt nur an zu pfeifen. Ich hab auch kein 
Oszilloskop zu Hause und kann deshalb auch nicht das ausgegebene Signal 
überprüfen. Es wär nett wenn mir jemand ein Tipp geben könnte woran es 
liegt oder wenigstens sagen ob ich ganz auf dem Holzweg bin.
Die Kommunikation über den Uart hab ich schon mit einem kleinen Programm 
getestet. Sie sollte also funktionieren.
Nicht meckern, dass das ganze so zusammengestückelt ist. Ich hab nicht 
wirklich Ahnung vom Programieren...

von Oliver (Gast)


Lesenswert?

Jens W. schrieb:
> Nicht meckern, dass das ganze so zusammengestückelt ist. Ich hab nicht
> wirklich Ahnung vom Programieren...

Meckern werde ich nicht, aber bitte such dir erst einmal ein 
grundlegendes Buch über C-Programmierung, und lies dir zumindestens die 
Basics an. Ganz ohne Ahnung wird das sonst nichts.

Oliver

von Joachim (Gast)


Lesenswert?

Hallo

Nur mal so als Hinweis:
Schau dir mal die letzte while-Schleife an.
Ist das, was du da machst, wirklich das, was du zu tun beabsichtigst?

Und Oliver hat recht, kauf dir ein Buch!

Gruß
Joachim

von Karl H. (kbuchegg)


Lesenswert?

Joachim schrieb:
> Hallo
>
> Nur mal so als Hinweis:
> Schau dir mal die letzte while-Schleife an.
> Ist das, was du da machst, wirklich das, was du zu tun beabsichtigst?

Und noch ein Hinweis:
Einrückungen sind nicht nur Zierde, sondern erfüllen eine vitale 
Funktion für den Menschen um sich Abhängigkeiten visuell einzuprägen. 
Dem Compiler hingegen sind die Einrückungen wurscht. Daher ist es 
essentiell, dass die Einrückungen so gemacht werden, dass sie mit dem 
übereinstimmen, was der Compiler anhand der C Regeln an Abhängigkeiten 
sieht.

von Jens W. (jens_w)


Lesenswert?

Hmm ja ihr habt da sicher Recht, dass ich da richtig in die Materie 
eintauchen muss. Ich hab nur gehofft dass ich nach meinen "Einführung in 
C++" Kurs wenigstens schon mal n bischen was hinbekomm.. Möcht mich auch 
gleich entschuldigen, wenn ich hier so ein Verbrechen gepostet habe...
@Joachim:
Ich hab gedacht, dass ich dort mehr oder weniger permanent mit uart_gets 
in die Funktion springe und die mir dann den Buffer in das "Daten"feld 
schreibt. Das wollte ich dann zum Integer konvertieren und in das OCR1A 
Register schreiben. Damit sollte dann der Vergleichswert des Zählers bei 
dem der Zustand an Pin OC1A von High nach Low wechselt aktualisiert 
werden.
So siehts zumindest in meinem Kopf aus ;) Aber alle Theorie ist grau.
Bin ich denn abgesehen von meinem nicht Können in C auf dem richtigen 
Weg?

Gruß Jens

von Karl H. (kbuchegg)


Lesenswert?

Jens W. schrieb:
> Hmm ja ihr habt da sicher Recht, dass ich da richtig in die Materie
> eintauchen muss. Ich hab nur gehofft dass ich nach meinen "Einführung in
> C++" Kurs wenigstens schon mal n bischen was hinbekomm..

Dann sollte dir aber der Unterschied zwischen
1
  while(1)
2
  uart_gets(Daten);
3
  wert=atoi(Daten);
4
  OCR1A=wert;

und
1
  while(1)
2
  {
3
    uart_gets(Daten);
4
    wert=atoi(Daten);
5
    OCR1A=wert;
6
  }

klar sein.

Deine Version sieht der Compiler so:
1
  while(1)
2
    uart_gets(Daten);
3
4
  wert=atoi(Daten);
5
  OCR1A=wert;
Nur das uart_gets ist in der Schleife und wird ständig wiederholt. Die 
anderen beiden Anweisungen sind nicht in der Schleife und da es sich bei 
der Schleife um eine Endlosschleife handelt, werden sie in der Tat 
überhaupt nie ausgeführt. (Und mit einer konsequenten vernünftigen 
Einrückstruktur kann man das als Mensch sogar sehen :-)

Ausserdem solltest du dir mal überlegen, welchen Wert OCR1A eigentlich 
hat, solange du ihm keinen Wert über die UART zuweist. Das Programm 
startet und .... von der Seriellen kommt einfach nix. Was soll dann 
passieren? Es wird ja wohl nicht Sinn der Sache sein, dass das Servo 
dann keine vernünftige Position einnimmt, weil es keinen vernünftig 
definierten Servopuls bekommt.

von Drachenbändiger (Gast)


Lesenswert?

Jens W. schrieb:
> Bin ich denn abgesehen von meinem nicht Können in C auf dem richtigen
> Weg?

Nur dann, wenn Du die o.g. Vorschläge liest und berücksichtigst, 
insbesondere den von Joachim (ich stoße Dich jetzt mal mit der Nase 
drauf, indem ich die Klammern so setze, dass Du siehst, was Dein Code 
macht):
1
  while(1) {
2
          uart_gets(Daten);
3
  }

von Drachenbändiger (Gast)


Lesenswert?

Entschuldigung, ich hatte während des Schreibens telefoniert und so den 
Beitrag von Karl Heinz übersehen!

von Oliver (Gast)


Lesenswert?

Nach einem einführenden Kurs in C++ sollte man eigentlich auch 
verstanden haben, daß man Funktiona nicht nur hinschreiben, sondern auch 
aufrufen muß, wenn sie etwas tun sollen. uart_init wäre solch ein 
Kandidat.

Und dein mit Sicherheit zu kleines Daten-Feld wird das Programm bei der 
ersten Eingabe vonmehr als zwei Zeichen ins Nirwana schicken.

Jens W. schrieb:
> Bin ich denn abgesehen von meinem nicht Können in C auf dem richtigen
> Weg?

Schwer zu sagen. Eine faire Antwort wäre vermutlich: Nein. Nicht, weil 
du auf dem falschen Weg bist, sondern weil dir (noch) die 
Voraussetzungen fehlen, überhaupt einen Weg von einem Nicht-Weg zu 
unterschieden.

Aber "learning by doing" ist schonmal ein richtiger Weg ;-)

Oliver

von Jens W. (jens_w)


Lesenswert?

Ahh ok Danke! Ich seh schon das war natürlich n bischen stupid von mir. 
Da wär ich vieleicht mit ner vernünftigen Einrückung auch selbst drauf 
gekommen.
Und Klammern vergessen gilt an der Uni noch als Formfehler...
Leider funktioniert das ganze immernoch nicht deswegen wär es nett, wenn 
mir jemand sagen könnte ob ich die Signalgenerierung für den Servo über 
den Timer1 überhaupt richtig angehe.

von Jens W. (jens_w)


Lesenswert?

Danke erstmal für eure Anregungen ich werd mich heut Nachmittag nochmal 
hinsetzen und das ganze ein wenig überarbeiten. Da es ja doch an 
mehreren Ecken mangelt.

von Karl H. (kbuchegg)


Lesenswert?

So etwas
1
  char Daten[3];
2
3
  ...
4
5
  uart_gets(Daten);

ist immer eine etwas haarige Sache. uart_gets kann sich nicht dagegen 
wehren, dass zu viele Zeichen über die UART hereinkommen. Dazu müsste es 
die Länge des Arrays kennen, was es nicht tut. Man müsste ihm die Länge 
mitgeben.

Das mindeste was du aber tun solltest ist, an dieser Stelle nicht 
kleckern sondern klotzen!
Wenn du davon ausgehst, dass dein Benutzer nicht mit dem Kopf auf die 
Tastatur fällt und dir so eine Eingabezeile rüberschickt

 1234444444444444444444444444444444444444444444444444444444444444

dann solltest du dich zumindest auf einfache Fehlbedienungen einstellen. 
Einem Benutzer zu sagen: Deine Eingabe darf nur 3 Zeichen umfassen, 
nämlich

#34

und dann ein einen String im Programm zu benutzen, der maximal 2 
Nutzzeichen fassen kann, geht zwar in diesem Fall gut (weil du ja den # 
wegwirfst), aber spätestens dann, wenn dein Benutzer

#487

eingibt, nur um zu sehen was passiert, dann krachts in deinem Programm 
ganz gewaltig. "487" passt nun mal nicht mehr in einen char[3].

Hier also lieber etwas vorsichtig und defensiv sein und die 
String-Arrays etwas größer dimensionieren. Das ein Benutzer schon mal
#87654
eingibt, sollte dein Programm auf jeden Fall abkönnen auch wenn es mit 
dem Super-GAU Fall "Baby drückt wahllos auf der Tastatur" heillos 
überfordert ist (und ja: ein gutes Programm kommt auch damit klar, aber 
von einem Anfänger erwarte ich sowas nicht)

von Karl H. (kbuchegg)


Lesenswert?

Jens W. schrieb:
> Und Klammern vergessen gilt an der Uni noch als Formfehler...

Diese Regel solltest du für dich als allererstes gleich über Bord 
werfen. Eine ansprechende, übersichtliche Form ist wesentlicher 
Bestandteil eines guten Programms. Sie hat nicht nur optisch dekorativen 
Zweck, sondern kann tatsächlich den Unterschied zwischen einem wartbarem 
und weitgehend fehlerfreiem Programm und einem unlösbaren 
Spaghettihaufen ausmachen.

Fehlerverseuchte Programme sind meistens auch die, die wie ein Haufen 
hingerotzter Code aussehen.

Genauso wie die Umkehrung:
Schüler sucht verzweifelt seit Stunden nach einem Fehler. Lehrer geht zu 
ihm und formatiert den Code als allererstes neu nach konsistenten, 
durchgehenden Regeln (welche das im Detail sind, ist erst mal egal). 5 
Minuten später greift sich der Schüler ans Hirn: Er hat den Fehler 
selbst gesehen. Spätestens wenn so etwas das 5te mal passiert, hat auch 
der dümmste Schüler begriffen, dass er sich mit dem 'Weglassen der 
Formatierung' im Grunde nur selbst ein Bein stellt.

Genau deswegen sind sauber strukturierte Programme im Schnitt mit 
weniger Fehlern beladen. Man sieht Fehler einfach besser. Die Ausrede: 
Das kann ich später immer noch machen, gilt einfach nicht. Gewöhn dir 
von Anfang an an, eine saubere Form zu schreiben. Dazu gehören: 
Einrückungen. Dazu gehören: ein einheitliches { } Schema

von Oliver (Gast)


Lesenswert?

Jens W. schrieb:
> Und Klammern vergessen gilt an der Uni noch als Formfehler...

Das bezweifele ich aber sehr stark. Klammern sind nunmal ein wichtiger 
Bestandteil in der C- und C++-Syntax, ohne die überhaupt kein gültiger 
oder gar funktionierender C-Code erstellt werden kann.

Oliver

von Jens W. (jens_w)


Lesenswert?

Ihr könnt mir ruhig glauben, dass Klammern vergessen, zumindest in 
meiner Abschlußklausur (mit Stift und Zettel), als Formfehler galt. Ich 
will damit nicht sagen, dass ich der Ansicht bin, dass dies richtig ist. 
Da wie schon gesagt: ohne Klammern läufts halt nicht.
Trotz alledem hab ich mein Programm nun zum Laufen gekriegt. Das 
Hauptproblem lag darin, dass ich den Uart nicht richtig initialisiert 
hatte.
Jetzt läuft aber alles und ich kann mein Servo über Matlab steuern und 
damit auch mein Versuchsschiff über Bluetooth. Wenn ich wieder zu Hause 
bin poste ich noch das fertige Programm falls interesse besteht.
Vielen Dank nochmal für die Hilfe vorallem an Karl heinz Buchegger!
mfg Jens

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
Noch kein Account? Hier anmelden.