Wednesday, October 23

Emgu Convert Colour image to Gray,Binary Image

พอดีมีคนถามหาโค๊ด ซึ่งเป็นโค๊ดที่ผมเริ่มศึกษา Emgu ใหม่ๆ (ตอนนี้ ก็ยังใหม่อยู่เหมือนเดิม ;P ) ก็เลยเอามาอัพไว้ที่บล๊อกสักหน่อย

ไม่มีอะไรมากครับ เป็นการโหลด Image เข้ามา แล้วทำการแปลงเป็นภาพ Gray , Binary Image เฉยๆ

Emgu Convert Colour image to Gray,Binary Image

ไลบรารี่ที่ดึงเข้ามาใช้ในโปรเจค

Emgu Convert Colour image to Gray,Binary Image

อันนี้เป็นโค๊ด

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;

using System.IO;
using Emgu.CV;
using Emgu.CV.Structure;


namespace CovertImage
{
    public partial class Form1 : Form
    {
        string imageFileName;
        Image<Bgr, Byte> imageCoverted;
        public Form1()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            string extension;
            OpenFileDialog openFile = new OpenFileDialog();
            openFile.Filter = "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*";
            openFile.FilterIndex = 1;
            openFile.RestoreDirectory = true;
            if (openFile.ShowDialog() == DialogResult.OK)
            {
                extension = Path.GetExtension(openFile.FileName);
                if (extension == ".jpg" | extension == ".gif" | extension == ".bmp")
                {
                    imageFileName = openFile.FileName;
                    Image<Bgr, byte> img = new Image<Bgr, byte>(openFile.FileName);
                    imageCoverted = new Image<Bgr, Byte>(openFile.FileName);
                    pictureBox1.Image = img.ToBitmap(pictureBox1.Width, pictureBox1.Height);
                    pictureBox2.Image = null;
                }
                else
                {
                    pictureBox1.Image = null;
                    pictureBox2.Image = null;
                    MessageBox.Show("File does not supported");
                }

            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            processImage(imageCoverted, 0);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            processImage(imageCoverted, 1);
        }

        private void processImage(Image<Bgr,byte> img,int Mode)
        {
            switch (Mode)
            {
                case 0:
                    label2.Text = "Gray";
                    pictureBox2.Image = img.Convert<Gray, byte>().ToBitmap(pictureBox2.Width, pictureBox2.Height);
                    break;
                case 1:
                    label2.Text = "Binary";
                    pictureBox2.Image = img.Convert<Gray, Byte>().ThresholdBinary(new Gray(127), new Gray(255)).ToBitmap(pictureBox2.Width, pictureBox2.Height);
                    break;
            }

        }

        private void toolStripStatusLabel1_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://vs-visual-studio.blogspot.com/");
        }
    }
}

ดาวน์โหลดซอร์สโค๊ดและโปรเจค https://dl.dropboxusercontent.com/u/65353188/CovertImage.zip

อ่านเพิ่มเติม...

Saturday, October 19

Seven-segment LED Control for .NET

Seven-segment LED Control for .NET         บางที การแสดงผลตัวเลข แบบ 7-segment บน C# application form ก็ดูดีเหมือนกันนะ ยิ่งถ้าเรากำลังออกแบบหน้าต่างสำหรับงานควบคุม แสดงผล แล้วหล่ะก็ ดูดีเลยทีเดียว

        วันนี้ เรามาติดตั้้ง 7-Segment ลงบน C# win form กันนะครับ พอดี มีคนทำไว้แล้ว เราก็แค่ ดึงมาใช้งานเลย

เริ่มจากดาวน์โหลด ซอร์สโค๊ดมาก่อนครับ จาก CodeProject จากนั้นทำการแตกไฟล์ไว้ที่ไหนก็ได้ เราต้องการแค่ไฟล์ SevenSegment.cs และ ไฟล์ SevenSegmentArray.cs ของเขามาใส่ไว้ที่ toolbox ของเรา

