porovnání obsahu řetězce po seriové lince

Odpovědět
RobertN
Příspěvky: 5
Registrován: 09 lis 2018, 09:10
Reputation: 0

porovnání obsahu řetězce po seriové lince

Příspěvek od RobertN » 10 úno 2019, 10:55

Dobrý den,

konunikuji přes seriovou linku s GSM SIM800C modulem. Chci ověřit, že v odpovědi z modulu je obsažen určitý text. Nyní to dělám pomocí substring, ale tam se může stát, že odpověď bude mít nějaký znak na víc nebo na míň a už je to nespolehlivé.
Zde je kod.

Kód: Vybrat vše

.
.
.

// vyčisti buffer
while (komunikaceSIM800L.available() > 0) {
    s = komunikaceSIM800L.read();           
     }


// Je modul registrován

    komunikaceSIM800L.println("AT+CREG?");

    delay(100);
    
   
  while (komunikaceSIM800L.available() > 0) {
    s = komunikaceSIM800L.read();           
    odpoved = odpoved+s;  
  } 
    
  
   if (odpoved.substring(18,21) == "0,1") {
  
  digitalWrite(LED,HIGH);
  }
  else
  {
    digitalWrite(LED,LOW);
  }


  
odpoved = "";

.
.
.

Chtěj jsem to udělat pomocí funkce strstr takto:

Kód: Vybrat vše

 if(strstr(odpoved, "0,1") != NULL)

   {
    digitalWrite(LED,HIGH);
  }
  else
  {
    digitalWrite(LED,LOW);
  }

Ale při kompilaci mi to hlásí

"cannot convert 'String' to 'const char*' for argument '1' to 'char* strstr(const char*, const char*)' "

Nevím, jak to převést a přiznám se, že ani nemůžu nikde najít co znamená to char s hvězdičkou...

Děkuji

RomanB
Příspěvky: 31
Registrován: 04 zář 2017, 14:28
Reputation: 0
Bydliště: Havířov

Re: porovnání obsahu řetězce po seriové lince

Příspěvek od RomanB » 10 úno 2019, 12:53

Předpokládám, že kod je z https://www.arduinotech.cz/inpage/jak-j ... ky-smskou/ a tam postupně načítá a pak porovnává to co potřebuješ pomocí

Kód: Vybrat vše

if (SIM800.available() != 0) {
	// if there are data in the UART input buffer, reads it and checks for the asnwer
	response[x] = SIM800.read();
	x++;
	// check if the desired answer  is in the response of the module
	if (strstr(response, expected_answer) != NULL)
	{
		answer = 1;
	}
}
Taky by jsi mohl definovat "odpoved" takto

Kód: Vybrat vše

char* odpoved ;
a ne jenom

Kód: Vybrat vše

odpoved = "";

pavel1tu
Příspěvky: 609
Registrován: 26 říj 2017, 08:28
Reputation: 1
Bydliště: Trutnov
Kontaktovat uživatele:

Re: porovnání obsahu řetězce po seriové lince

Příspěvek od pavel1tu » 10 úno 2019, 15:56

SMS je vždy stejně dlouhá ... jen ji musíš řádně zpracovat - jako v tom příkladu

já jedu řádek po řádku a zkoumám jen první znaky
po dotazu na SMS "AT+CMGR=1"
hledám řádek s "OK" - to znamená že není žádná SMS v paměti
nebo "+CMGR:" - to už je první řádek SMS, pak porovnám (na tom samém řádku) že je opravdu ješte nepřečtená "REC UNREAD" - vše za tím ignoruji tam je jen číslo odesílatele (to neporovnávám, ale v příští verzi už budu) a časová značka odeslání asi

a na dalším řádku už je jen čistý text SMS, který zpracuji

pak okamžitě SMS mažu

nevidím v tom problém
UNO, NANO, Mikro, PRO mini, DUE
http://pavel1tu.8u.cz/

gilhad
Příspěvky: 169
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: porovnání obsahu řetězce po seriové lince

Příspěvek od gilhad » 10 úno 2019, 17:01

Myslim, ze autor deklaraci promenne odpoved neuvedl a ma ji nekde v tech třech tečkách, co zastupují začátek včetně setupu.

Nicméně překladač je toho mínění, že ta proměnná je typu String (a autor se k ni taky tak chova, odpoved = odpoved+s; ) a funkce strstr vyžaduje ukazatele na řetězece (char *) jako parametry, nikoli nějaké objekty (String).

Pokud pouze změní deklaraci proměnné, tak mu to zase neprojde, bude muset změnit i její používání (například naplňování jednotlivými znaky) - stejně jako v tom linkovaném příkladu.

char * je ukazatel na znak (char), ten znak může být prvkem pole znaků (char[]) a pak se dá považovat i za ukazatel na začátek nějakého řetězce, dle konvence ukončeného znakem 0x00 (znak s kódem nula, také lze v řetězci zapsat jako '\0', resp. "text\0").

Co znamená char *a případně char b[100] a další podobné hrátky se znaky a řetězci lze najít v každé učebnici jazyka C - nenech se mýlit tím, že u Arduina se místo programu říká sketch a tvrdí že programují v jazyku Wiring - ve skutečnosti jde o knihovnu funkcí (digitalRead, digitalWrite ...) a objektů (Serial, Wire ...) pro C++ a programuje se v C++ (ořezaném o mnohé standardní věci, protože malé Arduino nepojme bez následků velké standardní knihovny a tak nějak v základu postrádá věci jako standardní vstup, výstup a error, nebo práci se soubory)

Nicméně pokud chceš to Arduino používat i pro větší projekty, než jen blikání LEDkou, tak vřele doporučuji se na to C/C++ podívat - a časem tě možná zaujme i assembler, až se dostaneš do úzkých kvůli velikosti paměti a omezení výkonu - který Wiring omezuje ještě víc a přístup "nemusím ničemu rozumět, prostě zkopíruju něco z netu a případně tam přidám ještě pár delay() navíc, stejně o nic nejde" v komunitě obvyklý to ještě umozní)

(Jo, digitalRead() je fajn, že to pochopí každý, ale trvá "strašně dlouho" - 41 cyklů než vůbec začne číst ten pin a pak ještě nějaké další, než vrátí hodnotu. Samotné přečtení toho pinu trvá jednu jedinou instrukci ( navíc můžeš jednou jedinou instrukcí načíst i víc pinů vedle sebe ) - takže pokud potřebuješ něco opravdu rychle, tak Arduino přístup "nebojte se, nemusíte tomu moc rozumět" brzy přestane stačit, protože cena za něj je řádově nižší výkon, než ten HW dovoluje)

RobertN
Příspěvky: 5
Registrován: 09 lis 2018, 09:10
Reputation: 0

Re: porovnání obsahu řetězce po seriové lince

Příspěvek od RobertN » 13 úno 2019, 19:43

Dobrý večer všem. Pro sepsání kódu jsem se různě inspiroval. Není to celé, jen výtah toho, co jsem chtěl řešit.
Proměnou odpoved jsem měl definovanou jako String.
Chtěl jsem zkusit hledat shodu v celém řetězci, který mi odpoví seriová linka obecně, nejen z GSM modulu. To po znacích mi funguje také a děkuji za inspiraci.
Děkuji gilhad za vysvětlení, že char * je ukazatel (pointer). Když jsem totiž zadal "char *" do Google tak mi to bralo, že hvězdička je zástupný znak a nic jsem nemohl dohledat :D
Po zadání "ukazatel c++" jsem už našel spoustu článků, ze kterých jsem to pochopil. K Assembleru sice už ve svém věku nedojdu, ale rozhodně jsem se zase mohl posunout někam dál.

Řešení mého problému jsem ale nakonec nalezl v příkazu "toCharArray" . Níže je již upravený kód, opět je to jen výřez, ale myslím, že to hlavní tam je.

Ještě jednou všem moc díky!

Kód: Vybrat vše


#define komunikaceSIM800L Serial1
#define LED 40
char s;
String odpoved;
.
.
.
 { 

// vyčisti buffer
while (komunikaceSIM800L.available() > 0) {
    s = komunikaceSIM800L.read();           
     }

komunikaceSIM800L.println("AT+CREG?");

delay(100);
    
  while (komunikaceSIM800L.available() > 0) {
    s = komunikaceSIM800L.read();           
    odpoved = odpoved+s;  

  } 
        
  char odpovedprevod[odpoved.length()+1];
    odpoved.toCharArray(odpovedprevod,odpoved.length()+1); 

 if(strstr(odpovedprevod, "+CREG: 0,1") != NULL)

   {
  
    digitalWrite(LED,HIGH);
  Serial.println("===== ANO - JE REGISTROVAN =================");
  }
  else
  {
    digitalWrite(LED,LOW);
  Serial.println(" XXXX  NE - NENI REGISTROVAN XXXXX");

  }


  
odpoved = "";


Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 1 host