วันจันทร์ที่ 31 มีนาคม พ.ศ. 2557

ตอนที่ 9 : ต่อ Android กับ PC แบบไม่ต้องใช้สาย


มีเคล็ดลับในการต่อ Android เข้ากับ Processing แบบต่อผ่าน WIFI แทนกัน สิ่งที่ต้องมี ตามนี้ครับ

1. หาโปรแกรม adb.exe ซึ่งจะอยู่ในชุด ADK ที่เราโหลดมา  

อันนี้ในเครื่องผม ทีนี้ต้องเข้าไปที่นี่ด้วย Command Prompt สังเกตุที่ Path นะครับ


จากนั้นให้เสียบสาย USB จาก Android มาที่ PC ก่อน จะมีเสียงติ๊งตึ่ง ซึ่งแสดงว่ามีการรับรู้ว่ามีการเชื่อมต่อแล้ว ให้พิมพ์คำสั่งตมนี้

adb devices -l   (ตัวอักษร แอล)


ผลการทำคำสั่ง จะมีรายการแสดงหมายเลขของ Android พร้อมคำอธิบาย ถ้าไม่ขึ้นตามนี้ให้ลองดึงสาย แล้วเสียบใหม่ จากนั้นให้ลองพิมพ์ adb shell ls หน้าจอจะแสดงรายการไฟล์ที่มีอยู่ใน Android ส่วนนี้ไม่เกี่ยวนะครับ เพียงให้รู้ว่าต่อเข้า Android ได้แล้ว

จากนั้นพิมพ์ adb tcpip 5555 เครื่องตอบกลับตามรูป



ทีนี้ให้ดึงสาย USB ออก แล้วป้อนคำสั่ง adb connect 192.168.1.3 หมายเลข IP หาได้จากเครื่องในส่วนของการตั้งค่า WIFI ให้แท๊บที่ Access point ที่เราเชื่อมต่อใน Android ดู IP แล้วมาใส่ตามคำสั่ง


ผลแสดงเชื่อมต่อกับ Android ถ้าได้ตามนี้ เมื่อทดลอง Processing มันจะคอมไฟล์ลงเครื่องของเราเอง ทีนี้ก็ไม่ต้องต่อสาย USB แล้ว

วันเสาร์ที่ 29 มีนาคม พ.ศ. 2557

ตอนที่ 1 : Ketai เกริ่นนำ

Ketai เป็น Library แบบ Open source เพื่อดึงเอาความสามารถของเซนเซอร์ที่มีใน Android มาใช้งานผ่านโปรแกรม Processing ซึ่งอาจเกี่ยวกันกับ Arduino แบบบางๆ คืออาจเชื่อมต่อหรือไม่เชื่อมต่อกับ Arduino ก็ได้

จากที่ Android เองมีเซนเซอร์อยู่มากมาย อย่างน้อยก็ WiFi, Accelerometer, GSM เพื่อส่ง SMS ซึ่งถ้าเราต้องการให้ Arduino ทำอะไร ปกติก็ต้องไปจัดหา Shield ตัวนั้นๆ มาใช้ แต่ถ้ามี Android แล้วเราก็เขียนคำสั่งผ่าน Ketai ไปบอกให้เซนเซอร์ตัวนั้นๆ ทำงาน

ยกตัวอย่างการทำ Remote Sensing ที่ต้องการให้ส่งข้อมูลไปยัง Control Center ด้วยการส่งเป็น SMS ก็สามารถเปิด Library ในส่วน SMS จัดข้อมูลแล้วก็ส่งได้เลย ซึ่งปกติเราก็ต้องเขียนโปรแกรมบน Arduino ทั้งหมดบน GSM Shield หรือไม่ก็อาจส่งข้อมูลเข้า Server ของ Control Center ผ่านความสามารถในการเชื่อต่อ internet ได้อีกทางหนึ่ง

เอาเป็นว่ามันจะช่วยร่นเวลาในการพัฒนาโปรแกรมของเราให้สั้นลง มีความน่าเชื่อถือมากขึ้น ติดตามตอนต่อไปครับ


ตอนที่ 8 : ทดลองกับ Android กับ Arduino (จบครับ)

สิ่งที่ต้องมี
1. Android mobile หรือ Tablet
2. สาย USB OTG
3. บอร์ด Arduino

โปรแกรมที่ต้องลงในบอร์ด Arduino


void setup(){
  pinMode(11,OUTPUT);
  digitalWrite(11,LOW);
  Serial.begin(9600);
}

void loop(){
  if(Serial.available() > 0){
    while(Serial.available()){
      if(Serial.read() == 'B')
        digitalWrite(11, !digitalRead(11));
    }
  }
  else
 {

  Serial.println(random(255));
  delay(100);

 }
}

ทดสอบการทำงานด้วย Serial monitor เห็นตัวเลขวิ่ง และเมื่อป้อนอักษร B กดปุ่ม Send หลอด LED ติด ป้อน B กดปุ่ม Send หลอด LED ดับ เป็นโอเค

เปืดโปรแกม Processing เลือก Android mode เรียก Sketch ที่ทดลองกับ PC แต่ต้องปรับโปรแกรมเล็กน้อย ตามนี้

ให้ทำการ import library -> Android Serial Library for Processing


import com.yourinventit.processing.android.serial.*;
import controlP5.*;

//import processing.serial.*; ลบบรรทัดนี้ทิ้งได้เลยครับ หรือใส่ // ไว้ด้านหน้าก็ได้

ControlP5 cp5;
Serial port;

String inData="";

