C# datareceived event'i sorunu

Başlatan Ali_54, 10 Kasım 2011, 12:17:06

Ali_54

merhaba logicmemo,

yukardaki string buffer; lı kod çalışmadı, ama zaten değiştirdim. galiba sıkıntı şurada;

   string k =readexciting; dediğimde oluyor. ama data receive eventine bi de
  textbox1.text+=k;   gibi bişey koyduğumda hata veriyor. ama bu atama datareceive eventinden koduunu timer içine aldım,
yani tarama yoluyla kontrol ediyor textboxa atmak için. o zaman çalıştı işte. data receive eventinde hata veriyor.
1 harf öğretenin 4 gün kölesi olurum.

Ali_54

yani şöyle çalışıyor şu an:

 
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace seri_iletişim_read_send
{
    public partial class Form1 : Form
    {
        string gelen="";
        string gelen2="";
        public Form1()
        {
            InitializeComponent();
        }

        private void seriport_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
          
                gelen = serialPort1.ReadExisting();
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)
            { serialPort1.Open(); }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text += gelen;
           
            
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            
            if (gelen != gelen2)
            { textBox1.Text += gelen;  }
      
            gelen2 = gelen;
            
        }

   
    }
}
1 harf öğretenin 4 gün kölesi olurum.

lojikmemo1


Aynı nesneye hem bir olay yada timer den hem de kullanıcı kodundan erişildiğinde bu hatayı vermesi normal ama senin kodunda bu da yok. Senin çözüm yönteminde textbox'a, seri port olayı doğrudan değil de timer'in clock olayından dolaylı erişiliyor. Bu çözüm uygun fakat ilgili kodda gerekmemesi lazımdı.
İnsanlara Akılları Ölçüsünde Söz Söyleyiniz.

mir_as82

Kodunu aşağıdaki gibi değişirsen sonuç alabilirsin. Fakat içerdeki "UpdateUI(Updating)" ni yerine farklı birşey yazman gerekebilir. Sonuç alırsan hangi kodu yazdığını da bize bildirirsen iyi olur.

private void seriport_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
         
                gelen = serialPort1.ReadExisting();
                 
                this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new UpdateUI(Updating));


        }

Ali_54

1 harf öğretenin 4 gün kölesi olurum.

RcALTIN

Alıntı yapılan: Ali_54 - 16 Kasım 2011, 16:21:29
merhaba logicmemo,

yukardaki string buffer; lı kod çalışmadı, ama zaten değiştirdim. galiba sıkıntı şurada;

   string k =readexciting; dediğimde oluyor. ama data receive eventine bi de
  textbox1.text+=k;   gibi bişey koyduğumda hata veriyor. ama bu atama datareceive eventinden koduunu timer içine aldım,
yani tarama yoluyla kontrol ediyor textboxa atmak için. o zaman çalıştı işte. data receive eventinde hata veriyor.

Kaç defa yazacağım bilmiyorum ne yapman gerektiğini, textbox dediğin nesne senin main thread'ına bağlıdır, burada oluşan bir nesnedir. Seriportun datareceived eventi kendine başka bir thread açar ve sürekli dinleme yapar ki böylece yeni data geldiğinde bunu alabilesin. Sen şimdi event içinde datayı alıyorsun, tutup bir başka thread'a ait textboxa yazdırmaya çalışıyorsun. Bu mümkün fakat derleyici sana "Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on." yani "Çapraz-iş parçacığı işlemi geçersiz ;textbox1 bu thread üzerinde oluşturulmamış ki" mealinde birşeyler söylüyor, ee o zaman nasıl mümkün? Tabiki, bu denetimi aşağıdaki kodu form_load eventine veya form constructor'ının içine yazarak devre dışı bırakırsan.
CheckForIllegalCrossThreadCalls = false;


umarım bu sefer sallarsın mesajımı, resmen zorla birşeyler öğretmeye çalışıyoruz yani, aynı konudaki aynı şeyleri yazan 3. mesajım...
KİMSEYİ ENGELLEDİĞİM YOK, ÖZEL İLETİ DEVRE DIŞI !

since1990

Alıntı Yapumarım bu sefer sallarsın mesajımı, resmen zorla birşeyler öğretmeye çalışıyoruz yani, aynı konudaki aynı şeyleri yazan 3. mesajım...
evet hocam ben kullanmıştım hatta şöyle bir not ta yazmıştınız.
Alıntı Yapyok aslında nasıl olması gerektiğini öğrenmek istiyorum diyorsan; araştırman gereken konular: delegate, invoke
Bu nedenle tekrar teşekkürler. :D
"Dinlenmemek üzere yola çıkanlar asla yorulmazlar. Türk gençliği, gayeye, idealizme durmadan ve yorulmadan yürüyecektir. Bütün ümidim gençliktedir." Mustafa Kemal Atatürk

Ali_54

rıdvan hocam, bahsettiğiniz düzeltmeyi denedim oldu. tam anlayamamıştım mesajınızı. bide gözümden kaçmış özür dilerim.
ben iyi bir programcı değilim,  tread kavramları çok önemli programcılık açısından, ama ben bu kavramlara henüz uzağım. yolu uzattığım için üzgünüm.  ama daha saygılı olmanızı beklerdim.
Alıntı yapılan: RcALTIN - 17 Kasım 2011, 01:01:21
Kaç defa yazacağım bilmiyorum ne yapman gerektiğini, textbox dediğin nesne senin main thread'ına bağlıdır, burada oluşan bir nesnedir. Seriportun datareceived eventi kendine başka bir thread açar ve sürekli dinleme yapar ki böylece yeni data geldiğinde bunu alabilesin. Sen şimdi event içinde datayı alıyorsun, tutup bir başka thread'a ait textboxa yazdırmaya çalışıyorsun. Bu mümkün fakat derleyici sana "Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on." yani "Çapraz-iş parçacığı işlemi geçersiz ;textbox1 bu thread üzerinde oluşturulmamış ki" mealinde birşeyler söylüyor, ee o zaman nasıl mümkün? Tabiki, bu denetimi aşağıdaki kodu form_load eventine veya form constructor'ının içine yazarak devre dışı bırakırsan.
CheckForIllegalCrossThreadCalls = false;


