PDA

توجه ! این یک نسخه آرشیو شده میباشد و در این حالت شما عکسی را مشاهده نمیکنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : چگونگی شناسائی اتوماتیک پورت comو خواص آن در vb.net



morteza_rk
13-06-2012, 16:04
سلام

کسی می دونه که چطور میشه با VB.NET برنامه ای نوشت که خودش بتونه لیست پورت های COM مورد استفاده در قسمت Device Manager رو پیدا کنه و خواص هر پورت رو بفهمه؟ مثلا میزان باودریت ، شماره پورت ، فعال بودن یا نبون Hand Shak و ...

فکر می کنم این برنامه یکم اختصاصیه و خوراک بهنام باشه! نه؟

ama_trig
13-06-2012, 18:36
VB.NET

Imports System.IO.Ports



Dim mysp As New SerialPort
Dim pnames() As String
pnames = SerialPort.GetPortNames()

For i As Integer = 1 To pnames.Length
cbPN.Items.Add(pnames(i - 1))
Next
خواص که سخت افزار شما زمان وصل شدن تایین می کنه، تنظیمات dm کار خاصی انجام نمی دن و برنامه به راحتی می تونه override کنه، اما اگه منزور پرت باز شده هست، فکر نمی کنم با .net بشه.
اگر هم پرت بسته است، تک تک پرت ها را باید باز کرد و چک کرد.
منطقی ترین راه اینه که سخت افزار مرتب 2 کاراکتر پشت سر هم بفرسته، شما توی نرم افزار با بادریت های مختلف مثلا از 300+ شروع به چک کردن می کنین، روی هر پرت با یک تاخیری ورودی می خونین هر موقع AB یا BA رسید می تونین baud رو درست فرض کنین، لاقل توی صنعت این روش کاربرد داره، روش های دیگه ام هست، مثلا سخت افزار TXD برای یه مدت مشخص که پروتوکل شده است high نگه می داره، portبعد بافر خودش رو مرتب چک کنه اگه چیزی نرسید دوباره TXD ... با نرم افزار port باز می شه، چند بار اندازه می گیره، با baud مورد نظر یه پیام توقف میفرسته که می تونه بگه handshake و ... تنظیمات ثانویه چی باشه.

روشه هم که من استفاده می کنم، سخت افزار و نرم افزار هر دو 38400 پرت باز می کنن، نرم افزار یکی یکی پرت ها رو چک می کنه، هر موقع A رسید، وضعیت درسته!

morteza_rk
13-06-2012, 18:48
سلام دادا

منظور من پورت باز شده نیست. همه ی ما می دونیم که 256 تا پورت کام توی Device Manager وجود داره که معمولا فقط 4 - 5 تاش مورد استفاده هستن ، حالا ما می خوایم از بین این 256 تا اون پورتی که مد نظر خودمون هست پیدا کنیم.

برای مثال من یه مبدل پورت USB به COM رو وصل می کنم به پورت USB در این زمان این مبدل به جای یکی از پورت های COM شماره 1 تا 256 قرار می گیره. حالا من می خوام برنامه ام توی VB.NET بیاد اولا شماره ی این پورت که درواقع همون مبدل هست رو پیدا کنه و ثانیا مقدار باودریت رو تشخیص بده و احیانا سایر موارد. (فعلا این دو مورد در اولویت هستن)

البته روشی که برای تشخیص میزان باودریت گفتید جالبه ريال ولی من فکر می کنم که باید راهی آسونتر برای این مقصود وجود داشته باشه.

راستی اگه ممکنه یه مقدار راجع به کدی که گذاشتید توضیح بدید!

behnam6500
13-06-2012, 19:42
روشی که دوست عزیز گذاشتن، میاد نام تمامی پورتهای سریال که در سیستم تعریف شده رو برمیگردونه. و در یک combo box که تعریف کردن میریزه.

از ادرس زیر میتونید لیست پورت ها رو ببینید:

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM

با قطعه کد زیر هم میونید به پیکربندی پورت سریال دسترسی داشته باشید:



Private Sub GetPortInfo()


Dim searcher As New ManagementObjectSearcher("select * from Win32_SerialPortConfiguration")

Try
For Each share As ManagementObject In searcher.[Get]()


Try
textBox1.Text += share("Name").ToString() + vbCr & vbLf
Catch
textBox1.Text += share.ToString() + vbCr & vbLf
End Try

If share.Properties.Count <= 0 Then
MessageBox.Show("No Information")
Return
End If

For Each PC As PropertyData In share.Properties


textBox1.Text += PC.Name + ": "

If PC.Value IsNot Nothing AndAlso PC.Value.ToString() <> "" Then
Select Case PC.Value.[GetType]().ToString()
Case "System.String[]"
Dim str As String() = DirectCast(PC.Value, String())

Dim str2 As String = ""
For Each st As String In str
str2 += st + " "
Next

textBox1.Text += str2 + vbCr & vbLf

Exit Select
Case "System.UInt16[]"
Dim shortData As UShort() = DirectCast(PC.Value, UShort())


Dim tstr2 As String = ""
For Each st As UShort In shortData
tstr2 += st.ToString() + " "
Next

textBox1.Text += tstr2 + vbCr & vbLf

Exit Select
Case Else

textBox1.Text += PC.Value.ToString() + vbCr & vbLf
Exit Select
End Select

End If
Next
Next

Catch
End Try

End Sub

morteza_rk
13-06-2012, 20:28
ممنون بهنام جان

من قطعه کد بالارو کپی کردم توی ویژوال استودیو 2010 در یک پروژه ی VB.net اما موقع اجرا کردن از قسمت ManagementObjectSearcher ایراد می گیره!

الان کد علاوه بر استخراج اطلاعات پیکره بندی پورت ، شماره ی پورت رو هم مشخص می کنه؟

behnam6500
13-06-2012, 21:02
فضای نام system.management رو اضافه کن، همچنین اگه رفرنس system,.management.dll به پروژه اضافه نشده بود، ضاافه کن...

بله شماره پورت رو هم میده. در اصل این روشی که اینجا اوردم، نه فقط برای پورت سریال، بلکه برای مشاهده پیکربندی سیستم به کار میره...

morteza_rk
13-06-2012, 21:21
بهنام جان هر کاری میکنم نمیشه

فضای نام system.management رو اضافه کردم رفرنسشم خودش داشت ولی باز از همون قسمت ایراد میگیره
اگه میشه فقط همین تکه کد رو توی پروژه ی vb.net کامپایل کن و ضمیمه کن .

behnam6500
13-06-2012, 22:59
دو قطعه کد گذاشتم... یکی این، یکی هم مثل روشی که دوستمون در این تاپیک گذاشتن...

فکر کنم برای شما بهتر و راحت تر این باشه که از همون روش اول استفاده کنید...

ama_trig
13-06-2012, 23:06
روشی که خودم گفتم + روش دوست عزیز رو پیوست (البته فقط کامپایل شدنی :wink:)کردم.
ABR یا Automatic baud rate detection
تنها فکر می کنم با نمونه برداری ممکن هست و دیگر هیچ!
چون فقط سیگنالی که دارین، جنسش از نوع خود کلاک شده هست :018:


