الجمعة، 5 أبريل 2013

التحكم عبر الحاسوب بالاجهزة الخارجية بلغة VB.NET



مقدمة
كثيرا ما نحتاج الى استخدام الحاسوب لعرض نتائج معينة ترسل من جهاز خارجي او التحكم بجهاز خارجي عبر الحاسوب .او تحسس بحالة جهاز معين وتمرير حالته الى الحاسوب الذي بدوره يحلل الحالة ويأمر الجهاز الخارجي بتنفيذ عمل معين من خلال إرسال أوامر للجهاز الخارجي.مثلا أجهزة التكييف تمرر نسبة هواء الغرفة الى الحاسوب وهو بدوره يرى اذا كانت درجة البرودة اعلى من المطلوب يرسل امر الى المكيف بتقليل نسبة البرودة . او  مثلا التحكم بمروحة نشغلها ونوقفها  عبر الحاسوب  .
اي هنا الحاسوب فقط يرسل أوامر تم تعريف معناها لدى الجهاز الخارجي لتنفذ . مثلا في برمجة PIC (الذي يكتب كوده بلغة Micro C )الخاص بجهاز إنارة خارجي مربوط بحاسوب  تم تحديد الرقم 8H لتشغيل الضوء الأخضر على الجهاز الخارجي فعند ارسال 8H بلغة VB.NET الى الجهاز الخارجي عبر المنفذ المربوط عليه الجهاز سوف يعمل الضوء الأخضر في داخله .
اي هنا دور لغة VB.NET هي تمرير أوامر  من الحاسوب الى الجهاز الخارجي  وتكون هذه الأوامر معرفة لدى الجهاز الخارجي   او يستلم الحاسوب  بيانات من الجهاز الخارجي  ليحللها ويعالجها
سنحتاج الى Cable  يربط بين الحاسوب والجهاز الخارجي ليمرر البيانات بين الطرفين كما في الشكل(1) بالأسفل   طبعا الأجهزة الخارجية ممكن ان تتصل بالحاسوب عبر Serial Port او عبر USB ففي كلا الحالتين يفتح منفذ بين الجهاز والحاسوب لكن في حالة  USB تنتقل البيانات بشكل تسلسلي وسريع و Serial Port  أيضا ينقل بشكل تسلسلي .واغلب الحواسيب الحديثة لا تحتوي على Serial Port وتستخدم USB في إرسال واستلام البيانات
 
شكل(1) Cable يربط بين حاسوب وجهاز خارجي


المنافذ COM & LPT
وبما إننا نريد أن نتعامل مع أجهزة خارجية فلا بد من وجود منفذ معين يتصل به هذا الجهاز الخارجي وكل جهاز خارجي يتصل مع الحاسوب يكون له  الحاسوب منفذ معين من خلال هذا المنفذ نستطيع إرسال بيانات للجهاز واستلام البيانات القادمة من الجهاز من خلال هذا المنفذ وتكون أرقام المنافذ بشكل التالي COM وبعده رقم المنفذ مثلا COM3 معناه المنفذ الثالث .
ولمعرفة المنفذ الذي سيشغله أي جهاز نفتح  Device Manager من خلال الذهاب إلى

 ("Start"? "Run"? "devmgmt.msc")
صورة من جهاز LapTop نرى انه يستخدم كثير من المنافذ من اجل تقنية Bluetooth 
صورة من حاسبة مكتبية

في تبويب Ports (COM & LPT) سوف تظهر لنا المنافذ المستغلة في الحاسوب مثلا هنا حدد COM1  مستخدم من قبل منفذ الاتصال. فعند ربط أي جهاز خارجي بالحاسوب سيظهر هنا اسم الجهاز ورقم المنفذ الذي سيستغله ومن خلال معرفة الرقم الذي يستغله الجهاز الخارجي نستخدم هذا المنفذ في إرسال بيانات له ونستقبل بيانات منه

التعامل مع الأجهزة الخارجية في بيئة VB.NET
هناك مكتبة خاصة بالتعامل مع الأجهزة الخارجية تحتوي على جميع الأدوات التي سنحتاجها في التعامل مع أي جهاز خارجي  سوف نستدعيها في أي برنامج نتعامل من خلاله مع المنافذ وهي المكتبة التالية

VB.NET Code
Imports System.IO.Ports
بما إننا نتعامل مع المنافذ  هناك أداة اسمها SerialPort  تمكنا من الاتصال والتعامل مع الأجهزة الخارجية فيها  فيه كل ما نحتاج إليه



أو نكونها بالكود نعرف  كائن جديد من نوع  SerialPort في التعريفات العامة بشكل التالي 
VB.NET Code
Dim SerialPort1 As New SerialPort

تطبيق: لدينا جهاز خارجي فيه شاشة عرض يعرض البيانات القادمة من الحاسوب على شاشته .عند ربطه بالحاسوب يأخذ   منفذ COM1 .وهذا الجهاز مبرمج انه يستقبل البيانات بشكل سلسلة نصية لكلي يعرضها على شاشته؟
 


المطلوب انه نكون برنامج فيه Textbox1 وزر إرسال Button1 ونكتب في Textbox1 بيانات ونضغط إرسال تعرض هذه البيانات على الجهاز الخارجي. وأداة ComboBox1 لعرض جميع منافذ. نكون مشروع جديد كما في الشكل
 


في البداية نستدعي المكتبة المتخصصة بالتعامل مع المنافذ ونكون كائن جديد من نوع SerialPort  للتعامل من خلاله مع المنفذ وإرسال بيانات إلى الجهاز الخارجي