void setup(){
  size(600,600);

  println(Serial.list());
  port = new Serial(this, Serial.list()[1], 9600);
  port.clear();
  port.bufferUntil('\n');

  cp5 = new ControlP5(this);

  cp5.addTextfield("text1")
     .setPosition(100,100)
     .setSize(100,20)
     .setCaptionLabel("Data")
     .setFont(createFont("Verdana", 16))
     ;

  cp5.addButton("button1")
     .setValue(0)
     .setPosition(250, 100)
     ;
   
  cp5.addSlider("slider1")
     .setPosition(150,200)
     .setValue(100)
     .setMax(255)
     .setMin(0)
     ;
   
  cp5.addKnob("knob1").setSize(100,200)
     .setPosition(150,250)
     .setMax(255)
     .setMin(0)
     .setValue(100)
     ;
}

void draw(){
  Textfield t = (Textfield) cp5.getController("text1");
  t.setText(inData);
  cp5.getController("slider1").setValue(int(inData));
  cp5.getController("knob1").setValue(int(inData));
}

void button1(int value)
{
  println("Button pressed");
  port.write("B");
}

void serialEvent(Serial port){
  inData = port.readStringUntil('\n');
  inData = trim(inData);
}

เสียบสาย USB OTG เข้ากับเครื่อง Android ปลายอีกด้านนำสาย USB จากบอร์ด Android เสียบเข้า

ปิดหน้าต่าง Serial monitor เสียก่อน กดปุ่ม Run ของ Processing เครื่องทำการลงโปรแกรมไปที่ Android และเริ่มทำงาน ถ้าเกิดเออเร่อร์ เหตุที่เป็นไปได้คือ ตัเลขในวงเล็บระบุหมายเลข COM Port ไม่ถูกต้องให้เลือนบรรทัดที่แสดงเออเร่อร์ขึ้นไปหาตัวเลขเพื่อนำไปป้อนในโปรแกรม ส่วนใหญ่แล้วจะเป็น [0] ครับ

กดปุ่ม Run อีกครั้ง ตอนนี้เอง Android จะแสดงป๊อบอัพ ขึ้นมาถามว่าจะใช้โปรแกรมไหนเมื่อมีการเสียบสายเข้ากับ Arduino ให้เลือกชื่อโปรแกรมที่เราเพิ่งติดตั้งไป จะเห็นหน้าตาโปรแกรมเหมือนกับที่ทดสอบบน PC ทดลองกดปุ่ม สังเกตุหลอด LED

ปัญหาที่น่าจะพบคือ Android ไม่แสดงป๊อบอัพ นั่นก็หมายถึงไฟล์ AndroidMaifest.xml ไม่ได้แก้ไข ตามที่ได้แนะนำ ให้ทำการแก้ไขไฟล์ AndroidManifest.xml จากตอนที่แล้ว

ทั้งหมดที่เขียนมา หวังว่าพอจะจุดประกายไอเดีย ในการนำไปใช้งาน

สำหรับผมเองมองว่าตัว Android จะมี Sensor อยู่ภายในตัวมันเองเยอะมาก แทบจะเรียกได้ว่าใช้แทน Arduino shield ได้เป็นอย่างดี เช่น Camera, GPS, Bluetooth, Accelerometer, Compass, NFC, Clock, SD Card, WiFi หน้าจอ LCD ขนาดใหญ่ พร้อม Touch screen (ถ้าเป็น Tablet ต่อออก HDMI เหมือนที่ผมทำคลิปตัวอย่าง อันนี้ยิ่งไอเดียบรรเจิด)  รวมๆแล้ว ถ้าซื้อ Shield ทั้งหมดก็หลายตังค์ แต่ซื้อ Android ตัวเดียว ประมาณ 3 - 4 พัน มีครบเลย ถ้ามีไอเดียดีๆ งานที่ออกมาจะดูทันสมัย ขายได้ราคาเลยหละ

ถ้าใครได้แนวคิดแล้วทำเป็นเรื่องเป็นราว สละเวลามาแบ่งปันกันบ้างก๊ดีนะครับ

ตอนต่อไปผมจะแนะนำ Library อีกตัว ชื่อ Ketai ตัวนี้จะนำเอา Sensor ทั้งหมดที่มีใน Android มาประยุกต์ใช้งาน เขียนบน Processing เชื่อมเข้า Arduino เพื่อขับ Hardware รอติดตามนะครับ

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


AndroidSerial Library

วันศุกร์ที่ 28 มีนาคม พ.ศ. 2557

ตอนที่ 7 : AndroidSerial library


AndroidSerial libaray ไม่อยู่ในรายการ Import Library ต้องติดตั้งเอง ก่อนอื่น download ก่อนครับ


ยังไม่ต้องแตกไฟลนะครับ ต้องหาตำแหน่งที่จะไปเก็บก่อน วางมั่วๆโปรแกรมหาไม่เจอ จะใช้งานไม่ได้ครับ


ขั้นแรกให้เปิดโปรแกรม Processing ก่อน เข้า Menu -> File - Preference
ดู Path ที่แสดงในช่อง Sketchbook Location



เมื่อรู้ตำแหน่งเก็บ Sketchbook แล้ว เปิดเข้าไปจะพบโฟลเดอร์ libraries ให้เอาโฟลเดอร์ AndroidSerial ใส่ไปในโฟลเดอร์นี้

วางเรียบร้อยก็ปิดโปรแกรม แล้วเปิดขึ้นใหม่ เข้าไปที่ Sketch -> Import Library จะเห็น Android Serial Library for Processing เพิ่มเข้ามา เป็นอันเรียบร้อย ให้คลิ๊กที่ Android Serial Library for Processing โปรแกรมจะ import library มาที่พื้นที่เขียนโปรแกรม


อันนี้ต้องทำทุกครั้งที่สร้าง Sketch ใหม่

