Autor Téma: Lazarus - komunikace přes serial port  (Přečteno 2743 krát)

Vašek

  • Host
Lazarus - komunikace přes serial port
« kdy: 04-11-2016, 16:40:19 »
Dobrý den všem.
Potřeboval bych vyřešít komunikací přes Lazars s arduinem.
Poradí někdo nebo alespon nasměruje někam?



Offline Slappy

  • Mladík
  • **
  • Příspěvků: 66
  • Karma: 1
  • Slappy
    • Verze Delphi: 10.2 Tokyo + Vsetky :)
    • unSigned
Re:Lazarus - komunikace přes serial port
« Odpověď #1 kdy: 04-11-2016, 17:29:14 »
Ak chces nieco bezpracne, tak skus pozriet http://www.winsoft.sk/comport.htm.

Je to komponent (balik komponentov) pre Delphi, .NET, Android, OS X, Firemonkey atd.

Kedze obsahuje full sources, tak by to zrejme slo pouzit aj v Lazaruse. Pripadne sa skus dohodnut s autormi (su z Kosic), ze ci by poskytli zdrojaky na vyskusanie alebo nieco podobne (pouzivame od nich nejake komponenty a maju dobry prozakaznicky pristup).

V najhorsom pripade su uplne naspodu nejake odkazy, ktore ta nakopnu dalej, len treba viac kodit :)

Predam knihy C++ Builder: http://forum.delphi.cz/index.php/topic,15076.0.html

Moje projekty: http://www.unsigned.sk Tvorba cool dizajnovych instalatorov v NSIS a Inno Setup, Visual Studio a RAD Studio

Offline raul

  • Plnoletý
  • ***
  • Příspěvků: 167
  • Karma: 9
    • Verze Delphi: FPC :D
Re:Lazarus - komunikace přes serial port
« Odpověď #2 kdy: 06-11-2016, 11:42:19 »
Synapse obsahuje synaser - jednoznacne. Komunikuju takto s nekolika arduiny. Funguje pod linuxem, windows, arm/linuxem apod. Idealni.
Lazarus 1.6.3:), FPC, Intel/Arm, Windows/Linux

Vašek

  • Host
Re:Lazarus - komunikace přes serial port
« Odpověď #3 kdy: 09-11-2016, 17:31:59 »
A neporadíš jak na to?

Připojít na port mí funguje.
Kód: [Vybrat]
var
  Form1: TForm1;
  ComPort : string = 'COM5';
  Ser : TBlockSerial;
implementation

{$R *.lfm}

{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
  Ser := TBlockSerial.Create;
 try
   Ser.Config(9600, 8, 'N', 0, False, False);
   Ser.Connect(ComPort);
   Ser.Purge;
   Ser.Flush;
   if Ser.LastError = 0 then
   begin
         Memo1.Lines.Add('Připojen na ' + ComPort);

   end
   else
   begin
     Memo1.Lines.Add('Nejde se připojit na ' + ComPort);
   end;
 finally

 end;
end;   

Odesilat by mnělo jít takto
Kód: [Vybrat]
if Ser.LastError = 0 then
begin
Ser.SendString('ahoj');
end;

Asi to neumím odchytit na straně arduina ;)
Kód: [Vybrat]
String x;

void setup() {
 pinMode(13, OUTPUT);
 Serial.begin(9600); // initialize serial communication
}

void loop() {
       if (Serial.available() > 0) {
              x = Serial.read();
              if(x == "ahoj")
                    digitalWrite(13, HIGH);
                          }
}


Offline raul

  • Plnoletý
  • ***
  • Příspěvků: 167
  • Karma: 9
    • Verze Delphi: FPC :D
