06. การติดต่อกับพอร์ทอนุกรม
สายดาว์นโหลดของอาร์ดูโนเป็นพอร์ทอนุกรม สามารถใช้สายนี้สื่อสารกับคอมพิวเตอร์ที่มีพอร์ทอนุกรมได้ การทดลองนี้จะใช้พอร์ทอนุกรมของอาร์ดูโน สื่อสารกับเคร่องพีซี โดยที่พีซีจะใช้โปรแกรม
Serial Monitor ของโปรแกรม Arduino
โปรแกรม Hyper terminal หรือ
ใช้โปรแกรม Processing
หมายเหตุ พอร์ทอนุกรมใช้ขาสัญญาณเพื่อการติดต่ออยู่ 2 ขาคือ
ขารับข้อมูล RxD ใช้ขา D0
ขาส่งข้อมูล TxD ใช้ขา D1
ดังนั้นเมื่อใช้พอร์ทอนุกรม ขา D0 และ D1 จึงใช้เป็นสัญญาณ Digital I/O ไม่ได้
ข้อควรระวัง ในบทความนี้มีโปรแกรมอยู่ 2 แบบ คือ โปรแกรมของ Arduino และ โปรแกรมของ Processing
ต่อวงจรตามรูปที่ 1
รูปที่ 1
ตัวอย่างที่ 1 พิมพ์ข้อมูลทั้งอักขระออกทางพอร์ทอนุกรม RS232
** โปรแกรม Arduino **
/* RS232 Hello world */
void setup()
{
Serial.begin(9600); // set baudrate
Serial.println("Hello, I'm Arduino."); // prints title with ending line break
}
void loop()
{
}
วิธีที่ 1 ใช้คำสั่ง Serial Monitor ของโปรแกรม Arduino
จะปรากฏหน้าต่าง
เราสามารถ RUN โปรแกรมได้ใหม่โดยกดสวิทช์รีเซ็ต บนบอร์ด Arduino
วิธีที่ 2 ใช้โปรแกรม Hyper terminal รับข้อมูล ดูวิธีการใช้งานได้จาก https://sites.google.com/site/eplearn/software/hyper_terminal
วิธีที่ 3 ใช้โปรแกรม Processing รับข้อมูลแล้วแสดงออก ทางจอภาพ ดูได้จาก https://sites.google.com/site/eplearn/processing/serial_port
------------------------------------------------------------------------------------------------------------------------
ตัวอย่างที่ 2 รับข้อมูลจากพอร์ทอนุกรม โดยใช้ Serial Monitor เป็นตัวส่งข้อมูล แล้วแสดงผลออกทาง LCD
ข้อมูลที่รับความยาวไม่เกิน 16 ตัวอักษร หรือ กดคีย์ Enter
** โปรแกรม Arduino **
/* Read a text received on serial arduino port and display on LCD*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#define INLENGTH 16
#define lf 10
#define cr 13
char inString[16];
int inCount;
int incomingByte = 0;
void setup()
{
Serial.begin(9600);
lcd.begin(16, 2);
pinMode(13, OUTPUT);
digitalWrite(13, HIGH); // set the LED on
lcd.println("Ready to receive");
}
void loop()
{
inCount = 0;
do
{
while (!Serial.available()); // wait for input
inString[inCount] = Serial.read(); // get it
if ((inString [inCount] == cr)||(inString [inCount] == lf)) break;
++inCount;
} while(inCount < INLENGTH);
inString[inCount] = 0; // null terminate the string
lcd.setCursor(0,1); //col, row
lcd.print(" ");
lcd.setCursor(0,1); //col, row
lcd.print(inString);
}
------------------------------------------------------------------------------------------------------------------------
ตัวอย่างที่ 3 จากตัวอย่างที่ 2 เปลี่ยนจากการใช้ Serial Monitor ของ Arduino เป็นตัวส่งข้อมูล มาเป็นใช้ โปรแกรม Processing เป็นตัวส่งข้อมูล
โปรแกรม Arduino ใช้โปรแกรมที่ 2
โปรแกรม Processing ใช้โปรแกรมต่อไปนี้
** โปรแกรม Processing **
import processing.serial.*;
int i = 0;
Serial myPort; // กำหนดตัวแปรสำหรับพอร์ทอนุกรม
int lf = 10; // กำหนดตัวแปรสำหรับรหัส ASCII ของ Linefeed
String myString = null; // กำหนดตัวแปรสตริง
void setup() {
size(300, 300);
println(Serial.list()); // แสดงพอร์ทที่มีอยู่
myPort = new Serial(this, Serial.list()[1], 9600); //เรียกใช้พอร์ทหมายเลข [1]
}
void draw(){
}
void mouseClicked() {
i++;
myPort.write("Thammasat");
myPort.write(" ");
myPort.write(str(i));
myPort.write(10);
}
การทดลองทำดังนี้
1. run Arduino
2. run Processing
3. เมื่อปรากฏหน้าต่างการทำงานของ Processing ให้ใช้ คลิกเมาส์ในหน้าต่างนั้น ทุกครั้งที่คลิก จะปรากฏข้อความที่ LCD
------------------------------------------------------------------------------------------------------------------------
ตัวอย่างที่ 4 จากตัวอย่างที่ 2 ให้ใช้โปรแกรม Processing button_4.zip (อยู่ด้านล่างหน้าเพจนี้) เป็นโปรแกรมส่งข้อมูล
------------------------------------------------------------------------------------------------------------------------
ตัวอย่างที่ 5 จากตัวอย่างที่ 4 ให้แก้ไขโปรแกรม Arduino เป็นการทำให้ LED ติดตามการปิดเปิดสวิทช์ของโปรแกรม Processing โดยใช้วงจรตามรูปที่ 5
รูปที่ 5
------------------------------------------------------------------------------------------------------------------------
ตัวอย่างที่ 6 พิมพ์ข้อมูลทั้งอักขระ และตัวแปรออกทางพอร์ทอนุกรม RS232
** โปรแกรม Arduino **
/* RS232 print data*/
void setup()
{
Serial.begin(9600);
// prints title with ending line break
Serial.println("Prints data to the serial port as human-readable ASCII text.");
}
int number = 0;
void loop()
{
Serial.print("Number = ");
Serial.println(number);
if (number==20)
{
while(true)
{
continue;
}
}
number++;
}
เมื่อ RUN โปรแกรม จะได้ผลดังรูป
------------------------------------------------------------------------------------------------------------------------
ตัวอย่างที่ 7 รับข้อมูลจากพอร์ทอนุกรม แล้วพิมพ์ข้อมูลนั้นกลับไปที่พอร์ทอนุกรม RS232 แสดงทาง Hyper terminal ในรูปของเลขฐานสิบและฐานสิบหก ข้อมูลที่รับเข้ามาเกิดจากการ พิมพ์แป้นคีย์บอร์ดของเครื่งพีซี
** โปรแกรม Arduino **
/* RS232 get and print data*/
int incomingByte = 0;
void setup()
{
Serial.begin(9600);
// prints title with ending line break
Serial.println("Reads incoming serial data.");
}
void loop()
{
if (Serial.available() > 0)
{
incomingByte = Serial.read(); // read the incoming byte:
Serial.print("I received: "); // say what you got:
Serial.print(incomingByte);
Serial.print(" ");
Serial.println(incomingByte, HEX);
}
}
ผลการทำงาน
หรือ
------------------------------------------------------------------------------------------------------------------------
ตัวอย่างที่ 8 รับข้อมูลจากพอร์ทอนุกรม แล้วพิมพ์ข้อมูลออกทางจอ LCD
** โปรแกรม Arduino **
#include <LiquidCrystal.h>
/* Get data from RS232 and display on LCD*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 4, 9, 10, 11, 12);
int incomingByte = 0;
void setup()
{
Serial.begin(9600);
lcd.begin(16, 2);
// prints title with ending line break
Serial.println("Reads incoming serial data and display on LCD.");
}
void loop()
{
if (Serial.available() > 0)
{
incomingByte = Serial.read(); // read the incoming byte:
lcd.setCursor(1,0);
lcd.print("key = ");
lcd.print(incomingByte);
}
}
------------------------------------------------------------------------------------------------------------------------
ตัวอย่างที่ 9 รับข้อมูลจากพอร์ทอนุกรม เป็น text string ความยาวไม่เกิน 16 ตัวอักษร หรือพิมพ์ enter แล้วแสดงผลออกทาง LCD
** โปรแกรม Arduino **
/* Read a text received on serial arduino port and display on LCD*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 4, 9, 10, 11, 12);
#define INLENGTH 16
#define INTERMINATOR 13
char inString[INLENGTH+1];
int inCount;
int incomingByte = 0;
void setup()
{
Serial.begin(9600);
lcd.begin(16, 2);
// prints title with ending line break
//Serial.println("Reads incoming serial data and display on LCD.");
pinMode(13, OUTPUT);
digitalWrite(13, HIGH); // set the LED on
lcd.setCursor(0,0); //col, row
lcd.println("Ready to receive");
}
void loop()
{
inCount = 0;
do
{
while (!Serial.available()); // wait for input
inString[inCount] = Serial.read(); // get it
if (inString [inCount] == INTERMINATOR) break;
++inCount;
} while(inCount < INLENGTH);
lcd.setCursor(0,1); //col, row
lcd.print(inString);
inString[inCount] = 0; // null terminate the string
}
------------------------------------------------------------------------------------------------------------------------
ตัวอย่างที่ 10 ใช้โปรแกรมในตัวอย่างที่ 5 สำหรับ อาร์ดูโน รับข้อมูลจากพอร์ทอนุกรม เป็น text string ความยาวไม่เกิน 16 ตัวอักษร หรือพิมพ์ enter แล้วแสดงผลออกทาง LCD ข้อมูลมาจากโปรแกรม Processing ที่เกิดเมื่อกดเมาส์
โปรแกรม ของ Processing
** โปรแกรม Processing **
import processing.serial.*;
Serial port; // The serial port object
void setup()
{
size(300, 300);
// In case you want to see the list of available ports
println(Serial.list());
port = new Serial(this, Serial.list()[1], 9600);
// Write message to Com port
port.write(" "); //clear display on Arduno
port.write(13); //terminate
port.write("Ready Go");
port.write(13);
}
void draw()
{
background(204);
line(150, 150, mouseX, mouseY);
if (mousePressed) {
port.write(" "); //clear display on Arduno
port.write(13); //terminate
port.write(str(mouseX));
port.write(" "); //seperate
port.write(str(mouseY));
port.write(" ");
port.write(13); //terminate
}
}