ทีนี้ เรามาสร้างโปรเจคใหม่ บน C# ของเรา ให้เลือกเป็น windows form นะครับ เราจะได้ form เปล่าๆ ขึ้นมา  1 form  ยังไม่ต้องทำอะไร กับมันครับ ให้เราไปคลิกขวาที่ project ของเรา แล้วเลือก Add->Existing Items… แล้วก็เลือกไฟล์ SevenSegment.cs และ ไฟล์ SevenSegmentArray.cs  ที่ดาวน์โหลดมา เอามาไว้ที่โปรเจคของเรา

Seven-segment LED Control for .NET

จากนั้น ก็ไปที่เมนู Build—> Build Solution (F6) ไม่น่าจะมี Error อะไรเกิดขึ้น เพราะเรายังไม่ได้ Coding อะไรเลย น่าจะ success นะครับ จากนั้น ให้สังเกตที่ Toolbox ของเรา จะเกิดกลุ่ม Tab ใหม่ขึ้นมา ชื่อ SenvenSegTest Components

Seven-segment LED Control for .NET

เพียงแค่นี้ เราก็ได้ 7-segment มาไว้ใช้งานบนหน้าฟอร์มของเราแล้วครับ ที่เหลือ ก็แล้วแต่จะโปรแกรมมิ่ง กันเอาเองนะครับ ลองศึกษาดูวิธีการใช้งานจาก source code ที่ดาวน์โหลดมาแล้วกันครับ ไม่น่าจะยากเกินความสามารถกันนะครับ

อ่านเพิ่มเติม...

C# Random number

ปกติก็ใช้ไม่บ่อยนะ แต่เวลาจะใช้ทีไรลืมทุกที ปกติจะใช้เวลาทดสอบโปรแกรม ให้มันสุ่มตัวเลขขึ้นมา แล้วเอาไปแสดงที่หน้า control แต่ด้วยความที่มักจะลืม ก็เลยเขียนไว้ที่บล๊อกซะเลย ดูซิ มึงจะลืม อีกไหม  55555+

ประกาศตัวแปรไว้ใน class project ของเรา เป็นตัวแปร Random

Random num = new Random();

ทีนี้ พอเราจะนำมันไปใช้งาน ก็แค่ สั่งให้มันสุ่มตัวเลขมาให้เรา โดยจะมี 2 เมธอดที่สำคัญคือ

Next และ Double ( 2 ตัวนี้ ก็น่าจะเพียงพอแล้ว )

Random object C#

ถ้าเราต้องการให้มันสุ่มตัวเลขจำนวนเต็ม ตั้งแต่ 0 จนถึง System.Int32.MaxValue เช่น เราต้องการให้มีค่าตั้งแต่ 0 ถึง 1000 เราก็ใช้รูปแบบนี้  num.Next(1000)

หากต้องการสุ่มจำนวนเต็มตั้งแต่ 500 ถึง 1000 ก็ใช้รูปแบบนี้ num.Next(500,1000)

หากเราต้องการสุ่มเลยทศนิยม ก็ใช้ num.NextDouble() มันจะสุ่มตัวเลขระหว่าง 0.0 ถึง 1.0 ซึ่งเป็นตัวเลขชนิด Double

แล้วถ้าอยากได้ค่าอยู่ระหว่า่ง 0.0 ถึง 100.99 หล่ะ ง่ายๆ ก็แค่เอา

num.NextDouble() * 100  แค่นี้ เราก็จะได้ตัวเลขที่ถูกสุ่มมาระหว่าง 0.0 ถึง 1.0 แล้วคูณด้วย 100 

หวังว่า คงไม่ลืมแล้วหล่ะ เขียนเอง อ่านเอง แบบนี้

อ่านเพิ่มเติม...

Saturday, October 5

