TBlockSerial.Recvstring

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
Maik81SE
Beiträge: 327
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.4 FPC 3.2.2)
CPU-Target: x86-64; avr
Wohnort: Lübeck
Kontaktdaten:

TBlockSerial.Recvstring

Beitrag von Maik81SE »

Moin @ll,

ich wende mich heute mit mit bezüglich der Function Recvstring an euch.

Vorweg, ich habe/will mir einen PortScanner bauen, der mir meine angeschlossen Matrix-Boards scant.
Soweit auch alles schick.
Daten Ports werden alle abgefragt und wenn ttyUSB* nicht erreichbar, wird das TBlockSerial auch geschlossen.
Bei vorhandenem ttyUSB wird ein Datensatz gesendet. In diesem Fall $<a>

Das der Befehl auf meinem M328p ankommt und verarbeite wird, seh ich positiv in der Console, da ich da genau die antwort erhalte, welche gewünscht wird.
Nun wollte ich diese Antwort aber auch in der Form2.Caption anzeigen lassen, jedoch erhalte ich bei dem Aufruf Form2.Caption := USB[Module].Recvstring(2000); einen Leerstring.

Hat von euch jemand eine Idee, wo der der Datensatz verloren geht?

Code: Alles auswählen

procedure TForm2.InitTimerTimer(Sender: TObject);
begin
  // Kontroll-Ampel defaullt auf GELB schalten
  USB_Connect[Module].State  := slYELLOW;
  // Prüfe ob LCK-File vorhanden.
  // Wenn ja, löschen selbiger (zB. da Programmabsturz die File nicht gelöscht hat)
  if FileExists('/var/lock/LCK..ttyUSB' + intToStr(Module-1)) then DeleteFile('/var/lock/LCK..ttyUSB' + intToStr(Module-1));
  Setlength(TX_Send, 255);
  // Erstelle USB[x] und prüfe auf Erreichbarkeit
  // Wenn erreichbar, setze Kontroll-Ampel auf GRÜN
  // andernfalls ROT;
  USB[Module]                := TBlockSerial.Create;
  try
    try
      USB[Module].Config( 9600, 8, 'N', SB1, false, false);
      USB[Module].Connect(Port + IntToStr(Module-1));
      Caption                := Port + IntToStr(Module-1) + '|' + IntToStr(USB[Module].LastError) + ' ' + USB[Module].LastErrorDesc;
       if USB[Module].LastError = 0 then begin
         _USB[Module].Connect:= True;
         _USB[Module].Error  := False;
         USB_Connect[Module].State:= slGREEN;
         USB[Module].SendString('$<a>');
         Form2.Caption       := USB[Module].Recvstring(2000);
         end
       else begin
         USB_Connect[Module].State:= slRED;
         MCURun.Enabled      := False;
         end;
    except
      USB[Module].Free;
      end;
  finally
    Statusbar1.Panels[1].Text     := USB.LastErrorDesc + ' | ' + Port + IntToStr(a);
    end;
  if Module = 1 then begin
    InitTimer.Enabled        := false;
  end;
  dec(Module);
end;
Danke im Voraus für eure Aufmerksamkeit und einen schönen Feierabend gewünscht.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.4 FPC 3.2.2);

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TBlockSerial.Recvstring

Beitrag von MmVisual »

Du musst auf die Antwort erst warten.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 364
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: TBlockSerial.Recvstring

Beitrag von Jorg3000 »

Hi!
Ist denn der grundsätzliche Aufbau überhaupt richtig?
Ohne mich jemals mit USB beschäftigt zu haben, kommt es mir merkwürdig vor, dass bei jedem Timer-Event ...

Code: Alles auswählen

USB[Module].Config( 9600, 8, 'N', SB1, false, false);
      USB[Module].Connect(Port + IntToStr(Module-1));
... die Kommunikation neu konfiguriert wird.

Zumindest passt der Timer nicht gut zu den 2 Sekunden Wartezeit in .Recvstring(2000), denn wenn keine Daten zurückkommen, wartet und steht das Programm, oder?

Intuitiv würde ich die Kommunikation nur einmal initialisieren, bevor man den Send/Receive-Timer startet.
Grüße, Jörg

Benutzeravatar
Maik81SE
Beiträge: 327
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.4 FPC 3.2.2)
CPU-Target: x86-64; avr
Wohnort: Lübeck
Kontaktdaten:

Re: TBlockSerial.Recvstring

Beitrag von Maik81SE »

MmVisual hat geschrieben: Di 7. Jan 2025, 08:30 Du musst auf die Antwort erst warten.
Da war ja och was :shock:

Code: Alles auswählen

repeat
  temp              := USB[Module].RecvTerminated(1, CRLF);
  until temp <> '';
  Form2.Caption     := temp;
Ob das jetzt die sauberste Lösung ist wag ich mal zu bezweifeln, aber auf jedenfall Funktional und bis zur den Finalen Daten erst mal mit der ToDo für mich akzeptabel
Jorg3000 hat geschrieben: Di 7. Jan 2025, 10:11 Hi!
Ist denn der grundsätzliche Aufbau überhaupt richtig?
Ohne mich jemals mit USB beschäftigt zu haben, kommt es mir merkwürdig vor, dass bei jedem Timer-Event ...

Code: Alles auswählen

USB[Module].Config( 9600, 8, 'N', SB1, false, false);
      USB[Module].Connect(Port + IntToStr(Module-1));
... die Kommunikation neu konfiguriert wird.

Intuitiv würde ich die Kommunikation nur einmal initialisieren, bevor man den Send/Receive-Timer startet.
Zugegeben.
Das mal hab ich mich gefühlt 2018 :?: :!: das letzte mal damit beschäftigt, So mit kann ich dir auch nicht sagen, an welchem Bsp ich mich damals orientiert hatte.

Auf deine Frage, warum ich die Kommunikation bei jedem Durchlauf neu konfiguriere.
Ich verwende ein WS2812 - Matrixboard auf einem ATMega328p und 2 ATMega16 AVRs.
Jeder spricht über USB mit meinen Programm und somit brauch ich für jeden AVR die selbe Config, ungeachtet dessen, ob ich ttyUSB0, ttyUSB1 oder ttyUSB2 anspreche.

Und was ist einfacher als ein offenes Array zu nutzen und die Config entsprechend pro ttyUSB* neu zu bauen?
Jorg3000 hat geschrieben: Di 7. Jan 2025, 10:11 Zumindest passt der Timer nicht gut zu den 2 Sekunden Wartezeit in .Recvstring(2000), denn wenn keine Daten zurückkommen, wartet und steht das Programm, oder?
bei 10 Sekunden steht das Programm nicht.
Aber da ich die Rückgabe nun kommt, wie ich es mir wünschte, kann ich den nun auch Step-by-Step runtergehen

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.4 FPC 3.2.2);

Antworten