PDA

View Full Version : خواندن مقدار از پورت (ساعت)



rezaei manesh
چهارشنبه 30 خرداد 1386, 11:38 صبح
سلام
من باید با ساعت ارتباط بگیرم
حالا می خوام دستورات خاصی رو به ساعت بفرستم و جواب ها رو دریافت کنم
کاتالوگ ساعت مثلا برای خواندن تاریخ و ساعت دستگاه به این شکل هست

Command Ctrl + E ( 05H ) ----->clock

clock ----->(SOH)3 + ( YYYYMMDDWHHMM)13 + (CHK)1 + (CR)1

CHK : از Xor کردن همه بایت های تاریخ - ساعت بدست می آید-SOH کاراکتر با کد اسکی (01H) می باشد.
خوب من حالا بعد از باز کردن پورت کد زیر رو نوشتم


StrTemp = Chr(17) & Chr(69)
SerialPort1.Write(StrTemp)
StrTemp = SerialPort1.ReadExisting
Dim StrTemp2 As String = "test" 'SerialPort1.ReadLine


مشکل کجاست که من هیچی از ساعت دریافت نمی کنم؟

__H2__
چهارشنبه 30 خرداد 1386, 14:07 عصر
سلام
فرض میکنیم که سرعت و بیت توازن و ... صحیح تنظیم شده اند.
احتمال اول: ساعت کندتر از رایانه رفتار میکند و به محض اجرا خط ارسال شما نمیوانید داده ها را بخوانید - راه حل: قبل از خواندن اطلاعات ریسمان را چند ثانیه ای بخوابانید.


احتمال دوم: کلاسس دات نت اطلاعات را به فورمتی غیر از ASCII ارسال میکند، مثلاً Unicode که باعث عدم تشخیص در مقصد میشود - راه حل: مشخصه Encoding را تنظیم کنید. یا از همه بهتر، اطلاعات را خودتان به صورت بایتی ارسال کنید و نه رشته ای.

ضمناً من درست متوجه نشدم، اون 05H در خط اول کاتالوگ ساعت را میگویم. چیست؟ نباید بعد از ارسال دو بایت قبلی این را هم ارسال کنید؟!!!

کد پیشنهادی!


SerialPort1.Encoding = System.Text.Encoding.ASCII
SerialPort1.Write(New Byte() {17, 69}, 0, 2)
'SerialPort1.Write(New Byte() {17, 69, 5}, 0, 3)
System.Threading.Thread.Sleep(2000)
Dim str As String = SerialPort1.ReadExisting

rezaei manesh
چهارشنبه 30 خرداد 1386, 14:33 عصر
سلام
ممنون از توجه تان
من این طوری پورت رو باز می کنم


With SerialPort1
If .IsOpen Then .Close()
.PortName ="com1"
.BaudRate = 9600
.Parity = IO.Ports.Parity.None
.DataBits = 8
.StopBits = IO.Ports.StopBits.One
.Encoding = System.Text.Encoding.ASCII
.ReadTimeout = 4000 ' // 4 second timeout
.Open()
End With

بعد از اجرای کد شما هم با 5 هم بدون اون خروجی ساعت حرف G هست که نمی دونم چی هست؟!!

__H2__
چهارشنبه 30 خرداد 1386, 14:57 عصر
سلام مجدداً
پیشنهاد میکنم اطلاعات را باینری بخوانید و در یک آرایه بایتی بریزید. و حتماً تعداد بایتهای دریافتی را چک کنید.
این خیلی بهتر است و برای ادامه کارتان هم ساده تر است.

شاید بایتهای دریافتی درست قابل تبدیل و نشان دادن به فرمت String نباشند! مثلاً کدهای زیر 32 که درست تبدیل به رشته نمیشوند.

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

rezaei manesh
چهارشنبه 30 خرداد 1386, 17:09 عصر
BaudRate رو می دونم که درست می دم(9600)
بیت توازن رو نتونستم پیدا کنم
اینطوری؟


Dim rxbyte As New ArrayList
Do
rxbyte.Add(.SerialPort1.ReadByte)
'ta key edame peyda kone??

