GSM parancsok közti idő soros porton

 ( TCH | 2018. december 12., szerda - 22:29 )

Épp egy 4 vezetéket használó (RX, TX, RTS, CTS) soros porton csatlakoztatott GSM modulon (QuectelMC60) keresztül próbálok HTTP kéréseket küldeni valahova, viszont egyszerűen nem jövök rá, hogy mégis mennyi időt kell várni két parancs között. A manualt végigolvastam (mind a 260 oldalt) és az ugyan le van benne írva, hogy az egyes parancsoknak mennyi a válaszideje, amíg jön a response, de az már nem, hogy utána mikor lehet küldeni a következő adatot.

Most össze van a szó legszorosabb értelmében drótozva egy sor utasítás a megfelelő várakozásokkal, hogy kimenjen a lekérés. Ha nem így csinálom, hanem megvárom, hogy visszajöjjön a válasz és aztán küldöm a következő parancsot, akkor N számú parancs után a soros port lerohad. Nem megy ki többet rá adat, újra kell indítani a programot. A flush nem segített rajta.

Ötlet, hogy mit kúrok el? (A hardware flow be van kapcsolva, de kipróbáltam software flow-val is.)

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

SEND után nem kell egy OK-nak visszajönnie?

De, vissza is jön. De ennek ellenére, ha az OK-ra várok és nem "random" időket, akkor a soros port egy idő után "bedugul". (Vagy mittudomén mit csinál.)

Ezt úgy képzelem, hogy küldesz valamilyen AT parancsot, ezt ő nyugtázza, utána küldheted a következőt. Az más kérdés, hogy a GSM interface-en mikor lesz belőle valami, mit és hogyan bufferel a modem. Szerintem különféle státuszok lekérdezésére is vannak megfelelő AT parancsok. Nagyon rég böködtem már GSM modemet.

A flow kontroll kell, mert úgy korrekt, de elég valószínű, hogy nem tudod annyi adattal elárasztani, amit ne tudna benyelni legalább a bufferébe, ha nem is azonnal dolgozza azt fel. Mint ahogyan te is jelezheted az RTS vonalon, hogy a másik oldal csihadjon kicsit, mert nem tudsz mit kezdeni a sok adattal. Viszont ez alsó rétegre vonatkozik, a flow kontroll akár üzenet közben várakoztat, ha megtelt a buffer.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

> Ezt úgy képzelem, hogy küldesz valamilyen AT parancsot, ezt ő nyugtázza, utána küldheted a következőt.

Én is így képzeltem, de nagyon nem így működik. Ha az OK-ra (vagy ami a response, arra) várok, akkor egy idő után nem mennek ki a parancsok a soros buszon...

> Az más kérdés, hogy a GSM interface-en mikor lesz belőle valami, mit és hogyan bufferel a modem. Szerintem különféle státuszok lekérdezésére is vannak megfelelő AT parancsok.

Vannak, de olyan nincs köztük, hogy "küldhetek-e már adatot". Mondjuk szép is lenne, hiszen ahhoz, hogy lekérdezzem, hogy küldhetek-e adatot, ahhoz adadot kéne küldenem. :P

> A flow kontroll kell, mert úgy korrekt, de elég valószínű, hogy nem tudod annyi adattal elárasztani, amit ne tudna benyelni legalább a bufferébe, ha nem is azonnal dolgozza azt fel.

256 byte a parancssorbuffer és 300 ms a minimum válaszidő (annál gyorsabban egy parancs sem reagál). Ezt még 9600 bauddal is el lehetne "árasztani", de én nem is küldök azonnal, megvártam, amíg visszajön a response, de ennek ellenére nem megy, ha nem várok egy csomó időt.

> Mint ahogyan te is jelezheted az RTS vonalon, hogy a másik oldal csihadjon kicsit, mert nem tudsz mit kezdeni a sok adattal. Viszont ez alsó rétegre vonatkozik, a flow kontroll akár üzenet közben várakoztat, ha megtelt a buffer.

