Auswertefehler oder Übertragungsfehler?

Für sonstige Unterhaltungen, welche nicht direkt mit Lazarus zu tun haben
Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Auswertefehler oder Übertragungsfehler?

Beitrag von Maik81SE »

Moin @ll

Ich habe gerade mal an einer Funktion versucht einige Fehler auszuschließen, aber iwo seh ich gerade den Wald vor lauter Bäumen nicht.

Ich sende einen Befehl zB

Code: Alles auswählen

$<5#L1C1D0DUD2#>$<5#L1C2D0DUD2#>$<5#L1C3D0DUD2#>$<5#L1C4D0DUD2#>$<5#L1C5D0DUD2#>$<5#L1C6D0DUD2#>$<5#L1C7D0DUD2#>$<5#L1C8D0DUD2#>
diese Übertragung sehe ich auch 1 : 1 auf der RX-Leitung, wenn ich diese mit der TX verbinde.

Wenn ich dies jedoch auf den Interrupt USART__RX laufen lasse, herhalte ich folgende Ausgabe.

Code: Alles auswählen

<5#L1C1DbDUDb#16>
<n#L1C1DbDUDb#16>
<T<SL1C4D2D�D#
<S>SL1C4D2D�D#
<S>SL1C4D2D�D#
<S>SL1C4D2D�D#
<S>SL1C4D2D�D#
Die erste Rückgabe gibt genau den Wert zurück, welchen ich auch sende.
Ab der Zweiten Rückgabe scheint er Iwo die Daten zu verändern.

Das erste Zeichen nach der < sollte die 5 enthalten.
und wenn wir uns die Rücknahme mal anschauen, zieht sich der Fehler immer weiter.

Code: Alles auswählen

var
  RX                         : array [0..19] of char;

procedure USART__RX; public Name 'USART__RX_ISR'; interrupt;
var
  i                          : uint16;
begin
  asm cli end;
  i                          := 0;
// Read Data from Master
  if (UARTReadChar = WakeUp) then begin
    repeat
      RX[i]                  := UARTReadChar;
      inc(i);
      until (i = 19) or (RX[i-1] = '>');
  end;