Re:Lazarus - komunikace přes serial port
« Odpověď #4 kdy: 09-11-2016, 22:09:19 »
Jednak by odeslani melo byt spis :
Ser.SendString('ahoj'#13#10); // pridat NEJAKY oddelovac - pokud necekas jen vylozene na ahoj

Serial.read() v arduinu cte jeden znak, takze budto musis pouzit tridu string (asi nema smysl rozepisovat)
teoreticky muzes (v tvem pripade) pouzit neco jako
if (Serial.available() and (Serial.read() == "a") and (Serial.read() == "h") and  .....
{
 digitalWrite(13,high);
}

nebo udeat neco jako (syntaxi presne dohledej)

switch (Serial.read)
{
  case 'a' : {
// neco udelat
break;
}

  case 'b' : {
//udelat neco jineho
break;
}
}

Protoze pameti je v arudinu malo, pouzivaji se spis jednodussi protokoly stylu
a = rozsviti ledku 1
b = zhasne ledku 1
apod
samozrejme muzes udelat i slozitejsi, ja mam treba modemu podobny protokol
AT+POSITION=300 // posune motor 1 na 30stupnu
+POSITION:300 // vraci arduino po vykonani posledniho prikazu
+DEBUG:POSITION:WORKING // vraci arduino ze na tom dela

nicmene nekde uz musim pouzit mega a nekde pouzivam esp8266 (wemos mini) kvuli rychlosti (160mhz) a vic ramky (ani nevim, ale proste vic). na tom esp8266 si clovek musi uz par veci ohlidat a tak nejak kouknout jak se to chova - uz to neni arduino - zapoj cokoliv kamkoliv a max to nebude neco delat. ten wemos je citlivejsi na vic veci - ale to je na delsi debatu (kazdopadne zvladne upocitat plynuly rozjezdy krokace i na vic nez 4tis kroku/s - coz je cca max arduina).

v arduino doporucuju si udelat nejakou knihovnu co se protokolu tyce (ja si dokonce psal generator te knihovny) a tu pak jen poustet. knihovna je konkretni ke kazdemu projektu - ale da se pekne vyuzit ten swtich/case, takze to nezere pamet a zaroven je to pekne rychle (klasicky if instr=="neco" then ... else if instr=="necojineho" then - je silene narocny a chudak arduino)
(forek, timhle zpusobem presne jeden magor udelal z 1ghz procesoru procesor 50mhz - mel tam totiz tolik zbytecnych podminek...)

vysledny loop pak u me vypada nejak takto:

void loop ()
{
  tryLink(); // zkousi se spojit s master zarizenim, oznamit kdo jsem apod a pokud linknou, tak rozsviti ledku
  TimeCriticalMethod();  // hlavni cinnost arduina (protoze se jedna o krokac zavisly na casech, tak poustim skoro vsude)
  SerialWork(); // samotne volani knihovny, ktera jednak zjistuje co komp chce (ony case serial read) a druhak zavola danou metodu co se ma udelat - v mezicase opet vola timecriticalproc
  TimeCriticalMethod();
}

P.S.> S kazdym connect se ti arduino resetuje - coz muze a nemusi vadit. Jen pro info, aby ses nedivil proc ti program nepokracuje pri dalsim priipojeni.
Lazarus 1.6.3:), FPC, Intel/Arm, Windows/Linux

Vašek

  • Host
Re:Lazarus - komunikace přes serial port
« Odpověď #5 kdy: 10-11-2016, 09:21:16 »
Vyřešeno - dik za tip  ;)

Vašek

  • Host
Re:Lazarus - komunikace přes serial port
« Odpověď #6 kdy: 10-11-2016, 14:10:58 »
Tak odesilaní je ok.
Problem se čtením.
Fungovat to funguje ale do te doby než se přeruší spojení s arduinem.
Ve FormCreate zavolam proceduru pripoj.
Kód: [Vybrat]
Procedure pripoj;
 begin
  Ser := TBlockSerial.Create;
 try
   Ser.Config(9600, 8, 'N', 0, False, False);
   Ser.Connect(ComPort);

   Ser.Purge;
   Ser.Flush;
   if Ser.LastError = 0 then
   begin
         form1.Memo1.Lines.Add('Připojen na ' + ComPort);
   end
   else
   begin
     form1.Memo1.Lines.Add('Nejde se připojit na ' + ComPort);
   end;
 finally

 end;

A pak přes button spustím timer (zatim provizorní - pak bych to chtěl ve vlaknu)
Kód: [Vybrat]
procedure TForm1.Timer1Timer(Sender: TObject);
var
i:integer;
Rcvd : string;
begin
Rcvd := '';
try
if Ser.LastError = 0 then
   begin
       Rcvd := Ser.Recvstring(10000);
       Memo1.Lines.Add(Rcvd);
       Ser.Purge;
   end
else
Memo1.Lines.Add('chyba'+ IntToStr(Ser.LastError));
ser.free;
pripoj;
finally
end;
end;

Zkoušel jsem to dat i do  try - except - end a take nic.

Offline raul

  • Plnoletý
  • ***
  • Příspěvků: 167
  • Karma: 9
    • Verze Delphi: FPC :D