حالا من می خوام برنامه ام توی VB.NET بیاد اولا شماره ی این پورت که درواقع همون مبدل هست رو پیدا کنه و ثانیا مقدار باودریت رو تشخیص بده و احیانا سایر موارد. (فعلا این دو مورد در اولویت هستن)
منظوررتون از این قسمت چی هست، baud و شما تعیین نمی کنین، یعنی سخت افزار و شما توافق می کنین، که با چه سرعتی حرف بزنین، موقعی که از توافق نامه اطلاع ندارین، فکر نمی کنم راهی بجز آزمایش وجود داشته باشه، بخصوص اگر از سری های FT232 استفاده می بکنین، حتی اگه پرت با baud اشتباه باز کنین، مجبورین کل این ic ریست کنین(ورژن های قدیمی). چون خودش بقیه تنظیمات و از روی packet تشخیض می داد، مگر این که با سرعت بیشتر اون هم از مضربی از سرعت اصلی باز کنین.

البته تشخیص baud روی سخت افزار کمی جالب تره، کافی با تایمر 1 زمان و اندازه بگیرید، بعدش ...
در مورد تشخیص هم که کارو آسون تر کردین، کافی vendor id, pid و بدونین روی device قفل کنین

ref:
You can see links before reply
You can see links before reply
You can see links before reply
You can see links before reply
You can see links before reply

ama_trig
13-06-2012, 23:41
اینهم برای سکن هاب


Dim mos As New ManagementObjectSearcher("SELECT * FROM Win32_USBHub")

For Each mo As ManagementObject In mos.Get()
MessageBox.Show(mo.Properties.Item("Description").Value + vbCrLf + mo.Properties.Item("DeviceID").Value)
Next

behnam6500
13-06-2012, 23:49
من از این روش، برای بدست اوردن مو به مو جزئیات سیستم استفاده میکنم...

morteza_rk
14-06-2012, 02:59
ممنون از هر دو عزیز

الان فقط یه مشکلی هست!

ببینید من وقتی از توی رجیستری میرم و نگاه می کنم چهارتا از پورت های COM من اونجا هستن که به ترتیب اینجوریه COM2 و COM4 و COM1 و COM8 ، وقتی هم که کدهای شمارو اجرا می کنم دقیقا همین چهارتا پورت توی کمبو باکس ظاهر میشه. ولی موقع دریافت خواص هر پورت ، بجز پورت COM8 خواص بقیه مو به مو نشون داده میشه.

حالا پورت COM8 چیه؟ دقیقا همون پورتیه که من بهش مبدل USB to COM وصل کردم!

بنظر شما قضیه چیه؟

behnam6500
14-06-2012, 11:50
نام پورت 8 چی هست؟

وقتی که مبدل رو میکشی از تو رجیستری حذف میشه؟

morteza_rk
14-06-2012, 14:26
وقتی که مبدل رو میکشی از تو رجیستری حذف میشه؟

آره دادا ، حذف میشه. وقتی هم که می زنمش به یه پورت دیگه شماره پورت کامش عوض میشه که طبیعیه ، هم توی Device Manager عوض میشه هم توی رجیستری و هم توی برنامه ای که گذاشتین. ولی بازم موقع نمایش خواص اسم این پورت رو نشون نمیده.

من دوتا عکس از Device Manager و رجیستری پیوست کردم که اسمشم توی عکس مشخصه.

morteza_rk
14-06-2012, 15:18
ببینید من در اصل هدفم اینه که پروژه هایی که با VB.NET و AVR ارائه میدم خودش بطور اتوماتیک بتونه پورت COM مربوطه رو پیدا کنه و شروع به تبادل اطلاعات کنه و در صورت لزوم وضعیت باودریت ، DTR و RTS رو تغییر بده.

مثلا فرض کنید با میکرو برنامه ای نوشتیم که هر ثانیه اطلاعات دما رو می فرسته به کامپیوتر ، ما از یک مبدل COM to USB استفاده می کنیم. و برد میکرو رو وصل می کنیم به کامپیوتر ، حالا برنامه ی ویژوال باید داده هارو دریافت کنه و مثلا توی یه تکست باکس نشون بده.

در حالت عادی فرد برای ایجاد ارتباط بین سخت افزار و برنامه ی ویژوال باید اول بره توی Device Manager و ببینه که مبدل چه شماره ای از پورت COM رو داره و مقدار باودریت چقدره ، بعد بیاد توی برنامه ویژوال از یه کمبو باکس شماره پورت و باودریت رو ست کنه.

اما من می خوام کل این فرایند بطور اتوماتیک انجام بشه. و در ضمن اون ، بتونم مقدار باودریت رو کم و زیاد کنم.

behnam6500
14-06-2012, 17:38
اینکه چرا اون پورت رو نشون نداده من چیزی نمیدونم

ولی در پروژه ای که انجام داده بودم، دقیقن همین کار رو کرده بودم که نرم افزار بصورت اتوماتیک دو پورت کام رو شناسایی میکرد و برنامه رو برای اونا ست میکرد. شیوه کار هم بدین صورت بود که هر پورت رو داده ای میفرستادم و در صورت دریافت پاسخ شناساییش میکردم...

به همین سادگی شما هم میتونید پورت رو شناسایی کنید.

morteza_rk
14-06-2012, 18:00
اینکه چرا اون پورت رو نشون نداده من چیزی نمیدونم
بیشتر روی این قسمت کار می کنم.


شیوه کار هم بدین صورت بود که هر پورت رو داده ای میفرستادم و در صورت دریافت پاسخ شناساییش میکردم...

مهندس جان اگه میشه این بحث رو باز کن. ضمن اینکه من چطور می تونم پورتی که روی باودریت 9600 شناسائی شده رو بطور اتوماتیک ست کنم روی مثلا 57600 !؟

morteza_rk
14-06-2012, 19:22
راستی بهانم جان شما توی پروژه ای که انجام داده بودی از مبدل COM to USB استفاده کرده بودی؟

morteza_rk
14-06-2012, 19:34
آقا یه نکته ی کنکوری!

من روی مادربرد کامپیوترم یه پورت COM واقعی دارم. الان چک کردم ، دیدم وقتی خواصشو تغییر میدم (باودریت ، Parity ، Stop bit و ....) و بعدش میام از برنامه ی شما استفاده می کنم ،خواصی که توی برنامه نشون داده میشه همون خواص پیشفرض هست و هیچ تغییری نمی کنه!

نکته ی دوم اینکه خواصی که برای هر 3 پورت نشون داده میشه کاملا مثل هم هست! اصلا با هم فرق ندارن.

behnam6500
14-06-2012, 19:37
من از مبدل usb به serial استفاده کردم. این رو بگم که این مبدل ها در پروژه های صنعتی و پروژه هایی که نیاز به کار زیاد دارند، اصــــــــــــــــلا قابل اطمینان نیستند! خیلی راحت از کار می افتند! داده نمیفرستند و...

شما بیا باود ریت دیفالت درست کن به عنوان مثال 57600 و بریزش توی eeprom میکرو.

برنامه وی بی میاد به پورتهای سریال وصل میشه، دستور دریافت باود ریت رو میفرسته (قابل تعریف توسط شما)

در صورت درست باز شدن پورت، و باود صحیح، میکرو به دستور شما پاسخ میده و مقدار باود رو از eeprom میخونه و میفرسته! اینطر ی هم پورت رو پیدا کردی و باود رو.

البته این کار فقط یک بار و هنگام کانفیگ کردن دستگاه انجام میشه. چرا که برنامه وی بی وقتی این کار رو انجام بده، داده ها رو یه جا ذخیره میکنه و برای دفعات بعد، از اونجا میخونه.