ยังมีอีกส่วนหนึ่งที่ต้องเพิ่มเติมเข้าไปในโฟลเดอร์ของ Sketch ปกติแล้วตอนที่เราทำการบันทึก Sketch โปรแกรมจะทำการสร้างโฟลเดอร์ใหม่ให้เรา ตั้งชื่อตามที่เราระบุ ถ้าตามที่ผมเก็บโฟลเดอร์ใหม่จะเก็บอยู่ในโฟลเดอร์ Works ในโฟลเดอร์ที่สร้างใหม่ ถ้าเราเลือก Android mode โปรแกรมจะสร้างไฟล์ชื่อ AndroidManifest.xml ซึ่งจะขาดส่วนสำคัญในการเชื่อมต่อกับ USB อยู่

อันนี้โปรแกรมสร้างให้ในไฟล์ AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package=""
          android:versionCode="1"
          android:versionName="1.0">
  <uses-sdk android:minSdkVersion="10" />
  <application android:label=""
               android:icon="@drawable/icon"
               android:debuggable="true">
    <activity android:name="">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>
</manifest>


แต่ที่ต้องการเป็นตามนี้ 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
               android:versionCode="1" 
               android:versionName="1.0" 
               package="">
      <uses-feature android:name="android.hardware.usb.host"/>
      <uses-sdk android:minSdkVersion="10"/>
      <application android:icon="@drawable/icon" android:label="">
      <activity android:name="">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
      <intent-filter>
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
      </intent-filter>
      <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"        android:resource="@xml/device_filter"/>
    </activity>
  </application>
</manifest>

ใช้เฉพาะถ้าเลือก Android mode และใช้ AndroidSerial 

โอเคส่วนสุดท้ายครับ ใน Sketch โฟลเดอร์ให้สร้างโฟลเดอร์ res จากนั้นเข้าไปที่โฟลเดอร์ res สร้างโฟลเดอร xml ตามรูป แล้วสร้างไฟล์ device_filter.xml อาจใช้ Notepad ช่วยครับ


เนื้อหาในไฟล์ครับ

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 0x0403 / 0x6001: FTDI FT232R UART -->
    <usb-device vendor-id="1027" product-id="24577" />

    <!-- 0x2341 / Arduino -->
    <usb-device vendor-id="9025" />

    <!-- 0x16C0 / 0x0483: Teensyduino  -->
    <usb-device vendor-id="5824" product-id="1155" />

    <!-- 0x10C4 / 0xEA60: CP210x UART Bridge -->
    <usb-device vender-id="4292" product-id="60000" />
 
</resources>

พิมพ์เองคงยากให้ Copy แล้ว Paste จากนั้นบันทึก ข้อควรระวังในการใช้ Notepad ตอนบันทึกมันจะใล่ .txt ต่อท้ายชื่อไฟล์ ต้องดูให้ดีว่าไฟล์นั้นต้องชื่อ device_fileter.xml

เพิ่มเติมครับ ในไฟล์นี้จะเป็นการเลือกข้อมูลของ Chip USB ที่อยู่บนอร์ด Arduino ถ้าทดลองแล้วไม่ทำงาน อาจจะเป็นส่วนนี้ ซึ่งเราสามารถหาค่าของ vender-id และ product-id โดยดูจาก Properties ของบอร์ด


ตัวอย่างบอร์ดของผมจะเป็น 0403 และ 6001 เป็นเลขฐาน 16 ซึ่งจะเท่ากับ 1027 และ 24577 เมื่อแปลงเป็นเลขฐานสิบ ยังไงถ้าไม่ได้ก็เอาตัวเลขของบอร์ดมาใส่แทนได้ครับ ไม่น่าจะงงนะครับ

เอาหละตอนนี้ก็ใช้พลังสมองเยอะหน่อย ก็จะไม่ยาวไปกว่านี้ เอาไว้ทดลองกันตอนต่อไปดีกว่า


เตรียมการเข้าสู่ Android mode

วันพฤหัสบดีที่ 27 มีนาคม พ.ศ. 2557

ตอนที่ 6 : เตรียมการเข้าสู่ Android mode

ตอนนี้ผมว่าเป็นตอนที่ต้องทำความเข้าใจให้ดี ไม่งั้นจะหลงทางได้ง่าย ๆ

การพัฒนาโปรแกรมบน Android  ใช้การพัฒนาในลักษณะต่อยอดจากที่มีอยู่ ซึ่งเค้าเรียกว่า Development Kit ซึ่งจะเห็นและได้ยินกันอยู่บ่อย บางค่ายก็จะเรียกว่า Framework

Android Development Kit (ADK) ก็เป็นส่วนสำคัญขาดไม่ได้ ในการพัฒนาโปรแกรม ซึ่งเราจำเป็นต้องติดตั้งชุดนี้ลงในเครื่อง PC ก่อนเป็นอย่างแรก ง่ายๆครับ download กันเลย


ไม่มีการติดตั้งใดๆ แตกไฟล์ออกวางในตำแหน่งที่สามารถเข้าถึงได้ง่ายๆ



ผมเองจะทำโครงสร้างโฟลเดอร์ลักษณะนี้เพื่อจะได้หาง่าย ชื่อโฟลเดอร์ยาวมาก ตอนจะเรียกใช้งานใน command prompt พิมพ์กันเมื่อยเลย ใครจะ rename ก็ไม่ว่ากัน ผมทิ้งไว้แบบนี้จะได้ไม่ทำให้สับสน เปิดเข้าไปดูก็จะมีโฟลเดอร์อีก ทีนี้ต้องเริ่มงานสำคัญกันแล้ว เปิดโปรแกรม SDK Manager.exe


จะเห็นหน้าต่างนี้

