วันจันทร์ที่ 26 กันยายน พ.ศ. 2559

การเขียนโปรแกรมรับค่าตัวเลขจาก Serial Port(Send number to serial Arduino)


หลายคนอาจส่งสัยว่าทำไมต้องเขียนบทความนี้ขึ้น ขณะที่เราก็สามารถใช้งาน function ที่อยู่ใน Aduino ชื่อว่า Serial.parseInt() ใช่ได้เหมือนกันครับ แต่ความเร็วในการใช่งานนั้นถือว่าช้าพอสมควร จากตัวอย่าง code ที่ผมเขียน ใช่เวลาประมาณ 1 วินาที ในการเปรียบเทียบค่า



ซึ่งงานบ้างงานรอเวลาไม่ได้ขนาดนั้นและผมก็ไปหาข้อมูลมาว่าทำไมถึงช้า ตามที่ผมจับใจความได้เขาบอกว่า function parseInt() นั้นจะมองหา ข้อมูลใน Serial buffer  และอ่านทีละตัวอักษร และ ค้นหาจนกระทั่งไม่เจอ ตัวอักษรใน buffer จะทำการ parse ทำให้เกิดเวลาเพิ่มมากขึ้น


ดังนั้นผมจึงค้นหาวิธีจากการเขียนของคนนี้ มา เขาเขียนโดยทำการอ่านข้อมูลจาก Serial buffer จนกระทั่งเจอตัวอักษร ที่เขากำหนดไว้ และนำเอาไปเปรียบเทียบเป็น ตัวเลขโดยโค็ดที่ผมตัดมาเป็นตัว นี้ครับ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int number;
long timer;
long timerBegin;
long timerEnd;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}
char inputString[5] ; // เก็บตัวแปร char
void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available() > 0)
  {
    timerBegin = millis();
    Serial.readBytesUntil(90,inputString,5); // 90 ในที่นี้คือ z มันค่าการอ่าน byte ออกมา,แล้วทำการนำค่าเอาไปเก็บไว้ใน InputString 
    number = atoi(inputString);//แปลงค่า char เป็น number 
    timerEnd = millis();
    timer = timerEnd-timerBegin;
    Serial.print("number is : ");Serial.print(number);Serial.print(" time is : ");
    Serial.print(timer);Serial.println(" ms"); 
  }


}

โดยหลักการทำงานของมันคือ ให้Serial port อ่านข้อมูลจาก buffer จนกระทั่งเจอตัวอักษรที่เรากำหนดไว้ในที่นี้ผมกำหนดเป็น Z แต่การดึงข้อมูลออกไปใช้งานอาจจะต้องมีการดัดแปลงแก้ไขโค็ดอีกนิดหน่อย ผลลัพที่ออกมา ได้ความเร็วในการทำงานแค่ 5 millisecond ครับ

วันจันทร์ที่ 12 กันยายน พ.ศ. 2559

การเขียนโปรแกรมอ่านค่า Joystick USB เพื่อนำไปควบคุมหุ่นยนต์ครับ (read data from USB gamepad Sent to Serial port)

วันนี้ผมจะมา นำเสนอวิธีการเขียนโปรแกรมเพื่ออ่านค่า USB GamePad(joystick) ซึ่งในการเขียนอ่านค่านั้นจำเป็นต้องใช่ library ของ Microsoft DirectX ซึ่งจะเป็นตัว DirectInput นั้นจะทำหน้าที่ในการ ประมวลผลข้อมูลที่มาจาก keybord,Mouse และสำคัญที่สุดสำเราบทความนี้ คือ Joystick หรือเกมส์คอนโทรลเลออื่นๆ ก็สามารถทำได้
      โดยท่านผู้อ่านสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับการใช้งาน Class และ Method การใช้งานต่างๆได้เพิ่มเติมที่  https://msdn.microsoft.com/en-us/library/windows/desktop/bb318766(v=vs.85).aspx
หน้าตาโปรแกรมที่ออกแบบครับ

รออัพเดท วิดีโอ และ eport ตัว exe