Ez egy Orange Pi, 4 vezetékesre konfigurált soros porttal, az RTS/CTS kezelése be van építve, elméletileg nekem nem kell figyelnem CTS-t, a rendszer magától megvárja, hogy clear legyen, amíg beönti a buffert a buszra. Vagy szerinted pont itt a baj, hogy pont hogy nem?

Hát, én inkább debuggolnám a hw-t a helyedben, hogy hova tűnik a zadat a buszon mint magic időzítésekre bízzam a dolgokat a megfelelő response megvárása helyett


// Happy debugging, suckers
#define true (rand() > 10)

Egybe van építve, meg oszcilloszkópom sincs. Amúgy eszemben sincs időzítésre bízni.

Az én Huawei GSM modulom esetében egy usleep(100000) volt a nyerő megoldás.

Na hallod, jól implementálták azt az eszközt, amelybe gyógyidőzítések kellenek, s nem tudhatod, az mindig elég, vagy csak néha, netán olykor sok.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Huawei-rol volt szo. Bar kezdenek feljonni, kinaiaknal nem ritka, hogy a sajat - kinai - adatlapjat sem tartja be.

Egy hopapiros nyomtatot probaltam kb. fel eve beuzemelni. Valamilyen nyugati kutyu klonja elvileg. Nagy nehezen megtalaltam az adatlapjat, google translate-en keresztul sikerult ertelmezni, de a grafika rajzolasnal 64x64 pixel fole nem tudtam menni. Pedig tobb grafikai parancsat is implementaltam, es egyiknel sem reagalt nagyobbra.

--
When you tear out a man's tongue, you are not proving him a liar, you're only telling the world that you fear what he might say. -George R.R. Martin

Új lehetsz hardveres területen :-)!

Jellemzően alacsonyabb szintű eszközökkel dolgozom. Ellenállás, kondenzátor, induktivitás, dióda, MOSFET, bipoláris tranzisztor, műveleti erősítő, mikrokontroller, multiplexer, tápegység és vezérlőik, s effélék.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nekem is voltak olyan USB-s mobil stickjeim, amik egy ido utan/random nem fogadtak parancsot. Volt amikor soft reset segitett, de az is elofordult hogy a tapot is el kellett venni >=1mp idore. Szoval az ilyen nem beepitett (minipci-e), hanem USB-s 4G routerek nem veletlenul rosszak.

Sajnos en is terveztem hardvert (FPGA) es tudom, hogy megy ez. Szorit az ido, nem megy at az 1000-bol 1-2 teszteseten. Aztan felulrol mondjak, hogy azokat ki is lehet szedni am a setbol :) Valoszinuleg igy szuletnek a mai csoda termekek is (mar ha egyaltalan tesztelik).

Itt is usleep()-pel működik, de nem ugyanannyit kell várni a különféle parancsok között.

Pedig a válaszból tudod, hogy kész a modem oldal. Addig ne küldj semmi mást. Ha eseménykezelős nyelvvel dolgozol, akkor a ciklusban hívj processEventet, hogy az eventek továbbítva legyenek. Egyes modemek csökkentett módba kapcsolnak rövid tétlenség után ("bealszanak"). Pl. samsung modemeknél at+factolog paranccsal ki lehet kapcsolni ezt a videlkedést. Próbáld olvasni a portot akkor is, ha az OS szerint az rx buffer üres. Furcsa, de néha ez triggereli a modem oldalt, hogy küldjön. Általában nem nagy a modem oldali ringbuffer (1-4 kb). Próbálkozz flow control nélkül.

> Pedig a válaszból tudod, hogy kész a modem oldal. Addig ne küldj semmi mást.

Így csináltam, de nem jó. Mondjuk pl. a AT+CPIN="1234"[CR] először visszaadja az OK-ot, majd sok másodperc múlva még küld egy "SMS ready.", ill. "Call ready." üzenetet is, tehát nem mindig az OK jön legutoljára.

> Ha eseménykezelős nyelvvel dolgozol, akkor a ciklusban hívj processEventet, hogy az eventek továbbítva legyenek.

Ez Pascal/UNIX-os socket/filekezelés, select(), ioctl(), read(), write(), stb.