C# ติดต่อโลกภายนอกด้วย SerialPort Class

     ถึงแม้ว่าคอมพิวเตอร์จะพัฒนาไปไกล จนถึงระดับ 64 บิตแล้วก็ตาม สิ่งหนึ่งที่ยังเป็นที่นิยม ยังมีใช้อยู่ทั่วไปก็คือ พอร์ตอนุกรม โดยเฉพาะในโลก Embedded system แล้ว หากคุณต้องการที่จะรับส่งข้อมูลระหว่างอุปกรณ์ภายนอก และโปรแกรมภายในคอมพิวเตอร์แล้ว พอร์ตอนุกรม หรือ Serial Port ก็ยังเป็นที่นิยมอยู่ ด้วยความที่มันติดต่อกันในรูปแบบที่ไม่ซับซ้อน สามารถเข้าใจได้ง่าย ช่วยให้งานจบได้เร็ว จึงทำให้ทุกวันนี้ เรายังพบเห็นโปรแกรมที่รับส่งข้อมูลทางพอร์ตอนุกรมอยู่ ถึงแม้่ว่าคอมพิวเตอร์บางเครื่องจะไม่มีพอร์ตอนุกรมแล้วก็ตาม เราก็ยังสามารถที่จะใช้ตัวแปลง USB to Serial ทำงานได้เหมือนๆ กัน

C# ติดต่อโลกภายนอกด้วย  SerialPort Class

วันนี้เรามาเขียนโปรแกรมรับส่งข้อมูลทางพอร์ตอนุกรมกันครับ โดยผมจะเขียน application เพื่อรับส่งข้อมูลระหว่างคอมพิวเตอร์ กับ ไมโครคอนโทรลเลอร์ผ่านทาง Serial Port โดยมีเงือนไขดังนี้

MCU ทำการส่งข้อมูลออกไป โดยมีรูปแบบดังนี้  #ADC1,ADC2,ADC3* โดยเราให้

  • # แสดงการเริ่มต้นส่งข้อมูล
  • ADCx ค่าอนาล๊อกที่อ่านได้จากช่อง Analog input ของ MCU มีค่าอยู่ระหว่าง 0-1023
  • * แสดงจุดสิ้นสุดข้อมูล

ซึ่ง Visual C# จะรับข้อมูลแล้วไปประมวลผลตามที่เราออกแบบไว้ จากนั้น Visual C# สามารถส่งข้อมูลออกไปหาที่ตัว MCU ได้ด้วยรูปแบบดังนี้ #Button1,Button2,Button3* โดยเราให้

  • # แสดงการเริ่มต้นส่งข้อมูล
  • Buttonx แสดงค่าสถานะการกดปุ่ม  0:ปุ่มไม่ถูกกด,  1:ปุ่มถูกกด 
  • * แสดงจุดสิ้นสุดข้อมูล

ผมออกแบบหน้าต่างฟอร์มแบบนี้ครับ

C# ติดต่อโลกภายนอกด้วย  SerialPort Class

ในส่วนของโค๊ด

เริ่มจากเราต้อง using System.IO.Ports; เพื่อจะสร้างออปเจค serial port จาก class SerialPort เมื่อเราได้ using เข้ามาแล้ว เราจึงสามารถทีจะสร้างออปเจคได้

serial = new SerialPort(comportComboBox.SelectedItem.ToString(), 9600, Parity.None, 8, StopBits.One);

เราทำการเพิ่ม event handler ให้กับออปเจค เพื่อจะแยกโค๊ดไปเขียนการรับค่าทาง serial port

serial.DataReceived += new SerialDataReceivedEventHandler(serial_DataReceived); // พิมพ์ serial.DataReceived += แล้่วกด Tab 2 ครั้ง โปรแกรม Visual C# ide เขาจะสร้าง method serial_DataReceived  ให้อัตโนมัติ

แล้วผมก็เขียนโค๊ดจัดการการรับข้อมูลใน event handler นี้

void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)

        {

            string d = serial.ReadLine();

            int intBegin = d.IndexOf("#");

            int intEnd = d.IndexOf("*");

            int length = intEnd - (intBegin+1);

            char[] ch = { ','};

            raw = d;

            data = d.Substring(intBegin + 1, length).Split(ch);

            this.BeginInvoke(new updateAnalogLabel(updateLabel));

        }

ส่วนการอัพเดทตัวเลขที่ได้รับมาไปที่ control ต่างๆบนฟอร์มนั้น เราต้องอาศัย delegate พังก์ชั่นจัดการในส่วนนี้ เพราะในระหว่างที่รับข้อมูลอยู๋นั้น มันไม่มีส่วนไหนของโปรแกรมไปอัพเดทข้อมูลบนฟอร์มเลย เราจึงต้องพึง delegate เพื่อทำ callback ฟังก์ชั่น