Re:Lazarus - komunikace přes serial port
« Odpověď #7 kdy: 10-11-2016, 14:22:58 »
A co to dela ? (Krom toho ze je problem)

Ser.RecvString(10000) = cekej max 10 s jestli neni neco ke cteni coz by koncilo enterem (tusim, osobne to mam uz vice zapouzdrene a tohle jsem psal pred rokem)
Prdel je - co si pamatuju - ze kdyz se to pekne trefilo, tak mohlo dojit k vypadku dat, nebot treba ah prislo v jednu chvili a oj[enter] v druhe a ah uz bylo zapomenuto.

To byl duvod meho zapouzdreni, kde zpracovani probiha ve vlaknu
- pri vicemene jakekoliv chybe je vlakno ukonceno, nebot dalsi automatika zajisti zalozeni noveho vlakna (pri detekci portu) krom
- neprijde vyse zmineny link, pak se nastavi dtr (aby se arduino resetlo) a pocka se dele, pokud neprijde, vlakno se ukonci
- vlakno prijima data bez reseni co a jak (s timeoutem 100ms) a strka do fronty
- aplikace si bere data z fronty (metoda pak resi i hledani enteru apod)
- aplikace co chce poslat zada do fronty

Btw1> Ten timer doufam nemas nastaven na mene nez nejakych 11-12s (a je to prasarna - pises docasne, budiz ti tedy odpusteno)
Btw2> Co dela Ser.Purge ? (Z hlavy nevim, ale nemyslim ze bych ho tam mel takto pouzit)
Lazarus 1.6.3:), FPC, Intel/Arm, Windows/Linux

Vašek

  • Host
Re:Lazarus - komunikace přes serial port
« Odpověď #8 kdy: 10-11-2016, 16:44:20 »
A co to dela ? (Krom toho ze je problem)
Však jsem pisal.
Fungovat to funguje ale do te doby než se přeruší spojení s arduinem.
V tom else volam znovu proceduru pripoj ale nefunguje to.
Zkoušel jsem to dat i do  try - except - end a volat tu proceduru pripoj v except a take nic .

Zlaty python .

Offline raul

  • Plnoletý
  • ***
  • Příspěvků: 167
  • Karma: 9
    • Verze Delphi: FPC :D
Re:Lazarus - komunikace přes serial port
« Odpověď #9 kdy: 10-11-2016, 16:46:01 »
Nenapsal si konkretne co ti to dela, proto jsem se ptal. Nefunguje neni popis problemu.

A kdy tu komunikaci taky ukoncujes ? To odpojis arduino (ale na woknech to neodpojis) a cekas ze to pujde znovu pripojit ?

Python mozna zlaty je - ja rikam zlate C a jeden silenec tvrdi ze neni nad asm :D V rozumnem jazyce co neudelas, nemas. Pokud to nevyhovuje, pak je neco spatne.
« Poslední změna: 10-11-2016, 16:48:24 od raul »
Lazarus 1.6.3:), FPC, Intel/Arm, Windows/Linux

Vašek

  • Host
Re:Lazarus - komunikace přes serial port
« Odpověď #10 kdy: 10-11-2016, 17:34:57 »
Ano.
Pokud odpojím arduino a pak se znovu připojí na stejný port mnělo by se to znovu připojít, ně?

Offline raul

  • Plnoletý
  • ***
  • Příspěvků: 167
  • Karma: 9
    • Verze Delphi: FPC :D