برای تنظیم مقدار باود هم کافیه که با برنامه به میکرو دستور تغییر بدی و اونم توی حافظش مقدار جدید رو بنویسه. و بعدش هم ریست سریال و کار با باود جدید...

morteza_rk
14-06-2012, 23:49
دادا منظور من اینه که همون اول من از کجا بدونم که مقدار باودریت مبدلم چنده؟ (با توجه به اینکه برنامه ای فرستادی فقط مشخصات مبدل منو نشون نمیده)

فرض می کنیم مبدل بطور پیشفرض باودریتش 19200 هست. حالا برنامه ی من داره برای پیدا کردن پورت صحیح یه مقدار رو می فرسته به سمت میکرو که اگه میکرو اونو دریافت کرد ارتباط برقرار میشه. حالا دو تا سوال پیش میاد :

1. حالا من این داده ام رو دارم با باودریت 9600 می فرستم. (چون من نمی دونم باودریت پیشفرض چنده) در اینصورت حتی اگر پورت رو هم بصورت صحیح انتخاب کرده باشم بازم در سمت میکرو چیزی دریافت نمیشه.

2. حالا فرض می کنیم که موفق شدم ارتباط رو برقرار کنم. حالا چطور خواص پورت COM رو overide کنم؟ مثلا باودریتشو بذارم روی یه مقدار جدید؟

نمیشه یه جورایی از طریق Vandor ID و Product ID مبدل رو پیدا کنیم و بعدش خواصشو استخراج کنیم؟

behnam6500
15-06-2012, 01:32
دوست عزیز مقدار باود ریت مبدل با توجه به ارتباطش اتوماتیک تغییر میکنه!

اگر داده فرستاده شد، وقتی که جوابی نیومد و timeout داد یعنی درگاه درست نیست.

یعنی چی override میکنی؟؟؟ شما خاصیت باود ریت رو که تغییر بدی، اون پورت روی مقدار جدید ست میشه.

vid و pid منحصر به فرده در محصولاتی که دارای usb هستند. حالا اگه همه مبدلهای دارای مقادیر منحصر به فرد باشند، میتونید vid , pid رو سرچ کنید، در صورت وجود بقیه کارها رو انجام بدید...

به نظرم داری خیلی سختش میکنی... طبق روشی که گفتم خیلی راحت میتونی پورت رو پیدا کنی و باود ریت ست کنی! فقط یه کم مانور برنامه نویسی بده!

اگه نه خوب سوییچ کن روی برنامه نویسی usb

morteza_rk
15-06-2012, 02:56
دوست عزیز مقدار باود ریت مبدل با توجه به ارتباطش اتوماتیک تغییر میکنه!
یعنی چی override میکنی؟؟؟ شما خاصیت باود ریت رو که تغییر بدی، اون پورت روی مقدار جدید ست میشه.


چه جالب!؟ اینو نمی دونستم! یعنی فکر می کردم مثلا اگه باودریت مبدل روی 9600 باشه و از اونطرف برنامه ی ویژوال و برنامه ی میکرو روی 19200 باشن نمی تونن براساس پورت مبدل ارتباط برقرار کنن! فکر می کردم حتما باید برم از توی Device Manager باودریت مبدل رو بکنم 19200 !

ولی الان که تست کردم دیدم میشه! جالب بود!؟

نمی دونستم دیگه دادا ، زدن نداره که! میرم ببینم چه می کنم.!؟

behnam6500
15-06-2012, 03:08
اختیار داری رفیق... سرور مایی...

باود ریت مبدل اتوماتیک تغییر میکنه! فقط میمونه باود ریت دستگاهت که باید طبق اون روشی که گفتم تغییر بدی...

ama_trig
15-06-2012, 03:38
VS2008 VB.Net


Imports System.IO.Ports

Public Class Form1

Private Function answer(ByVal sp As SerialPort)
Dim okmsg() As Char = "B"
sp.Write(okmsg, 0, okmsg.Length)
End Function

Private Function DetectSerialPort()

Dim testport As New SerialPort
Dim portnames() As String
Dim bauds() As Integer = {4800, 9600, 19200, 38400, 76800, 115200}
Dim readbuf As Byte

portnames = SerialPort.GetPortNames()

For Each portname In portnames
For Each baud In bauds
testport = New SerialPort(portname, baud)
If testport.IsOpen = False Then
testport.ReadTimeout = 200
testport.Open()
Try
readbuf = testport.ReadByte()
If (readbuf = 65) Then
answer(testport)
'sleep 1 sec
testport.ReadExisting()
'clear buff
Return testport
End If
testport.Close()
Catch ex As TimeoutException 'not our port
testport.Close()
Continue For
End Try
End If
Next
Next
Return Nothing
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim sp As SerialPort = DetectSerialPort()

If sp Is Nothing Then
MessageBox.Show("our device not attached")
End If

End Sub
End Class
AVR-GCC


while (1)
{
USARTWriteChar(65);
readbuf1 = USARTRead_USARTBuffer();
if(readbuf1 == 'B')
break;
}
*تنظیمات پرت باز شده، امکان override شدن در .net ندارن، پرت باید بست با تنظیمات جدید باز کرد، مگر اینکه buffer و پروتوکل و ... , همه اینها رو خودتون از صفر پیاده سازی کنین.

*این روش تابع سخت افزار ارتباطی هم هست، قبلا هم گفتن با FT ها، بخصوص driver های قدیم مشکل داره، چون اگه buffer شون با باود و تنظیمات اشتباه شروع به پر شدن بکنه، تنها راه ریست کردن بود(درست یادم نیست چی بود مشکل)

morteza_rk
15-06-2012, 03:48
اختیار داری رفیق... سرور مایی...

فدات! من کوچیک همه ی بچه های انجمنم ، مخصوصا مدیرا!


باود ریت مبدل اتوماتیک تغییر میکنه! فقط میمونه باود ریت دستگاهت که باید طبق اون روشی که گفتم تغییر بدی...
اوناشو دیگه استادم! (البته جسارت نباشه) تو برنامه نویسی میکرو مشکلی نیست. الان دارم با timeout ور میرم!

ama_trig دادا ، گل کاشتی بابا ، دمت گرم. به کمک شما و بهنام جان فهمیدم که باید چیکار کنم. واقعا از هر دو عزیز ممنونم.

behnam6500
15-06-2012, 11:36
نوع داده ای توابعت رو تعیین کن...

تابع answer چون بصورت sub routine نوشتی به جای function بنویس Sub

این یک ثانیه تاخیر چیه؟ دقیقن نفهمیدم برای چی گزاشتیش؟

behnam6500
15-06-2012, 11:47
FT232 مشکل داره برای کار؟؟؟ اگه آره ایرادش چی هست ؟

مبدل بهتر از ft چی داریم؟

ama_trig
15-06-2012, 15:07
نوع داده ای توابعت رو تعیین کن... حق با شماست، ولی ویژگی basic برای سرعتی نوشتن هست سطحش هم انقدر بالاست که خودش ... :018:و کلا این سومین کدی هست که توی این زبون کامپایل کردم :)) ، این هم کد اصلی نیست که قرار کسی استفاده کنه و فقط برای مفهوم کردن هست.



تابع answer چون بصورت sub routine نوشتی به جای function بنویس Sub
خیلی کارهای دیگه توی این قسمت باید انجام داد، فقط یه نمونه هست، در نهایت هدف اصلیم این بود که بشه firmware سخت افزار و توی این تابع برگردوند، تازه handshake ها و ... باید اینجا کار کنن ولی حق با شماست، این دو خط باید توی برنامه بود، تازه یه اشکال اساسی دیگه باید byref بود درسته که خودش ذاتی این طوریه :wink:



این یک ثانیه تاخیر

تا سخت افزار حتما از مد فرستادن پشت سر هم خارج شه، شما 1 ثانیه بعد، buffer و خالی کنین، همه چی اماده ارتباط باشه.



FT232 مشکل داره برای کار
خیر، فکر می کنم بهترین هست، اما برای این کار که هی baud رو عوض کنی(baud اشتباه)، ,بخصوص بقیه تنظیمات عوص کنی، چک کنی، اگه سخت افزار هی مشغول فرستادن باشه، یادمه توی ورژن های قدیمی من باهاشون مشکل داشتم. ولی در کل بین همه ی اینها، فکر می کنم با کیفیت ترین و قوی ترین هست.

morteza_rk
15-06-2012, 15:23
FT232 مشکل داره برای کار؟؟؟ اگه آره ایرادش چی هست ؟

مبدل بهتر از ft چی داریم؟

من تا حالا با سری FT کار نکردم. ولی از آی.سی PL2303 خیلی راضیم. البته توی این برنامه ای خصوصیات پورت هارو نشون میداد خواص اون پورتی که با این مبدل ایجاد شده بود رو نشون نمی داد. بخاطر همین می خوام یه دونه FT232 هم بخرم و با اونم تست کنم.

ولی در کل PL2303 مبدل خوبی هست.


این هم کد اصلی نیست که قرار کسی استفاده کنه و فقط برای مفهوم کردن هست.
درسته ، من کامپایلش کردم ولی در عمل از قسمت testport.open() ایراد می گیره. اونم دقیقا وقتی که همه ی پورت هارو تست می کنه و می رسه به پورت COM8 (که همون مبدل باشه)

دارم سعی می کنم که خودم یه برنامه بنویسم. نمی دونم که آخرش موفق میشم یا نه. آخه من به اندازه ی شما دو نفر وارد نیستم.

ama_trig
15-06-2012, 17:36
ایراد چی هست؟ پیغام خطا؟
با مقدار تنظیمات درست پرت باز کردین، اطلاعات بفرستین بگیرین،کار کنه توی vs؟
منظورتون از خاصیت پرت ها چی هست؟ + کاربردش براتون چی هست؟

morteza_rk
15-06-2012, 20:07
ایراد چی هست؟ پیغام خطا؟


مهندس تا دیشب که پیغام می داد پورت نمی تونه باز شه چون توسط یه برنامه ی دیگه باز مونده. اما امروز که اجرا می کنم خطا نمیده در عوض اون پیغام آخری رو میده که میگه our device not attached در صورتیکه نباید به اینجا برسه.

از اون طرف من یه کد خودم نوشتم ، ولی اصلا اجرا نمیشه! پیغام خطا هم نمیده. هرچی هست مربوط به if هست. لطفا ببینید این کد مشکلش چیه؟ البته هنوز اول کارم. فعلا تا اینجاشو جواب بگیرم...





Imports System.IO.Ports

Public Class Form1

Dim Entr As Char = Chr(13)
Dim portnames() As String
Dim bauds() As Integer = {9600, 57600}
Dim serialdata As String

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

portnames = SerialPort.GetPortNames()

For i As Integer = 1 To portnames.Length

SerialPort1.PortName = portnames(i - 1)

For j As Integer = 1 To bauds.Length

SerialPort1.BaudRate = bauds(j - 1)
SerialPort1.ReadTimeout = 200

If SerialPort1.IsOpen = False Then

TextBox1.Text = "Opening port..."
SerialPort1.Open()
SerialPort1.Write("MRK" + Entr)
SerialPort1.Close()

End If

Next

Next

End Sub

End Class

ama_trig
15-06-2012, 22:54
با مقدار تنظیمات درست پرت باز کردین، اطلاعات بفرستین بگیرین،کار کنه توی vs؟ یعنی مستقیم برین سراغ تنظیمات درست و چک کنین ارتباط سالم هست با میکرو

منظورتون از خاصیت پرت ها چی هست؟ + کاربردش براتون چی هست؟

برنامتون درسته تا جایی که چک کردم، منظورتون از اجرا نمی شه، برای پرت مورد نظر، دستورات داخل if هست؟
تازه یه نکته هم هست که منطقی تره که هر بار serialport جدید بسازین، البته نباید تاثیری داشته باشه.


SerialPort1= New SerialPort(portnames(i - 1), bauds(j - 1))

morteza_rk
16-06-2012, 03:26
با مقدار تنظیمات درست پرت باز کردین، اطلاعات بفرستین بگیرین،کار کنه توی vs؟ یعنی مستقیم برین سراغ تنظیمات درست و چک کنین ارتباط سالم هست با میکرو

اینو که همیشه تست می کنم مهندس ، توی هر برنامه ای این تست رو انجام میدم.


منظورتون از خاصیت پرت ها چی هست؟ + کاربردش براتون چی هست؟
منظورم خواص پورت بود ، مثل باودریت و ... که مشکلم در این قسمت رفع شد.


منظورتون از اجرا نمی شه، برای پرت مورد نظر، دستورات داخل if هست؟
یعنی وقتی برنامه رو اجرا می کنم کلا فرم بالا نمیاد و انگار نه انگار که اجرا کردم! اما اگه IF رو پاک کنم (یا دستورات داخلشو) برنامه اجرا میشه و فرم بالا میاد ولی تا اینجاش که فایده ای نداره ، اصل کار تیکه ی داخل if هست.

behnam6500
16-06-2012, 12:16
مرتضا جان کدت درسته. اما دلیل اینکه فرم بالا نمیاد و خروجی رو نمیتونی ببینی اینه که خاصیت WriteTimeOut پورت سریال رو تنظیم نکردی! همونطور که SerialPort1.ReadTimeout = 200 رو نوشتی، برای writetimeout هم بنویس...

ama_trig
16-06-2012, 13:15
خب پس، سر کدوم خط گیر میکنه، که فرم قفل می شه، از رویداد form_load خارج کینین، ببرینش توی رویداد یک دکمه، تک تک، خطها یکی یکی رو اجرا کنین، handshake هم روی xonxoff تست کنین تا مطون شین در سخت افزاری قفل نشه،writetimeout هم که دوست عزیز گفتن.
فرض بر این هست که با برنامه درست، اطلاعات درست میره، حالا اینو امتحان کنید، baud دستی اشتباه تنظیم کنین، پرت باز کنین، تست کنین، ببندید، دوباره خط بعد با مقدار درست باز کنین.

morteza_rk
16-06-2012, 18:34
ممنون از هر دو نفر که پیگیر موضوع هستید.

الان دو مورد رو اضافه کردم و برنامه کار می کنه. 1. writetimeout و 2. try - catch

اما مشکلی که هست اینه که برنامه نمی تونه میزان باودریت رو ست کنه. یعنی وقتی اجراش می کنم نمی تونه داده رو بفرسته به میکرو ، اما اگه قبلش یکبار با هایپر ترمینال یه داده ای رو بفرستم و بعداز اون با برنامه ی خودم تست کنم ، می تونه داده رو بفرسته. از طرفی فقط یکبار داده رو می فرسته و از دفعه های بعدی هر چقدر دکمه رو می زنم باز کار نمی کنه.

