mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Nochmals Frage zu UART


Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend !

Wie lang darf denn ein String maximal sein, welchen ich an den µC 
(Attiny2313) per UART senden darf ?

Meine ISR Routine packt alle empfangen Bystes in ein char Array und das 
solange bis ein ! ankommt, wenn das ! ankommt ist der Befehl 
vollständig.

Wenn ich nun: hi! sende bekomme ich auch hi! zurück. wenn ich allerdings 
etwas längeres sende z.b. hihallo! dann kommt es abgehackt wieder 
zurück. Was kann ich dagegen tun ? Gibt es irgendwelche Strategien ?

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die erste Frage ist, benutzt du einen Quarz als Taktgeber für den 
Controller?
Da ich davon ausgehe, dass du so weit schon gedacht hast, ist die 
nächste Frage: Wie groß ist der Fehler zwischen eingestellter und 
tatsächlicher Baudrate am Controller?
Wenn der Fehler zu groß ist und der Controller zwischen den Byte keine 
Zeit hat, sich neu zu synchronisieren, addiert sich meines Wissens der 
Fehler, so dass er irgendwann so groß ist, dass der Controller nichts 
Sinnvolles mehr empfängt.

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie lang darf denn ein String maximal sein, welchen ich an den µC
> (Attiny2313) per UART senden darf ?

So lang wie Dein Speicher groß ist, d.h. wenn Du die empfangenen Daten 
ins Backup-Device umleitest, dann beliebig lang. Sonst zweckmäßigerweise 
nur so viel wie Du (ggf. zwischenspeichern und) verarbeiten(!) kannst 
:-)

> [..] dann kommt es abgehackt wieder zurück. Was kann ich dagegen tun ?

Den Fehler finden ;-) 'Abgehackt' klingt nach zu wenig Speicher 
reserviert oder nach zu wenig Zeit für den Datenempfang. Zeich mal den 
Code, dann kann Dir vielleicht geholfen werden.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dussel schrieb:

> Wenn der Fehler zu groß ist und der Controller zwischen den Byte keine
> Zeit hat, sich neu zu synchronisieren,

hat er aber.
Genau das ist der Zweck von Start- und ganz besonders Stopbit.

> addiert sich meines Wissens der
> Fehler, so dass er irgendwann so groß ist, dass der Controller nichts
> Sinnvolles mehr empfängt.

Das stimmt so nicht.
Solange die Fehler nicht so gross sind, dass es innerhalb eines Bytes zu 
Fehlern kommt, ist alles in Butter. Mit jedem neuen Startbit 
synchronisiert sich der Empfänger wieder auf den Sender.

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ist das.
Wenn du nicht direkt "online" schon was weiterverarbeitest, musst du den 
gesamten Zeichestring irgendwo zwischenspeichern.
Wieviel Platz du dafür hast, hängt vom Controller und vom Compiler (und 
dessen Einstellungen) und deinem sonstigen RAM-Bedarf ab.
Also: Frage so nicht beantwortbar.

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Genau das ist der Zweck von Start- und ganz besonders Stopbit.
Ok, wenn du das sagst. Ich glaubte nur, mal gelesen zu haben, dass der 
Controller eventuell das Start- und Stopbit nicht mehr richtig erkennt, 
wenn die Daten zu schnell hintereinander kommen, so dass es praktisch 
fast nur noch ein einziger Datenstrom ist.
Dann fällt das aber als Fehlerquelle schonmal weg :-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dussel schrieb:
>>Genau das ist der Zweck von Start- und ganz besonders Stopbit.
> Ok, wenn du das sagst. Ich glaubte nur, mal gelesen zu haben, dass der
> Controller eventuell das Start- und Stopbit nicht mehr richtig erkennt,
> wenn die Daten zu schnell hintereinander kommen, so dass es praktisch
> fast nur noch ein einziger Datenstrom ist.