'temporary
MissageBox.ShowDialog(rxbyte(i), "test", frmMessageBox.mButtons.Ok)
i = +1
If i = 10 Then Exit Do
'/temporary
Loop

کی باید از حلقه خارج شم
در ضمن این می ده 71 که کد G هست

Alireza_Salehi
چهارشنبه 30 خرداد 1386, 17:17 عصر
چیزی که مشخصه اینه که String و char هر دو به صورت پیش فرض یونیکد هستند یعنی هر کاراکتر 2 بایت! بنابراین کدی که شما در پست 1 نوشتید مفهومی متفاوت با آنچه باید باشد ایجاد خواهد کرد.(شما قصد ارسال 2 بایت داشته اید ولی 4 بایت می فرستید)

بنابراین همون طور که __H2__ گفتند از بایت استفاده کنید خیلی راحت تر خواهید بود.

مثلا برای ارسال 05H به صورت زیر عمل کنید:


Dim output() As Byte = {48, 53, 72}
SerialPort1.Write(output, 0, output.Length)


البته این طوری باید کد کاراکترهای ASCII را بدانید.

یا این که این طوری یک رشته یونیکد را با ارایه بایت ASCII تبدیل کنید:


Dim OutputString As String = "05H"
Dim ASCIIENC As New System.Text.ASCIIEncoding()
Dim Output() As Byte = ASCIIENC.GetBytes(OutputString)
SerialPort1.Write(Output, 0, Output.Length)

rezaei manesh
چهارشنبه 30 خرداد 1386, 18:23 عصر
من کد را به شکل زیر تغییر دادم اما تغییری در نتیجه نداشتم


Dim OutputString As String = Chr(17) & Chr(69) ' & "05H"
Dim ASCIIENC As New System.Text.ASCIIEncoding()
Dim Output() As Byte = ASCIIENC.GetBytes(OutputString)
.SerialPort1.Write(Output, 0, Output.Length)

System.Threading.Thread.Sleep(2000)

Dim rxbyte As New ArrayList

Do While .SerialPort1.BytesToRead > 0
Dim b As Byte = .SerialPort1.ReadByte()
rxbyte.Add(b)
MissageBox.ShowDialog(b, "test", frmMessageBox.mButtons.Ok)
Loop

لازم به ذکر است که ساعت مدل st2000 شرکت علم و صنعت هست

__H2__
پنج شنبه 31 خرداد 1386, 09:47 صبح
سلام

من کد را به شکل زیر تغییر دادم اما تغییری در نتیجه نداشتم


Dim OutputString As String = Chr(17) & Chr(69) ' & "05H"
Dim ASCIIENC As New System.Text.ASCIIEncoding()
Dim Output() As Byte = ASCIIENC.GetBytes(OutputString)
.SerialPort1.Write(Output, 0, Output.Length)

System.Threading.Thread.Sleep(2000)

Dim rxbyte As New ArrayList

Do While .SerialPort1.BytesToRead > 0
Dim b As Byte = .SerialPort1.ReadByte()
rxbyte.Add(b)
MissageBox.ShowDialog(b, "test", frmMessageBox.mButtons.Ok)
Loop

لازم به ذکر است که ساعت مدل st2000 شرکت علم و صنعت هست

گرچه میتوان کد را اصلاح کرد و بهترش کرد، (مثلاً حلقه نیازی نیست!) ولی کد فوق صحیح است و ایرادی جدی ای نمیتوان به آن گرفت، پس اگر کار نکرده، پیشنهاد میکنم پارامترهای اتصال را دستکاری کنید. (پست 3)

راستی مطمئن هستید شماره پورت COM را درست داده اید؟! بعضی وقتها XP تابلوبازی های خاصی در می آورد.!

در دستور نمایش پیغام هم پیشنهاد میکنم rxbyte.Count را چاپ کنید و نه b را، چون اینطوری بهتر میفهمید چند بایت دریافت کرده اید. (اگر دریافتی داشته باشید!)

rezaei manesh
پنج شنبه 31 خرداد 1386, 11:22 صبح
سلام
از بابت شماره پورت مطمئن هستم اما پارامتر های ارسال رو در مورد همه آیتم ها مطمئن نیستم فقط دو مورد اول رو مطمئن هستم
rxbyte.Count هم صفر بر هست!!!!
کد بالا رو چطور باید اصلاح کنم؟
ممنون از پیگیری تان

