جداسازی کرکتر

9up

Active Member
با عرض سلام و خسته نباشید
یه سوال داشتم
لطفا راهنماییم کنید

من با میکرو کنترلر یه سری دیتا رو به صورت زیر میفرستم به پورت سریال:
کد:
%24.5-

حالا چطور میشه این کاراکترها رو از هم تشخیص داد!؟

من میخوام وقتی کاراکتر "%" اومد، بقیه اعداد رو توی یه تکست نشون بده و وقتی به کاراکتر "-" رسید، کل اون خط پاک بشه تا دوباره از اول شروع بشه. (یعنی 24.5 نوشته شده در تکست پاک شود تا مقدار بعدی که 24.6 است جای آن قرار گیرد)

در حقیقت 24.5 توی تکست نشون داده بشه و اون دوتا کاراکتر کدی هستند که صحت دریافت اطلاعات از میکرو را تعیین می کنند.

با تشکر.
 

ms_vb

Member
سلام
من نمیدونم شما چطور داده ها را میفرستید
ولی فرض میکنیم داده های ارسال شما در یک متغیر بنام Data ذخیره میشه
میتونید داده ها رو به شکل زیر تفکیک و بررسی کنید:

[BASS]
Dim Data As String = "%24.5-"
Dim Count As IEnumerator
Dim WriteInTextBox As Boolean = False
Count = Data.GetEnumerator
While Count.MoveNext
Select Case Count.Current
Case "%"
WriteInTextBox = True
Case "-"
WriteInTextBox = False
TextBox1.Text = ""
Case Else
If WriteInTextBox Then
TextBox1.Text += Count.Current
Else
'کدهای زمانی که "%" استفاده نشده
End If
End Select
End While
[/BASS]
 
آخرین ویرایش:
  • Like
Reactions: 9up

9up

Active Member
با تشکر از پاسخ شما.
ولی مشکلم حل نشد.

بزارید کامل توضیح بدم تا شاید راه حلی باشه.

دما توسط میکرو خونده و توسط ماژول USB به کامپیوتر ارسال میشه. اگر دما توسط نرم افزارهایی که برای کامپایلرهای برنامه نویسی میکروکنترلر هستند، نشان داده بشه، هیچ مشکلی نیست. (مثل برنامه Serial Communicator در نرم افزار ProtonIDE و BascomAVR Terminal Emulator در نرم افزار bascomAVR که تصاویری از اون هم پیوست کردم)
حال اگر همین دیتا رو توسط VB بخونم مشکل داره و کامل نشون داده نمیشه!! پس مطمئنا مشکل از برنامه VB است.

کد ارسال دیتا توسط واحد Usart میکروکنترلر:
[BASS]HSerOut [Dec FT/10,".",Dec FT Dig 0][/BASS]

کد دریافت دیتا در vb.NET 2010:
[BASS]Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived ReceivedText(SerialPort1.ReadExisting()) 'Automatically called every time a data is received at the serialPort
End Sub
Private Sub ReceivedText(ByVal [text] As String)
'compares the ID of the creating Thread to the ID of the calling Thread
If Me.rtbReceived.InvokeRequired Then
Dim x As New SetTextCallback(AddressOf ReceivedText)
Me.Invoke(x, New Object() {(text)})
Else
Me.rtbReceived.Text = [text]
End Sub[/BASS]

لطفا راهنمایی کنید.
ProtonIDE.pngApp.pngBascom.png
 

ms_vb