Das ist nur beim ersten Anschalten der UART problematisch, wenn die UART 
auf einen bereits laufenden Datenstrom aufgeschaltet wird. Dann kann es 
passieren, dass die UART nie das Startbit identifizieren kann. Hat sie 
aber das Startbit erst einmal UND ist der Taktfehler klein genug, dass 
es innerhalb eines Bytes zu keinem Fehler kommt, dann findet sie auch 
das nächste Startbit wieder zuverlässig. Es beginnt mit der ersten 
Flanke nachdem das letzte Byte vollständig empfangen wurde. Die Pause 
zwischen dem letzten Bit des letzten Bytes und dem Beginn des Startbits 
ist nicht informationstragend sondern einfach nur eine Pause 
unbestimmter Länge (für den Empfänger).

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen !

Ich habe leider jetzt keine Zeit um die notwendigen Informationen zu 
schreiben, aber sobald ich zu Hause bin, werde ich mich wieder melden.

Danke erstmal !

MfG,

MC_AVR

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag !

Ich benutze einen externen Quarz mit 11.059200 MHz. Meine BAUD Rate ist 
9600. Nach den Berechnungsgleichungen in dem AVR GCC Tutorial folgt 
daraus:


UBRR_VAL = 71.5  (Clever gerundet ;) )
BAUD_REAL = 9533.79
BAUD_Error = 0.993103 das wäre doch ein Fehler von: 0.689%, also 
1-0.993103 eben. Damit bin ich ja unter der kritischen 1% Grenze.

Mein Code für den Datenempfang:
// Globale Variable für den Daten-Puffer
volatile char received_data[20];

/* Interrupt Routine für Datenempfang */
ISR(USART_RX_vect)
{
  
  

   received_data[i] = UDR; // Lade die empfangenen Bystes in den Daten-Puffer


 // send_uart("interrupt\n");

  if(received_data[i]==0x21) // !-Zeichen erhalten, Befehl fertig => Flag setzen.
  {
  // send_uart("!-Angekommen\n");
  rx_flag = 1;
  
  i=0;
  }
  else
  {
  i++;  
  }  
}
/*----ENDE----*/

Ein Datenpuffer von 20 Char, sollte aber eigentlich für meine Strings 
reichen.

MfG,
MC_AVR

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schöne Routine.
Der Fehler sitzt wieder mal in den Teilen, die du nicht zeigst.

Häng doch ganz einfach deinen Source Code komplett als Attachment an. 
Dann suchen wir uns die Teile raus, die wir brauchen.

Ist für dich einfacher und für uns auch.

PS:
Was ist der Unterschied zwischen

  if(received_data[i]==0x21)

und

  if( received_data[i]== '!' )

Richtig! Im zweiten sieht auch ein Blinder mit Krückstock, worauf du 
vergleichst ohne zuerst im Web nach 5 ASCII Tabellen suchen zu müssen 
und zu vergleichen, ob die Kommentare neben dem Code noch zeitgemäss 
sind. Ausserdem kann man sich dann den Kommentar komplett sparen, weil 
alles Wissenswerte im Code steht.

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

Bewertung
0 lesenswert
nicht lesenswert
Ja ich habe immer Angst so fiese Kommentare immer zu bekommen :-(.

Ist die Routine wirklich schön oder ist das nur wiedermal "ironisch" 
gemeint ;).

Der Code ist im Anhang !

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:
> Ja ich habe immer Angst so fiese Kommentare immer zu bekommen :-(.
>
> Ist die Routine wirklich schön oder ist das nur wiedermal "ironisch"
> gemeint ;).

Sieh sie dir an.
Hast du Einrückungen?
Sind die konsistent?
Wieviele tatsächlich arbeitende Code-Zeilen hat die Funktion?
Wieviele Code-Zeilen hast du im Editor dafür verbraucht?
Wieviel Leerraum umfasst die Funktion? Bringt der irgendwas ausser den 
Code in die Länge ziehen?

>
> Der Code ist im Anhang !