ที่เห็นนี่ได้ติดตั้งในส่วนของ Android 2.3.3 (API 10) แล้ว ถ้าเปิดแล้วพบว่าเป็น Not Installed ให้ติ้กที่ช่องหน้า Android 2.3.3 (API 10) ที่ปุ่ม Install ... package ให้กดปุ่มเพื่อเริ่มติดตั้ง 


กดเลือก Accept License ตามด้วย Install รอจนติดตั้งสำเร็จ และเห็นว่าเปลี่ยนเป็น Installed เป็นอันใช้ได้

มีอีก Package หนึ่งที่ต้องติดตั้งด้วยคือ Build-tools ตัวนี้ถ้าไม่มีตอนคอมไฟล์ใน Processing จะแจ้งเออเร่อร์


จะเห็นว่ามี Build-tools หลายตัว ผมเลือกตัวล่าสุด ใช้ได้ก็เลยไม่ได้ลองตัวอื่น
เรื่องของ ADK ก็เป็นอันเรียบร้อย จะรู้ว่าใช้ได้หรือไม่ก็ต้องลองเขียนโปรแกรมเลย

ทีนี้เราจะใช้ Processing ใน Android mode ก็ต้องติดตั้งกัน เหมือนเดิมครับ ถ้าจำได้ตอนติดตั้ง PDE X ก็แบบเดียวกัน Add mode


หา Android mode แล้วก็ติดตั้ง เสร็จเรียบร้อย ปิด เปิด โปรแกรม แล้วก็เลือก Android mode

ลองเขียนโปรแกรมง่ายสักตัว เอาจากตอนแรกๆ ก็ได้ ยังไม่ต้องใช้ ControlP5 ประมาณนี้

void setup() {
  size(500,500);
}

void draw(){
  background(128);
  rect(100,100,100,150,5);
}

ทีนี้ก็เสียบสาย USB จาก Android มายัง PC ถ้ายังไม่เคยใช้ก็อาจมีการติดตั้ง driver กันเล็กน้อย แต่ส่วนสำคัญที่จะต้องมีคือ Android Phone


ถ้ายังไม่มีตัวนี้จะไม่สามารถส่งโปรแกรมไปที่ Android ได้ เครื่องผมเป็น Samsung ก็จะเป็นประมาณนี้

เมื่อทดลอง run โปรแกรม จะสังเกตุเห็นการส่งข้อมูลไปยัง Android ตัวเลข 92862519 นี่แต่ละเครื่องจะไม่เหมือนกันครับ




ผลแสดงบนหน้าจอ Android 


ลองเพิ่มส่วน ControlP5 เข้าไปจากตอนที่แล้ว แต่จะมาใช้ทั้งหมดไม่ได้นะครับ ต้องตัดส่วนที่เกี่ยวกับ Serial ออกก่อน ประมาณนี้

//import com.yourinventit.processing.android.serial.*;
import controlP5.*;
//import processing.serial.*;

ControlP5 cp5;
//Serial port;

String inData="";

void setup(){
  size(600,600);
  
  //println(Serial.list(this));
  //port = new Serial(this, Serial.list(this)[0], 9600);
  //port.clear();
  //port.bufferUntil('\n');
  
  cp5 = new ControlP5(this);
  
  cp5.addTextfield("text1")
     .setPosition(100,100)
     .setSize(100,20)
     .setCaptionLabel("Data")
     .setFont(createFont("Verdana", 16))
     ;
  
  cp5.addButton("button1")
     .setValue(0)
     .setPosition(250, 100)
     ;
     
  cp5.addSlider("slider1")
     .setPosition(150,200)
     .setValue(100)
     .setMax(255)
     .setMin(0)
     ;
     
  cp5.addKnob("knob1").setSize(100,200)
     .setPosition(150,250)
     .setMax(255)
     .setMin(0)
     .setValue(100)
     ;
}

void draw(){
  //Textfield t = (Textfield) cp5.getController("text1");
  //t.setText(inData);
  //cp5.getController("slider1").setValue(int(inData));
  //cp5.getController("knob1").setValue(int(inData));
}

void button1(int value)
{
  println("Button pressed");
  //port.write("B");
}

//void serialEvent(Serial port){
//  inData = port.readStringUntil('\n');
//  inData = trim(inData);
//}


ทดลอง Run ครับ

มาถึงตรงนี้ เราสามารถใช้ Processing ได้ ทั้งบน PC, PC + Arduino และ Android เหลืออีกจุดหนึ่งก็คือให้ Android เชื่อมต่อกับ Arduino โดยตรงผ่านสาย USB OTG ก็ต้องเป็นตอนต่อไปครับ


ตอนที่ 5 : ControlP5

ผมมีแก้ไขเนืือหาตอนที่ 4 เป็นส่วนสำคัญมากๆ 
ลองย้อนกลับไปดูครับ
---------------------------------------------------------------------------------

จากตอนที่แล้ว มีหลายอย่างที่ยังไม่ได้อธิบาย ในส่วนของ Serial เองเป็น library ที่ช่วยในการใช้ Serial port ก็จะเหมือนกับ Serial ใน Arduino ก็คือต้องระบุว่าจะเชื่อมต่อกับ COM ช่องไหน และ Baudrate  ซึ่งในโค๊ดใช้คำสั่งประกอบกัน 2 ส่วนคือ

Serial port;

เป็นการประกาศตัวแปรแบบ Serial ตั้งชื่อว่า port

ในส่วนของการเตรียมการ setup() ก็นำตัวแปรไปใช้

void setup() {
.
.
  println(Serial.list()); // แสดงรายการ COM port

  port = new Serial(this, Serial.list()[1], 9600);

  port.clear() // ล้างข้อมูลใน Buffer

  port.bufferUntil('\n'); กำหนดว่าเมื่อพบ \n ก็หยุดการล้างข้อมูล  
.
.
}

