Arduino ile Veri Bölme ve Servo – Parse, Split

Elinizde “1:565-2:1012-3:765-4:432” bunun gibi bir veri var ve Arduino ile bunu parçalara ayırıp, servolarınıza veya başka bir yere aktarmak mı istiyorsunuz.

Mesela 565 olan 1. değeri s1 diye bir değişkene aktarmak istiyorsunuz. Yapınız sabit ama karakter sayısı değişken mi? O zaman bu yazı tam size göre. Neyse, bu kadar reklam yeter.

Öncelikle sabit yapıdan kastım, sürekli 4 adet veri göndermek istemeniz mesela. değerlerin kaç basamaklı olduğu -substring’in aksine- hiç önemli değil (ilgili veri tipi ram sınırları içerisindeyse).

Örneğin PHP veya Python kullansaydık, kolaylıkla parse, regex gibi yöntemleri kullanabilirdik. Ne yazıkki C’de direkt olarak parse veya regex yok (Harici kütüphaneleri saymıyorum tabii ki.). Hemen nasıl yapabileceğimizi anlatıyorum:

Kullanacağımız fonksiyon sscanf. Bu mübarek komut bizi bir sürü zorluktan kurtarıyor. Kullanımı ise şöyle:

int sscanf(const char *str, const char *format, ...)

Str bizim giriş verimiz iken, format ise veri yapımızdır. Virgülden sonra ise üzerine yazılacak değişkenler geliyor. Return olarak da çıkan veri sayısını veriyor.

Başlığa her ne kadar arduino yazsam da bu bir C kodu. Arduino zaten C/C++ ile yazılıyor. Peki bu kodu örnek olarak nasıl kullanabiliriz?

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  int s1key, s2key, s3key; //keyler
  int s1, s2, s3; //değerler
  char* mesaj = "1:565-2:1012-3:765-4:432";  //gelen veri
  int n = sscanf(mesaj, "%d:%d-%d:%d-%d:%d", &s1key, &s1, &s2key, &s2, &s3key, &s3); // sayi:sayi-sayi:sayi-sayi:sayi şeklinde gelmesi lazım. 
  Serial.print(F("n="));Serial.println(n); //çıkarılan toplam key ve value sayısı.
  Serial.print(F("key1="));Serial.print(s1key);Serial.print(F(", s1="));Serial.println(s1); //bu kısımlar sadece yazdırmak için. direkt s1 değişkenini kullanabilirsin.
  Serial.print(F("key2="));Serial.print(s2key);Serial.print(F(", s2="));Serial.println(s2);
  Serial.print(F("key3="));Serial.print(s3key);Serial.print(F(", s3="));Serial.println(s3);
  
}

void loop() {
  // put your main code here, to run repeatedly:

}

Mesaj adlı giriş verimizi Key ve Value‘lere (Anahtarlara ve Değerlere) böldük. Ardından bunları Serial’e yazdırdık. Bu verileri

analogWrite(9,s1);

gibi de kullanabilirsiniz.

Üstteki kodumuzun çıktısı ise şöyle:

n=6
key1=1, s1=565
key2=2, s2=1012
key3=3, s3=765

Bir sorunuz olursa buralardayım. Yorum bırakabilirsiniz. Sağlıcakla kalın.

Bir kısmı https://arduino.stackexchange.com/a/20829 adresinden düzenlenmiştir. 