mal reinschauen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Fehler besteht schon mal darin, dass du für die Auswertung (und sei 
es nur für das momentan auskommentierte Zurücksenden) davon ausgehst, 
dass in deinem Buffer ein C-String steht. Das tut er aber nicht. Du hast 
in deiner Empfangsroutine den Buffer nirgends mit einem \0 Zeichen 
abgeschlossen, welches das Ende des Strings anzeigt. Deine ganze 
Stringverarbeitung wird alles Mögliche machen, weil jede Funktion über 
das Ende des Strings hinausknallt bzw. du höllisch darauf aufpassen 
musst, dass bei dir ! das Ende eines Strings anzeigt.

Erfinde nicht deine eigenen Konventionen. Das du den ! benötigst um auf 
der Übertragungsstrecke das Ende eines Befehls zu kennzeichnen ist eine 
Sache. Aber in deinem Programm solltest du auf die übliche C-Konvention 
zurückgreifen: Jeder String hat als letztes Zeichen ein '\0'. Dort endet 
der String.

<weiterschau>

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D.h. ich sollte wenn das Ausrufungszeichen angekommen ist einfach 
received_data[20] = '\0'; ausführen ?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:
> D.h. ich sollte wenn das Ausrufungszeichen angekommen ist einfach
> received_data[20] = '\0'; ausführen ?

Wieso 20?

Welches ist dein letztes Zeichen im Buffer, das noch gültig war und zum 
String gehört?

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:
> D.h. ich sollte wenn das Ausrufungszeichen angekommen ist einfach
> received_data[20] = '\0'; ausführen ?

nö, deine Strings sind ja schließlich nicht immer 19 Zeichen lang...

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja das ! zeichen, aber dann müsste ich ja mit einer String Funktion das 
! suchen und dann einfach +1 von dieser Stelle das '\0' addieren. Meinst 
du es so ?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR(USART_RX_vect)
{
  received_data[i] = UDR; // Lade die empfangenen Bystes in den Daten-Puffer

  if( received_data[i] == '!' ) // !-Zeichen erhalten, Befehl fertig => Flag setzen.
  {
    // send_uart("!-Angekommen\n");
    rx_flag = 1;
    received_data[i] = '\0';
    // oder wenn du drauf stehst, dass das ! erhalten bleibt
    // received_data[i+1] = '\0';
    i = 0;
  }
  else
  {
    i++;  
  }  
}

Du schreibst das ! an die Stelle i im Buffer.
Welches ist daher die nächste Position an die das \0 Zeichen muss?

(Jetzt kannst du dir aussuchen, ob du das ! im String lassen willst, 
oder ob du es gleich entfernst, weil es ja keine Information trägt)

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aha ! Dann muss ich später beim Parsen nicht extra das ! rausfiltern, 
d.h. ich kann mir ein strtok_r ersparen !

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zurück zum Problem.

> Wenn ich nun: hi! sende bekomme ich auch hi! zurück. wenn
> ich allerdings etwas längeres sende z.b. hihallo! dann kommt
> es abgehackt wieder zurück.

Was heißt in dem Zusammenhang 'abgehackt'?

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich gebe zu die Definition abgehackt war etwas ungünstig gewählt. Ein 
Beispiel Output wäre sowas:

hallo!Karo@Karo hallo! hallo!karo@KaroKaro  so sah es aus. Mal kam die 
gesendete Zeichenkette richtig zurück und mal nicht. Liegt das 
wahrscheinlich daran, dass ich das nicht mit einem \0 abgeschlossen habe 
?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch was:
volatile char received_data[20]; // Buffer wo die empfangenen Daten gespeichert werden...
volatile int rx_flag;   // Status-Flag für vollständig übertragene Befehle...
int i=0;    // Index-Variable für den Daten-Puffer

i ist dür diese Variable so ziemlich der ungünstigste Name, den du dir 
hast aussuchen können.