private delegate void updateAnalogLabel();

        private void updateLabel()

        {

            analog1Label.Text = data[0];

            analog2Label.Text = data[1];

            analog3Label.Text = data[2];

            serialRecieveTextBox.AppendText(raw);

        }

ในส่วนของการส่งข้อมูลออกจากโปรแกรมไปทาง serial port ที่เราได้ตกลงกันไว้คือ โปรแกรม C# จะทำการส่งสถานะการกดปุ่มบนฟอร์ม เพื่อไปบอกให้ MCU ขับหลอด LED 

private void sendStateButton()

        {

            string s = "#" + Convert.ToInt32(stateButton1).ToString() + "," + Convert.ToInt32(stateButton2).ToString() + "," + Convert.ToInt32(stateButton3).ToString() + "*";

            if (serial != null)

            {

                if (serial.IsOpen)

                {

                    serial.Write(s);

                }

            }

        }

ผมอัพไว้ที่ dropboxแล้ว

https://dl.dropboxusercontent.com/u/65353188/easySerial2013.zip

อ้างอิง : SerialPort Class  , Delegates Tutorial

หรืออ่านเต็มๆ ได้ที่นี่ครับ คลิก

อ่านเพิ่มเติม...

Thursday, September 26

Properties.Settings.Default.Save(); จำค่าไว้ก่อนปิด

พอดีมีคนถามมา ก็เลยลองหาดูในเนต ก็เจอว่ามีวิธีการเก็บบันทึกค่าต่างๆ ที่เรากรอกทิ้งไว้ในฟอร์ม ก่อนปิดหน้าต่างโปรแกรม แล้ว สามารถเรียกกลับมาคืนได้ ผมเคยคิดว่าจะเก็บลง Registry ของ windows (ซึ่งไม่น่าจะง่าย) แต่ มาเจอวิธีที่ง่ายกว่านั้นอีก เรามาดูกันเลย

เริ่มแรกก็สร้างฟอร์มง่ายๆ ก่อน ให้มีแค่ Textbox อันเดียวก็พอ

จากนั้นคลิกขวาที่โปรเจคของเรา ในหน้าต่าง Solution Explorer แล้วเลือก Properties เลือกที่ Tab setting และทำการกรอกค่าตามรูป

simple form

------+-------+-------
Name          Type         Scope
------+-------+-------
text             string       User
x                  int           User
y                   int          User

Properties Settings

ในที่นี้ เราจะให้ text เก็บค่าใน textbox ที่เคยพิมพ์ไว้ ส่วน x และ y จะเก็บค่าตำแหน่ง form ก่อนปิดหน้าต่างโปรแกรม เมื่อกำหนดเรียบร้อยแล้วให้ทำการบันทึกไฟล์ไว้ก่อน

จากนั้นทำการกำหนดและเขียนโค๊ดดังนี้

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 persistingForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.Manual;
        }

        private void textBox1_KeyUp(object sender, KeyEventArgs e)
        {
            Properties.Settings.Default.text = textBox1.Text; // เก็บค่าสตริงจาก textbox1 ลงใน properties text
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Properties.Settings.Default.x = this.Location.X;
            Properties.Settings.Default.y = this.Location.Y;
            Properties.Settings.Default.Save(); // อย่าลืมสั่ง save ก่อนปิดโปรแกรม
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Location = new Point(Properties.Settings.Default.x, Properties.Settings.Default.y);
            textBox1.Text = Properties.Settings.Default.text;
        }
    }
}

ลองรันโปรแกรม ดูครับ แล้วลองเปรียบเทียบกับโปรแกรมก่อนๆ หน้านี้ดูครับ จะเห็นว่า โปรแกรมนี้ที่เราเขียนขึ้น จะมีการจดจำค่าก่อนปิดโปรแกรมตามที่เรากำหนดไว้ในโค๊ด  ลองเอาไปประยุกต์ดูครับ

ขอให้สนุกกับ .NET ครับ

อ้างอิง:  http://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx

อ่านเพิ่มเติม...

Saturday, September 14

List video devices from PC by DirectShowLib