// Send Data to Terminal as controll
  UARTSendChar(RX[0]);
  UARTSendByte(byte(RX[1]) + 48);                                               // Datenbyte in Lesbaren Text umwandeln (Overload-Funktion)
  UARTSendChar(RX[2]);
  UARTSendChar(RX[3]);
  UARTSendByte(byte(RX[4]) + 48);
  UARTSendChar(RX[5]);
  UARTSendByte(byte(RX[6]) + 48);
  UARTSendChar(RX[7]);
  UARTSendByte(byte(RX[8]) + 48);
  UARTSendChar(RX[9]);
  UARTSendChar(RX[10]);                                                         // Zahl bedarf hier keine umwandlung, da im Teststring größer 48dec
  UARTSendChar(RX[11]);
  UARTSendByte(byte(RX[12]) + 48);
  UARTSendChar(RX[13]);
  case byte(RX[14]) of                                                           // Umwandlung der länge in Lesbaren Wert.
       12: begin UARTSendString('12'); end;
       13: begin UARTSendString('13'); end;
       14: begin UARTSendString('14'); end;
       15: begin UARTSendString('15'); end;
       16: begin UARTSendString('16'); end;
       17: begin UARTSendString('17'); end;
       end;
  UARTSendChar(RX[15]);
  UARTSendChar(#10);
  UARTSendChar(#13);
  asm sei end;
end;

begin
  asm cli end;
  Set_IO;
  UARTInit(true);
  for a := 0 to 19 do RX[a]  := char($00);
  asm sei end;
  repeat
        until 1 = 0;

end.
nun stellt sich mir die Frage, ob dies ein Fehler ist, welches durch die Verwendung der ISR erzeugt wird oder ob ich einen anderen Aspekt nicht sehe.

Ich Wünsche euch einen angenehmen Restsonntag und bleibt Gesund.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von af0815 »

Du definierst hier eine Interruptmethode, führst aber darinen Sachen aus, die meiner Meinung nichts in einer Interruptroutine zu tun haben. Wenn Interrupt, dann Zeichen empfangen, in den Puffer stopfen und raus. Alles andere gehört meiner Meinung nach in die Main-Schleife. Und in einem Empfangsinterrupt sende ich nichts.

Das nächste, wenn ich Kommuniziere, verwende ich grundlegend mal Byte und mische das nicht mit Char (oder bleibe nur beim Char). Wenn ich für einen Test etwas zurücksende, so mache ich keine Umwandlung zwischen Byte, Char und String. Wenn sende ich den Puffer so zurück wie ich ihn empfangen habe oder ich wandle alles in Hex um und sende das retour. Es ist dann aber genau 2x so viel aber ich sehe lesbar was im Puffer war.

Im Interrupt schau ich mal ob das Zeichen ein WakeUp war, wenn ja, dann lösche ich den Empfangs Puffer setze den Pufferzähler (hier i, würde ich aber global wie den Puffer machen) und schreiben der ersten Wert in den Puffer, erhöhe den Pufferzähler und merke mir, das eine Übertragung läuft. Bei den nächste Interrupts, weis ich das eine Übertragung läuft und schreiben den Wert in Empfangspuffer und erhöhe den Pufferzähler. Ist das Ende erreicht, so nehme ich das Übertragungsflag weg und Signalisiere der Mainloop das Daten hier sind. Die kann dann das ganze übernehmen, sich die Daten wegkopieren und zurücksenden. Damit ist alles sauber getrennt.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von Maik81SE »

af0815 hat geschrieben:
So 13. Mär 2022, 16:16
Du definierst hier eine Interruptmethode, führst aber darinen Sachen aus, die meiner Meinung nichts in einer Interruptroutine zu tun haben. Wenn Interrupt, dann Zeichen empfangen, in den Puffer stopfen und raus. Alles andere gehört meiner Meinung nach in die Main-Schleife. Und in einem Empfangsinterrupt sende ich nichts.

Das nächste, wenn ich Kommuniziere, verwende ich grundlegend mal Byte und mische das nicht mit Char (oder bleibe nur beim Char). Wenn ich für einen Test etwas zurücksende, so mache ich keine Umwandlung zwischen Byte, Char und String. Wenn sende ich den Puffer so zurück wie ich ihn empfangen habe oder ich wandle alles in Hex um und sende das retour. Es ist dann aber genau 2x so viel aber ich sehe lesbar was im Puffer war.

Im Interrupt schau ich mal ob das Zeichen ein WakeUp war, wenn ja, dann lösche ich den Empfangs Puffer setze den Pufferzähler (hier i, würde ich aber global wie den Puffer machen) und schreiben der ersten Wert in den Puffer, erhöhe den Pufferzähler und merke mir, das eine Übertragung läuft. Bei den nächste Interrupts, weis ich das eine Übertragung läuft und schreiben den Wert in Empfangspuffer und erhöhe den Pufferzähler. Ist das Ende erreicht, so nehme ich das Übertragungsflag weg und Signalisiere der Mainloop das Daten hier sind. Die kann dann das ganze übernehmen, sich die Daten wegkopieren und zurücksenden. Damit ist alles sauber getrennt.
also wenn ich mir das mal auf der Zunge zergehen lasse, sagst du mir damit.
-> Bleib bei einem Type
-> Verwende Zusatzvariablen, zum gewisse Funktionen nur dann laufen zu lassen, wenn die entsprechende Bedingung erfüllt ist und
-> Lösche an der richtigen Stelle den Empfangsbuffer...

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von af0815 »

Kurzfassung ja, mit einem Zusatz - Interrupt ist so kurz wie möglich zu halten. Interrupt ist Interrupt und main ist main.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von Maik81SE »

af0815 hat geschrieben:
So 13. Mär 2022, 17:54
Kurzfassung ja, mit einem Zusatz - Interrupt ist so kurz wie möglich zu halten. Interrupt ist Interrupt und main ist main.
ergo sollte der Interrupt maximal nur so aussehen.

Code: Alles auswählen

procedure USART__RX; public Name 'USART__RX_ISR'; interrupt;
//procedure USART__RX;
begin
  asm cli end;
  i                          := 0;
// Read Data from Master
  if (UARTReadChar = WakeUp) then begin
    repeat
      RX[i]                  := UARTReadChar;
      inc(i);
      until (i = 19) or (RX[i-1] = Trans_end);
  end;
  Status_Flag          := $01;		// Wert nur als Bsp, wenn man mit uint8 als Status arbeiten sollte.
  asm sei end;
end;

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von af0815 »

nichtmal das. Ein Zeichen in der Puffer und auf den nächsten Interrupt warten. Dafür ist der da. Asynchon unabhängig eine kurze Aufgabe übernehmen.

Lazaus/fpc nehmen im Hintergrund dir einiges ab. Normalerweise muss man im Interrupt aich die verwendeten Register und Zustände sichern, da der Interrupt dad laufende Programm an fast jeder Stelle unterbrechen kann.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von Maik81SE »

af0815 hat geschrieben:
So 13. Mär 2022, 18:15
nichtmal das. Ein Zeichen in der Puffer und auf den nächsten Interrupt warten. Dafür ist der da. Asynchon unabhängig eine kurze Aufgabe übernehmen.

Lazaus/fpc nehmen im Hintergrund dir einiges ab. Normalerweise muss man im Interrupt aich die verwendeten Register und Zustände sichern, da der Interrupt dad laufende Programm an fast jeder Stelle unterbrechen kann.
Verstehe ich das richtig, das Jedes Zeichen einen Interrupt auslöst und ich mir daher den WakeUp Quasi Schenken kann?

Hintergrund dieses WakeUp, ist um Fehlerhafte Befehls Starts auszuschließen.
Unter dem dürfen keine Daten Außer "Trans_Start, Trans_Sektor und Trans_End übernommen werden.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von af0815 »

Ein Interrupt unterbricht das aktuelle Programm in Main um einen wichtigen Zustand zu bearbeiten. Deswegen sperrt man kurz weitere Interrupts. Bearbeitet das Ereignis und gibt die Interrupts wieder frei. Die Interrupts werden deswegen in Hardware ausgelöst um sicher auf asynchrone Ereignisse reagieren zu können. Oder auch um ein Timing stabil hin zu bekommen, unabhängig davon was in der Hauptschleife passiert.

Klassisch ist zum eine Hardware Com Schnittstelle die Zeichen mit hohen Tempo empfangen kann und einer Softwareemulierten langsamen Com Schnittstelle fürs Logging.

Bei deinem Ansatz löst der Interrupt durch das erste Zeichen aus, das pollst du einfach. Das heisst auch alles andere steht, weil du den ganzen Microcontroller quasi im Interrupt stoppst. Da geht zwischendurch nichts mehr. Die Main steht, alle weiteten Interrupts sind blockiert. Ohne Zeichen auf der Com. ist der Controller einfach tot.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von siro »

Meine Herangehensweise wäre folgende:

Code: Alles auswählen

const StartZeichen = '<';
const EndeZeichen  = '>';
const RxBufferSize = 20;

var AuswerteFlag:Boolean;
var RxCount:Integer;
var RxBuffer:Array[0..RxBufferSize-1] of Char;
                                                       
procedure USART__RX; public Name 'USART__RX_ISR'; interrupt;
var rxByte : Char;
begin
  rxByte:=UARTReadChar;                  // das empfangene Byte lesen,
  if rxByte = StartZeichen then begin    // wenn das Startzeichen erkannt wurde, dann
    rxCount:=0;                          // Puffer von vorne an neu beschreiben, index also auf 0
  end else begin                         // ansonsten (keine neue Sequenz)
    if rxByte <> EndeZeichen then begin  // solange es kein Endezeichen ist
      RxBuffer[rxCount]:=rxByte;         // Byte einfach in den Empfangspuffer schreiben
      inc(rxCount);                      // ein Zeichen mehr im Empfangspuffer
      if rxCount = RxBufferSize then;    // eventuellen Uebrlauf abfangen....
    end else AuswerteFlag :=TRUE;        // EndeZeichen erkannt, alle Daten sind da, das Hauptprogramm soll Auswerten
  end;
end;  // ab hier sind Interrupts automatisch wieder eingeschaltet, weil der Compiler einen "RETI" Befehl einfügt.        


const Absturz=FALSE;  // :-)

main
  Repeat
    if AuswerteFlag then begin  // alle Daten sind da
                                // mache was Du wills mit den Daten
                                // hier auch Senden wenn erforderlich
      AuswerteFlag:=FALSE;      // signalisiere dass alles getan wurde. 
                                // Dieses Flag wird wieder True beim nächsten EndeZeichen im Interrupt  
    end;                                
  Until Absturz;

Du bekommst mit jedem empfangenen Zeichen einen neuen Interrupt.
Durch das Lesen des Empfangsregisters, wird das Empfangs-Interrupt-Bit wieder gelöscht.


Siro
Zuletzt geändert von siro am So 13. Mär 2022, 19:11, insgesamt 1-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von Maik81SE »

af0815 hat geschrieben:
So 13. Mär 2022, 18:51
Ein Interrupt unterbricht das aktuelle Programm in Main um einen wichtigen Zustand zu bearbeiten. Deswegen sperrt man kurz weitere Interrupts. Bearbeitet das Ereignis und gibt die Interrupts wieder frei. Die Interrupts werden deswegen in Hardware ausgelöst um sicher auf asynchrone Ereignisse reagieren zu können. Oder auch um ein Timing stabil hin zu bekommen, unabhängig davon was in der Hauptschleife passiert.

Klassisch ist zum eine Hardware Com Schnittstelle die Zeichen mit hohen Tempo empfangen kann und einer Softwareemulierten langsamen Com Schnittstelle fürs Logging.

Bei deinem Ansatz löst der Interrupt durch das erste Zeichen aus, das pollst du einfach. Das heisst auch alles andere steht, weil du den ganzen Microcontroller quasi im Interrupt stoppst. Da geht zwischendurch nichts mehr. Die Main steht, alle weiteten Interrupts sind blockiert. Ohne Zeichen auf der Com. ist der Controller einfach tot.
Also würdest du dann eher Alle Zeichen inkl "WakeUp" einlesen und dannach die Gültikteil des "DatenStreams auswerten, bzw im Case Index "0" schauen, ob über die Uart Das WakeUp rein kommt uns ab da mit dem Indikator mit jedem Interrupt durchlauf um 1 erhöhen bzw bei der UART komblett auf den Interrupt verzichten, so wie es bei C :? gehandhabt habe?

Code: Alles auswählen

if (getch(true) == WakeUp)
        {

            /* Einlesen des DatenStrings */

            for (i=0; i<=20; i++)
            {
                rxd[i] = getch(true);
                if (rxd[i] == '>') break;
            }
        }
Obtion 2 und 3 wären wohl unter dem Aspekt am sinnvollsten oder hab ich da nich einen Denkfehler?

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von af0815 »

Siehe Lösung von Siro.

Und die ganze Ausgabe kommt in die main, dort wo das Auswerteflag gesetzt ist.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von Maik81SE »

siro hat geschrieben:
So 13. Mär 2022, 19:01
Meine Herangehensweise wäre folgende:

Code: Alles auswählen

const StartZeichen = '<';
const EndeZeichen  = '>';
const RxBufferSize = 20;

var AuswerteFlag:Boolean;
var RxCount:Integer;
var RxBuffer:Array[0..RxBufferSize-1] of Char;
                                                       
procedure USART__RX; public Name 'USART__RX_ISR'; interrupt;
var rxByte : Char;
begin
  rxByte:=UARTReadChar;                  // das empfangene Byte lesen,
  if rxByte = StartZeichen then begin    // wenn das Startzeichen erkannt wurde, dann
    rxCount:=0;                          // Puffer von vorne an neu beschreiben, index also auf 0
  end else begin                         // ansonsten (keine neue Sequenz)
    if rxByte <> EndeZeichen then begin  // solange es kein Endezeichen ist
      RxBuffer[rxCount]:=rxByte;         // Byte einfach in den Empfangspuffer schreiben
      inc(rxCount);                      // ein Zeichen mehr im Empfangspuffer
      if rxCount = RxBufferSize then;    // eventuellen Uebrlauf abfangen....
    end else AuswerteFlag :=TRUE;        // EndeZeichen erkannt, alle Daten sind da, das Hauptprogramm soll Auswerten
  end;
end;  // ab hier sind Interrupts automatisch wieder eingeschaltet, weil der Compiler einen "RETI" Befehl einfügt.        
also von der Fußschleife Weg und mit einer Kopfschleife Spielen.

Aber was den cli und sei angeht.
Die werd ich lieber zur Sicherheit mit reinpacken um die Gewissheit zu haben, das nicht noch von wo anders einer Querschiest, aber das ist ja dann der Persönliche Geschmack eines Jeden einzelnen.

Aber eine Frage hab ich mal aus Reinem Interesse...
Warum Schreibst du vor Jeder Variable / Const die Definition?
Machst du es, weil du es mal so gelehrnt hast oder einfach nur der Lesbarkeit halber?
Frage, da ich es mal in dieser Richtung gelehrnt habe.

Code: Alles auswählen

const
  WakeUp                     = 36; // '$'
  Trans_Start                = 60; // '<'
  Trans_Sektor               = 35; // '#'
  Trans_End                  = 62; // '>'
af0815 hat geschrieben:
So 13. Mär 2022, 19:22
Siehe Lösung von Siro.

Und die ganze Ausgabe kommt in die main, dort wo das Auswerteflag gesetzt ist.
Den hab ich im Schreibmoment nicht mitbekommen... :mrgreen:
Danke nochmal für den Nachtrag.

EDIT
Ich hab das gerade mal auf Papier durchgespielt und bin auf eine Böse Falle gestoßen.
Die Fangzeichen können ja auch Teil des Befehles sein, da die Farbwerte Alle Zahlen von 0 bis 255 enthalten dürfen/müßen.

Entweder muß ich beim Senden drauf achten oder dies in den Abfragen berücksichtigen.
Letzteres bläht die Interrupt-Abfrage auf und ich glaube NIEMAND wird es merken wenn in den Farben die Werte 36 und/oder 62 fehlen.
und wenn, dann muß er/sie/es wirklich alle Farben RGB (255*255*255) sehen können ^_^

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von af0815 »

Bei den Steuerzeichen gibt es mehrere Möglichkeiten. Die sicherste ist, nach dem Startzeichen die Länge anzugeben. Dann wird alles gelesen bis die Anzahl vorhanden ist. Oder man "Escaped" die Zeichen. Dann stimmt aber deine fixe länge nicht. Noch eine Alternative ist, auf das Startzeichen zu warten, dann eine fixe Anzahl zu lesen und dann auf das Endezeichen zu prüfen. Ist das da, passt alles und wir nehmen die Daten. Wenn nicht schmeissen wir das weg.

Bezüglich cli und sei, schau dir einfach mal die Ausgabe mit den Pascalzeilen an, dann sieht man es gleich ob man es braucht oder nicht.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von Maik81SE »

af0815 hat geschrieben:
So 13. Mär 2022, 21:15
Bei den Steuerzeichen gibt es mehrere Möglichkeiten. Die sicherste ist, nach dem Startzeichen die Länge anzugeben. Dann wird alles gelesen bis die Anzahl vorhanden ist. Oder man "Escaped" die Zeichen. Dann stimmt aber deine fixe länge nicht. Noch eine Alternative ist, auf das Startzeichen zu warten, dann eine fixe Anzahl zu lesen und dann auf das Endezeichen zu prüfen. Ist das da, passt alles und wir nehmen die Daten. Wenn nicht schmeissen wir das weg.

Bezüglich cli und sei, schau dir einfach mal die Ausgabe mit den Pascalzeilen an, dann sieht man es gleich ob man es braucht oder nicht.
Werd die heute Abend mal nach folgendem Schema Testen.

Code: Alles auswählen

procedure USART__RX; public Name 'USART__RX_ISR'; interrupt;
var temp: byte;
begin
  asm cli end;
// Read Data from Master
  temp                       := UARTReadChar;
  if (Temp = WakeUp) and (RX_Count > 0) then begin
    RX_Count                 := 0;
    end else begin
      if (temp <> Trans_End) and (RX[RX_Count - 1] <> Trans_Sektor) then begin
        RX[RX_Count]         := temp;
        inc(RX_Count);
        if RX_Count = RX_Max_Buffer then
          RX[0]              := $62;
        end else
      end;
  asm sei end;
end;
Counter Reset bei ungültiger Kombination ausgeschloßen.
Ebenso die Auswertung des Befehlsende an der richtigen Stelle Obtimiert.
Da ich weiß, wann welches Zeichen kommen soll/muss/darf kann brauch ich nur das Letzte Zeichen mit querschieben.
Muß dies Natürlich entsprechend im Befehl erweitern, oder ich geh save und schreib den Trans_End > 2 mal...

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Auswertefehler oder Übertragungsfehler?

Beitrag von siro »

Zu meinem Code mit den vielen "const":
Das mache ich mal so, oder auch anders, das hat jetzt keinen tiefern Sinn.

Synchronisation stellt oft eine Problem dar bei der Datenübertragung.
Ich würde jetzt einfach mal für ein START das Zeichen $FE
und für eine STOP Zeichen ein $FF nehmen.
Dann gibt es die beiden "hellsten Werte" eben nicht, aber das sieht eh keiner, ich hab grad mal nen Versuchsaufbau gemacht
und mir angesehen:
RGB_Test1.jpg
RGB_Test1.jpg (50.68 KiB) 1931 mal betrachtet
! Achtung! C-Code....man vergebe mir.... :P

Code: Alles auswählen

    for (i=0; i<10; i++)      // 10 mal blinken in weiss 
    {
      FillLeds(255,255,255);  // volle Helligkeit
      Delay_ms(500);         
      FillLeds(253,253,253);  // zwei Bits weniger
      Delay_ms(500);
    }  
    
    for (i=0; i<10; i++)  // 10 mal blinken in ROT
    {
      FillLeds(255,0,0);  // volle Helligkeit
      Delay_ms(500);
      FillLeds(253,0,0);  // zwei Bits weniger
      Delay_ms(500);
    }

    for (i=0; i<10; i++)  // 10 mal blinken in GRÜN
    {
      FillLeds(0,255,0);  // volle Helligkeit
      Delay_ms(500);
      FillLeds(0,253,0);  // zwei Bits weniger
      Delay_ms(500);
    }

    for (i=0; i<10; i++)  // 10 mal blinken in BLAU
    {
      FillLeds(0,0,255);  // volle Helligkeit
      Delay_ms(500);
      FillLeds(0,0,253);  // zwei Bits weniger
      Delay_ms(500);
    }
Ich kann da kein blinken/flackern erkennen.....
Ich sehe es aber am Strom, dass er sich in meinem Aufbau mit 6 LEDs um ca. 600 Mikroampere ändert.

Ich steuere meine RGBs mit einem kleinen Microchip PIC Controller 12F1840 bzw sogar einem 6 Beinigen PIC10F322
Leider kann ich die nicht in Pascal programmieren, hier ist C und oder Assembler angesagt. :cry:

Übrigens: in den unteren dunklen Werten sieht man schon einzelne Bitschritte...

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Antworten