Forum: Diğer Konular RSS
C++ seri port kontrolü işlev dışındaki string değişkenin deger almaması
erdem (Moderatör) #1
Üye Tem 2009 tarihinden beri · 984 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: C++ seri port kontrolü işlev dışındaki string değişkenin deger almaması
#include <iostream>
#include <string>
#include "serial/serial.h"
 
using std::cout;    using std::string;
 
typedef serial::Serial SeriPort;
 
const string  veriGonder(SeriPort & seriPort,  string ileti)
{
    const size_t iletiUzunlugu = seriPort.write(ileti);
 
    const string okunanIleti = seriPort.readline(iletiUzunlugu, "\n");
 
    seriPort.waitReadable();
 
    if (okunanIleti.size() == iletiUzunlugu)
    {
        cout << "Okunan ileti = " << okunanIleti << '\n';
        return okunanIleti;
    }
    else
    {
        cout << "Veri okuma başarısız" << '\n';
        veriGonder(seriPort, ileti);
    }
}
 
 
int main()
{
    SeriPort seriPort("/dev/ttyACM0", 9600, serial::Timeout::simpleTimeout(1000));
 
    cout << "Seri port açık mı ?\n";
 
    if (seriPort.isOpen())
        cout << "Evet\n";
    else
        cout << "Hayır\n";
 
    const string ileti = "Merhaba\n";
 
 
    const string okunan = veriGonder(seriPort, ileti);
    cout << "İşlev dışındaki okunan değişkeni =  " << okunan << '\n';
    return 0;
}

Gene seri porta veri gönderen bir uygulama üzerinde çalışıyorum. Seri portta Arduino bağlı. Programdan ne gönderirsem adeta yankı yaparak tekrar programa gönderiyor.

Ama şimdi asıl sorun buradaki C++ kodunda olabilir. Program çalıştırıldığında çıktısı şu şekilde:

$ ./seri1
Seri port açık mı ?
Evet
Veri okuma başarısız
Okunan ileti = Merhaba

İşlev dışındaki okunan değişkeni = 


Şöyle ki ilk kez veriGonder() işlevi çağrıldığında veriyi gönderiyor ama okuyamıyor. İkinci kez veriGonder() işlevini öz yinelemeli olarak çalıştırdığımızda veri gönderiyor bu sefer okuyor. Buraya kadar normal.

Hatta okunan ileti'yi işlev içinde yazıyoruz. Ama işlev dışında okunan değişkenine atamıyor.  :huh:
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Gözüme kod hatası çarpmıyor ama özyineleme olayı karıştırıyor: Acaba başarılı olmasının nedeni iki kere göndermek mi yoksa iki kere okumak mı; anlayamıyoruz. Bir de, başarısız olduğunda okunanIleti.size() herhalde 0, değil mi?

Ali
erdem (Moderatör) #3
Üye Tem 2009 tarihinden beri · 984 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Evet başarısız olduğunda okunanIleti.size() başarısız olduğunda 0 oluyor.

Başarılı olmamasının nedeninin seri portun çalışma mantığıyla ilgili olabileceğini düşünüyorum. Örnegin

Program Veri Gönder       Arduino Veriyi Geri Gönder       Program Veri Oku       
"Merhaba\n"                         Başarısız                                Başarısız
"Merhaba\n"                       "Merhaba\n"                             "Merhaba\n"
"Merhaba\n"                       "Merhaba\n"                             "Merhaba\n"

Ama farkettim ki ilk gönderilen veriden sonra doğru bir şekilde çalışıyor. O yüzden ilk seferinde rastgele bir veri göndererek o kısmı halletim.

Şimdi programı bir kütükten verileri okuyacak şekilde değiştirdim.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <fstream>
 
#include "serial/serial.h"
 
using std::cout;    using std::string;  using std::random_shuffle;
using std::vector;  using std::ifstream;
 
typedef serial::Serial SeriPort;
 