ในกรณีที่เราอยากทำให้ Application ของเราสามารถเลือกได้ว่าจะติดต่อกับกล้องตัวใน ถ้าเครื่องคอมพิวเตอร์ของเรามีมากกว่า 2 ตัว เราจะทำอย่างไร ถึงจะทำให้ application ที่เรากำลังสร้างนั้นมองเห็นกล้องทั้งหมดในเครื่องคอมพิวเตอร์เครื่องนั้นได้

วันนี้ผมจะแนะนำความสามารถของ Library ตัวหนึ่งชื่อ DirectShowLib ที่เอาไว้ดึงรายชื่อกล้องทั้งหมดที่ต่ออยู่ในเครื่องคอมพิวเตอร์ของเราออกมาเป็นตัวแปร array จากนั้นเราก็สามารถที่จะใช้ ComboBox ใช้แสดงรายชื่อกล้องทั้งหมด ไว้ให้ user เอาไว้เลือกต่อได้ ว่าจะติดต่อกับกล้องตัวไหน

อันดับแรก ก็ให้ไปดาวน์โหลด Library ตัวนี้ก่อนครับ อยู่ใน sourceforge ก็มี ดาวน์โหลดได้ที่นี่ http://sourceforge.net/projects/directshownet/files/ เมื่อดาวน์โหลดมาได้แล้ว เราต้องการไฟล์ DirectShowLib-2005.dll ที่อยู่ในโฟลเดอร์ \DirectShowLibV2-1\lib ของมัน

เรามาเริ่มสร้างโปรเจคกัน ในที่นี้ผมให้เป็น Windows Forms Application ที่เมนู Project เลือก Add reference หรือคลิกขวาที่ References ที่ ใต้ชื่อ Project เราที่ solution explorer ทำการ Browse หาไฟล์  DirectShowLib-2005.dll

image

สร้างหน้าต่าง form ตามรูป แล้วทำการเขียนโค๊ด (อันนี้ผมไม่บอกละเอียดแล้วนะ ถือว่า พอมีประสบการณ์กันบ้างหล่ะ)

image

เรามาดูที่โค๊ดกันครับ หัวใจของเรื่องนี้ ก็อยู่ตรงที่ เราสร้างตัวแปร object จาก Class DsDevice ที่อยู่ใน namespace ของ DirectShowLib (ฉะนั้นอย่าลืมที่ using DirectShowLib; ด้วยนะครับ)

ผมประกาศตัวแปร DsDevice[] videoDevices; ก่อน

จากนั้น ผมก็ทำการสร้างอินสแตนซ์จาก Class DsDevice แล้วก็เอามาวนลูปแสดงใน ComboBox


videoDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
if (videoDevices.Length == 0)
{
     throw new Exception();
}

for (int i = 1, n = videoDevices.Length; i <= n; i++)
{
     string cameraName = i + " : " + videoDevices[i - 1].Name;
     cameraCombo.Items.Add(cameraName);
}
cameraCombo.SelectedIndex = 0;

ทีเหลือก็ไม่มีอะไรมาก เอา index ที่ได้จากการเลือก combobox สร้างอินสแตนซ์ Capture แล้วก็โยนให้ picturebox แสดงผล

ลองดูโค๊ดเต็มๆ

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;

using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;

using DirectShowLib;

namespace AnyCameras
{
    public partial class Form1 : Form
    {
        DsDevice[] videoDevices;
        private Capture capture = null;

        public Form1()
        {
            InitializeComponent();
            timer.Interval = 100;

            // show device list
            try
            {
                videoDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
                if (videoDevices.Length == 0)
                {
                    throw new Exception();
                }

                for (int i = 1, n = videoDevices.Length; i <= n; i++)
                {
                    string cameraName = i + " : " + videoDevices[i - 1].Name;
                    cameraCombo.Items.Add(cameraName);
                }
                cameraCombo.SelectedIndex = 0;
            }
            catch
            {
                cameraCombo.Items.Clear();
                cameraCombo.Items.Add("No cameras found");
                cameraCombo.SelectedIndex = 0;
                cameraCombo.Enabled = false;
            }       
       
        }

        private void StartCamera()
        {
            capture = new Capture(cameraCombo.SelectedIndex);
            timer.Start();
        }