i wird gerne für for Schleifen benutzt. Nimm einfach mal an, du würdest
programmieren
void Auswert( int irgendwas )
{
  for( i = 0; i < irgendwas; ++i )
    mach_was;
}

und dabei vergessen, für dieses i eine lokale Variable anzulegen. Was 
glaubst du wohl wird mit deiner UART Bufferverwaltung passieren.

Defensiv programmieren! Der Compiler soll Fehler finden können. Dazu 
gehört auch, Variablennamen zu wählen, bei denen Tippfehler oder 
Unterlassungen sofort auffallen! Globale Variablen nennt man niemals i, 
j, k, l, x, y, oder sonstige Namen, die in einem Programm häufig 
vorkommen

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:
> Ich gebe zu die Definition abgehackt war etwas ungünstig gewählt. Ein
> Beispiel Output wäre sowas:
>
> hallo!Karo@Karo hallo! hallo!karo@KaroKaro  so sah es aus. Mal kam die
> gesendete Zeichenkette richtig zurück und mal nicht. Liegt das
> wahrscheinlich daran, dass ich das nicht mit einem \0 abgeschlossen habe
> ?

Ja. Höchst wahrscheinlich.
Deine Strings waren keine Strings.

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lieber Karl Heinz Buchegger, ich habe nun die Strings mit einem \0 
beendet und der UART sendet bei längeren Zeichenketten genau das zurück 
was ich gesendet habe ! Ich werde und mein Code etwas überarbeiten.

Ich bedanke mich herzlich bei dir und den anderen für die freundliche 
Unterstützung.

Bei Fragen werde ich mich wieder melden :)

MfG,
MC_AVR

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bekomme eine Warnmeldung und zwar in dieser Zeile:

dir_com = strtok_r(received_data,";",&tmp);

Compiler Warnung: main.c:133: Warnung: Übergabe des Arguments 1 von 
»strtok_r« entfernt Kennzeichner von Zeiger-Ziel-Typ

Kann ich dieser Warnmeldung ignorieren ? Ich habe gelernt, dass man 
Warnmeldungen wie Fehler betrachten soll :)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:
> Ich bekomme eine Warnmeldung und zwar in dieser Zeile:
>
> dir_com = strtok_r(received_data,";",&tmp);
>
> Compiler Warnung: main.c:133: Warnung: Übergabe des Arguments 1 von
> »strtok_r« entfernt Kennzeichner von Zeiger-Ziel-Typ

gemeint ist das volatile.

> Kann ich dieser Warnmeldung ignorieren ? Ich habe gelernt, dass man
> Warnmeldungen wie Fehler betrachten soll :)

In deinem Fall kannst du die erst mal ignorieren, auch wenns nicht ganz 
sauber ist.

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe noch eine Frage !

Ich möchte nun ein Stopp Befehl einführen, das sobald ein bestimmtes 
Zeichen eintrifft, soll der Motor gestoppt werden. Wenn ich nun den 
Motor den Befehl gebe x Schritte auszuführen und dieser dann quasi in 
einer Schleife ist, ja den Stopp Befehl ignorieren. Wie könnte ich das 
lösen ? Läuft die ISR Routine immer parallel zu anderen Funktionen bzw. 
Schleifen ? Wenn ja könnte ich ja von der ISR Routine das CLK Signal für 
den L297 sofort lahmlegen und der Motor wäre dann im Haltemoment.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:
> Ich habe noch eine Frage !
>
> Ich möchte nun ein Stopp Befehl einführen, das sobald ein bestimmtes
> Zeichen eintrifft, soll der Motor gestoppt werden. Wenn ich nun den
> Motor den Befehl gebe x Schritte auszuführen und dieser dann quasi in
> einer Schleife ist, ja den Stopp Befehl ignorieren. Wie könnte ich das
> lösen ? Läuft die ISR Routine immer parallel zu anderen Funktionen bzw.
> Schleifen ? Wenn ja könnte ich ja von der ISR Routine das CLK Signal für
> den L297 sofort lahmlegen und der Motor wäre dann im Haltemoment.