const string  veriGonder(SeriPort & seriPort, const string & ileti)
{
    const size_t iletiUzunlugu = seriPort.write(ileti);
 
    const string okunanIleti = seriPort.readline(iletiUzunlugu, "\n");
 
    seriPort.waitReadable();
 
    if (okunanIleti.size() == iletiUzunlugu)
    {
        return okunanIleti;
    }
    else
        return string("");
}
 
 
int main()
{
    SeriPort seriPort("/dev/ttyACM0", 9600, serial::Timeout::simpleTimeout(1000));
 
    cout << "Seri port açık mı ?\n";
 
    if (seriPort.isOpen())
        cout << "Evet\n";
    else
        cout << "Hayır\n";
 
    typedef vector<string> Kelimeler;
 
 
    Kelimeler kelimeler;
    string satir;
 
    ifstream giris ("kelimeler.txt");
    while (getline (giris, satir))
        kelimeler.push_back (satir);
 
    veriGonder(seriPort, "Başlıyor");
 
    for (int i = 0; i < kelimeler.size(); ++i)
    {
        random_shuffle(kelimeler.begin(), kelimeler.end());
        const string ileti = kelimeler[i] + "\n";
        string okunan = veriGonder(seriPort, ileti);
        cout << "Seri port okunan veri = " << okunan << '\n';
    }
 
    return 0;
}

Ama random_shuffle ile her seferinde rastgele bir karışım yapamıyoruz anladığım kadarıyla ..
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Neden yapılamayacağını anlamıyorum ama random_shuffle çağrısının for döngüsünden önce olacağını görebiliyorum: oku, karıştır, ve kullan.

Döngü içinde karıştırırsan, önceden gönderdiğin kelimelerin henüz göndermediğin indekslerde belirme olasılığı var.

Ali
erdem (Moderatör) #5
Üye Tem 2009 tarihinden beri · 984 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Evet haklısınız. random_shuffle'ı döngü dışına taşıdım.

Demek istediğim şuydu. Programı her çalıştırdığımda bu sırayla kelimeleri yazıyor.

$ ./seri1
Seri port açık mı ?
Evet
Seri port okunan veri = indirmeyecekleri

Seri port okunan veri = kuzeylilerden

Seri port okunan veri = toplanacağınız

Seri port okunan veri = donanımlarının


Ben istiyorum ki programı her çağırdığımda sözcükleri farklı karıştırsın.
erdem (Moderatör) #6
Üye Tem 2009 tarihinden beri · 984 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Tamam şimdi hallettim teşekkürler!   :-)

Rastgele sayı üretecini unutmuşum.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <fstream>
 
#include "serial/serial.h"
 
using std::cout;    using std::string;  using std::random_shuffle;
using std::vector;  using std::ifstream;
 
 
 
typedef serial::Serial SeriPort;
 
const string  veriGonder(SeriPort & seriPort, const string & ileti)
{
    const size_t iletiUzunlugu = seriPort.write(ileti);
 
    const string okunanIleti = seriPort.readline(iletiUzunlugu, "\n");
 
    seriPort.waitReadable();
 
    if (okunanIleti.size() == iletiUzunlugu)
    {
        return okunanIleti;
    }
    else
        return string("");
}
 
 
int main()
{
    SeriPort seriPort("/dev/ttyACM0", 9600, serial::Timeout::simpleTimeout(1000));
 
    cout << "Seri port açık mı ?\n";
 
    if (seriPort.isOpen())
        cout << "Evet\n";
    else
        cout << "Hayır\n";
 
    typedef vector<string> Kelimeler;
 
 
    Kelimeler kelimeler;
    string satir;
 
    ifstream giris ("kelimeler.txt");
    while (getline (giris, satir))
        kelimeler.push_back (satir);
 
    veriGonder(seriPort, "Başlıyor");
 
    srand(time(NULL));
    random_shuffle(kelimeler.begin(), kelimeler.end());
    for (int i = 0; i < kelimeler.size(); ++i)
    {
        const string ileti = kelimeler[i] + "\n";
        string okunan = veriGonder(seriPort, ileti);
        cout << "Seri port okunan veri = " << okunan << '\n';
    }
 
    return 0;
}
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-23, 23:32:26 (UTC -08:00)