จะมีข้อที่อาจเกิดความยุ่งยากขึ้นบ้าง ถ้าบน PC มีช่อง COM หลายอัน ก็ต้องหาให้เจอว่า Arduino ต่อกับ COM ไหน ก็เอาหมายเลขของ COM นั้นมาใส่ในวงเล็บ แต่ก็คิดว่าเมื่อเขียนโปรแกรม ก็น่าจะมีการให้โปรแกรมช่วยค้นหาหมายเลขสำหรับ COM ที่ต้องการ เอาเป็นว่าใช้วิธีที่บอกไปในตอนที่แล้วไปก่อนแล้วกัน

ส่วนของ this เอง คือระบุว่าจะใช้กับ PApplet ตัวไหน ก็ให้ใส่ไว้แบบนี้ เพราะคงจะน้อยครั้งที่เราจะมี PApplet มากกว่า 1 ตัว

เมื่อกำหนดทั้งหมดแล้ว โปรแกรมก็พร้อมที่จะรับ-ส่ง ข้อมูลแล้วหละ

ที่จะพูดต่อก็คือ ในส่วนของ ControlP5

ControlP5 เป็น Library ที่ใช้ในการวาง Control ต่างๆ ได้แก่ Button, Textfield, Slider, Knob ที่เราเห็นในตัวอย่างจากตอนที่แล้ว และอีกมากมายที่เห็นในรูป




หลายคนเคยเขียน Java หรือภาษาแบบ OOP จะคุ้นกับการใช้ Class แต่ถ้าไม่คุ้นก็ค่อยติดตามไป ไม่ยากครับ

ขอเรียกทั้งหลายที่อยู่ในรูปว่าเป็น Controller การเรียกใช้งานก็ผ่านการประกาศตัวแปร เช่นถ้าต้องการจะใช้ Button ก็ตามนี้

Button button;
Textfield textfield;

ประมาณนี้ครับ

แต่ใน Processing จะมีการเพิ่ม Control ด้วยคำสั่งลักษณะที่ต้องทำความเข้าใจนิดนึง ซึ่งก่อนอื่นต้องสร้างกล่องเก็บ Control ก่อน ตามนี้

ControlP5 cp5;

ใน setup() ก็ใช้ cp5 ด้วย

cp5 = new ControlP5();

ตอนนี้ก็มีกล่องเก็บ Control แล้ว พร้อมจะเก็บ Control ทั้งหลาย สมมุติจะใช้ Button จะทำตามนี้

button = cp5.addButton("button");

ซึ่งอาจไม่ต้องเอาตัวแปร button มารับค่าก็ได้ โดยตัด button = ด้านหน้าออก ก็สามารถทำงานได้ จากตัวอย่างในตอนที่แล้ว มีการกำหนดค่าด้วย .setValue และระบุตำแหน่งด้วย .setPosition ด้วย เอาเป็นว่าใช้วิธีการเขียนตามที่แนะนำไปก่อน เดี๋ยวจะสับสน

ผมว่าอ่านโค๊ดกันก็น่าจะเข้าใจได้ไม่ยาก สำหรับการสร้าง Control ตัวอื่นๆ

ในส่วนของการรับข้อมูลจาก Serial


void serialEvent(Serial port){
  inData = port.readStringUntil('\n');
  inData = trim(inData);
}

serialEvent เป็นคำเฉพาะเพื่ออ่านข้อมูลเข้า ไม่แน่ใจว่าสามารถเขียนแบบอื่นได้หรือปล่าว ยังไม่ได้ลอง ส่วนสำคัญอีกจุดหนึ่งคือ การอ่านค่า ด้วยคำสั่ง port.readStringUtil('\n'); เป็นการอ่านข้อมูลที่เข้ามาจนพบตัว \n (new line) แล้วก็เก็บค่าไว้ในตัวแปร inData ประกาศเป็นแบบ Global ซึ่งทำให้นำเอาไปใช้ในส่วนอื่นได้

ในส่วนของ draw() ก็จะนำเอา inData ไปใช้กับทุก Control

มีอีกส่วนหนึ่งคือการใช้งาน Button


void button1(int value)
{
  println("Button pressed");
  port.write("B");
}


ข้อสังเกตุคือชื่อของฟังค์ชั่นจะเป็นตัวเดียวกับชื่อของ Control คือ button1 ตัวฟังค์ชั่นเองจะคอยรับเหตุการณ์ที่เกิดกับ button ในที่นี้ก็คือการกดปุ่ม โปรแกรมก็จะทำคำสั่งภายใน ก็คือการส่งตัวอักษร B ไปให้ Arduino นั่นคือ สั่งปิด เปิด LED นั่นเอง ส่วนของคำสั่ง println จะแสดงค่าในหน้าต่างด้านล่างของ Processing เพื่อให้สามารถ debug โปรแกรมได้

ยังไงอ่านแล้วยังไม่เข้าใจ ส่งความคิดเห็นมาได้ครับ

ตอนต่อไป จะเป็นการเตรียมเชื่อต่อกับ Android ซึ่งมีเรื่องที่ต้องทำเยอะมาก จะพยายามค่อยๆ อธิบาย คอยติดตามนะครับ

พูดคุยกับ Arduino บน PC กันก่อนดีกว่า

วันพุธที่ 26 มีนาคม พ.ศ. 2557

ตอนที่ 4 : พูดคุยกับ Arduino บน PC กันก่อนดีกว่า

ตามที่ได้เกริ่นไว้แต่แรกว่า เราจะทำการเชื่อมต่อไปยัง Arduino ด้วยสาย USB แบบ OTG ส่วนการจะเชื่อมต่อด้วยวิธีอื่นๆ ผมเองไม่มีตัว Module อื่นๆ อยู่ แต่ถ้าจะมีใครใจดีช่วยจัดหาให้ ก็ยินดีที่จะทดลองการเชื่อมต่อแบบอื่นๆ