کد کامل رو پیوست کردم.

ama_trig
17-06-2012, 00:42
برنامه که درسته به ظاهر، سخت افزار باید دید + برنامش
برنامه رو یه امتحان کنین، اگه بتونین، با اسکوب خروجی چک کنین، ببینین شاید برنامه درسته، اگه می تونین با سیستم مدرسه قدیم (RS232 + MAX232) :018:یه امتحان کنین سخت افزار رو شاید این سری PL مشکل دارن.
تازه error flag رو هم روی سخت افزار چک کنین، ببینین وضعیتش چطوره

یه آزمایش کنین با ترمینال بدون این که سخت افزار ریست کنین، دوبار baud عوض کنین با یه دکمه ، توی pc هم این کار انجام بدین(البته از باود بیشتر به کمتر) ببینین هنوز کار می کنه، البته usb2com ریست نکنین
دقیقا این مشکل نیست، چون baud وردی این ic ها گویا automatic ست می شه و بعد ست شدن هم عوض نمیشه، به محض این که اولین char می رسه. این حرف از این جا می گم که موقعی که با ترمینال درست حسابی baud ست می کنین ، می نویسه auto و تا زمانی که اولین baud درست تنظیم نشه کار نمی کنه مگه این که به هم بریزه.
baud خروجیش اگه با baud ورودی فرق داشته باشه به هم می ریزه.


FT232 امروز API هاشو تازه دیدم، گویا خیلی خیلی قوی تر از اون چیزی بود که فکرشو می کردم.
Interact with FTDI chip - CodeProject (You can see links before reply)

بطور کلی هی baud چک کردن، عوض کردن، کار جالبی نیست، و :unh: اما یه چیز دیگه، می تونین کار بر عکس هم امتحان کنین، سخت افزار baud تشخیص بده این شکلی می شه نرمش بیشتری هم نشون داد.
(char space اگه بفرستین، زمان یک بودن پین RX اگه اندازه بگیرین، می تونین baud تشخیص بدین.) تئوری :mrgreen:
یه چند تا سوال دیگه، اگه وصل نکنین سخت افزار رو، موقع باز کردن یا نوشتن روی usb2serial مگه گیر می کنه؟ 2 پست قبل نوشتین مشکل گیر کردن دارین) نمی دونم، ولی فکر نمی کنم write کردن گیر بندازه، مگه این که handshake استفاده کنین، که توی برنامتون handshake نیست.

morteza_rk
17-06-2012, 00:58
موقع باز کردن یا نوشتن روی usb2serial مگه گیر می کنه؟ 2 پست قبل نوشتین مشکل گیر کردن دارین) نمی دونم، ولی فکر نمی کنم write کردن timeout تولید کنه.

اون گیر کردن بخاطر این بود که وقتی پورت COM2 یا COM4 باز بودن برنامه دچار مشکل میشد که این قسمت توسط دستور try - catch راه افتاد.


برنامه رو یه امتحان کنین، اگه بتونین، با اسکوب خروجی چک کنین، ببینین شاید برنامه درسته، اگه می تونین با سیستم مدرسه قدیم (RS232 + MAX232) یه امتحان کنین سخت افزار رو شاید این سری PL مشکل دارن.


اسکوپ که ندارم. پورت RS232 هم فعلا ندارم. سوکتش روی مادربرد هست ولی هنوز براش هدر نخریدم یا نساختم.


تازه error flag رو هم روی سخت افزار چک کنین، ببینین وضعیتش چطوره
این مورد از کجا قابل تست کردنه؟


یه آزمایش کنین با ترمینال بدون این که سخت افزار ریست کنین، دوبار baud عوض کنین با یه دکمه ، توی pc هم این کار انجام بدین(البته از باود بیشتر به کمتر) ببینین هنوز کار می کنه، البته usb2com ریست نکنین
با هایپر ترمینال که باید دوتا کانکشن بسازم. یکی با باودریت کمتر و یکی با باودریت بیشتر. اینجوری شرایط آزمایش نمیره زیر سوال؟


چون baud وردی این ic ها گویا automatic ست می شه و بعد ست شدن هم عوض نمیشه، به محض این که اولین char می رسه. این حرف از این جا می گم که موقعی که با ترمینال درست حسابی baud ست می کنین ، می نویسه auto و تا زمانی که اولین baud درست تنظیم نشه کار نمی کنه مگه این که به هم بریزه.
baud خروجیش اگه با baud ورودی فرق داشته باشه به هم می ریزه.
در این مورد تردید دارم دادا! حداقل راجع به PL2303 !


می تونین کار بر عکس هم امتحان کنین، سخت افزار baud تشخیص بده این شکلی می شه نرمش بیشتری هم نشون داد

بنظرم این روش جالب نیست. زیادم وقت می گیره.

من یه نظر دیگه دارم. ببینید من که همیشه باودریت میکروم روی 57600 هست و نیازی ندارم هیچوقت عوضش کنم. بنابراین باودریت پورت سریال برنامه رو می ذارم روی 57600 ، در این حالت میمونه فقط پیدا کردن پورتی که پورت مورد نظر ماست!

سعی می کنم یه برنامه این تیپی بنویسم و تستش کنم.

ama_trig
17-06-2012, 01:09
نقل قول:
تازه error flag رو هم روی سخت افزار چک کنین، ببینین وضعیتش چطوره
این مورد از کجا قابل تست کردنه؟

error flag باید datasheet نگاه کنین، اکثر UART های میکرو ها بیت error دارن



unsigned intUSART_Receive( void)
{
unsigned charstatus, resh, resl;
/* Wait for data to be received*/
while( !(UCSRA & (1<<RXC)) )
;
/* Get status and ninth bit, then data*/
/* from buffer*/
status = UCSRA;
resh = UCSRB;
resl = UDR;
/* If error, return -1*/
if( status & (1<<FE)|(1<<DOR)|(1<<PE) )
return-1;
/* Filter the ninth bit, then return*/
resh = (resh >> 1) & 0x01;
return((resh << 8) | resl);
}




با هایپر ترمینال که باید دوتا کانکشن بسازم. یکی با باودریت کمتر و یکی با باودریت بیشتر. اینجوری شرایط آزمایش نمیره زیر سوال؟

نه، پرت می بندین، توی اونیکی دوباره باز می کنین، فقط تنظیمات baud برای سخت افزارتون رو هم تغییر بدین.