VB.NET Code
 Imports System.IO.Ports
Public Class Form1
Dim SerialPort1 As New SerialPort
End Class
لكي نحمل ComboBox1 بجميع منافذ الحاسبة الفعالة في حدث تحميل النافذة Form1_Load نكتب الكود التالي. حيث يعمل أجراء SerialPort.GetPortNames بجلب جميع منافذ الحاسبة الفعالة لكي نعرضها منفذ منفذ داخل اداة ComboBox1  وحتى يسهل لنا اختيار المنفذ المطلوب بكل برنامج
VB.NET Code
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ComboBox1.Items.Clear()
For Each Nport As String In SerialPort.GetPortNames
ComboBox1.Items.Add(Nport)
Next
End Sub
في زر الإرسال نكتب الكود التالي  .هنا استخدمنا أسلوب يفتح منفذ و بعد كل إرسال يغلق المنفذ نستطيع أيضا فتح المنفذ مرة واحدة واستمرار إرسال البيانات عليه.وسيقوم هذا الكود بإرسال النصوص التي سنكتبها داخل  Textbox1 الى الجهاز الخارجي المربوط على المنفذ الذي سنختاره من ComboBox1
VB.NET Code
Try
With SerialPort1
.PortName = ComboBox1.Text
.BaudRate = 34800
.DataBits = 8
.Parity = IO.Ports.Parity.None
.StopBits = IO.Ports.StopBits.One
.Handshake = IO.Ports.Handshake.None
End With

If Not (SerialPort1.IsOpen = True) Then
SerialPort1.Open()
End If

SerialPort1.DiscardOutBuffer()
SerialPort1.Write(TextBox1.Text)

SerialPort1.Close()
MsgBox("تم ارسال البيانات الى الجهاز الخارجي")
Catch ex As Exception
MsgBox(ex.Message)
End Try
كود البرنامج كامل
VB.NET Code
Imports System.IO.Ports
Public Class Form1
Dim SerialPort1 As New SerialPort
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
With SerialPort1
.PortName = ComboBox1.Text
.BaudRate = 34800
.DataBits = 8
.Parity = IO.Ports.Parity.None
.StopBits = IO.Ports.StopBits.One
.Handshake = IO.Ports.Handshake.None
End With
If Not (SerialPort1.IsOpen = True) Then
SerialPort1.Open()
End If
SerialPort1.DiscardOutBuffer()
SerialPort1.Write(TextBox1.Text)
SerialPort1.Close()
MsgBox("تم ارسال البيانات الى الجهاز الخارجي")
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ComboBox1.Items.Clear()
For Each Nport As String In SerialPort.GetPortNames
ComboBox1.Items.Add(Nport)
Next
End Sub
End Class



تطبيق : برنامج استلام بصمة شخص من جهاز خارجي: ونفس الوقت نستطيع ارسال صورة من نفس الحاسبة له للتأكد من صحة توصيله للبيانات





VB.NET Code
Imports System.IO.Ports
Imports System.Text
Imports System.IO
Public Class Form1
Dim sizeimage As Integer = 0
Dim SerialPort1 As New SerialPort
Dim sendimage As Image

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
sizeimage = SerialPort1.BytesToRead
Dim comBuffer As Byte() = New Byte(sizeimage - 1) {}
SerialPort1.Read(comBuffer, 0, sizeimage)
Dim MS As MemoryStream = New MemoryStream(comBuffer)
PictureBox1.Image = Image.FromStream(MS)
MS.Close()
SerialPort1.DiscardOutBuffer()
Catch ex As Exception
End Try
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
With SerialPort1
.PortName = ComboBox1.Text
.BaudRate = 34800
.DataBits = 8
.Parity = IO.Ports.Parity.None
.StopBits = IO.Ports.StopBits.One
.Handshake = IO.Ports.Handshake.None
.WriteBufferSize = 120000000
.ReadBufferSize = 120000000
End With
If Not (SerialPort1.IsOpen = True) Then
SerialPort1.Open()
End If
Timer1.Enabled = True
MsgBox("تم تشغيل بدء التنصت  ")
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Timer1.Enabled = False
End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Try
Dim pfd As New OpenFileDialog
pfd.ShowDialog()
Dim a12 As Image = Image.FromFile(pfd.FileName)
Dim MY_MemoryStream As MemoryStream = New MemoryStream
a12.Save(MY_MemoryStream, Imaging.ImageFormat.Jpeg)
Dim ArrImage As Byte() = MY_MemoryStream.GetBuffer ' here change it to Bytes
MY_MemoryStream.Close()
SerialPort1.Write(ArrImage, 0, ArrImage.Length)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ComboBox1.Items.Clear()
For Each Nport As String In SerialPort.GetPortNames
ComboBox1.Items.Add(Nport)
Next
If ComboBox1.Items.Count > 0 Then
ComboBox1.Text = ComboBox1.Items(0)
End If
End Sub
End Class
حجم الصورة التي تتم معالجتها هنا يجب ان يكون صغير لصغر حجم Buffer

هناك 3 تعليقات:

غير معرف يقول...

عاشت ايدك اخي حسين ما قصرت. بس الرابط مال تحميل الأمثلة ميشتغل ياريت اتصحح الخطئ حتى اكدر احمل الأمثلة وشكرااا

Unknown يقول...

اخي الكريم الرابط يعمل بشكل طبيعي

غير معرف يقول...

بارك الله فيك مهندس حسين ابدعت في الشرح والله,,ربي يوفقك ان شاء الله.
أخوك حسام من ليبيا