        private void StopCamera()
        {
            timer.Stop();
            if (capture != null)
            {
                capture.Dispose();
            }
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            Image<Bgr, Byte> frame = capture.QueryFrame();
            cameraPictureBox.Image = frame.ToBitmap();
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            StartCamera();
            startButton.Enabled = false;
            stopButton.Enabled = true;
        }

        private void stopButton_Click(object sender, EventArgs e)
        {
            StopCamera();
            startButton.Enabled = true;
            stopButton.Enabled = false;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            timer.Stop();
            if (capture != null)
            {
                capture.Dispose();
            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://vs-visual-studio.blogspot.com/");
        }

    }
}

 

ลองดาวน์โหลดโค๊ดไปเล่นกันครับ https://dl.dropboxusercontent.com/u/65353188/AnyCameras.zip

อ่านเพิ่มเติม...

Thursday, September 12

AdvancedHMI with Visual C# 2010

HMI หรือ Human Machine Interface คือ อุปกรณ์ที่ใช้ในการติดต่อระหว่่างผู้ใช้ กับ เครื่องจักร เพื่อใช้ในการควบคุมและการแสดงผล ผ่านทางหน้าจอ เรามักใช้ในการแสดงผลแบบกราฟฟิก ซึ่งส่วนใหญ่ จะแสดงผลในเชิงสัญลักษณ์ หรือไอค่อนที่เป็นตัวแทน เครื่องจักร ถังน้ำ ปั้ม วาล์วน้ำ มอเตอร์ไฟฟ้า และอื่นๆ ที่เป็นส่วนที่เราต้องการติดตามการทำงานของพวกมัน โดยจะแสดงสถานะ ค่าต่างๆ บนหน้าจอแสดงผล พร้อมกับโครงสร้างของระบบการทำงานที่เรายกมาแสดง
ในปัจจุบันมีโปรแกรมหลายๆ ค่ายที่สามารถแสดงผลแบบ HMI ได้ ซึ่งมีทั้งแบบที่ง่าย แต่เสียเงิน และแบบที่ยาก แต่ ฟรี ก็มี วันนี้ เรามาลองติดตั้ง AdvancedHMI กับ C# กันดูครับ
AdvancedHMI
เริ่มแรกก็ไปดาวน์โหลด AdvancedHMI จากที่นี่ http://advancedhmi.com/ จากนั้น ทำการแตกไฟล์ออก ไปวางไว้ที่ไหนก็ได้ครับ เพราะเราจะสนใจแค่ dll ไฟล์ของมัน
เปิดโปรแกรม Visual C# 2010 express ขึ้นมาครับ เริ่มสร้างโปรเจค ตามปกติ ในที่นี้ผมสร้างโปรเจคเป็น windows form application นะครับ
ต่อมาให้เราทำการ add toolbox ที่เป็นของ AdvancedHMI ขึ้นมา  อาจจะสร้าง Add tab ขึ้นมาแล้วตั้งชื่อ AdvancedHMI แล้วคลิกขวา Choose items.. ไปที่
Add components AdvancedHMI
แท๊ป .NET Framework Components ให้เรา Browse ไปที่เก็บไฟล์  AdvancedHMIBeta358\AdvancedHMIDrivers\Support\MfgControl.AdvancedHMI.Drivers.dll แล้วคลิกเลือก OK
AdvancedHMI components
เราจะได้ Components ที่ทาง AdvancedHMI สร้างมาให้
ทำการ Add reference MfgControl.AdvancedHMI.Drivers.dll เข้าไปกับโปรเจคด้วย
Add reference MfgControl.AdvancedHMI.Controls.dll
จากนั้น ก็ลาากวางๆ ได้เลยครับ จินตนาการเอาว่า เราจะสร้างระบบเฝ้าติดตามอะไร ในที่นี้ ผมสร้างระบบปั้มน้ำ โดยให้มอเตอร์ปั้มน้ำเข้าถัง หากระดับน้ำต่ำกว่า ระดับที่เราตั้งไว้ และมีวาล์วคอยปิดเปิดทางน้ำออก ซึ่งสามารถปรับอัตราการไหลได้
AdvancedHMI Form design
ที่ส่วนหัวของโค๊ด ให้ทำการ using MfgControl.AdvancedHMI.Controls; เข้าไปด้วย ถ้าต้องการสร้าง object เพิ่ม
ในการเขียนโค๊ดส่งค่าให้แต่ละ Component ไม่ว่าจะเป็น Guage , Tank  หรืออะไรก็ตามแต่ ที่มีการแสดงผล แสดงค่าต่างๆ ต้องเช็คให้ดีด้วย ว่ามันรับค่าเป็น float , int หรือว่า double ถ้าเราส่งค่าให้มันไม่ตรงชนิดที่มันจะรับ มันจะแสดงผลผิดพลาด ลองเอา mouse ชี้ค้างไว้ตอนเรา กำหนดค่า ให้ field ที่ชื่อ value ของมันดูครับ มันจะบอกไว้อยู่
image
AdvancedHMI object
ในที่นี้ ผมใช้ Timer 3 ตัวในการกำหนดจังหวะให้กับระบบ มาดูโค๊ดเต็มๆ กันเลยครับ
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;
using MfgControl.AdvancedHMI.Controls;
namespace AdvanceHMI
{
    public partial class Form1 : Form
    {
        Random rnd = new Random();
        float waterActual = 100.0f;
        float flowrateIn = 2.0f;
        float flowrateOut = 2.0f;
       