ซึ่งในที่นี้ ผมจะทำการสร้างโปรเจคขึ้นมาเป็นแบบ Window Form Application โดย library ที่ใช่

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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 Microsoft.DirectX.DirectInput;
// หลักการทำงานของ joyStick หลักหลักเลยจะใช้งาน DirectX ของ microsoft ที่เป็น DirectInput 
// ตัว DirectInput มันจะเป็นการทำงานเกี่ยวกับการประมวลผลข้อมูลที่มาจาก joystick keybord mouse เป็นต้น 
//โดยข้อมูลเพิ่มเติมสามารถหาได้จาก  https://msdn.microsoft.com/en-us/library/windows/desktop/bb318766(v=vs.85).aspx 
  1. ทำการเชื่อมต่อ joystucโดย Method ที่งานเริ่มต้นคือทำการ ค้นหา Joystick คือ InitDevice()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 private void InitDevices()
        {
            
            //create joystick device สั่งให้ วนลูบหา Device ที่เชื่อมต่อแเข้ามาในเครื่องคอมพิวเตอร์ โดย Class ที่ใช่ get ค่า device คือ manager class 
            // manager class มี methode ในการทำงาน ได้หลายอย่างเช่น getDevice() findDevice() 
            //paramitor ที่อยู่ใน GetDevice มีสองตัว คือ 1 actionformat หมายถึง format ของ Device ที่ get เข้ามา มี keybord,gamecontrol  เป็นต้น 
            // paramitor ตัวที่สอง คือ flag จะต้องขึ้นต้นด้วย enumDeviceFlag เสมอ methode ที่สามารถใช่งานได้ คือ attachedOnly หมายถึงตัวที่มีการเชื่อมต่อมาเท่านั้น 
            foreach (DeviceInstance di in Manager.GetDevices(DeviceClass.GameControl,EnumDevicesFlags.AttachedOnly))
            {
                joystick = new Device(di.InstanceGuid); // เก็บค่าไว้ใน object joystick 
                break; 
            }

            if (joystick == null) // ถ้าวนหา แล้วไม่เจอ joystick สั่ง massegboxshow 
            {
                //Throw exception if joystick not found.
                MessageBox.Show("หา joyStick ไม่เจอ โปรดมั่นใจว่าคุณได้เสียบ joystick แล้ว");
                return;
            }

            //หลังจากที่เราแนบ device ไว้ใน object joystick แล้ว เราจะทำการ ค้าหาเข้าไปในตัว object อีกว่ามี อะไรอยู๋ในตัว object บ้าง 
            foreach (DeviceObjectInstance doi in joystick.Objects) 
            {
                if ((doi.ObjectId & (int)DeviceObjectTypeFlags.Axis) != 0) // objectid มี ค่า และ axis ค่าแกนของ object joystick มีค่าไม่เท่ากับ 0
                {
                    // ทำการ set range โดย paramitorhow หมายความว่าเราจะ set rang โดย fillter ค่าของอะไรเป็นหลัก ใน ที่นี้ ผมเลือก byid มีอย่างอื่นด้วยคือ byDevice 
                    //paramitor ตัวต่อมา คือ ทำการ ใส่ ตัว object ของเราลงไป โดยเลือกเป็น by id เหมือนกัน 
                    // paramitor ตัวสุดท้าย inputRange ผมเซ็ตให้มันมีค่า 0-1600 
                    joystick.Properties.SetRange(ParameterHow.ById,doi.ObjectId,new InputRange(0, 1600));
                }
            }

            joystick.Properties.AxisModeAbsolute = true;      // ทำให้ค่าที่ออกมาจาก joystick เป็นค่าที่ไม่ติดลบ

            //set cooperative level.
            joystick.SetCooperativeLevel(
            this,
            CooperativeLevelFlags.NonExclusive |
            CooperativeLevelFlags.Background);

            //Acquire devices for capturing.
            joystick.Acquire();                             // ทำการใส่ค่าที่รับมาจาก joystick ไปใน object

        }

2. วิธีการรับค่าข้อมูลโดยเราจะใช่การรับค่าของ Device ที่เราเชื่อมต่อมา ตาม code ด้านล่าง ซึ่งอาจจะต้อง Method ไปวางไว้ใน timer ให้เป็น loopเวลา คอยรับค่าที่ส่งมาจาก Joystick โดย ใน บรรทัดที่ 20 เราได้ทำการ สร้าง Object  button ขึ้นมาโดย buttonนั้น จะถูกแบ่งออกเป็น Array เช่น button[0] ก็จะเท่ากับ ตัวเลข 1 ที่อยู่ฝั่งขวาของ joystick เป็นต้น
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
  private void UpdateJoystick()   // อัพเดทการทำงานของ 
        {
            if (joystick != null)
            {
                string info = "Joystick: ";
                JoystickState state = joystick.CurrentJoystickState;    // รับค่าสถานะของ device ที่เรา get ค่ามา

                //Capture Position.
                info += "X:" + state.X + " ";
                info += "Y:" + state.Y + " ";
                info += "Z:" + state.Z + " ";
                info += "no:" + state.ARx + "";
                trackBar1.Value = state.X;
                trackBar2.Value = state.Y;
                

                label2.Text = "แกน X :" + state.X;
                label3.Text = "แกน Y :" + state.Y;
                //Capture Buttons.
                byte[] buttons = state.GetButtons();
          }
}