م. ببینید من که همیشه باودریت میکروم روی 57600 هست و نیازی ندارم هیچوقت عوضش کنم. بنابراین باودریت پورت سریال برنامه رو می ذارم روی 57600 ، در این حالت میمونه فقط پیدا کردن پورتی که پورت مورد نظر ماست!
پس حل شد، حتی می تونین بعدش با برنامه baud رو عوض کنین، پیشنهاد می دم اول با 9600 شروع کنین، بعدش عوض کنین(هم سخت افزار و هم نرم افزار توسط نرم افزار مقدار baud شون یکی شه!

behnam6500
17-06-2012, 01:12
مرتضا این یه کلاس برای پورت سریال هست که برای یکی از پروژه ها ساخته بودمش...

این کلاس رو توی پروژت اضافه کن شاید بتونی مشکلت رو با این حل کنی



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;

namespace CEWorld.IO.Ports
{
public class SerialPort
{
private System.IO.Ports.SerialPort ComPort = new System.IO.Ports.SerialPort();

public string[] GetPortNames()
{
string[] PortNames = System.IO.Ports.SerialPort.GetPortNames();
string[] p = { string.Empty };

foreach (string Port in PortNames)
{
p[p.GetUpperBound(0)] = Port;
Array.Resize(ref p, p.Length + 1);
}
Array.Resize(ref p, p.Length - 1);
return p;
}

public bool OpenPort(string PortName)
{
if (ComPort.IsOpen)
ComPort.Close();

ComPort.PortName = PortName;
try
{
ComPort.Open();
return true;
}
catch
{
return false;
}
return true;
}

public bool IsPortOpen()
{
return ComPort.IsOpen;
}

public void ClosePort()
{
if (ComPort.IsOpen)
ComPort.Close();
}

public string Send(string value)
{
ComPort.DiscardInBuffer();
ComPort.NewLine = "\r";


ComPort.WriteLine(value);

int t = 0;
string retData = string.Empty;

while (t <= 50)
{
retData = ComPort.ReadExisting();

if (!string.IsNullOrEmpty(retData))
{
return retData.Replace("\r", string.Empty).Replace("\n", string.Empty);
}

System.Threading.Thread.Sleep(10);
t++;
}
ComPort.DiscardInBuffer();
return string.Empty;
}
}
}

morteza_rk
17-06-2012, 01:31
ممنون بهنام جان

ولی اگه اشتباه نکنم این کلاسی که نوشتی مال #C هست! من بلد نیستم ازش توی VB.NET استفاده کنم. میشه بگب چطور می تونم این کارو بکنم؟ اصلا شدنی هست؟

الان اون کاری رو که توی پست قبلی گفتم انجام دادم. فعلا که خوب داره کار می کنه. تا ببینم می تونه جواب بقیه ی کارمم بده یا نه. ولی هنوز نفهمیدم چرا اون برنامه قبلیه که همه چیشم درسته چرا کار نمی کنه.

اینم کد جدید که کار می کنه ، البته فعلا!!!



Imports System.IO.Ports

Public Class Form1

Dim Entr As Char = Chr(13)
Dim portnames() As String
Dim serialdata As String

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SerialPort1.BaudRate = 19200
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

portnames = SerialPort.GetPortNames()

For i As Integer = 1 To portnames.Length

SerialPort1.PortName = portnames(i - 1)
SerialPort1.ReadTimeout = 100
SerialPort1.WriteTimeout = 20

Try
If SerialPort1.IsOpen = False Then

TextBox1.Text = "Opening port..."
SerialPort1.Open()
SerialPort1.Write("mrk" + Entr)
SerialPort1.Close()

End If
Catch ex As Exception
SerialPort1.Close()
End Try

Next

End Sub
End Class

behnam6500
17-06-2012, 01:38
یکی از مزیتهای دات نت همین استفاده از چند زبان در یک پروژه هست!

اصولن برای استفاده از این امر یا باید یه رفرنس بسازی ازش، یا در یه Solution استفاده کنی... ولی در Asp.net در تنظیمات web.config میتونی زبان دوم رو تعریف کنی... به هر حال...

این هم کدش به زبان vb.net


Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.IO.Ports

Namespace CEWorld.IO.Ports
Public Class SerialPort
Private ComPort As New System.IO.Ports.SerialPort()

Public Function GetPortNames() As String()
Dim PortNames As String() = System.IO.Ports.SerialPort.GetPortNames()
Dim p As String() = {String.Empty}

For Each Port As String In PortNames
p(p.GetUpperBound(0)) = Port
Array.Resize(p, p.Length + 1)
Next
Array.Resize(p, p.Length - 1)
Return p
End Function

Public Function OpenPort(PortName As String) As Boolean
If ComPort.IsOpen Then
ComPort.Close()
End If

ComPort.PortName = PortName
Try
ComPort.Open()
Return True
Catch
Return False
End Try
Return True
End Function

Public Function IsPortOpen() As Boolean
Return ComPort.IsOpen
End Function

Public Sub ClosePort()
If ComPort.IsOpen Then
ComPort.Close()
End If
End Sub

Public Function Send(value As String) As String
ComPort.DiscardInBuffer()
ComPort.NewLine = vbCr


ComPort.WriteLine(value)

Dim t As Integer = 0
Dim retData As String = String.Empty

While t <= 50
retData = ComPort.ReadExisting()

If Not String.IsNullOrEmpty(retData) Then
Return retData.Replace(vbCr, String.Empty).Replace(vbLf, String.Empty)
End If

System.Threading.Thread.Sleep(10)
t += 1
End While
ComPort.DiscardInBuffer()
Return String.Empty
End Function
End Class
End Namespace

morteza_rk
17-06-2012, 04:55
ممنون بهنام جان. ولی این کدی که گذاشتی واسه من خیلی خفنه! (کفـــمان بریــد! از بعضی جاهایش سر در نیاوردیم!) من علاقه دارم که کد خودم رو بنویسم. یعنی اهل کپی پیست نیستم. از طرفی مثل شما حرفه ای هم نیستم.

الان یه کدی نوشتم که باید داده رو از پورت سریال بخونه ، اما نمی خونه! کجاش مشکل داره به نظر شما؟
توضیح اینکه قسمت ارسال همون قبلیه ، فقط قسمت دریافت بهش اضافه شده.




Imports System.IO.Ports

Public Class Form1

Dim Entr As Char = Chr(13)
Dim portnames() As String
Dim serialdata As String

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

portnames = SerialPort.GetPortNames()
SerialPort1.BaudRate = 57600
For i As Integer = 1 To portnames.Length

SerialPort1.PortName = portnames(i - 1)
SerialPort1.ReadTimeout = 100
SerialPort1.WriteTimeout = 20

Try
If SerialPort1.IsOpen = False Then

TextBox1.Text = "Opening port..."
SerialPort1.Open()
SerialPort1.Write("mrk" + Entr)
SerialPort1.Close()

End If
Catch ex As Exception
SerialPort1.Close()
End Try

Next

End Sub


Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived

serialdata = SerialPort1.ReadLine()
show_recieved_data()

End Sub

Private Sub show_recieved_data()

TextBox2.Text = serialdata

End Sub

End Class

behnam6500
17-06-2012, 17:01
برای کار با سریال و دریافت داده حتمن از delegate استفاده کنید. چرا که از عملکرد برنامه اطمینان 100% پیدا میکنید. اصلش هم باید از delegate استفاده کرد.

این قطعه کدی هست که در یکی از پروژه هام نوشته بودم برای این منظور. البته با سی شارپ بوده که به وی بی باز نویسیش کردم برات...


Private Delegate Sub SerialWork(Serial As System.IO.Ports.SerialPort)
Private Delegate Sub SetReadSerialData(data As String)

Private Sub SerialWorkProcedure(Serial As System.IO.Ports.SerialPort)
If McuRS232.IsOpen Then
Dim _DataReceived As String = McuRS232.ReadExisting()
ReadSerialData(_DataReceived)
End If
End Sub

Private Sub McuRS232_DataReceived(sender As Object, e As System.IO.Ports.SerialDataReceivedEventArgs)
Dim SW As SerialWork = SerialWorkProcedure
SW.BeginInvoke(McuRS232, Nothing, Nothing)
End Sub

Private Sub ReadSerialData(data As String)
If Me.InvokeRequired Then
Try
Dim RSD As SetReadSerialData = ReadSerialData
Me.Invoke(RSD, data)
Catch generatedExceptionName As Exception
End Try
Else
'inja dade vojud darad!
DataReceived += data
End If
End Sub



سی شارپ:



private delegate void SerialWork(System.IO.Ports.SerialPort Serial);
private delegate void SetReadSerialData(string data);

private void SerialWorkProcedure(System.IO.Ports.SerialPort Serial)
{
if (McuRS232.IsOpen)
{
string _DataReceived = McuRS232.ReadExisting();
ReadSerialData(_DataReceived);
}
}

void McuRS232_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
SerialWork SW = SerialWorkProcedure;
SW.BeginInvoke(McuRS232, null, null);
}