> Egyes modemek csökkentett módba kapcsolnak rövid tétlenség után ("bealszanak"). Pl. samsung modemeknél at+factolog paranccsal ki lehet kapcsolni ezt a videlkedést. Próbáld olvasni a portot akkor is, ha az OS szerint az rx buffer üres. Furcsa, de néha ez triggereli a modem oldalt, hogy küldjön. Általában nem nagy a modem oldali ringbuffer (1-4 kb). Próbálkozz flow control nélkül.

De itt pont akkor rohad le, ha nem hagyom tétlenkedni, ha folyamatosan piszkálom a portot. Ha sokat várok, akkor megy.

> Próbálkozz flow control nélkül.

Az már sajnos megvolt.

Ha OK válasz megvárása mellett egymás után küldöd a sima AT parancsot egy ciklusban akkor is megáll egy idő után? Tehát: ATE0Q0V1-OK; AT-OK; AT-OK; AT-OK; ...

Érdekes, de így nem. Viszont baromi lassan reagál a sima AT parancsokra, illetve baromi lassan mennek ki.
Azonfelül azt is észrevettem, hogy van, amikor leállítás után, ha elindítom, akkor alapból egyetlen üzenet sem megy ki a soros portra.

Az SMS ready-től nem fog fejre állni.
És csak a modem bekapcsolása után 1x jön ilyen üzenet.
Ha ennyire zavar, indulás után első körben várd meg az SMS ready és Call ready-t és csak utána kezdjed a PIN-t beadni. És ott már jól fog működni a visszatérő OK. Az OK-ra várva ne felejts el timeout-ot is figyelni!

> Az SMS ready-től nem fog fejre állni.
> És csak a modem bekapcsolása után 1x jön ilyen üzenet.
> Ha ennyire zavar, indulás után első körben várd meg az SMS ready és Call ready-t és csak utána kezdjed a PIN-t beadni.

Az SMS és Call ready üzenetek csak akkor jönnek, ha beadom neki a PIN-t, különben nem.

> Az OK-ra várva ne felejts el timeout-ot is figyelni!

Nem felejtettem el; megfelelő response-ra, vagy timeout-ra szállt ki a várakozásból.

Akkor gondolom ignorálod őket.

M66-nál nincs ilyen gond.
Hmmm....

Legutolsó firmware van a modemen?

> Akkor gondolom ignorálod őket.

Persze, informatívak, nem kell velük foglalkozni.

> Legutolsó firmware van a modemen?

Ez egy jó kérdés. Hogyan tudom megnézni? A manualban nincs szó firmware-ről.

ATI ?

Ami infós parancs van, ráeresztettem.

ATI;+GMI;+GMM;+GMR;+GOI;+GSN;+GCAP
Quectel_Ltd
Quectel_MC60
Revision: MC60CAR01A05

Quectel_Ltd
Quectel_MC60
Revision: MTK 0828

Quectel_MC60

Revision: MC60CAR01A05

MC60

861359033291731

+GCAP: +CGSM,+FCLASS

OK

Sajnos én firmware related infót nem látok benne.

Revision: MC60CAR01A05

Az nem a firmware verziója, az a lapkáé, rákerestem.

A SMS ready meg a Call ready meg a bejovo hivast jelzo Call valamint sms erkezes, sms delivery report erkezes, azok ugynevezett unsolicited resultok, amiket kulon kezelned kell. Tehat vannak a sima AT parancsaid, amiket kiadsz, azokra varod ugye a valaszt, amig nincs valasz, addig nyilvan nem kuldessz masikat, emellett pedig tarolod a halozat/eszkoz allapotat, hiszen amig nincs call ready, addig folosleges vele barmit kezdeni, itt pedig nyilvan nem lehet elore megmondani az idot, mert lefedettsegtol kezdve barmitol fugghet, hogy mennyi ido alatt tud felcsatlakozni. Ha a modem ilyen unsolicated uzenetben tajekoztat arrol, hogy leszakadt a halozatrol, akkor ismetelten nem szabad vele addig dolgozni, amig vissza nem tudott kapaszkodni. Ha jott egy uzenet, akkor vagy az uzenetet kapod meg, vagy csak egy jelezest, hogy melyik slotba mentette el, ezt nyilvan le kell kezelni, mert ha betelnek a slotok, akkor kb 2-5 masodpercenkent fog ilyen random uzenetben zaklatni, hogy betelt a tarhely. Az unsolicated uzenetek johetnek akkor is, mikozben te az OK-t varod egy korabban elkuldott AT parancsra, tehat arra is fel kell keszulni, hogy egy AT-ra nem az adott AT-ra erkezo OK jon, hanem egy meglepetes uzenet.

