Picproje Elektronik Sitesi

DERLEYİCİLER => CCS C => Konuyu başlatan: assist - 15 Ocak 2011, 12:10:15

Başlık: Seri port ve string işlemleri
Gönderen: assist - 15 Ocak 2011, 12:10:15
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 (http://www.etproje.com/pic/RemoteController.rar)



Not: kod ticari değil Öğrenme amaçlıdır...
Başlık: Ynt: Seri port ve string işlemleri
Gönderen: isa_olcer - 01 Nisan 2020, 08:09:22
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?
Başlık: Ynt: Seri port ve string işlemleri
Gönderen: fide - 01 Nisan 2020, 09:25:51
İ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.

Başlık: Ynt: Seri port ve string işlemleri
Gönderen: 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 ?
Başlık: Ynt: Seri port ve string işlemleri
Gönderen: fide - 01 Nisan 2020, 14:04:50
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.
Başlık: Ynt: Seri port ve string işlemleri
Gönderen: SB7 - 01 Nisan 2020, 20:22:57
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 ?
Başlık: Ynt: Seri port ve string işlemleri
Gönderen: fide - 01 Nisan 2020, 20:31:32
https://www.hackster.io/FiDeNet/sms-location-info-with-arduino-telit-gm862gps-2d3076 (https://www.hackster.io/FiDeNet/sms-location-info-with-arduino-telit-gm862gps-2d3076)

https://www.hackster.io/FiDeNet/sms-controlled-relays-and-leds-2906ff (https://www.hackster.io/FiDeNet/sms-controlled-relays-and-leds-2906ff)

Yukardaki iki proje de gps ve gsm modül + arduino ile yapıldı. İstediğiniz yada istediğinize yakın kodlar mevcut olmalı.
Başlık: Ynt: Seri port ve string işlemleri
Gönderen: SB7 - 01 Nisan 2020, 22:45:19
@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 :)
Başlık: Ynt: Seri port ve string işlemleri
Gönderen: isa_olcer - 03 Nisan 2020, 06:46:19
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?
Başlık: Ynt: Seri port ve string işlemleri
Gönderen: z - 03 Nisan 2020, 07:25:32
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.
Başlık: Ynt: Seri port ve string işlemleri
Gönderen: fide - 03 Nisan 2020, 08:05:04
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ış.