__H2__
پنج شنبه 31 خرداد 1386, 14:52 عصر
سلام
یک مطلب مهم که شاید گیر کار شما باشد!!!!
من یک چیزهایی از قدیم یادم می آید ولی درست نمیدانم!!!! یک سری از ابزار آلات برای ارسال و دریافت از بافر استفاده میککند و تا وقتی بافر به حد قابل قبولی نرسد ارسال را انجام نمیدادند! الآن دیدم و متوجه شدم این کلاسس هم دو بافر دارد، پیشنهاد میکنم اندازه بافر خروجی را صفر یا یک تایین کنید تا به محض دادن بایت به ان، مجبور به شروع ارسال شود!!!!!

مثلاً این کد: (پارامترهای اتصال را شانسی نوشته ام!)


Dim sp As New System.IO.Ports.SerialPort("COM1", 9600, System.IO.Ports.Parity.Odd, 8, System.IO.Ports.StopBits.None)
sp.WriteBufferSize = 1 '3

sp.Write(New Byte() {17, 69, 5}, 0, 3)
System.Threading.Thread.Sleep(2000)
Dim iReceiveBytesCount As Integer = sp.BytesToRead

If iReceiveBytesCount > 0 Then
Dim buffer(iReceiveBytesCount) As Byte
sp.Read(buffer, 0, iReceiveBytesCount)
'...
End If
System.Windows.Forms.MessageBox.Show(CStr(iReceive BytesCount))

sh
پنج شنبه 31 خرداد 1386, 16:40 عصر
سلام
الان خونه نیستم که کدی که شاید کار کنه رو برات بفرستم ولی فعلا برای بررسی نحوه ارسال اطلاعات روی پورت هایپر ترمینال ویندوز رو باز کن و به اون پورت کانکت شو . در اکثر دستگاههای که من باهاشون کار کردم (ساعت و باسکولهای بزرگ جاده ای) اطلاعات با سرعت 2400 یا 1200 انتقال پیدا میکنن . با هاپیر ترمینال به راحتی میتونی مشکلاتت رو حل کنی و کدش رو بنویسی

rezaei manesh
یک شنبه 03 تیر 1386, 17:10 عصر
سلام
آقا شهریار من کار با هایپر ترمینال ویندوز رو بلد نیستم و...
اما تونستم بالاخره با ساعت یک ارتباط (عاطفی) برقرار کنم و تاریخ و ساعت اون رو بخونم
توسط کد های جناب __H2__ اما با کمی تغییر
فعلا هم دیگه ساعت ندارم تا ادامه بدم ادامه این قسمت می مونه برای چند روز دیگه و..
با تشکر از همه شما دوستان بسیار عزیز

rezaei manesh
سه شنبه 16 مرداد 1386, 10:43 صبح
با سلام مجدد
من بعد از یه مدت دوباره ساعت به دستم رسید و یک ماه هم فرصت دارم که همه کارهای مربوط به ساعت رو انجام بدم که کم هم نیستند و...
با همون کدی که قبلا ساعت رو می خوندم الان دیگه نمی شه الان یک بایت دریافت می کنم و اونم 0047 هست نمی دونم مشکل از کجاست در ضمن با هاپرترمینال هم ارتباط برقرار می کنم و همه چیز درسته وقتی که اونجا ctrl +E رو می زنم تاریخ و ساعت رو به هم می ده اما وقتی که همون تنظیمات رو تو کد انجام می دم اینطوری میشه
این هم کد هام


Public Function GetClockDateTime() As Int16
With My.Forms.FrmSettingDT
Dim i As Int16 = 0
'For i As Int16 = 0 To .grid1.RowCount - 1
Try
If .grid1.RowCount = 0 Then Return 0 'temp
Me.strCOMNO = .grid1.Rows(i).Cells("COMNO").Value 'com17
Me.intBAUDRATE = .grid1.Rows(i).Cells("BAUDRATE").Value '9600
.grid1.Rows(i).Cells(1).Selected = True
'Dim sp As New IO.Ports.SerialPort '("COM17", 9600, Parity.None, 8, StopBits.One)
With .SerialPort1 'sp
If OpenPort(My.Forms.FrmSettingDT.SerialPort1) = 1 Then
Try '{48, 53, 72}="05H"