Re:Lazarus - komunikace přes serial port
« Odpověď #11 kdy: 10-11-2016, 17:47:32 »
Co si takhle v metode pripoj misto jde/nejde vysledku taky vypsat co ti to pise (treba minimalne ten lasterror pripadne lasterrordesc (tusim) ?

Tipuju, ze ser.free a pripoj takhle hopem za sebou proste wokna nedaj, pripadne se v ser.free neodpojuje samotna komunikace (nevim z hlavy) atd atd atd.

Treba takovy tcp.bind v linuxu pri padu aplikace nekdy trva i minutu, nez linux dany port uvolni pro naslouchani znovu.

Trochu snahy chlape.

Ale jo, donutil si me :
procedure TForm1.Timer1Timer(Sender: TObject);
var
   i:integer;
   Rcvd : string;
begin
   Rcvd := '';
   try
     if Ser.LastError = 0 then // neni nahodou chyba predchozi komunikace - blbe, tohle mas delat uplne jinak, ne testovat jestli v predchozim timeru nebyla chyba
     begin
          Rcvd := Ser.Recvstring(10000); // cekej 10vterin do enteru
          Memo1.Lines.Add(Rcvd); // zapis cos prijal
          Ser.Purge; // nevim - asi vyprazdni nejaky buffer
     end else
          Memo1.Lines.Add('chyba'+ IntToStr(Ser.LastError));// napis chybu - jakou ? cislo chyby pred casem ?

    ser.free; // nejlepsi cast nakonec - pokazde kdyz tikne timer, zrus tenhle objekt, takze v dalsim tiku timeru testujes co ? podivej se do zdrojaku, jestli se tam vola neco jako close apod
   pripoj; // a hned zkousej znovu konnect..
   finally
   end;
end;


Sorry, ale divim se, ze ti to vubec funguje. Z patra - co 10sekund resetujes arduino.

Procedure pripoj;
 begin
  Ser := TBlockSerial.Create;
 try
   Ser.Config(9600, 8, 'N', 0, False, False); // juuu prima - Reconfigure communication parameters on the fly. You must be connected to port before! (asi mas nahodou stejne parametry arduina, protoze tohle je zbytecny radek)
   Ser.Connect(ComPort);

   Ser.Purge; // pripojim se, cimz resetuju arduino a delam co ?
   Ser.Flush; // a potom mazu odchozi buffer ?
   if Ser.LastError = 0 then // testuju chybu connectu ?
   begin
         form1.Memo1.Lines.Add('Připojen na ' + ComPort); // tak hlavne ze to vime
   end
   else
   begin
     form1.Memo1.Lines.Add('Nejde se připojit na ' + ComPort); // a hlavne ze vime, KDE nastala chyba (+ IntToStr(ser.lasterror) + ' ' + ser.lasterrordesc
   end;
 finally

 end;

Btw3> Jeste si dej pozor at arduinu nezacpes buffer - neni to pc, takze nemusi ustihat prijimat a zpracovavat data, takze delsi slova a castejc neposilat najednou.. (Ted nevim, ale mam pocit ze nejakych 64znaku nebo tak)
« Poslední změna: 10-11-2016, 17:57:35 od raul »
Lazarus 1.6.3:), FPC, Intel/Arm, Windows/Linux

Vašek

  • Host
Re:Lazarus - komunikace přes serial port
« Odpověď #12 kdy: 10-11-2016, 18:09:33 »
Tak dik že jsi mi vysvětlil, že se mam na to vysrat.
On bude problem v tom. že lazarus jsem spatřil poprve před tydnem a v delphi dělal naposled před 20 roky.

Offline raul

  • Plnoletý
  • ***
  • Příspěvků: 167
  • Karma: 9
    • Verze Delphi: FPC :D
Re:Lazarus - komunikace přes serial port
« Odpověď #13 kdy: 10-11-2016, 18:16:45 »
Vysr.. ne, ale precist si alespon Lukasovu dokumentaci - na rozdil od jinych dokumentaci totiz sedi.

Takze postup stylem (styl, ne program) :

Ser.create;
Ser.Connect();
lognisererrorifexist;
Ser.Config();
lognisererrorifexist;

while ser.lasterror = 0 do (bacha na timeout)
begin
    s := 'sem si dosad co chces poslat';
   if s <>'' then
begin
     ser.send....;
     lognisererrorifexist;
end;
   s := '';

    s := ser.read....;
    lognisererrorifexist;
   //se s si udelej co chces
end;
ser.closesocket; //uzavre socket komunikace
FreeAndNil(ser);


samozrejme tohle je uplne zjednoduseny priklad, musel bys popsat vic co chces a jak delat aby se dalo napsat vic.
Lazarus 1.6.3:), FPC, Intel/Arm, Windows/Linux

Vašek

  • Host
Re:Lazarus - komunikace přes serial port
« Odpověď #14 kdy: 10-11-2016, 18:27:17 »
Ono jsem to našel tady.
http://forum.arduino.cc/index.php?topic=37577.15

Odesilat i přijimat data mi jde, jen je ten problem, že se mi to samo znovu nepřipojí ale zas není duvod aby se to samo odpojovalo.
Asi to necham uležet :)

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Upozornění: do tohoto tématu bylo naposledy přispěno před 120 dny.
Zvažte prosím založení nového tématu.

Jméno: E-mail:
Ověření:
Křestní jméno zpěváka Gotta: