Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

Seri port ve string işlemleri

Başlatan assist, 15 Ocak 2011, 12:10:15

assist

merhaba arkadaşlar

seri prottan veri okuma ve işleme ile ilgili kod yazmaya çalışıyorum ama bir yerde takıldım. Telit marka GSM/GPRS modem üzerinden gelen bilgiyi işlemede sıkıntı çekiyorum. sebebi ise modemin komutlara farklı sürelerde farklı cevaplar göndermesi ve sık sık <CR> karakteri göndermesi.

bu yüzden şöyle bir yol izlemeye karar verdim

1. herhangi bir veri gelinceye kadar bekle
2. <CR>  karakterine aldırmadan gelen tüm veriyi bir diziye kaydet, veri akışı kesilince geri dön
3. gelen veride belirli bir kelime ara
4. istenilen kelime varsa birsonraki adıma geç, yoksa komutu istenilen kelime gelinceye kadar tekrarla

CCS örnek ve hazır kütüphane kodları üzerinde bazı değişikliklerle şu kodu yazdım:

char answer[60],ans[60];
int res;


char timed_getc() 
{
   long timeout;
   char retval;

   timeout=0;
   while(!kbhit() && (++timeout< (KEYHIT_DELAY*100)))
      delay_us(10);
   if(kbhit())
      retval = getc();
   else
      retval = 0;
   return(retval);
}

void get_coming(char* s)
{

char c='A';
int len=0;

c=getc();
if(c>15){ s[len++]=c;}

    do
    {
    c=timed_getc();
    if(c>15)
    if(len<57)
    { s[len++]=c;}
    }
      while(c!=0);
   s[len]=0;

  

}



int instr(char *s1, char *s2)
{
   char *s, *t;

   while (*s1)
   {
      for(s = s1, t = s2; *t && (*s == *t); ++s, ++t);

      if (*t == '\0')return 1;
      ++s1;

   }
   return 0;
}


void test()
{
int result;
strcpy(ans,"OK");

  printf( "enter including OK \n");
  get_coming(answer);
  
   result = instr( answer, ans );
  if( !result) printf( "Could not find \r");
  else printf( "Found a substring\r");

delay_ms(500);
}


test fonksiyonu proteusta düzgün çalışıyor fakat kodu işlemciye yükleyip modem üzerinde çalıştırınca bir süre sonra tıkanıyor gelen veriyi almamaya başlıyor.

benim pointer ve stringlerle pek aram yoktur. sorun onlarda olabilir diye düşünüyorum. acaba neyi yalnış yapıyorum?

kodun tamamı linkteki dosyada...

http://www.etproje.com/pic/RemoteController.rar



Not: kod ticari değil Öğrenme amaçlıdır...

isa_olcer

Aynı sorunu bende yaşıyorum bir cihazdan string şeklinde veri geliyor fakat sonunda <CR> (carriage return) karakteri göndermiyor. Bu nedenle gets ile veri alınmıyor, getc ile geliyor. Sorum getc komutu ile nasıl string alabilirim?

fide

İsa merhaba.
Öncelikle kullandığın geliştirme ortamı hk bilgi verirsen yardımcı olmamız kolaylaşır.
Gets ve gtc komutlarından pic ve ccs c kullandığını tahmin ediyorum.

Öncelikle diziler (array) anlamaya çalış.

Sonrasında diziye ekleme ve diziyi bölmek konularına bak.

http://fidenetgaraj.blogspot.com/2018/06/pic-mcuyu-internet-baglayalm.html?m=1

Yukardaki linkte sorunun cevabı var. İkeri düzey içinde yardımı olur.
Aynı başlık picproje forumda da var.

Veri alma işini çözdükten sonra gerekirse tekrar yardımcı oluruz.

Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

Pyrodigy

#3
İşlemcini, hızını, iletişim arayüz ayarlarını, nasıl data alım yaptığını (Kesme içinde mi), alım esnasında ki hata ayıklama kodlarını paylaşmamışsın.
Birde;
instr( answer, ans )
Bu işlem ne yapıyor ?
Persistance is the name of the game in this business....

fide

Alıntı yapılan: Pyrodigy - 01 Nisan 2020, 13:15:50İşlemcini, hızını, iletişim arayüz ayarlarını, nasıl data alım yaptığını (Kesme içinde mi), alım esnasında ki hata ayıklama kodlarını paylaşmamışsın.
Birde;
instr( answer, ans )
Bu işlem ne yapıyor ?
@assist iletisi 9 yıllık. Yeni değil. @isa_olcer yeni soru sormuş.
Bu arada gsm modüller cr karakteri gönderir ama crlf (/r/n) olarak gönderir.

Komut /r/nOK/r/n şeklinde cevap verebilir yada echo açıksa AT/r/nOk/r/n cevabı verir.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

SB7

Merhabalar benimde gps verilerini ayırma konusunda başım dertte. Yaklaşık 1 haftadır sorunu çözemiyorum yardımcı olursanız sevinirim.

Kullandığım GSM/GPS modülü SIM908.
Gps i aktifleştirmek ve verileri alma konusunda bir sıkıntım yok. Arduino uno kullanarak yazdığım gps fonksiyonları da bu şekilde.
#include <SoftwareSerial.h>

SoftwareSerial SIM(10, 11);

String konum;
int _timeout; String _tampon; 

String _serialOku();
String gps_konum();


void setup() {
SIM.begin(9600);
Serial.begin(9600); 

}
void loop() {

String deger = gps_konum();
Serial.print("deger="); Serial.print(deger); delay(1000);



}


String _serialOku(){
  _timeout=0;
  while  (!SIM.available() && _timeout < 12000  ) 
  {
    delay(13);
    _timeout++;
  }
  if (SIM.available()) {
   return SIM.readString();
  }
}


String gps_konum()
{
String koordinat;
  SIM.print (F("AT+CGPSINF=32\r"));
  koordinat=_serialOku();
  return koordinat;
}

Bu kodların çıktısı olarak seri port ekranında aldığım değerler de bu şekildedir:

deger=AT+CGPSINF=32

32,171242.000,A,3811.111111,N,3911.111111,E,0.00,0.00,010420,,E,A
OK

strtok fonksiyonu kullanarak aşağıdaki gibi bir veriyi virgüller yardımıyla parçalarına ayırabiliyorum.
String konum;="32,171205.000,A,3811.111111,N,3911.111111,E,0.00,307.27,290320,,E,A";

Ancak benim Seri Port ekranında aldığım veriler çok karmaşık. Bu yüzden sürekli boş değer seri port ekranında görünüyor. Alt satır ve boşlukları ayrıştırmak için ne yapmam gerekiyor. Ya da Seri port ekranında aldığım verileri nasıl istediğim formata dönüştürebilirim ?
-SB7

fide

Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

SB7

@fide Hocam Allah sizden razı olsun. Verdiğiniz siteler çok işime yaradı. 1 haftadır uğraştığım şeylerin hazır komutları varmış. Proje birkaç saat içinde bitti . Çok teşekkürler :)
-SB7

isa_olcer

CCS kullanıyorum. Teraziden RS232 ile tartım değeri alıyorum. Veri saniye on defa bu şekilde geliyor 45Kg için "41 63 7F 30 34 35" sorun gelen bilginin sonunda CR (0D) karakteri yok bu yüzden gets komutu çalışmıyor. Getc komutu ile tek tek aldığımda geliyor ama sıralama sürekli karışıyor. "7F" sabit karakter. Getc koduyla düzgün string almam için ne yapmalıyım?

z

getc ile 7F karakteri gelinceye kadar her geleni oku.

7F karakteri gelince tuzak kuruldu demektir. Peş peşe 3 tane getc ile gelen datayı yakala.

7F'in önünde bekleyen 41 63 benzeri veriler de lazım olacaksa onları da zaten 7F den önce okumuştun ordan kullanırsın.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

fide

#10
Ccs c de kbhit() komutu var. Yeni bir karakter gelince true oluyor.
İnterrupt içinde beklemek uygun değil ama sorunu çözmek için bazen 1-2 milisaniye beklemek gerekiyor.

En basit tabirle şöyle yap.
Baudrate 9600olsun. Bu da saniyede 1000byte civarında veri yapar.

1saniye /1000 = 1 milisaniye

İnterrupt içine girince ilk byte'ı al
Sonra 1ms bekle, kbhit() kontrolü yap. Veri varsa diziye al, yoksa string diziyi /0 karakteri ile sonlandır.

İleriki aşamada şöyle yapabilirsin.
char strArr[25];
strCnt=0;
While( sayac<1000)
{
if (kbhit())
{data=getc() ;
strArr[strCnt] =data;
strCnt++;
strArr[strCnt] ='/0' ;
sayac=0;}
delay_us(10);
sayac++;
}
Denenebilir.
strCnt değişkeni alınan datanın string dizi içinde tutulacağı yeri bildirir.
Sayac değişkeni ise sürekli yukarı doğru sayar. Her defasında 10 mikrosaniye bekler. Veri alınca sıfırlanır.
1000x 10us =10 milisaniye kadar yeni karakter için bekler. Gelmezse döngüden çıkar.
Diziyi işleyip istediğin veriyi almak sana kalmış.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com