---
Apple iMac 27"
áéíóöőúüű

Köszi, de ezt én is tudom; azt írtam, hogy "megfelelő response-ra, vagy timeout-ra szállt ki a várakozásból". Minden parancshoz tartozik egy stringlist, ami a termináló response-okat tartalmazza. Ha ez üres, akkor automatikusan az "OK" lesz, amire vár; a SMS/Call ready nem állítja meg a várakozást.

Amúgy itt csak TCPIP kommunikáció lesz, SMS és hasonlók nem.

Akkor viszont nem ertem sem a problemat, sem a kerdest. Az emlitett Quectel modut hasznalom (van MC20 es MC60 is), minden teljesen rendben mukodik, sehol nem kell elore nem tudhato idoket varakozni.

---
Apple iMac 27"
áéíóöőúüű

Nem mondtam, hogy az eszközzel van a baj, csak leírtam, hogy mit tapasztalok.
Mondjuk most betettem a serial send elé, hogy írja már ki, hogy mikor küldi ki a parancsot és azt látom, hogy a parancs kiküldése és a kimenetele között másodpercek telnek el, a jelek szerint ezért fut folyamatosan timeoutra.

Ez hiba, vagy ennek így kell mennie? Mert ha az utóbbi, akkor először azt is meg kell várnom, hogy a soros portról visszajöjjön a kiküldött üzenet és csak utána kezdhetek várni a timeoutra.

Visszajojjon a kikuldott uzenet? Itt a local echora gondolsz? Azt en csak kezzel torteno teszteleskor hasznalom, amikor a rendszer fut es hasznalja a modemet, a local echo ki van kapcsolva. De ha kezzel nyomkodom, nem emlekszem, hogy lassu lett volna az echo. Nalam a timeout egyebkent 1 perc, ha 1 perc eltelt, akkor ezutan megy egy modem off AT command, majd ujrakezdodik a "program". Ellenorzi a modem ki/bekapcsolt allapotat, bekapcsolja, pint ellenoriz, pint beallit es a call ready utan kezdi el a queueben felgyult feladatokat vegrehajtani a modemen.

---
Apple iMac 27"
áéíóöőúüű

> Visszajojjon a kikuldott uzenet? Itt a local echora gondolsz?

Igen.

> Azt en csak kezzel torteno teszteleskor hasznalom, amikor a rendszer fut es hasznalja a modemet, a local echo ki van kapcsolva.

Én is épp tesztelek.

> De ha kezzel nyomkodom, nem emlekszem, hogy lassu lett volna az echo.

Vagyis akkor valami el van keffentve a soros beállításaim között?

> Nalam a timeout egyebkent 1 perc, ha 1 perc eltelt, akkor ezutan megy egy modem off AT command, majd ujrakezdodik a "program". Ellenorzi a modem ki/bekapcsolt allapotat, bekapcsolja, pint ellenoriz, pint beallit es a call ready utan kezdi el a queueben felgyult feladatokat vegrehajtani a modemen.

És azok a parancsok, amiknek a lehetséges maximum válaszideje jóval több, mint egy perc? Pl. a AT+CGACT, AT+QIACT, AT+QISERVER parancsok; ezeknek 150 sec a max. response time. Én minden parancsnál a megadott maximum válaszidőt plusz 3 másodpercet vettem timeoutnak. Mondjuk lehet, hogy pont ez a kevés, rá kéne hagynom azt az időt is, ami addig tellik el, amíg kimegy az adat, mert utána viszont - ahogy nézem - azonnal (in 300 ms) válaszol a modem.