บทความตอนนี้จะทดลองเชื่อมต่อผ่านทาง PC เพื่อให้เห็นการเตรียมการต่างๆ ก่อน จากนั้นก็จะสามารถนำไปใช้ตอนที่จะเชื่อมต่อกับ Android ได้

เริ่มกันเลย โดยเปิดโปรแกรม Arduino ก่อน เพื่อสร้างโปรแกรมสำหรับโต้ตอบกับ Processing ได้ พิมพ์โปรแกรมตามนี้


void setup(){
  pinMode(11,OUTPUT);
  digitalWrite(11,LOW);
  Serial.begin(9600);
}

void loop(){
  Serial.println(random(255));
  delay(100);
  if(Serial.available()){
    while(Serial.available()){
      if(Serial.read() == 'B')
        digitalWrite(11, !digitalRead(11));
    }
  }
}

ที่บอร์ดต่อ LED ที่ Pin 11 กับ Gnd จากนั้นทดลอง Run โปรแกรม และเปิด Serial Monitor สังเกตุให้ค่า Baudrate เท่ากับ 9600 นะครับ

ตอนนี้จะเห็นหน้าจอแสดงตัวเลขแบบแรนดอม ที่ออกจากคำสั่ง Serial.println(random(255));

ให้พิมพ์ตัว B ลงในช่องรับข้อมูล ตามด้วยการเคาะ Enter จะเห็นว่า LED ที่ต่อไว้ติดสว่าง พิมพ์ B ตามด้วย Enter อีกครั้ง จะเห็นว่า LED ดับลง ตามคำสั่งเปรียบเทียบการอ่านค่าด้วย Serial.read ว่าเท่ากับตัวอักษร B หรือไม่ ถ้าเงื่อนไขถูกต้องก็ไปทำคำสั่ง 


digitalWrite(11, !digitalRead(11));

ก็คือถ้า LED ติดอยู่ก็ให้ดับ ถ้าดับอยู่ก็ให้ติด สลับไปมา

ถ้าได้ตามนั้นแล้วก็ทำในส่วนของ Processing ต่อไป ถ้าไม่ได้ก็ลองดูว่า มีตรงไหนที่พิมพ์ผิดไปบ้าง

เปิดโปรแกรม Processing ตามสะดวกนะครับ ว่าจะใช้ Mode ไหน ใช้ได้ทั้ง Java และ PDE X ครับ พิมพ์โค๊ดตามนี้ครับ


import controlP5.*;
import processing.serial.*;

ControlP5 cp5;
Serial port;

String inData="";

void setup(){
  size(600,600);
  
  println(Serial.list());
  port = new Serial(this, Serial.list()[1], 9600);
  port.clear();
  port.bufferUntil('\n');
  
  cp5 = new ControlP5(this);
  
  cp5.addTextfield("text1")
     .setPosition(100,100)
     .setSize(100,20)
     .setCaptionLabel("Data")
     .setFont(createFont("Verdana", 16))
     ;
  
  cp5.addButton("button1")
     .setValue(0)
     .setPosition(250, 100)
     ;
     
  cp5.addSlider("slider1")
     .setPosition(150,200)
     .setValue(100)
     .setMax(255)
     .setMin(0)
     ;
     
  cp5.addKnob("knob1").setSize(100,200)
     .setPosition(150,250)
     .setMax(255)
     .setMin(0)
     .setValue(100)
     ;
}

void draw(){
  Textfield t = (Textfield) cp5.getController("text1");
  t.setText(inData);
  cp5.getController("slider1").setValue(int(inData));
  cp5.getController("knob1").setValue(int(inData));
}

void button1(int value)
{
  println("Button pressed");
  port.write("B");
}

void serialEvent(Serial port){
  inData = port.readStringUntil('\n');
  inData = trim(inData);
}

ทดลอง Run เลยครับ ก่อน Run ให้ปิดจอ Serial monitor ก่อน ไม่งั้นจะเกิด Error ได้




ให้ดูในช่องด้านล่างจะเห็นรายการ COM ในภาพเห็นอยู่ 2 บรรทัด ของผมเลือก [1] เพราะ Arduino ต่ออยู่กับ COM4 ถ้าของใครต่อกับคอมอื่น ก็ให้ดูว่าตัวเลขในวงเล็บเป็นหมายเลขใดก็เอาหมายเลขนั้นไปใส่ในโปแกรม ตรงส่วนนี้ครับ


port = new Serial(this, Serial.list()[1], 9600);

ตัวอย่างถ้าตัวเลขในวงเล็บหน้า COM ที่ต่ออเป็น 10 ก็เปลี่ยน [1] เป็น [10]


                   port = new Serial(this, Serial.list()[10], 9600);

ตามนี้ครับ 

กด Stop หรือ ปิดหน้าต่าง แล้วทดลอง Run อีกครั้ง จะได้ผลการทดสอบตามนี้



ถ้าทั้งหมดทำงานถูกต้อง จะเห็นมีการเปลี่ยนของตัวเลขและการเลื่อนไปมาของแถบสีในช่อง แล้วเสี้ยวในวงกลมก็จะขยับไปมา ทั้งหมดเป็นการนำเอาตัวเลขที่ Arduino ส่งมา มาปรับค่า

คราวนี้ทดลองเลื่อนเม้าส์ไปที่ BUTTON แล้วกดปุ่มที่เม้าส์ จะเห็นว่า LED ที่ Arduino จะติด-ดับ เหมือนตอนป้อนตัวอักษร B ใน Serial monitor