void ReadSerialData(string data)
{
if (this.InvokeRequired)
{
try
{
SetReadSerialData RSD = ReadSerialData;
this.Invoke(RSD, data);
}
catch (Exception)
{
}
}
else
{
//inja dade vojud darad!
DataReceived += data;
}
}

morteza_rk
17-06-2012, 20:34
ممنون بهنام جان

حسابی به تو و ama_trig زحمت دادم. ولی در عوض کلی چیز یاد گرفتم. میرم که این تیکه کد رو تست کنم.

morteza_rk
17-06-2012, 21:35
دادا برنامه از سه نقطه ایراد می گیره. دوتاش میگه که آرگومان واسه توابع ندادی. یکیش هم از یه متغیر ایراد می گیره که میگه تعریف نشده. من برنامه رو پیوست کردم. بی زحمت یه نگاه بهش بنداز.

من چون سی شارپ بلد نیستم نتونستم با مقایسه این دو کد به نتیجه ای برسم. شرمنده.

morteza_rk
17-06-2012, 21:49
راستی چون نمی دونستم Delegate چیه ، راجع بهش تحقیق کردم. اینو فهمیدم :

"همه ی متدهایی که ما در برنامه نویسی به کار می بریم ، شیء نیستن. و در واقع یک آدرس سخت افزاری در حافظه دارن. که این آدرس درواقع مدخل این متدها در حافظه هست و هروقت ما این متدهارو فراخوانی کنیم این آدرس فراخوانی میشه.

حالا ما می تونیم آدرس یک متد رو به یک Delegate اختصاص بدیم. خب این کار چه فایده ای داره؟
وقتیکه ما یکبار یک Delegate رو فراخوانی می کنیم درواقع متد نسبت داده شده به اون فراخوانی میشه. و برای متدهای دیگه هم میشه با یه تغییر کوچیک از همین Delegate برای فراخوانیشون استفاده کرد. این کار باعث میشه که هر متد دارای یک آدرس سخت افزاری در حافظه نباشه ، بلکه از طریق Delegate بهش دسترسی داشته باشیم.

به عبارت دیگه با این روش متدها در زمان فراخوانیشون از حافظه فضا اشغال می کنن نه در زمان کامپایل کردن ، که همون اول بهشون آدرس سخت افزاری میده (چه فراخوانی بشن و چه فراخوانی نشن).

به عبارت ساده تر میشه گفت یک Delegate مشابه یک اشاره گر (Pointer) در محیط برنامه نویسی C عمل می کنه. "

درست گفتم بهنام جان؟

ama_trig
17-06-2012, 22:29
مشکل برنامه ی قبلی بر طرف شد؟


serialdata = SerialPort1.ReadLine()

نگفتین ایراد چی هست؟ گیر می کنه؟

کلا من که همیشه با این روش های async مشکل دارم، بخصوص روی baud های مقدار بالا، بعضی وقتها سخت افزار یک بار یه چیز طولانی می فرسته، ولی توی این مدل که نوشته میشه، دو بار یه چیزی invoke یا raise می شه، بخاطر همین کلا پیغامی کار می کنم، تا هم مطمئن باشم سخت افزار درسته(هنگ نکرده، ... ) هم نوشتنش هم راحت تره، بخصوص الان که می شه با حداقل منابع سیستم، قفل کرد روی readline
، همون کاری که برنامه ی اول می کرد.
یه نکته کاراکتر ("\r\n") باید دو تا باشن برای دات نت!

morteza_rk
17-06-2012, 22:48
نگفتین ایراد چی هست؟ گیر می کنه؟

مهندس من که نتونستم بفهمم ایرادش چیه. اگه دستور serialdata = SerialPort1.ReadLine() بذارم بعد از خط serialdata = SerialPort1.Write() همون چیزی رو که می فرسته می خونه! یعنی PC داره کلمه mrk رو می فرسته و همینم می خونه نه اون چیزی که از سمت میکرو میاد.

اگرم مثل برنامه ی قبلی از تابع datarecieved استفاده کنم اصلا کار نمی کنه. من که نتونستم بفهمم مشکل از کجاست.

دارم برنامه ی آخر بهنام رو تست می کنم که اونم فعلا سه تا پیغام خطا میده که من نتونستم رفعشون کنم تا حالا.

delta2010
17-06-2012, 23:24
سلام
من میخوام یک رشته ساده را از طریق پورت سریال ارسال و دریافت کنم بوسیله visual basic 2010
لطف می کنید یک برنامه ساده برای من بزارین که یک فیلد داشته باشه که اطلاعات را نشون بده و یک فیلد که رشته نوشته شده توی اون را به پورت سریال ارسال کنه

واقعاً ممنون میشم

morteza_rk
18-06-2012, 01:15
من میخوام یک رشته ساده را از طریق پورت سریال ارسال و دریافت کنم بوسیله visual basic 2010

سلام دادا ، یه سر به لینک زیر بزن. یه برنامه با VB.NET 2010 گذاشتم.

You can see links before reply

behnam6500
18-06-2012, 12:55
بابت اون 3 خطا عذر میخوام. دلیلش این بود که موقع بازنویسی کد به vb.net ، حواسم به syntax آدرس دهی متد ها نبود و اونارو مثل سی شار ادرس دهی کرده بودم!

صحیح برنامه اینجاست



Private Delegate Sub SerialWork(ByVal Serial As System.IO.Ports.SerialPort)
Private Delegate Sub SetReadSerialData(ByVal data As String)
Dim DataReceived As String = String.Empty

Private Sub SerialWorkProcedure(ByVal Serial As System.IO.Ports.SerialPort)
If SerialPort1.IsOpen Then
Dim _DataReceived As String = SerialPort1.ReadExisting()
ReadSerialData(_DataReceived)
End If
End Sub

Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
Dim SW As New SerialWork(AddressOf SerialWorkProcedure)
SW.BeginInvoke(SerialPort1, Nothing, Nothing)
End Sub

Private Sub ReadSerialData(ByVal data As String)
If Me.InvokeRequired Then
Try
Dim RSD As New SetReadSerialData(AddressOf ReadSerialData)
Me.Invoke(RSD, data)
Catch generatedExceptionName As Exception
End Try
Else
'inja dade vojud darad!
DataReceived += data
End If
End Sub

morteza_rk
18-06-2012, 18:00
بابت اون 3 خطا عذر میخوام. دلیلش این بود که موقع بازنویسی کد به vb.net ، حواسم به syntax آدرس دهی متد ها نبود و اونارو مثل سی شار ادرس دهی کرده بودم!

خواهش میشه دادا ، من باید عذر خواهی کنم که چند روزه شما و ama_trig رو مشغول این برنامه کردم.