3. การใช้งาน button ค่าที่ออกมาจาก joystick นั้น ถ้าปุ่มถูกกดค่าจะถูก ส่งออกมาเป็นค่า128 ถ้าไม่ถูกกด ค่าจะถูกส่งออกมาเป็น 0 ตามโค็ดตัวอย่าง
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 byte[] buttons = state.GetButtons();
                // MessageBox.Show("" + buttons[0]);
                if (buttons[0] == 0)
                {
                    //ไม่ต้องทำอะไร
                    
                }
                if (buttons[0] == 128)
                {
                    MessageBox.Show("ปุ่ม 1 ถูกกด");
                }

วันจันทร์ที่ 29 สิงหาคม พ.ศ. 2559

การสร้าง จอยสติก ในแอนดรอย(create virtual joystick) จาก unity3d

วันนี้ จะมา นำเสนอ วิธีการสร้าง virtual joysitck โดยใช้โปรแกรม unity3d ครับ

ภาพจอยสติ๊กจาก http://cmmakerclub.com/
  • โปรแกรมที่ต้องเตรียม คือ unity3d(โปรแกรมสร้างเกมส์แต่สามารถประยุกใช้ได้)  https://unity3d.com

    link video การสร้าง ครับ
    part1 https://www.youtube.com/watch?v=bIVeuMZ3iUo
    part2 https://www.youtube.com/watch?v=n2QbREspUQw

    จากความรู้ที่ผมได้ศึกษาโปรแกรม unity3d มาพอสมควร การเขียนโปรแกรมบน unity3d นั้นเขียนแบบ OOP เต็มรูบแบบ 

1
2
3
4
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

  • เราจะใช้ library ที่ต้องเพิ่มเข้ามา บรรทัดที่ 2 คือจะนำ object ที่มาจาก UI ใน unity3d ใช้งาน ในพวก UI ก็จะแบ่งเป็นพวก Image,Button,Canvas เป็นต้น ซึ้ง
  • บรรดทัดที่ 4 จะเป็น class ที่ทำหน้าที่เกี่ยวกับ event ที่มาจาก user เช่น การ กดปุ่ม touch(ที่อยู่ใน mobile) เป็นต้น

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class ScripteJoyStick : MonoBehaviour ,IDragHandler,IPointerUpHandler,IPointerDownHandler{
 public Image BgImg;
 public Image JoyStick;
 private Vector3 InputVector;
 // Use this for initialization
 void Start () {

 }
 // Update is called once per frame
 void Update () {
 }

}
เราจะสืบทอดคุณสมบัติจาก namespace ที่มาจาก   using UnityEngine.EventSystems; คือเครื่องมือจำพวก 
  • IDragHandler,IPointerUpHandler,IPointerDownHandler