Member
من نمیدانم الگوریتم شما در تابع ReceivedText چیه و نتونستم کدهای این تابع رو تحلیل کنم
ولی احتمال میدهم که اطلاعات شما توسط
کد:
[COLOR=#333333]SerialPort1.ReadExisting()[/COLOR]
خوانده شده باشه...
و مقدار این دستور دیتایی باشه که به برنامه شما ارسال شده
در اینصورت من نمیدانم مشکل شما چیه؟ و با کد زیر میتونید از داده ارسالی استفاده کنید:
[BASS]
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim Data As String = SerialPort1.ReadExisting()
Dim Count As IEnumerator
Dim WriteInTextBox As Boolean = False
Count = Data.GetEnumerator
While Count.MoveNext
Select Case Count.Current
Case "%"
WriteInTextBox = True
Case "-"
WriteInTextBox = False
rtbReceived.Text = ""
Case Else
If WriteInTextBox Then
rtbReceived.Text += Count.Current
Else
'کدهای زمانی که "%" استفاده نشده
End If
End Select
End While
End Sub

[/BASS]



 
آخرین ویرایش:
  • Like
Reactions: 9up

9up

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

Error.png
 

9up

Active Member
ببخشید، برنامه رو پیوست کردم. لطفا نگاه بندازید.
هیچ وقت، هیچ چیز، این قدر اعصابمو بهم نریخته بود!
هرکاری میکنم جواب نمیده!
الان دیتا رو پشت سر هم نشون میده.
اول اینکه نباید پشت سر هم نشون بده و فقط جای خودش بمونه. یعنی دیتای جدید اضافه نشه به تکست باکس. (معمولا برای اینکه به تکست باکس چیزی اضافه نشه نباید از & استفاده کرد ولی وقتی از & استفاده می کنم دیتا ناقص نشون داده میشه.)
و دوم اینکه باید % و - از اول و آخر حرف حذف و نمایش داده شه.


Untitled.png
 

پیوست ها

  • SerialPortInterface 1.rar
    66.7 کیلوبایت · بازدیدها: 1

ms_vb

Member
من متوجه الگوریتم شما نشدم
اگر اشتباه نکرده باشم شما میخواهید دما را به این شکل به کامپیوتر ارسال کنید:

%24.5
در این صورت مقدار SerialPort1.ReadExisting() شما باید
کد:
%24.5
باشه
برای اطمینان از اینکه این مقدار رو دریافت کردید برنامه تون رو trace کنید و با بردن ماوس به روی متغیر readExisting() مقدارش رو بخونید تا مطمئن شوید که به شما مقدار 24.5% رو داده
مقداری که دماسنج برای شما ارسال میکنه چیه؟ و چه مقداری میخواهید روی rtbReceived.Text به نمایش گذاشته بشه؟

برنامه زیر را ببینید:
مشاهده پیوست SerialPortInterface 1.zip
 

9up

Active Member
trace رو متوجه نشدم که کجاست!
اصلا دیگه نمیخوام از % و - استفاده کنم چون فاصله کمه و خطایی هم ایجاد نمیشه.
الان عددی که میفرستم درست تو VB نشون داده میشه . خطایی نداره.
فقط بهم بگین که چور می تونم این عدد رو به صورت مجزا نشون بدم.
میکرو هر 500 میلی ثانیه دما رو میفرسته و vb هم اونو پشت سر هم نشون میده. حالا اگه نخوایم پشت سر هم نشون بده باید چه کرد!؟!؟ (به جز راه حل &)
4 عدد مختلف رو تست میکنیم:
24.1
24.0
23.9
23.9

ولی تو VB اینجوری نشون میده:
24.124.023.923.9
 

ms_vb

Member
کد زیر رو
کد:
    Private Sub ReceivedText(ByVal [text] As String)
        'compares the ID of the creating Thread to the ID of the calling Thread
        If Me.rtbReceived.InvokeRequired Then
            Dim x As New SetTextCallback(AddressOf ReceivedText)
            Me.Invoke(x, New Object() {(text)})
        Else
            rtbReceived.Text &= [text]
        End If
    End Sub
به این کد تغییر بده:

کد:
    Private Sub ReceivedText(ByVal [text] As String)
        'compares the ID of the creating Thread to the ID of the calling Thread
        If Me.rtbReceived.InvokeRequired Then
            Dim x As New SetTextCallback(AddressOf ReceivedText)
            Me.Invoke(x, New Object() {(text)})
        Else
            rtbReceived.Text = [text]
        End If
    End Sub
 
  • Like
Reactions: 9up

9up

Active Member
این قضیه & رو می دونستم!! قبلا گفتم که وقتی & مینویسم عدد رو ناقص می نویسه توی تکست باکس!! (نمیدونم چه مرگشه)

داداش خیلی خستت کردم. حوصلتم سر اوردم. دستت درد نکنه. زحمت کشیدی. وقت گذاشتی. ممنونم ازت.

من هم یه خاکی تو سرم میریزم .

باز هم متشکرم.
 

ms_vb

Member
قبل از نوشتن
کد:
[COLOR=#333333]rtbReceived.Text = [text][/COLOR]
دستور
HTML:
MsgBox ([text])
رو بنویس ببین عددی که به برنامه پاس میشه درسته یا نه
خواهش میکنم
امیدوارم مشکلت حل شه
 
  • Like
Reactions: 9up

9up

Active Member
نه!!!
مثلا اگه عدد 23.8 باشه
یه بار
کد:
2
و بار دوم
کد:
3.8
مسیج میده!!

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

ms_vb

Member
خب شما باید از همون روش قبلی استفاده کنی و کاری کنی که تا به "%" نرسید اطلاعات textbox پاک نشه...
البته دقت داشته باش که "%" رو باید اول متن ارسالی بفرستی، نه آخرش
مثلا میکرو باید عدد زیر رو به برنامه ارسال کنه
کد:
[COLOR=#333333]%24.5[/COLOR]

تابع ReceivedText رو هم به شکل زیر تغییر بده

[BASS]

Private Sub ReceivedText(ByVal [text] As String)
'compares the ID of the creating Thread to the ID of the calling Thread
If Me.rtbReceived.InvokeRequired Then
Dim x As New SetTextCallback(AddressOf ReceivedText)
Me.Invoke(x, New Object() {(text)})
Else
Dim Count As IEnumerator
Count = [text].GetEnumerator
While Count.MoveNext
Select Case Count.Current
Case "%"
rtbReceived.Text = ""
Case Else
rtbReceived.Text += Count.Current
End Select
End While


End If
End Sub

[/BASS]
 
آخرین ویرایش:
  • Like
Reactions: 9up

9up

Active Member
سلام
آقا مشکل حل شد. خیلی خیلی ممنون
یه سوال دیگه دارم. شرمنده به خدا مزاحمت میشم. قول مید

اول 24.5% و بعد از 2 ثانیه تاخیر 90.3# را با میکرو ارسال می کنم.
حالا چطور میشه که هر کدوم از این دیتاهارو تو یه تکست باکس نشون بده و % و # اولش رو هم حذف کنه؟

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

با تشکر فراوان
 

ms_vb

Member
سلام
خدا را شکر
اول یه متغیر سراسری تعریف کن، تا نوع داده دریافتی رو ذخیره کنی:

کد:
Dim IsRecivedDama As Boolean = True

این متغیر وضعیت عدد دریافتی رو ذخیره میکنه که دماست یا نه اگه دما بود True در غیر اینصورت False میشه، که پیشفرضش رو True در نظر گرفتم که اگر میکرو مشخص نکرد که دماست یا رطوبت Textbox دما عدد رو نشون بده

دستور Select Case هم 3 تا Case خواهد داشت :


کد:
[LEFT]Case "%"
             IsRecivedDama = True
             txtReceivedDama.Text = ""
[/LEFT]
با این Case شما به کامپایلر میگویید که اگر "%" در متن ارسالی بود نوع داده دریافتی دما خواهد بود و Textbox مربوط به دما پاک خواهد شد تا آماده دریافت داده جدید شود



کد:
[LEFT]                    Case "#"
                        IsRecivedDama = False
                        txtReceivedRotobat.Text = ""
[/LEFT]
با این Case هم شما به برنامه اعلام میکنید که اگر متن دریافتی حاوی # بود نوع داده دریافتی رطوبت خواهد بود و TextBox مربوطه پاک خواهد شد تا آماده دریافت داده جدید شود



کد:
[LEFT]                    Case Else
                        If IsRecivedDama Then
                            txtReceivedDama.Text += Count.Current
                        Else
                            txtReceivedRotobat.Text += Count.Current
                        End If
[/LEFT]
و آخرین Case که مربوط به نمایش می باشد، اگر قبلا Case مربوط به دما اجرا شده باشد اطلاعات را داخل Text مربوط به دما و در غیر اینصورت داده های دریافتی را در Text مربوط به رطوبت قرار خواهد داد
 

پیوست ها

  • SerialPortInterface 1.zip
    149.5 کیلوبایت · بازدیدها: 3
آخرین ویرایش:
  • Like
Reactions: 9up

9up

Active Member
حقیقتش متوجه نشدم.

همون کدی که شما فرستادی رو یه case دیگه یهش اضافه کردم به این صورت:

[BASS] Private Sub ReceivedText(ByVal [text] As String) If Me.TempLable.InvokeRequired Then
Dim x As New SetTextCallback(AddressOf ReceivedText)
Me.Invoke(x, New Object() {(text)})
Else
Dim Count As IEnumerator
Count = [text].GetEnumerator
While Count.MoveNext
Select Case Count.Current
Case "%"
TempLable.Text = ""
Case "#"
TempLable.Text = ""
Case Else
TempLable.Text += Count.Current
End Select
End While
End If
End Sub[/BASS]

و این جوری نشون میده دیتاهارو:
از اول دیتاها، % و # رو حذف میکنه و و هر دو دیتا رو وی تکست باکس دما نشون میده. حالا می خوام این دیتا دومی تو یه تکست باکس مربوط به رطوبت نشون داده بشه.
 

جدیدترین ارسال ها

بالا