En nem hasznaltam GPRS-t es ezzel kapcsolatos dolgokat, csak SMS es hivas kezeles volt. Ott nem voltak ilyen hosszu valaszideju commandok. Egyebkent, amivel a legtobb bajom volt, az az autobauding, rendszeresen lelassult vagy eltimeoutolt a kapcsolat, ezert minden modemen fixen be lett love kezzel ez a beallitas, igy az elejetol kezdve rendben mukodik.

---
Apple iMac 27"
áéíóöőúüű

Most belőttem, hogy a baudrate ne autobauding legyen, de nem segített rajta sajnos...

Egyébként baromi nagy timeoutnál is az van, hogy egy idő után nem megy ki több parancs. Ezek szerint nem is a készülék nem válaszol, hanem ki sem megy.

Nem lehet, hogy az RTS-én jelzi - a te CTS-eden -, hogy nem tudja fogadni az adatot? Mérj rá, hátha ez derül ki!


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Thx, de közben már kiderült mi volt a baj: egyfelől a select() timeoutja 5000-re volt beállítva, így aztán, ha befelé nem érkezett adat, akkor a select() 5000 ms-ig várakozott, feltartván a másik ágban lévő write()-ot is és ezért nem ment kifelé sem, másfelől meg a bejövő adatokban kutató függvényt elkúrtam; az egyik ágban nem inkrementáltam egy pointert, ami végtelen ciklust eredményezett az egyik parancs visszatérése esetén.

Sz*rk: Az RTS/CTS itt hardware-esen kezelve van elvileg.

Attól, hogy hardware-esen van kezelve, ha a másik oldal nem eszi meg a buffert, nem engedi, hogy küldj adatot.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Elhiszem, de amúgy sem tudtam volna rámérni, mert nincs szkópom, meg egybe is van építve a gép a modullal.

Update: Amióta meggyógyítottam azt a két bugot, azóta tökéletesen megy, kivéve egy dolgot: amikor kiadom a TCP/IP open parancsot (AT+QIOPEN="TCP","1.2.3.4","80"), utána a soros port lemerevedik. Amit kiküldök rá, az nem megy ki, a modem meg sem kapja és ez így is marad, amíg az open vissza nem dobja, hogy CLOSED.

Erre van valakinek ötlete?

Csak tipp, egy regi ESP8266 firmware-nel volt olyan, hogy pont a kuldo parancsnal mindenkepp \r\n-t vart, en meg \n-t kuldtem (masnal elfogadta).
Egeszen veletlenul nincs keznel egy Saleae klonod? Azzal latnad merre mi megy..

--
When you tear out a man's tongue, you are not proving him a liar, you're only telling the world that you fear what he might say. -George R.R. Martin

Sajnos nincs kéznél, meg amúgy is egybe van építve, de itt tuti nem ez a helyzet, mert egyrészt ez \r-t vár, másfelől meg csak annál a parancsnál rohad le és nem is arról van szó, hogy csak a send nem megy ki; open után CLOSED-ig semmi nem megy ki a soros portra...

Open után megérkezik az OK, majd a CONNECT OK?

Csak CONNECT érkezik, nem CONNECT OK. Lecsekkoltam, hogy melyiknek kell és azt írja, hogy sima CONNECT csak transparent mode-ban jön, ami azt jelenti, hogy open után tök mindegy mit csinálok, az adat lesz, ami a szerver felé megy. /o\ Hát így nem csoda, hogy nem ment ki semmi, ha nincs normál módúra állítva... Thx, a rávezetést. (Csak azt nem értem, hogy előtte a kézi időzítésű összeállítással miért ment.)

Viszont így meg hiába megy ki a AT+QISEND=63, megjelenik a > által jelölt prompt és várja az adatot, mintha csak sima AT+QISEND ment volna ki, pedig a manual szerint, ha meghatározom a hosszát, akkor nem kell promptra várni. Itt mi lehet a hiba?

Sz*rk:
Ahogy ebből a kódból kipuskáztam, a prompt mindenképpen jön. Átírtam a kódot, hogy kiküldi csak a parancsot a hosszal, majd megvárja a promptot és aztán küldi a HTTP lekérést. És így működik. Az egész.

Kösz mindenkinek!