ผมเดาว่าตอนนี้ถ้าได้อ่านใน Source code ก็พอจะเดาได้ว่า ส่วนไหนทำอะไร

เพื่อไม่ให้หน้านี้ยาวเกินไป ขอยกยอดไปพูดถึงรายละเอียดในหน้าต่อไป

อ้อ คราวนี้ เราได้เพิ่มการใช้งาน library 2 ตัว คือ ControlP5 และ Serial สังเกตุจากคำสั่ง import ด้านบนสุดของโค๊ด

//-----------------------------------------------------------------

เพิ่มเติมครับ ต้องขอโทษผมลืมส่วนสำคัญมากๆ คือการเอา ControlP5 มาใช้งาน ไม่งั้นก็จะคอมไฟล์ไม่ผ่าน 

การนำ ControlP5 เข้ามา ให้เข้าที่
Sketch -> Import Library... -> Add Library แล้วเลือก ControlP5 กดปุ่ม Install เมื่อติดตั้งเสร็จก็เปิดปิดโปรแกรมครั้งหนึ่ง

//------------------------------------------------------------------




ตอนที่ 3 : ตัวช่วย ของ ตัวช่วย

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

บทความตอนนี้ก็เลยจะแนะนำการติดตั้ง เพื่อให้ชีวิตเราง่ายขี้น ตามตัวอย่างนี้






ก่อนอื่นต้องบอกว่า Processing เปิดโอกาสให้ผู้พัฒนาใช้โครงสร้างของตัวมัน แล้วนำเอาตัวช่วยอื่นๆ เข้ามาเสริมได้ โดยเรียกว่า Mode สำหรับตอนนี้เราจะติดตั้ง  PDE X mode เข้าเป็นส่วนหนึ่งของ Processing

กดเลือกตามรูป

เลือก PDE X แล้วกดปุ่ม Install
เรียบร้อย ปิดหน้าต่างได้เลย

ปิดโปรแกรมแล้วเปิดขึ้นใหม่ เลือก Mode เป็น PDE X โปรแกรมจะปิดแล้วเปิดขึ้นเอง และจะได้หน้าตาใหม่ตามรูป


ทดลองพิมพ์คำสั่งต่างๆ โปรแกรมจะเปิดหน้าต่างเล็กๆ ขึ้น เหมือนกับรูปด้านบน แสดงคำสั่งที่เกี่ยวข้อง โดยที่เราสามารถเลือกคำสั่งได้โดยการ Highlight ที่บรรทัดนั้นแล้วเคาะ Enter

ใน PDE X เองยังมีฟังค์ชั่นอื่นๆด้วย ผมเองก็ยังไม่ได้ใช้มากนัก นอกจากให้ช่วยในการเขียนคำสั่ง







ตอนที่ 2 : ตัวช่วย

งานนี้พระเอกของเราคือ Processing ตอนนี้ก็เลยต้องเชิญตัวช่วยเข้ามาอยู่กับเราก่อน ง่ายๆเลยครับ เข้าที่นี่เลย


ในหน้านี้ถ้ามีใจก็สามารถช่วยสนับสนุนเงินทองกันได้ครับ ถ้ายังไม่สะดวกก็เลือก No Donation แล้วก็กด Download ได้เลย 


การสนับสนุนก็สามารถทำได้ตลอดนะครับ ใช้ดีก็ช่วยๆกันหน่อย จะได้มีแรงมาทำงานดีๆให้เราได้ใช้กัน


เลือกตามนี่ครับ ใช้รุ่น 2.0.3 ตอนนี้รุ่นที่สูงกว่าไม่แนะนำ ยังพบปัญหาตอนใช้ Android mode

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

เอาหละเริ่มต้นเขียนโปรแกรมเลย ผมยังไม่อธิบายส่วนอื่นๆ อยากให้เห็นว่ามันทำงานยังไงก่อน พิมพ์ตามนี้เลยครับ


void setup(){

  size(400,400);

}



void draw(){

  background(128);
  stroke(color(255,128,0));
  strokeWeight(5);
  rect(150,150,100,100,5);
}

ตัวอักษรเล็กใหญ่ตามนั้นเลยนะครับ

ดูแล้วเหมือนตอนเขียนโปรแกรม Arduino นะ ต่างกันตรงที่จาก loop() มาใช้คำว่า draw() แทน การทำงานมันก็จะวนทำจากบรรทัดแรกถึงบรรทัดสุดท้ายแล้วก็วนกลับไปทำบรรทัดแรก

ส่วนของ setup() ก็เป็นการเตรียมการ ในที่นี้เป็นการเตรียมหน้าต่างขนาดกว้าง 400 สูง 400

กดปุ่ม Run ได้เลย ปุ่มเดียวกับใน Arduino นั่นแหละ


จะได้หน้าต่างขนาด 400 x 400 

พื้นหลังสีเทาจากคำสั่ง background(128) จริงแล้วในวงเล็บสามารถใช้คำสั่ง color(r,g,b) ได้ โดยที่ r คือ  ระดับของสีแดง g ตือระดับของสีเขียว และ b คือระดับของสีน้ำเงิน ดูตัวอย่างใน stroke ได้ครับ 

stroke เป็นการกำหนดสีของเส้นขอบ จริงแล้วจะกำหนดของอะไรก็แล้วแต่ที่มีเส้น เช่น เส้นตรง เส้นรอบรูปวงกลม ในที่นี้กำหนดเป็นสีส้ม ก็เกิดจากการผสมสีแดงขนาด 255 สีเหลืองขนาด 128 และไม่ใช้สีน้ำเงิน อันนี้ทดลองเปลี่ยนดูเองได้ครับ

strokeWeight เป็นการกำหนดน้ำหนักหรือขนาดของเส้น ในที่นี้กำหนดให้เท่ากับ 5 