umarım bu sefer sallarsın mesajımı, resmen zorla birşeyler öğretmeye çalışıyoruz yani, aynı konudaki aynı şeyleri yazan 3. mesajım...
saygılar.
1 harf öğretenin 4 gün kölesi olurum.

RcALTIN

beni saygısız ilan ederek olsa da, çok saygılı bir insan oluşunuz neticesiyle 4. mesajıma en azından bir cevap vererek aynı zamanda en başından beri temennim olan haliyle kendi sorununuzu çözüp kendinize bir iyilik yapmış olduğunuz için teşekkür ederim. azimli ve her bilgiyi değerlendiren bir yapınız olduğunu gördüm, çok büyük bir programcı olacağınızın ışıltısını daha şimdiden yansıtıyorsunuz, buna yürekten inanıyorum.  :-* bu arada adım rıdvan değil recep, kullanıcı adımın altında son 2 yıldır yazdığı gibi...
KİMSEYİ ENGELLEDİĞİM YOK, ÖZEL İLETİ DEVRE DIŞI !

Ali_54

receb bey,
mesajınız dikkatimden kacmıştı dedim. ve bunun icin özür diledim. kasıtlı olarak yapmadım. yanıtlarınız icin teşekkürler.
1 harf öğretenin 4 gün kölesi olurum.

microlight

konu  epeyice   eski  ama   yeni  bir konu işgali yapmak  istemedim.

pc den  pıc e  123  verisini  gönderince  lcd  de  sadece  yüzler  hanesi  görünüyor    şu  şelide  tavsiye eden oldu
Her iki yöne yolladığın bilgilerin sonuna bir adet 10 (line feed)ve 1 adet 13 (carriage return) ekle sorun ortadan kalkar.
  eğer yukarıdaki satır eksiz  bir  önri ise nasıl  ekilyeceğim 10,13'  çünkü  csharp a  yeni  başladım.c# uygulamalı  vidolu  dersler  var  ama  seri  port  ile ilgili olanına  rastlamadım  araştırdımda.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace serı
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            int a = MousePosition.X;
            int b = MousePosition.Y;
            textBox3.Text = a.ToString();
            textBox4.Text = b.ToString();

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer1.Start();
            timer1.Interval = 1;
         
        
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)
            {
               serialPort1.Open();
            }
            textBox1.Text = textBox5.Text;
            serialPort1.WriteLine(textBox5.Text);
            serialPort1.Close();
}
private void button2_Click(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)
            {
                serialPort1.Open();
            }   
    textBox2.Text = serialPort1.ReadLine();
    serialPort1.Close();    
            
}

    }
}


pbp kodları ise

ADCON1=7
DEFINE OSC 4
INCLUDE "TANIMLCD"
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 25 ' 2400 Baud @ 4MHz, 0,17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
'-------------------------VARIABLES---------------------------------------------
Cnt       VAR byte' Cnt is a word variable
inputData1 var byte' variable to receive data into
TEMP      var BYTE 52
POZ        VAR  BYTE
SONUC      VAR BYTE
DENEME     VAR BYTE
POZ=0:inputData1 =0:Cnt=0:SONUC=0:DENEME=123

SYMBOL GIE  =INTCON.7   'genel interruptları açıyor
SYMBOL PEIE =INTCON.6   'peripheralinterruptları açıyor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit
symbol led1=PORTA.0
SYMBOL Led2=PORTA.1
'---------------------------INITIALISATION--------------------------------------
RCIE=1
PEIE=1
GIE=1
INTCON=%11000000
ON INTERRUPT GOTO INT
PAUSE 500:LCDOUT $FE,1:LOW PORTB.2
 
START:
LCDOUT $FE,$80,CNT,"  ",Cnt 
 IF POZ<=0 THEN
 poz=poz+1
 HSerOut  ["bu devre ete hocadan  alintidir. ETE1 ve ETEA ile  led  kontrolu yapilir",10,13]  
 HSerOut  ["pic pc den mous X ve Y koordinat bilgisini alir",10,13]    
 ENDIF 
goto start

DISABLE
INT:
    GIE=0
    hSerIn ,[WAIT ("ETE"),INPUTDATA1]
    Cnt=inputdata1
    TEMP=RCREG
    GIE=1
    Resume
enable
END

microlight

yardımcı olurmusunuz  ustalar  kimse  cevap   yazmamış

microlight


lojikmemo1

Merhaba

serialPort1.WriteLine(textBox5.Text); komutu ile seri porttan giden veri tek başına bir 123 (integer veya byte) değildir. Senin verin '1'  '2'  '3' şeklide char tipinde sıra ile gider. Ayrıca buradaki '1' normla 1 sayısı değil ASCI table deki 1 dir. İşlemci kodunu tam inceleyemedim fakat işlemcin char tipinde veri alacak şekilde yazılım barındırıyorsa tek yapman gereken 3 tane char değeri alıp lcd ye basmak. Zaten bu yüzden sadece yüzler hanesi görünüyordur.

Kolay Gelsin.
İnsanlara Akılları Ölçüsünde Söz Söyleyiniz.

Gökhan BEKEN

Özel mesaj okumuyorum, lütfen göndermeyin.