Ganz ehrlich:
Die beste Lösung wäre es, das ganze Konzept zu verändern.
Du darfst nirgends Arbeitsschleifen haben, die längere Zeit brauchen. 
Von daher darf es keine 'Schleife in der der Motor läuft' geben.

Ein derartiger Ansatz führt praktisch immer zu deinen Problemen und noch 
viel schlimmeren. Wenn dein Programm mehrere Dinge 'gleichzeitig' machen 
soll, dann macht man das so:

Im Hauptprogramm gibt es eine einzige Schleife - die Endlossschleife.
In dieser Schleife wird geprüft, ob es eine bestimmte Aktion zu tun 
gibt, so wie du das mit dem UART Empfang gemacht hast.
Aber du darfst von dort nicht turn_stepper aufrufen bzw. turn_stepper 
darf nicht die komplette Bewegung abfahren, sondern immer nur einen 
Schritt. Durch die Endlosschleife in main() ist sowieso sichergestellt, 
dass irgendwann alle Schritte abgearbeitet sind, einer nach dem anderen.

So ungefähr

void turn_stepper_once(int direc, int steps)
{
  if(direc==1)
  {
    PORTD |= (1<<DIR);
  }
  else if(direc==0)
  {
    PORTD &=~ (1<<DIR);
  }

  PORTD |= (1<<CLK);
  _delay_ms(1);
  PORTD &=~ (1<<CLK);
  _delay_ms(1);
}


int main()
{
   ....


  while( 1 ) {
    if( rx_flag == 1 ) {
      // auf der UART ist etwas eingetroffen, werte es aus
      parser();
    }

    else if( stepsToGo > 0 ) {
      // hat der Motor noch etwas zu tun, dann lass ihn einen Schritt
      // machen
      turn_stepper_once( direction, stepsToGo );
      stepsToGo--;
    }

    ..... vieleicht gibt es noch andere Dinge zu tun
    ..... aber Achtung: nichts davon darf längere Zeit brauchen

  }  // das wars .. nächster Durchgang um alle möglichen Arbeiten zu erledigen

Im Grunde sollte man die 1ms _delay_ms in turn_stepper_once auch noch 
loswerden. So etwas will man eigentlich auf keinen Fall haben.

parser setzt dann ganz einfach die Werte in den globalen Variablen 
direction bzw. stepsToGo und durch die Hauptschleife wird diese 
Schrittanzahl nach und nach abgearbeitet. Soll der Motor sofort stehen, 
dann genügt es stepsToGo einfach auf 0 zu setzen.

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
d.h. ich muss an jedem Ende der while(1) Schleife das rx_flag auf 0 
setzen, so das quasi neue Daten ankommen können. Wichtig ist, dass ich 
nur eine einzige Schleife habe und zwar die while(1) Schleife in main. 
Wenn ich 1000 Schritte drehen soll, parse ich den Befehl gib die Anzahl 
der Schritte an StepsToGo (Globale Variable) durch. Das mit der ISR 
Routine kann aber so bleiben ?.  Ich werde meinen Code nun von neu aus 
schreiben bzw. das Konzept ändern und das hier posten. Wenn du dann noch 
Zeit hast, kannst du ja mal einen oder mehrere Blicke drauf werden :).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:
> d.h. ich muss an jedem Ende der while(1) Schleife das rx_flag auf 0
> setzen, so das quasi neue Daten ankommen können.