ต่อมาเราจะทำการ ประกาศ Image ขึ้นมา เพื่อจะให้ code ของเราควบคุมตัว objact อีกทีโดยการทำงานของโค็ดโปรแกรมเราจะสร้าง 3 method ขึ้นมาคอยดักจับการทำงานของ
  • void OnPointerDown(PointerEventData ped) // เมื่อมีการกดปุ่มหรือสัมผัส หน้าจอ 
  • void OnPointerUp(PointerEventData ped) // เมื่อไม่ได้กดปุ่ม โดยในที่นี้ผมจะสั่งให้ตัว object ที่เป็น Image เคลื่อนที่ไปยัง ตำแหน่งที่ 0 หรือ ต่ำแหน่งตรงกลางที่มันเคย อยู่ 
  • void OnDrag(PointerEventData ped) // เมือหน้าจอถูกกด แล้ว มีการเลื่อน pointer ไปจาก ตำแหน่งเดิม จะทำการย้าย ที่ตั้งของตัวภาพ ไหม่ตามโค็ดด้านล่าง

 using UnityEngine;  
 using System.Collections;  
 using UnityEngine.UI;  
 using UnityEngine.EventSystems;  
 public class ScripteJoyStick : MonoBehaviour ,IDragHandler,IPointerUpHandler,IPointerDownHandler{  
      private Image BgImg;  
      private Image JoyStick;  
      private Vector3 InputVector;  
      // Use this for initialization  
      void Start () {  
           BgImg = GetComponent<Image> (); // get component ที่เป็น Img ที่ script ไปฝั่งอยู่   
           JoyStick = transform.GetChild (0).GetComponent<Image> (); // get ตัวลูก หรือ ตัว subset ที่อยู่ ใน object ที่เป็น img อีกที   
      }  
      // Update is called once per frame  
      void Update () {   
      }  
      public virtual void OnPointerDown(PointerEventData ped){  
           OnDrag(pad);  
      }  
      public virtual void OnPointerUp(PointerEventData ped){ // จะเข้า มาทำงานก็ต่อเมื่อ เราไม่ได้ touch หรือกดปุ่มบนหน้าจอ   
     //ปรับตำแหน่งของ img ที่เป็น joy ให้แนวแกน x =0 และแนวแกน y = ตำแหน่งสุดท้ายที่เราเลือก pointer ไป  
           JoyStick.rectTransform.anchoredPosition = new Vector3(0,InputVector.z*(BgImg.rectTransform.sizeDelta.y/2));   
      }  
      public virtual void OnDrag(PointerEventData ped){  
           Vector2 pos = Vector2.zero;  
           if(RectTransformUtility.ScreenPointToLocalPointInRectangle(BgImg.rectTransform,ped.position,ped.pressEventCamera,out pos)) //  
           {  
                pos.x = (pos.x/BgImg.rectTransform.sizeDelta.x); // pos.x = ตำแหน่งของ joy หารด้วย ขอบ  
                pos.y = (pos.y/BgImg.rectTransform.sizeDelta.y);  
                InputVector = new Vector3(pos.x,0,pos.y);  
                InputVector =(InputVector.magnitude>0.8f)?InputVector.normalized:InputVector;  
                JoyStick.rectTransform.anchoredPosition = new Vector3(InputVector.x *(BgImg.rectTransform.sizeDelta.x/2),  
                                           InputVector.z*(BgImg.rectTransform.sizeDelta.y/2));  
                Debug.Log(JoyStick.rectTransform.anchoredPosition.y);  
           }  
      }  
 }  

วันอาทิตย์ที่ 28 สิงหาคม พ.ศ. 2559

การใช้งาน Site Netvault generate Graph

แนะนำการ ใช้งานเว็บไซต์ generate graph ซึ่งทางผมได้ทำการเขียน โดยทำการดึง library(ไม่รู้ใช้ถูกหรือเปล่า) จากเว็บของ Highchart โดยการทำงานของ Highchart จะทำการรับค่า array ไป plot ลงใน graph รายละเอียดเพิ่มติม

วิธีการใช้งาน
รูป report netvault 
  1. เตรียมข้อมูล json เพื่อนำไปเป็นข้อมูลในการ plot graph โดยในที่นี้ ผมจะแปลงข้อมูลจาก HTML Table ไปเป็น json file ซึ่งในที่นี้ผมจะแปลงข้อมูลของ site ตามรูปด้านบน ให้ทำการ คลิกขวา>ดูรหัสต้นฉบับ แล้วเลือก copy ตั้งแต่ tag <Table>

  2. ต่อมาทำการเข้าเว็บ convert html to jason คลิก แล้ววางข้อมูล ทำการ convert ข้อมูลเป็น json แล้วนำข้อมูลที่ได้ไปวางที่ เว็บ http://203.150.102.21/   ใน text area แล้ว กดปุ่ม GetJob(กดครั้งเดี๋ยวนะครับ ยังติด bug อยู๋)  แล้วทำการเลือก Job ที่ต้องการ generate แล้ว กดปุ่ม genGraph ตามรูป


  3. สามารถ ดู RTO ของ Job โดยเลือกดูผ่าน Job restore ของ job นั้น แล้ว กด gen RTO 
  • ตัว code ยังไม่ได้แก้ในเรื่องของ การ getJob ถ้ากดหลายครั้งจะทำให้ paramitor ใน list box เพิ่มขึ้น  ให้ทำการ refresh หน้าเว็บแล้วค่อยวางข้อมูลไหม่ลงไป