Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Lazarus - problen s while

Zdravím.
Nedavno jsem tu řešil programek na vyčitaní dat z vahy přes ser.port, který funguje, ale snažim se o další level.
Odešlu LazSerial1.WriteData(#$52#$0d#$0a);
A vrati se mi ST,GS,1450,kg
To první ST je že je vaha stabilní. Pokud není vrati NS, jako nestabilní. A tady je problem.
Normalně seděl na židli čipek, a když se na vaze zobrazilo ST, tak klik na tlačitko a data uložil a vytisknul.
Čipek už není.
https://i.postimg.cc/NG1h8qvN/v.png
https://postimg.cc/c6x4Wdwm

Po kliknutí na tlačitko by se v cyklu While mělo odesilat do váhy tak dlouho, dokud se mi nevratí stavvazeni = 'ST',
a pak vypsat bo Memo1.

Je to však opačně.
Nenapada někoho, de dělam chybu?
Děkují.

Předmět Autor Datum
Když se ptáš na chybu v programu, bylo by více než z vhodné sem dát jeho kód.
Wikan 16.01.2023 08:06
Wikan
Jsem s toho už tak dokokocený, že misto zdrojaku jsem tu dal 2X odrazek. Tak se omlouvam. :-[ https:…
BigSandy 16.01.2023 08:08
BigSandy
Tak na první pohled tam vidím dva problémy: 1) Ten cyklus se prodávádí, dokud stavvazeni JE roven 'S…
Wikan 16.01.2023 08:27
Wikan
Tak ten první bod jsem pořadně posral. Děkují opraveno. while (stavvazeni = '<>') do Ale stejnak to…
BigSandy 16.01.2023 08:53
BigSandy
Tohle nechápu, kam ti vypadlo to porovnávání s 'ST'? while (stavvazeni = '<>') do S tím druhým máš…
Wikan 16.01.2023 08:58
Wikan
No nevzpadlo. procedure TForm1.Button1Click(Sender: TObject); begin LazSerial1.WriteData(#$52#$0d…
BigSandy 16.01.2023 09:06
BigSandy
Určitě bys stabilnější výsledky dostával, pokud bys to WriteData volal po konci čtení a ne v cyklu.
Wikan 16.01.2023 09:11
Wikan
Nechapu. Mužeš trochu vic info? Jako to volat v LazSerial1RxData? Jsem zkusil tam dat timer a přes…
BigSandy 16.01.2023 09:18
BigSandy
Teď úplně nechápu proč Timer. Na začátku zavoláš LazSerial1.WriteData(#$52#$0d#$0a); v TForm1.Button…
Wikan 16.01.2023 09:26
Wikan
JJ, už to chapu. Tak jak to mam s tým timerem, ale do IF přidat else a tam to znovu zavolat. A v to…
BigSandy 16.01.2023 09:45
BigSandy
No jak chceš, takhle by ses vyhnul různým timerům a sleepům.
Wikan 16.01.2023 09:49
Wikan
Jasně, timer pujde pryč. Přes button odešlu WriteData a pak pod tým ve while budu čekat, až hodnota…
BigSandy 16.01.2023 10:03
BigSandy
Dát jako On timer čtení váhy, je taky docela dobrý nápad. Po zmáčknutí tlačítka by se pak vzalo to,…
ml1 16.01.2023 13:34
ml1
Lazarus zdědil po pascalu cyklus reperat, ten je podle mě na to vhodnější (kód se musí provst minimá…
ml1 16.01.2023 13:26
ml1
Tak to čtení mám tak jak poradil Wikan a bych řek, že je to dobrý napad. procedure TForm1.LazSeria…
BigSandy 17.01.2023 08:49
BigSandy
Já bych se i v tomhle případě na cyklus vykašlal. Přidat bych si tam počítadlo, při každém neúspěšné…
Wikan 17.01.2023 08:52
Wikan
Ona to je vaha na nakladní auta do 65 tun. Když někdo na ní vjede slušně, pomalu tak se ustali mnohe…
BigSandy 17.01.2023 09:18
BigSandy
Kluci, jsem se zadrhl na tom posledním. Chci to uložit, ale aby v nazvu bylo datum a čas a soubor mu…
BigSandy 17.01.2023 15:53
BigSandy
formatdatetime('dd-mm-yyyy h:nn', now) Jsi si jistý tvou dvojtečkou? Tak v názvu souboru být nemůže…
Wikan 17.01.2023 16:00
Wikan
2023-01-17 16:22 16-22 I tak se mu to melibi. Když vezmu text soubor a dam přejmenovat, vyhodi chybu…
BigSandy 17.01.2023 16:26
BigSandy
Vyhodí chybu. Aha. A nenapíše jakou chybu?
host 17.01.2023 16:29
host
Lazarus žadnou nevyhodi a zamrzne. Pokud toužiš po te systemové tak tady 2023-01-17 16:22 16-22 Ozna…
BigSandy 17.01.2023 18:21
BigSandy
Tak to je snad jasný, že název souboru s dvojtečkou není platný...
host 17.01.2023 18:28
host
Tak jak kde, že ano ... u mě to například není žádný problém: [gilhad@cobra-mk3(0) ~] $ ls -al aa*…
gilhad 17.01.2023 20:03
gilhad
No jistě, vždycky se najde někdo, kdo musí dokázat opak. Z kontextu je asi všem jasné, že to provozu…
host 17.01.2023 20:06
host
Nevím, jestli jsem něco nepřehlídnul, ale jediné, co by na to ukazovalo, by bylo, že mu to bez vysvě…
gilhad 17.01.2023 20:12
gilhad
Nechce se mi plýtvat energií na nějaké přesvědčování a dokazování. Souhlasím s tím, že v některých o… poslední
host 17.01.2023 20:14
host
Tak takhle: formatdatetime('yyyy-mm-dd"T"hh-nn', now)
Wikan 17.01.2023 20:06
Wikan

Tak na první pohled tam vidím dva problémy:
1) Ten cyklus se prodávádí, dokud stavvazeni JE roven 'ST'. Ale ty ho chceš provádět dokud NENÍ, ne? Možná bych zvážil repeat..until místo while.
2) Ten cyklus je řízený proměnnou stavvazeni, která se v tom ale cyklu nemění. Takže jakmile se tam program jednou dostane, už tam i navždy zůstane.

Nechapu. Mužeš trochu vic info?
Jako to volat v LazSerial1RxData?

Jsem zkusil tam dat timer a přes něj odesilat co vteřinu žadost a toto je ok.


procedure TForm1.LazSerial1RxData(Sender: TObject);
var
    sl: TStringList;
begin
data := '';
sleep(50);
data := lazserial1.ReadData;
sl := TStringList.Create;
sl.Delimiter := ',';
sl.DelimitedText := data;
if Trim (sl[0]) = 'ST' then
                    begin
                       stavvazeni := Trim (sl[0]);
                       vaha := Trim (sl[2]);
                    end;
sl.Free;
end;

Dát jako On timer čtení váhy, je taky docela dobrý nápad. Po zmáčknutí tlačítka by se pak vzalo to, co už bylo načteno (osobně bych bral aspoň poslední 3 hodnoty, pokud jsou označené jako stabilní a neliší víc než málo, nebo bych čekal v cyklu while, dokud by tento stav nenastal (v tom while by se muselo volat application.processmessages), ještě mě napadá, že by button mohl nastavit nějaký příznak (čekání na platnou hodnotu) a podle toho by potom fungovala obsluha timeru, nebo by byl druhý timer, který by to zajišťoval). Osobně bych se bránil tomu zaseknout program čekáním na něco, co třeba ani nastat nemusí.

Lazarus zdědil po pascalu cyklus reperat, ten je podle mě na to vhodnější (kód se musí provst minimálně jsdnou)
Na že by céčko něco takového nemělo (do while), ale moc se to nepoužívá, ani nevim proč, jestli kvůli těm třem klikům navíc.

Osobně bych to viděl na:


zvaženo:=false;
repeat
  přečíst z váhy
  když má na začátku ST (a podařilo se správně přečíst i zbytek atd.), nastav zváženo:=true
until zvazeno

To musí fungovat. Ještě by bylo dobré dát tam nějaký timeout, aby program neuváznul v té smyčce navěky. Pokud to načtení netrvá moc dlouho, tak bych to před dalším zpracováním načetl třeba třikrát a porovnal výsledky, aby se eliminovala možnost chyby přenosu. Protože jestli ten textovej řetězec neobsahuje žádnou konktrolu (jako třeba GPS, kde je xor kontrola), klidně chyba jednoho bitu udělá ze 1450 kilo třeba 3450 (samozřejmě v lepším případě udělá údaj nesmyslným, ale když jsem koukal na záznamy z GPS, hlavně na ty věty, které neprošly kontrolou, tak tam byly právě i takové, kde by se chyba jinak nepoznala, i když většina byla chybná na první pohled (třeba useknutá nebo s nesmyslnými znaky nebo nějak jinak poškozená)).

Tak to čtení mám tak jak poradil Wikan a bych řek, že je to dobrý napad.


procedure TForm1.LazSerial1RxData(Sender: TObject);
var
    sl: TStringList;
begin
data := '';
stavvazeni := '';
vaha := '';
sleep(50);
data := lazserial1.ReadData;
sl := TStringList.Create;
sl.Delimiter := ',';
sl.DelimitedText := data;

if Trim (sl[0]) = 'ST' then
                    begin
                        stavvazeni := Trim (sl[0]);
                        vaha := Trim (sl[2]);
                        Label1.Caption:= Trim (sl[0]);
                        Label2.Caption:= Trim (sl[1]);
                        Label3.Caption:= Trim (sl[2]);
                        Label4.Caption:= Trim (sl[3]);
                    end
                    else LazSerial1.WriteData('hups');
sl.Free;
end;              

Ale to "ještě by bylo dobré dát tam nějaký timeout, aby program neuváznul v té smyčce navěky" mi nedalo spat.
Takže asi klasika s repeat.


procedure TForm1.Button1Click(Sender: TObject);
var i:Integer;
begin
i:=0;
LazSerial1.WriteData('hups');

repeat
    inc(i);
    Application.ProcessMessages;
    if stavvazeni = 'ST' then  continue;
    sleep(50);
until i=100;

Memo1.Lines.AddText('stav vazeni ' + stavvazeni);
Label5.Caption:= stavvazeni;
Label6.Caption:= vaha;
end;       

Nějake připominky? :-D

Ona to je vaha na nakladní auta do 65 tun.
Když někdo na ní vjede slušně, pomalu tak se ustali mnohem rychlejí než když na ní vjede nějake prase. a prasat je hodně.

Neopakuje se važení.
Při kliknuti se odešle jen jednou WriteData
V LazSerial1RxData se to opakuje dokud vaha je stabilní a pak ukonči
A přes repeat jen hlidam, až se ustali a načtu vahu.

Kluci, jsem se zadrhl na tom posledním.
Chci to uložit, ale aby v nazvu bylo datum a čas a soubor musí být bez připony.
Když použiju formatdatetime('ddddd h:nn', now), mám 17.01.2023 15:46
Počitač bere tečku mezí 01.2023 a tedy mám soubor 17.01 s připonou 2023 15:46
Potřebují změnít ty . třeba za -.
Projet postupně znak po znaku a nahradít bych zvlad.
Je jednodušší zpusob?

Dik.

Tak jak kde, že ano ... u mě to například není žádný problém:


[gilhad@cobra-mk3(0) ~] $ ls -al aa*
ls: cannot access 'aa*': No such file or directory
[gilhad@cobra-mk3(0) ~] $ echo -e "test\n druhý řádek" > aa:bb
[gilhad@cobra-mk3(0) ~] $ ls -al aa*
-rw-r--r-- 1 gilhad users 21 2023-01-17 20:02 aa:bb
[gilhad@cobra-mk3(0) ~] $ cat aa:bb
test
 druhý řádek
[gilhad@cobra-mk3(0) ~] $ rm aa:bb
[gilhad@cobra-mk3(0) ~] $ ls -al aa*
ls: cannot access 'aa*': No such file or directory
[gilhad@cobra-mk3(0) ~] $ 

Zpět do poradny Odpovědět na původní otázku Nahoru