Seri Porttan String Alma ve ayırma

Başlatan Mucit23, 23 Mayıs 2015, 23:50:09

Mucit23

Bluetooth ile haberleşen Arduino için yazılmış olan bir android program var. HC-05 Bluetooth modülü kullanarak Android programdan veri okuyabiliyorum. Program her bir karakter gönderdiğinde uart kesmesi oluşuyor. Buraya kadar sıkıntı yok. Donanım problemsiz bir şekilde çalışıyor.

Sorun yazılımda.

Android programı bluetooth ile aşağıdaki gibi veriler gönderiyor.

*11|11|5#
*11|11|39#
*11|11|255#

'*' karakteri paketin başını '#' karakteri ise paketin sonunu bildiriyor. Aradaki '|' karakteri ise veriler arası ayrımı yapıyor.

Baştaki iki haneli 11 verisini ayrı bir diziye, ortadaki 11 verisini başka bir diziye ve en sondaki 0-255 arası değişen veriyi ise başka bir diziye char olarak yüklemem gerekiyor. Bu paketi sırayla almayı bir türlü yapamadım. Bu işlevsel olarak nasıl yapabilirim?

superconductor

Hocam pek şık değil farkındayım ama umarım yardımcı olur.
İlk iki verinin uzunluğunu sabit olarak düşündüm.

char rx1[20]="*11|11|255#";     //Ham paket
int buffer[3];                              //ayrılmış veri dizisi

func(rx1,buffer);                        //Kullanım örneği


void func(char *rx, int *buffer)
{
    int index=0;
    char temp=0;
    do
    {
        temp=rx[++index];
        rx[index]=rx[index]-48;
    }
    while(temp!=0);

    buffer[0]=((rx[1])*10)+rx[2];

    buffer[1]=(rx[4]*10)+rx[5];

    if(index==9)          buffer[2]=rx[7];
    else if(index==10) buffer[2]=rx[8]+rx[7]*10;
    else if(index==11) buffer[2]=rx[9]+rx[8]*10+rx[7]*100;
}


bunun yerine sscanf fonksiyonuda kullanılabilir sanırım.

Mucit23

Teşekkür ederim.

Gerçekten bayağı uğraştım ama bende yaptım. Biraz uzun olmuş olabilir ama gayet iyi çalışıyor.
#int_rda 
void uart_isr() 
{ 
         inchar=getc();
         
         if(index==0)
         {
           if(inchar==START_CMD_CHAR)
           {
             string[index]=inchar;
             index++;
           }
         }
         else
         {  
             string[index]=inchar;
             index++;
             if(inchar==END_CMD_CHAR)
             {
               type[0]=string[1];type[1]=string[2];
               if(index==8)//  kanal değeri tek hane gelmiş
               {
                 channel[0]=string[4];channel[1]="";
                 temp=1;
               }
               else
               {
                  channel[0]=string[4];channel[1]=string[5];
               }
               if(index==9-temp)
               {
                 value[0]=string[7-temp];
                 value[1]="";
                 value[2]="";
               }
               else if(index==10-temp)
               {
                 value[0]=string[7-temp];
                 value[1]=string[8-temp];
                 value[2]="";
               }
               else if(index==11-temp)
               {
                 value[0]=string[7-temp];
                 value[1]=string[8-temp];
                 value[2]=string[9-temp];
               }
               status=1;index=0;
             }  
        }
}       

iyildirim

#int_rda 
void uart_isr() 
{
    char ptr;
    
    inchar=getc();
        
    if (index==0)
    {
        if(inchar=='*')
        {
            index++;
            ptr = 0;
            type[1] = 0;
            channel[1] = 0;
            value[1] = 0; value[2] = 0;
        }
    }
    else
    {
        if (inchar == '|'){
            index++;
            ptr = 0;
        }
        else (inchar == '#'){
            index = 0;
        }
        else if (inchar>='0' && inchar<='9')
        {
            if (index==1)
                type[ptr] = inchar;
            else if (index==2)
                channel[ptr] = inchar;
            else (index==3)
                value[ptr] = inchar;
                
            ptr++;
        }
    }        
}

3 ayrı array yerine 2 boyutlu tek bir array kullanmak alttaki  if bloğundan da kurtarır. 

Bunun dışında struct bir yapıda tanımlanan  tip, kanal, value array leri  union kullanarak tek bir array olarak görüp,  kesme içinde "|" karakteri geldiğinde pointeri 0, 2, 4 e atayıp, gelen veriyi tek bir diziye alıp struct üzerinden okumak gibi yöntemlerde olabilir.

Mucit23

Hocam aslında iflerin çok olmasının sebebi gelen verinin boyutunun farklı olabilmesinden

Gelen veri *11|11|255# olabileceği gibi *11|1|3# de olabiliyor. Ayrıca *11|11|25#  gibi değerde gelebiliyor. Aslında zaten ilk başta yapılan dizi boyutunu takip ederek * ile # arasında gelen verileri string isimli diziye almak. Bu kısmı kolayca hallettim. Ama dizi boyutuna bağlı olarak string içerisindeki veriyi 3 ayrı parçaya ayırmak için bayağı didindim. Biraz fazla if kullanmış olabilirim bu yüzden. En son # karakteri alınınca parçalama işlemine başlıyorum. Bu yüzden bütün işlemin en sonunda koşullu kısım çalışıyor. Çok da kötü değil sanırım.

iyildirim

Çalışıyorsa sorun yok hocam.
Sadece kodun index e çok bağımlı olması  biraz sevimsiz geldi.