เมื่อกำหนดองค์ประกอบแล้วก็วาดรูปสี่เหลี่ยม โดยตัวแปรไล่ไปตามลำดับตามนี้ 
ตำแหน่งมุมซ้ายบน x = 150, y = 150
ขนาดกว้าง 100 และ สูง 100
ความมนของมุมเท่ากับ 5

rect(x,y,width,height,radius)

ทดลองเปลี่ยนค่าตามชอบใจได้เลย

ทีนี้ลองมาทำอะไรให้มันรู้ถึงความสามารถของ Processing กันสักตัวอย่างนึง

ก่อนอื่นต้องรู้คำสั่งเพิ่มเติมกันอีกนิด ได้แก่ mouseX และ mouseY ทั้งสองคำสั่งเป็นการอ่านค่าปัจจุบันของตำแหน่งที่ mouse อยู่ เราจะเอาทั้งสองคำสั่งไปใส่ไว้ในคำสั่ง rect ตามนี้

rect(mouseX, mouseY, 100, 100, 5);

ลองดูครับว่าจะมีอะไรเกิดขึ้น

ครับเมื่อ draw() วนกลับมาก็จะอ่านค่าตำแหน่งของ mouse แล้วก็จะนำมาใช้เป็นค่าตำแหน่งของรูปสี่เหลี่ยม ทีนี้จะเกิดอะไรขึ้นถ้าลองใส่ comment ที่คำสั่ง background(128);

// background(128);

สิ่งที่เกิดขึ้นก็คือมีรูปสี่เหลี่ยมเต็มไปหมด ก็เพราะว่าไม่ได้ทำการเคลียร์หน้าจอนั่นเอง




ทีนี้อยากให้ใช้คำสั่งอื่น เพิ่มเข้าไป เช่น line, elipse โดยคำสั่งเป็นตามนี้

line(x1, y1, x2, y2); 


x1,y1 ตำแหน่งมุมบนซ้าย และ x2,y2 ตำแหน่งมุมล่างขวา

ellipse(x,y,width,height);

ค่าตัวแปรเหมือนกับคำสั่ง rect

เรื่องของ Processing เบื้องต้น ขอเป็นเท่านี้ก่อน อยากให้ทดลองทำดูให้คุ้นชินก่อน ค่อยใส่ตัวช่วยอื่นต่อ แล้วพบกันครับ





จุดเริ่มต้น                                                                                                                 

ตอนที่ 1 : จุดเริ่มต้น

ผมว่าหลายคนที่เล่น Arduino น่าจะมีความคิดที่จะทำการเชื่อมต่อมันกับอุปกรณ์หรือระบบภายนอก ต่อกับคอมพิวเตอร์หรือมือถือผ่าน Serial port, Bluetooth, WiFi, LAN, XBee 

สำหรับผมเองเลือกเอามือถือ Android หรือ Android Tablet เชื่อมผ่านสาย USB แบบ On The Go (OTG) ไปยังบอร์ด Arduino ซึ่งเป็นระบบที่มีค่าใช้จ่ายต่ำที่สุด หาได้ง่าย

จากประสบการณ์ที่ผ่านมา ผมได้ทดลองใช้ Development โปรแกรมหลากหลายเพื่อสร้างแอปบน Android เช่น Adobe Flash Builder (ActionScript 3), Android Development Kit (Java) ซึ่งสองตัวนี้จะพบกับปัญหาในการเชื่อมต่อผ่าน USB เพื่อจำลองการทำงานให้เป็น Serial Port อีกตัวหนึ่งที่ใช้คือ Xamarin เป็น IDE ตระกูล Visual Studio ทั้งหมดสามารถสร้างแอบได้ แต่เหนื่อยมากครับ ผลที่ได้ไม่ประทับใจ

ในส่วนของ Processing นั้น ผมได้เคยเห็นมันมาตั้งแต่เริ่มเล่น Arduino แต่ตอนนั้นรู้สึกว่าจะใช้ชื่อว่า Wiring ลองดูอยู่พักนึง ซึ่งตอนนั้นมันก็เชื่อมต่อกับ Arduino ได้แล้ว ผมเองก็ไม่รู้จุดประสงค์หลักของตัว Processing ว่าทำมาเพื่ออะไรกันแน่ เห็นแต่ว่ามันสามรถสร้างลายเส้นแบบสวยๆ ได้หลากหลายรูปแบบ และวิธีการเขียนโปรแกรมก็คล้ายๆกัน

เนื่องจาก Processing เป็น Open Source ก็เลยมีคนมาช่วยพัฒนาต่อยอด เหมือนกับ Android ที่สามารถเพิ่มความสามารถได้อย่างรวดเร็ว ปัจจุบันมี Library มากมาย แต่ที่เราจะใช้ก็ได้แก่ ControlP5, AndroidSerial

ControlP5 เป็น Graphic User Interface (GUI) เป็น Library สำหรับการวาง Button, Slider, Text ฯลฯ

AndroidSerial เป็น Library ช่วยให้สามารถจำลอง Serial Port ผ่านช่อง USB ตัวนี้แหละที่ทำให้การสร้างแอป เชื่อมต่อกับ Arduino ง่ายขึ้นมาก 

จริงแล้วตัว Processing ก็มี Library ชื่อ Serial อยู่แล้ว แต่จะเชื่อมต่อกับ Serial port ของ PC ไม่สามารถเชื่อมต่อกับ Android ได้ โดยคำสั่งต่างๆ ก็ไม่แตกต่างกัน

สำหรับการทดสอบเบื่องต้น จะทำงานผ่าน Serial port ของ PC ก่อน เพื่อให้ง่ายกับการทดลอง เชื่อมต่อไปยัง Arduino

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