c# rs232 ile ilgili konular açılmmış, ancak receieve olayı ile ilgili kod paylaşan görmedim. gönderme olayını yapabiliyorum. ancak, veri alma olayı için datareceived nesnesini kullanmak gerekiyormuş. kesme gibi çalışan bu event le ilgili veri alma kodu paylaşabilir misiniz? form uygulaması için. mesela veriyi alıp textboxa, değişkene yada listbox a aktarmak gibi.
Merhaba
C# bilmiyorum ama VB.net ile kodlar böyle belki işinize yarar.
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim gelen As String = SerialPort1.ReadByte '
If gelen = 49 Then' yani hex 31 klavye rakkam"1"
gelen="1"
textbox1.text="1"
End If
End Sub
http://www.table-ascii.com/
Arkadaşım bende çok uğraştım aynı olayla sonradan bi arkadaşımdan yardım aldım ve olayı çözdüm ;)
Şöyle yapacaksın, yani ben öyle yaptım;
design penceresi varya hani buton falan ekleyebildiğin yer, işte oraya gelip toolboxtan serial port ekle pencerene.
(http://a1111.hizliresim.com/r/b/fv7s.jpg) (http://bit.ly/c25MCx)
Sonra serialport yazısına tıkla sağ tarafta açılan pencereden seriportun adını com noktasını baud rateini belirle. Sonra o pencerenin az yukarısında şimşek işareti(events) var, ona tıkla
http://(http://a1111.hizliresim.com/r/b/fv3u.jpg) (http://bit.ly/c25MCx)
ondan sonra açılan pencereden datareceievede çift tıkla açılankod aralığına data gelince ne yapacağını yaz.
http://(http://a1111.hizliresim.com/r/b/fv4v.jpg) (http://bit.ly/c25MCx)
Örneğin gelen datayı yakalamak için,
private void seriport_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte[] buffer;
buffer = new byte[1]; //
seriport.Read(buffer, 0, 1);
//buffer gelen sayıya eşit oluyor ordan istediğin matrise kaydet istediğini yap ;)
}
Not: Portu açmayı unutma;)
if (!seriport.IsOpen)
{ seriport.Open(); }
ÇOK TEŞEKKÜR EDERİM. datareceive bölümü işleme girmeye başladı. ancak byte olarak aldığımız şeyleri stringe çevirip texboxa aktaramadım. c# değişkenlerine aşına değilim. text boxa kadar nasıl aşıyabilirim gelen bilgiyi?
şöyle denedim:
byte[] buffer;
buffer = new byte[1]; //
serialPort1.Read(buffer,0,1);
string s = System.Text.ASCIIEncoding.ASCII.GetString(buffer);
textBox1.Text= s;
textBox1.Text= buffer[0].tostring();
tostring te hata verecek buffer[0] yazip noktaya basinca tostring yazar onu tikla...
tamam. yazımı düzeltip te denedim dediğiniz gibi. ama çalışırken yine hata verdi.
ne hatasi verdi hocam?visual studio icinde debug yaparak mi calistiriyosunuz yoksa programin exe sinden mi calistiriyosunuz?
Alıntı yapılan: Ali_54 - 11 Kasım 2011, 14:51:05
tamam. yazımı düzeltip te denedim dediğiniz gibi. ama çalışırken yine hata verdi.
textbox'a atarken "çapraz iş parçacığından erişim bla bla" diyor di mi? ya bir delegate yazıp, texboxu invoke edeceksin yada form ctor veya load eventi bloklarından birine
CheckForIllegalCrossThreadCalls = false;
yazacaksın.
Alıntı yapılan: RcALTIN - 11 Kasım 2011, 15:17:03
textbox'a atarken "çapraz iş parçacığından erişim bla bla" diyor di mi? ya bir delegate yazıp, texboxu invoke edeceksin yada form ctor veya load eventi bloklarından birine CheckForIllegalCrossThreadCalls = false;
yazacaksın.
Direkt olarak derlediginiz projenin exe sinden calistirirsaniz da oyle bi hata vermez egerki debug yapmicaksaniz
Alıntı yapılan: justice_for_all - 11 Kasım 2011, 15:27:13
Direkt olarak derlediginiz projenin exe sinden calistirirsaniz da oyle bi hata vermez egerki debug yapmicaksaniz
doğru ama debugdan mahrum kalmaya gerek yok...
direk run dan (f5 ten) çalıştırıyorum
verdiği hata kutucuk içinde şöyle:
başlığı: invalid operation exception was unhandled
msjı ie: Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on.
hata olark işarelediği satır: textBox1.Text = buffer[0].ToString();
kodun tamamı:
using System;
using System.Collections.Generic;
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
{
public Form1()
{
InitializeComponent();
}
private void seriport_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte[] buffer;
buffer = new byte[1]; //
serialPort1.Read(buffer,0,1);
string s = System.Text.ASCIIEncoding.ASCII.GetString(buffer);
textBox1.Text = buffer[0].ToString(); // veri geldiği zaman hata verdği satır. gelen veriyi textbox ta göstermek istemiştim. :(
}
private void Form1_Load(object sender, EventArgs e)
{
if (!serialPort1.IsOpen // port kapalı ise aç
{ serialPort1.Open(); }
}
private void button1_Click(object sender, EventArgs e)
{
string a="aa"; // şu an amaçsız
}
}
}
tabi orada
string s = System.Text.ASCIIEncoding.ASCII.GetString(buffer);
satırı amaçsz kamış şu an
debug yapıyorsunuz ve iki üst mesajımda bahsettiğim durum oluşuyor, çözümünüde o mesajda belirtmiştim.
Merhaba
Verdiğin kodu derledim bende sorun çıkmadı. Proje dosyasını verirsen onun üzerinde bakabilirim.
anladım. saçma bişey ama debug da hata verip exe sinin çalışması. garıp geldi.
her neyse şöyle bi yol buldum ve bu çalışıyor.
string k;
k=serialport1.readexiting(); deyince oldu. ordan istediğim gibi kullanabikiyorum. ilgilenen herkese teşekkür ederim arkadaşlar.
datareceive eventinde tek satırlık kod işi bittirdi :)
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.
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;
}
}
}
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ı.
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));
}
hiç tanımadı bunu
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...
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
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.
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...
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.
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
yardımcı olurmusunuz ustalar kimse cevap yazmamış
yardım eden yokmu :(
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.
Burda konuşlulmuştu seri port konusu:
https://www.picproje.org/index.php/topic,47970.msg357819.html#msg357819 (https://www.picproje.org/index.php/topic,47970.msg357819.html#msg357819)
Burda hazır uygulama var:
http://gokhanbeken.com/dosyalar/rs232_uygulamasi.rar (http://gokhanbeken.com/dosyalar/rs232_uygulamasi.rar)
Selamlar.
C#a yeni başladım. O yüzden hiç bilmediğimi söyleyebilirim.
Seri porttan veri almakla ilgili bir program hazırlıyorum. Veriyi datareceiv event içinde readline() ile alıyorum.Ancak baya uzun bir hata mesajı çıkıyor.Run time da.
private void SeriPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
Gelen_Veri = SeriPort.ReadLine();
this.Invoke(new EventHandler(Parse_Veri));
}
catch (Exception hata)
{
MessageBox.Show("Hata:" + hata.Message);
}
}
private void Parse_Veri(object s, EventArgs e)
{
tbTerminalRx.Text += Gelen_Veri;
string[] Gelen_VeriParse = Gelen_Veri.Split(Ayirac,StringSplitOptions.RemoveEmptyEntries);
tbTerminalRx.SelectionStart = tbTerminalRx.Text.Length;
tbTerminalRx.ScrollToCaret();
Gelen_Veri = string.Empty;
}
Hata mesajı ise şöyle;
The I/O operation has been aborted because of either a thread exit or an application request.
Readline kullanmadığımda bu hatayı almıyorum ancak gelen veriyi başka bir yerde kullandığım için en düzenli readline ile veriyi alabiliyorum.
Bu sorunun kaynağı ve çözümü nedir?
Kimsenin çözüm bulamadığı bir konu mu bu yahu?
Edit: Sorun çözüldü.Mcu tarafında veriyi göderdiğim kısımı \r\n şeklinde düzelttim ve artık c# tarafında readline ile eri alabiliyorum.
Cross-thread hatası için; x thread'ından form kontrollerine erişim için kullandığım güzel bir yöntemi paylaşıyorum.
static void SynchronizedInvoke(ISynchronizeInvoke sync, Action action)
{
if (!sync.InvokeRequired)
{
action();
return;
}
sync.Invoke(action, new object[] { });
}
x thread'ı içerisindeki kullanımı ise;
SynchronizedInvoke(txtMessage, () => txtMessage.Text = "QWERTY");