        public Form1()
        {
            InitializeComponent();
            tank1.Value = waterActual;
            waterPump1.Value = false;
            txtWaterDetect.Text = "70";
            trackBar1.Value = 70;
            lbWaterLevel.Text = ((int)waterActual).ToString();
        }
        private void btnStart_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true; // timer system
            timer2.Enabled = true; // timer water flow rate in
            timer3.Enabled = true; // timer water flow rate out
            timer1.Interval = 200;
            timer2.Interval = 200;
            timer3.Interval = 500;
            timer1.Start();
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            lbWaterLevel.Text = waterActual.ToString();
            if ((int)waterActual <100)
            {
                if ((int)waterActual <= trackBar1.Value)
                {
                    timer2.Start();
                    waterPump1.Value = true;
                }
               
            }
            else
            {
                timer2.Stop();
                waterPump1.Value = false;
            }
            if (pneumaticBallVave1.Value == true)
            {
                timer3.Start();
                pneumaticBallVave1.Value = true;
            }
            else
            {
                timer3.Stop();
                pneumaticBallVave1.Value = false;
            }
        }
        private void btnStop_Click(object sender, EventArgs e)
        {
            timer1.Stop();
            timer2.Stop();
            timer3.Stop();
        }
        private void label1_Click(object sender, EventArgs e)
        {
        }
        private void timer3_Tick(object sender, EventArgs e)
        {
           
            waterActual = waterActual - flowrateOut;
            tank1.Value = waterActual;
        }
        private void timer2_Tick(object sender, EventArgs e)
        {
            waterActual = waterActual + flowrateIn;
            tank1.Value = waterActual;
        }
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            txtWaterDetect.Text = trackBar1.Value.ToString();
        }
        private void button1_Click(object sender, EventArgs e)
        {
        }
        private void pneumaticBallVave1_DoubleClick(object sender, EventArgs e)
        {
           
        }
        private void trackBar2_Scroll(object sender, EventArgs e)
        {
            flowrateOut = (float)trackBar2.Value;
            label3.Text = trackBar2.Value.ToString();
        }
        private void pneumaticBallVave1_Click(object sender, EventArgs e)
        {
            pneumaticBallVave1.Value = !pneumaticBallVave1.Value;
        }
    }
}
ลองโหลดไฟล์ไปเปิดกันดูครับ ไม่รู้ว่าจะเปิดกันได้หรือเปล่า ถ้าไม่ได้ก็สร้างเอาใหม่ ก็แล้วกันครับ แลบลิ้น
https://dl.dropboxusercontent.com/u/65353188/AdvanceHMI.zip
อ่านเพิ่มเติม...
 

แจกฟรี พื้นที่ฝากไฟล์ 2 GB

ads

ติดตามข่าวสารผ่าน Twitter

ติดตาม Blog นี้

Blog อื่นๆของฉัน

จำนวนการเยี่ยมชมบล๊อก