20 Comments on "Arduino ile Veri Bölme ve Servo – Parse, Split"

  1. hocam merhaba,
    Gps modülden gelen 8 satır kodun içinden sadece 1 tanesini alıp plc aktarmak istiyorum bunu bu yöntemle çözebilir miyim tavsiyeniz nedir? İyi çalışmalar dilerim..

  2. Merhabalar ;
    Seri porttan string olarak ” B 123456 ” böyle bir veri alıyorum ben bunun tüm verilerini
    integer olarak tek tek alıp işlemek istiyorum. verim sabit değil.

    if (Serial.available() > 0) {
    c = Serial.readString();

    c değişkenimden veriyi alıp değerlendireceğim nasıl yaparım selamlar.

    • Metin Özyıldırım | 18 Şubat 2018 at 00:10 | Cevapla

      Tüm verilerini derken 1,2,3 gibi her basamağı mı? Yoksa sadece b’den mi kurtulmak istiyorsunuz?

      • merhabalar; aradan rast gele hanelerden veri almak istiyorum. tek tek veya çoklu olarak. şimdilik rakamlarla işim var ama ilerde harflerlede işlem yapmam gerekebilir. örnek verirseniz sevinirim.

        • Metin Özyıldırım | 18 Şubat 2018 at 16:43 | Cevapla

          Tam olarak anlamasam da ‘c’ değişkenine atadığınız verinin istediğiniz karakterini c[0] şeklinde alabilirsiniz. c=’asd’ durumunda size a döndürür. c[1] ise s döndürür.

          • feyyaz kurt | 18 Şubat 2018 at 17:52 |

            şöyle diyeyim, c bir string değer. bunun içinde örneğin “ABC 1234567890” gibi bir değer var. ben bunun içinden “45678” çekip almak istiyorum. ve tipinide integer çevirmek istiyorum.

          • feyyaz kurt | 21 Şubat 2018 at 13:33 |

            merhabalar olayı aştık. yazılım konusunda uzman bir arkadaş senin ip ucun substring dedi. burdan yola çıkarak

            if (Serial.available() > 0) {
            c = Serial.readString();

            if (c.substring(0,1) == “B”)

            {
            d=c.substring(2, 6) ;
            e=c.substring(0,1) ;
            b=(d.toInt());
            Serial.println(c);
            Serial.println(b);
            Serial.println(e);
            }
            else
            {
            b=0;
            }

            bu şekilde işi çözdüm. teşekkürler

  3. alper güzeler | 2 Mart 2018 at 21:46 | Cevapla

    Hocam merhaba umarım mesajımı görürsünüz .Projem için sscanf kullanmam lazım ve bir sorun yaşıyorum.C# üzerinden arduinonun seriport una 2 adet rakamlardan oluşacak veri göndereceğim.örneğin 2:30 veya 5:45 bu şekilde :(iki nokta) ile ayrılmış 2 adet veri gelecek. Arduinodan ise seriporttan bu veriyi okuyup VOID LOOP içinde sscanf ile ayırmak istiyorum ve değişkenlere atamak istiyorum.Fakat sorun yaşıyorum. Yabancı kaynaklardan da araştırdım bakmadığım yer kalmadı fakat şu kadar basit görünen şeyi bir türlü yapamadım.Projemin temelini oluşturuyor.Lütfen bu dediğimi yapabilecek kısa örnek bir kod yazabilir misiniz? Ben onu kendime göre düzenlerim.Çok teşekkür ederim şimdiden…

    • Metin Özyıldırım | 4 Mart 2018 at 17:18 | Cevapla

      Alper hocam yukarıdaki örnek tam olarak dediğinizi yapıyor. C# ile gönderebiliyorsanız gerisi aşağıdaki gibi.
      int veri1,veri2;
      sscanf(mesaj, “%d:%d”, &veri1, &veri2);

  4. alper güzeler | 2 Mart 2018 at 21:55 | Cevapla

    örneğin
    void setup() {
    // put your setup code here, to run once:
    Serial.begin(9600);

    }

    void loop() {

    if(Serial.available()>0){
    int a,b;
    char c=Serial.read();
    sscanf(c,”%d:%d”,&a,&b);
    Serial.println(a);
    Serial.println(b);
    }

    }

    şeklinde bir kod yazdım fakat seriport tan örneğin 1:2 değerini gönderdiğimde bana çıkışta gösterdiği şey

    -23550
    -23294
    -23550
    -23294
    -23550
    -23294
    -23550
    -23294

    oluyor.Baudrate i de kontrol ettim.Sorunu 2 gündür çözemedim.Yardımcı olursanız çok sevinirim.

    • Metin Özyıldırım | 4 Mart 2018 at 19:39 | Cevapla

      serialRead = Serial.read();
      char charBuf[serialRead.length() + 1];
      serialRead.toCharArray(charBuf, serialRead.length());
      sscanf(charBuf,”%d:%d”,&a,&b)

      Elimde arduino yok şu anda. Bu şekilde dene, olmazsa Serial.readString() olarak değiştir. Kolay gelsin.

  5. alper güzeler | 7 Mart 2018 at 23:42 | Cevapla

    hocam merhaba yine rahatsız ediyorum fakat bir sorunum daha var. tek iki nokta(:) ile ayırma işlemini hallettim sayenizde.Ör. 2:44 1:45 gibi…Fakat bir de 3 adet veriyi aynı şekilde ayırmam lazım fakat sorun yaşıyorum.Ör. 34:66:37 veya 4:123:5 gibi üç veriden oluşursa nasıl bu verileri ayırabilirim.Şimdiden teşekkür ederim…

    String serialRead = Serial.readString();
    int a,b;
    char charBuf[serialRead.length() + 1];
    serialRead.toCharArray(charBuf, serialRead.length());
    sscanf(charBuf,”%d:%d”,&a,&b);

    ikili ayırmada kullandığım kod.
    Bir sorum daha vardı. String uzunluğunu neden 1 arttırdık?

    • Metin Özyıldırım | 8 Mart 2018 at 08:20 | Cevapla

      Merhabalar öncelikle, +1 arttırılmasının sebebi char arrayde sona null byte () için yer bıraktık. Üç adet veri alabilmek için :%d ekleyebilirsiniz bir tane daha. Eğer ne zaman iki ne zaman üç adet veri geleceği belli değilse strtok komutunu inceleyebilirsiniz.

  6. merhabalar ,
    benim ardiuno dan String olarak nem=32 isi=23 gibi bir değeri esp8266 nodemcu ya gönderiyorm .karşı tarafta anlamlandırmak istiyorumi
    yani 32 rakamıı cekmek istiyorum

  7. Merhabalar,
    bnim elimdeki ardiuno uno dan esp8266 nodemcu ya yon=KB isi=24 gibi bir string değişken yolluyorum .
    ben bu değişken arasında KB ve 24 değişkenlerini esp tarafında kullanmak için anlamlandırmak istiyorum.

    if (swSer.available() > 0) {

    c=swSer.read();
    Serial.write(c);

    }

    • Metin Özyıldırım | 11 Nisan 2018 at 19:38 | Cevapla

      Hiç Esp kullanmadım ama o da arduino destekliyor diye biliyorum. Yukarıdaki -veya yorumlardaki- örnekler gibi yapabilirsiniz. sscanf(“yon=%s isi=%d”, &yon, &isi) gibi bişey olacaktır.

Leave a comment

Your email address will not be published.


*