'''''''''''''''
.Write(New Byte() {17, 69, 5}, 0, 3)
' ''or
'Dim OutputString As String = Chr(17) & Chr(69) ' & "05H"
'Dim ASCIIENC As New System.Text.ASCIIEncoding()
'Dim Output() As Byte = ASCIIENC.GetBytes(OutputString)
'.Write(Output, 0, Output.Length)
''''''''''''''''

System.Threading.Thread.Sleep(2000)
Dim iReceiveBytesCount As Integer = .BytesToRead
Dim Text2Display As String = ""
If iReceiveBytesCount > 0 Then

Dim buffer(iReceiveBytesCount) As Byte
.Read(buffer, 0, iReceiveBytesCount)
For j As Integer = 0 To buffer.GetUpperBound(0)
Text2Display += buffer(j).ToString("X2") & " "
Next

End If
MessageBox.Show(CStr(iReceiveBytesCount))
MissageBox.ShowDialog(Text2Display, "test", frmMessageBox.mButtons.Ok)
'End If
Catch ex As Exception
MissageBox.ShowDialog(ex.Message.ToString, "خطا", frmMessageBox.mButtons.Ok)
End Try
' Else
' MissageBox.ShowDialog("خطا در ارتباط با ساعت ", "خطا", frmMessageBox.mButtons.Ok)
End If
End With
Catch ex As Exception
MissageBox.ShowDialog("خطا در ارتباط با ساعت " & vbCrLf & ex.Message.ToString, "خطا", frmMessageBox.mButtons.Ok)
End Try
'Next
End With
End Function

Private Function OpenPort(ByRef SerialPort1 As SerialPort) As Int16
Try
With SerialPort1
If .IsOpen Then .Close()
.PortName = Me.strCOMNO
.BaudRate = Me.intBAUDRATE
.Parity = IO.Ports.Parity.None
.DataBits = 8
.StopBits = IO.Ports.StopBits.One
'.Encoding = System.Text.Encoding.ASCII
'.ReadTimeout = 4000 ' // 4 second timeout
'.WriteBufferSize = 1 ' 3 ' error
.Open()
End With
OpenPort = 1
Catch ex As Exception
MissageBox.ShowDialog("خطا در باز کردن پورت " & Me.strCOMNO & vbCrLf & ex.Message.ToString, "خطا", frmMessageBox.mButtons.Ok)
OpenPort = -1
End Try

End Function
''''''''''''''''''''''''''
اینم یه مدل دیگه که فرقس نمی کنه فقط 0071 می ده جای 47
Dim sp As New System.IO.Ports.SerialPort(Me.grid1.Rows(0).Cells("COMNO").Value, 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One)

Try
'sp.WriteBufferSize = 3
If Me.SerialPort1.IsOpen Then Me.SerialPort1.Close()
If sp.IsOpen Then sp.Close()
sp.Open()
sp.Write(New Byte() {17, 69}, 0, 2)
System.Threading.Thread.Sleep(2000)
Dim iReceiveBytesCount As Integer = sp.BytesToRead
If iReceiveBytesCount > 0 Then
Dim buffer(iReceiveBytesCount) As Byte
sp.Read(buffer, 0, iReceiveBytesCount)
For i As Integer = 0 To buffer.Length - 1
MissageBox.ShowDialog(buffer(i), "پیام", frmMessageBox.mButtons.Ok)
Next i

End If
System.Windows.Forms.MessageBox.Show(CStr(iReceive BytesCount))
Catch ex As Exception
MsgBox(ex.Message)
Finally
If sp.IsOpen Then sp.Close()

End Try

End Sub

در هاپر ترمینال این رو می ده با تنظیماتی که در عکس گذاشتم
13860516311085***
جای * شکلک میده

rezaei manesh
چهارشنبه 17 مرداد 1386, 19:10 عصر
سلام
با تشکر از کمک دوستان
من مشکلم حل شد کلا ساختار رو یکمی تغییر دادم درست شد