morteza_rk
18-06-2012, 20:41
دادا نمیشه! دارم روانی میشم. :( :unh:

مگه من نباید اونجائیکه نوشتی "inja dade vojud darad" مقدار datareceived رو بریزم توی یه textbox ؟
پس چرا هیچی نشون نمیده؟

اصلا تابع SerialPort1_DataReceive انگار اجرا نمیشه! آخه اونجا یه دستور میزارم که اگه اجرا شد توی یه textbox نشون بده. ولی هیچی نشون نمیده.

واااااااااااایییییییییییی ی.... مغزم درد می کنه!

behnam6500
18-06-2012, 23:26
پروژت رو بزار اینجا

morteza_rk
19-06-2012, 01:09
بفرما داداش ، ببخشید دیگه. ii998)

behnam6500
19-06-2012, 01:27
پروژت رو ازش جواب گرفتم.

دوتا ایراد تو کارت بود که باعث میشد جواب نده.

اولی اینکه event دریافت از پورت رو به component serial نسبت نداده بودی! این یه نمره...

دومی اینکه در button اول، پورت رو باز میکنی، میفرستی و میبندی... در دکمه دوم میخوای بخونی ولی از پورتی که اصلن باز نشده! این هم یه نمره!

برای مورد اول در properties به seriaport1 رخداد datareceived عنوان متد SerialPort1_DataReceived رو نسبت بده.

این هم خروجی که از برنامت گرفتم رو با یه ماژول sim908 تست کردم (دم دستم بود)

mrk

NORMAL POWER DOWN

+CREG: 3
??????????????
RDY

+CPIN: NOT INSERTED

+CFUN: 1

+CREG: 2

+CREG: 0

GPS Ready

morteza_rk
19-06-2012, 03:31
برای مورد اول در properties به seriaport1 رخداد datareceived عنوان متد SerialPort1_DataReceived رو نسبت بده.

از توی Properties بلد نیستم. ولی فهمیدم چی گفتی. الان نسبت دادم. اگه ممکنه از توی properties نسبت دادن رو هم بگو.


دومی اینکه در button اول، پورت رو باز میکنی، میفرستی و میبندی... در دکمه دوم میخوای بخونی ولی از پورتی که اصلن باز نشده! این هم یه نمره!

من کلا با باز و بسته کردن پورت توی VB.NET مشکل دارم. الان وقتیکه خط Serialport1.close رو حذف می کنم برنامه کار می کنه ولی فقط یکبار! بعداز اون دیگه هرچی دکمه ی اول رو بزنم بی فایدست. حالا نمی دونم دقیقا پورت رو کجا باید ببندم.

behnam6500
19-06-2012, 22:39
نه! برنامه با هر بار کلیک کردن شما اطلاعات رو نشون میده!

شما یه text box کوچیک گذاشتی که اطلاعات data receive نشون بده! اطلاعات اون متغیر شامل تمامی داده هایی هست که پورت دریافت کرده!

باید بعد از \r\n محتویات متغیر رو خالی کنی تا خود داده جدید توش بشینه. بعد از این کار یه textbox بضورت multi line بزار و در رخداد دریافتت که داده نهایی داری اینطوری بنویس:

textbox1.text+=datareeived;

جواب میده...

morteza_rk
20-06-2012, 13:53
ممنون بهنام جان. میرم که تست کنم. چقدر ریزه کاری داشت و من نمی دونستم!

morteza_rk
22-06-2012, 04:03
آقا این مخ منو کار گرفته! هر کاری می کنم نمیشه ، یعنی هرچی که می فرستم همونو می خونه. نه چیزی که از میکرو میاد.


باید بعد از \r\n محتویات متغیر رو خالی کنی تا خود داده جدید توش بشینه.
این روش مال زبان سی نیست؟ منکه بلد نیستم توی بیسیک اجراش کنم!

ولی وقتی کد TextBox2.Text += DataReceived میذرام توی یک دکمه ی دیگه درست کار می کنه ، البته اول همون چیزی که خودش می فرسته رو می خونه و بعدش چیزی که از میکرو میاد.

ولی وقتی TextBox2.Text += DataReceived میذارم توی تابع ReadSerialData همون چیزی رو که می فرسته می خونه. مگر اینکه خیلی تند دکمه ی ارسال رو بزنم تا یه چیزایی بخونه.

کد اینه :




Imports System
Imports System.IO.Ports

Public Class Form1

Dim i As Byte = 0
Dim Entr As Char = Chr(13)
Dim portnames() As String
Dim serialdata As String = ""

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

If SerialPort1.IsOpen = False Then

TextBox1.Text = "Opening port..."
SerialPort1.Open()
SerialPort1.Write("mrk" + Entr)
'SerialPort1.Close()

End If

End Sub

Private Delegate Sub SerialWork(ByVal Serial As System.IO.Ports.SerialPort)
Private Delegate Sub SetReadSerialData(ByVal data As String)
Dim DataReceived As String = ""

Private Sub SerialWorkProcedure(ByVal Serial As System.IO.Ports.SerialPort)
If SerialPort1.IsOpen Then
Dim _DataReceived As String = SerialPort1.ReadExisting()
ReadSerialData(_DataReceived)
End If
End Sub

Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim SW As New SerialWork(AddressOf SerialWorkProcedure)
SW.BeginInvoke(SerialPort1, Nothing, Nothing)
End Sub

Private Sub ReadSerialData(ByVal data As String)
If Me.InvokeRequired Then
Try
Dim RSD As New SetReadSerialData(AddressOf ReadSerialData)
Me.Invoke(RSD, data)
Catch generatedExceptionName As Exception
End Try
Else
'inja dade vojud darad!
DataReceived += data
TextBox2.Text += DataReceived
data = ""
DataReceived = ""
SerialPort1.Close()
End If
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
'TextBox2.Text += DataReceived
'DataReceived = ""
'SerialPort1.Close()
End Sub

End Class

morteza_rk
22-06-2012, 04:08
راستی این چه پیغامی خطاییه؟ آقا این رسما پدر منو در آورده.

behnam6500
22-06-2012, 19:43
برنامه درسته

چیزی که باعث میشه برات درست کار نکنه اینه که در مکانهای نا مناسب پورت میبندی!!!!

مثل این:

'inja dade vojud darad!
DataReceived += data
TextBox2.Text += DataReceived
data = ""
DataReceived = ""
SerialPort1.Close()

شما یه کاری بکن

زمانیکه برنامه داره با پورت کار میکنه و یا این احتمال وجود داره که دستگاه داده میفرسته، پورت باید باز باشه.

برای راحتی کارت در لود فرم، پورت رو باز کن و در رخداد closing اون رو ببند.

اون خطا هم به خاطر میتونه باشه که پورت بسته شده ولی چون یک thread در پردازشهای cpu بهش اختصاص داده شده بوده تو عملکردش اختلال به وجود میاد و پردازشش متوقف میشه!

morteza_rk
22-06-2012, 21:14
ممنون

میرم ببینم می تونم کاری کنم یا نه؟! خدائیش اولش اصلا فکر نمی کردم که انقدر پیچیده بشه موضوع.

morteza_rk
20-09-2012, 16:47
بالاخره بعداز یه مدت تونستم از طریق Delegate با پورت سریال کار کنم که نتیجه ی راهنمائی های دوستان خوبم ama_trig و بهنام جان هست. البته یه 10 روز وقتم رو گرفت ، ولی یادم رفت اینجا بذارم. تا الان که یهو یادم اومد.

دوتا برنامه نوشتم یکی برای VB.NET و یکی هم برای #C ، و به عنوان نتیجه گیری این تاپیک اینجا میذارم.