Nein.
Du musst das rx_flag am Ende von parser() auf 0 zurück setzen. Denn dann 
wurde ja der übertragene String bearbeitet.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Multitasking

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, stimmt ! Ich werde nun erstmal so ein Ablaufplan (Struktogramm) 
auf Papier mit sämtlichen Funktionen machen um einen Überblick zu 
erschaffen. Ich programmiere öfters Sachen viel zu sehr kompliziert und 
auch leider falsch, wie man sieht. Wie "seit" ihr denn so gut im Coden 
geworden ? Ist es nur die reine Intelligenz oder einfach die Praxis ?

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:
> Ich werde nun erstmal so ein Ablaufplan (Struktogramm)
> auf Papier mit sämtlichen Funktionen machen um einen Überblick zu
> erschaffen.

Bei grösseren Programmen macht man das Design zweckmäßigerweise 
"vorher".

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jup ;)

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

Bewertung
0 lesenswert
nicht lesenswert
Hallo !

Ich habe das Programm etwas überarbeitet und es funktioniert einwandfrei 
! Das Stoppen funktioniert auch!

Das delay habe ich nur drin, da der Schrittmotor normalerweise ohne dem 
delay sich zwar dreht, aber sehr langsam und dabei summt. Gibt es dafür 
abhilfe ?

Der Code ist im Anhang.
Ich wäre über  Verbesserungsvorschläge und Tipps sehr dankbar !

Eine Frage hätte ich noch da: Gibt es für Linux ein Programm mit dem ich 
viele Befehle Zeile für Zeile nacheinander senden kann ? Ich benutze für 
Linux zwar das Programm HTerm, was auch super ist, wenn ich aber die 
Funktion: send file benutze und in die Datei z.b. sowas rein schreibe:

d:r;100!
d;l;200!

und das schicke passiert nichts. Wie muss ich so eine Textdatei denn 
gestalten ? Oder sollte ich für mein Vorhaben ein kleines Konsolen 
Programm schreiben, welches aus einer Datei Zeile für Zeile die Befehle 
sendet ?

Danke !

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:

> Das delay habe ich nur drin, da der Schrittmotor normalerweise ohne dem
> delay sich zwar dreht, aber sehr langsam und dabei summt. Gibt es dafür
> abhilfe ?

Ja natürlich.
Aber dann müsstest du nochmal alles umdrehen.
Du müsstest dann mit einem Timer einen Zeittakt in einer ISR erzeugen

Die 2ms sind, denk ich verschmerzbar, zumal ja die UART sowieso 
unabhängig weiterläuft und du gar nicht so schnell das Stopp-Kommando 
schicken kannst, als das dir die 2ms weh tun.



> Funktion: send file benutze und in die Datei z.b. sowas rein schreibe:
>
> d:r;100!
> d;l;200!
>
> und das schicke passiert nichts.

Hast du berücksichtigt, dass du über die UART dann auch alle 
Zeilenumbrüche bekommst? Die musst du entweder ausfiltern oder in deiner 
Parserei berücksichtigen

Da du aber hier
      if(dir_com_s[2]=='l')
fix davon ausgehst, dass die Richtungsinformation immer das 3.Zeichen 
ist, wirft dich jegliche Abweichung von deinem Schema aus der Bahn :-), 
selbst wenn es eine harmlose Abweichung ist.

      d:r;100!
kann dein Parser zb auch nicht richtig auflösen, obwohl ich einfach nur 
einen Haufen Leerzeichen gemacht habe.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn's ohne Zeilentrenner sein muss:

while read line; do
  printf "%s" "$line"
  sleep .1
done < infile >/dev/ttyS1

Überträgt zeilenweise aus infile, ohne den Zeilentrenner zu senden.  Es 
wartet ca. 100 ms nach jeder Zeile.

EDIT: /dev/ttyS1 als Schnittstelle angenommen.

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann man die 100ms pause länger machen ? das geht glaub ich alles zu 
schnell... der Motor dreht dann nur hin und her...

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hat sich erledigt.. hab den sleep befehl übersehen ! sorry

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend ! Wie meinst du das mit den Leerzeichen ? :).

Ich muss mir noch mal ein bessere Parserei ausdenken oder was könntest 
du mir empfehlen ?.

Danke und gute Nacht ;-).

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.