UART พอร์ตบน Raspberry Pi และ USB2Uart

หลังจากที่ได้ติดตั้ง pi4j ลงในบอร์ด Raspberry Pi ไปก่อนหน้านี้ ซึ่งได้พูดเรื่องการติดตั้ง pi4j การคอมไพล์และรันโปรแกรม การแสดงข้อความออกที่ Console การเซ็ต Gpio ของ Raspberry Pi ซึ่งเนื้อหาที่ลงไว้ผมอ้างอิงและทำตามเว็บ pi4j.com

บทความนี้ผมจะทดสอบการใช้งาน Library pi4j ในส่วนของ Serial Port ของ Raspberry Pi ซึ่งใช้ผ่าน /dev/ttyAMA0 และจะใช้งาน Library เพื่อทดสอบการทำงานร่วมกันกับ USB2Uart ซึ่งใช้พอร์ต /dev/ttyUSB[n] ขึ้นอยู่กับจำนวนของ USB ที่ต่อเสียบอยู่บน Raspberry Pi นั้น เนื้อหาผมจะเริ่มต้นที่ /dev/ttyAMA0  และจึงต่อที่ USB2Uart

Uart พอร์ตบน Raspberry Pi มีมาให้ใช้งานเพียง 1 พอร์ตเท่านั้น (น้อยจัง) ซึ่งจะสามารถใช้งานผ่าน /dev/ttyAM0 โดยใช้ Header P1 ตำแหน่ง Pin ที่ 8(TxD), 9(RxD) เพื่อการสื่อสารข้อมูลดังรูปภาพด้านล่างนี้

/dev/ttyAMA0

/dev/ttyAMA0

/dev/ttyAMA0

/dev/ttyAMA0

ทำการแก้ไข /etc/inittab และ Comment  2:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100 พิมพ์ nano /etc/inittab และรีบูทระแบบใหม่อีกรอบ

/etc/inittab

/etc/inittab

การทดสอบการทำงานพอร์ตผมไขว้สาย TxD กับ RxD เข้าหากัน เมื่อโปรแกรมส่งข้อมูลออกและอ่านกลับเข้ามาที่ dataReceived (กรณีที่ต้องการอ่านข้อมูลเองใช้เมธอด read() ) ผมจะใช้โค้ดเดิมที่มีอยู่แล้วใน  pi4j ไฟล์ชื่อ SerialExample.java และแก้ไขไฟล์เพื่อให้ข้อความที่รับกลับเข้า Terminal เปลี่ยนสีข้อความที่ได้กำหนดไว้โด้ดด้านล่างนี้ครับ

* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import java.util.Date;

import com.pi4j.io.serial.Serial;
import com.pi4j.io.serial.SerialDataEvent;
import com.pi4j.io.serial.SerialDataListener;
import com.pi4j.io.serial.SerialFactory;
import com.pi4j.io.serial.SerialPortException;

/**
 * This example code demonstrates how to perform serial communications using the Raspberry Pi.
 * 
 * @author Robert Savage
 */
public class SerialExample {

    public static void main(String args[]) throws InterruptedException {

        // !! ATTENTION !!
        // By default, the serial port is configured as a console port 
        // for interacting with the Linux OS shell.  If you want to use 
        // the serial port in a software program, you must disable the 
        // OS from using this port.  Please see this blog article by  
        // Clayton Smith for step-by-step instructions on how to disable 
        // the OS console for this port:
        // http://www.irrational.net/2012/04/19/using-the-raspberry-pis-serial-port/

        String msgBlue = "\033[1;34m";
        String msgReset = "\033[0m";
        String msgYellow = "\033[1;33m";

        System.out.println(" Serial Communication Example ... started.");
        System.out.println(" ... connect using settings: 38400, N, 8, 1.");
        System.out.println(" ... data received on serial port should be displayed below.");

        // create an instance of the serial communications class
        final Serial serial = SerialFactory.createInstance();

        // create and register the serial data listener
        serial.addListener(new SerialDataListener() {
            @Override
            public void dataReceived(SerialDataEvent event) {
                // print out the data received to the console
                System.out.print(event.getData());
            }            
        });

        try {
            // open the default serial port provided on the GPIO header
            serial.open(Serial.DEFAULT_COM_PORT, 115200);
            // continuous loop to keep the program running until the user terminates the program
            for (;;) {
                try {
                    // write a formatted string to the serial transmit buffer
                    serial.write(msgBlue+"CURRENT TIME: %s", new Date().toString());

                    // write a individual bytes to the serial transmit buffer
                    serial.write((byte) 13);
                    serial.write((byte) 10);

                    // write a simple string to the serial transmit buffer
                    serial.write(msgYellow+"Second Line");

                    // write a individual characters to the serial transmit buffer
                    serial.write('\r');
                    serial.write('\n');

                    // write a string terminating with CR+LF to the serial transmit buffer
                    serial.writeln(msgReset+"Third Line");
                }
                catch(IllegalStateException ex){
                    ex.printStackTrace();                    
                }

                // wait 1 second before continuing
                Thread.sleep(1000);
            }

        }
        catch(SerialPortException ex) {
            System.out.println(" ==>> SERIAL SETUP FAILED : " + ex.getMessage());
            return;
        }
    }
}

คอมไพล์โปรแกรม

javac -classpath .:classes:/opt/pi4j/lib/'*' SerialExample.java

รันโปรแกรม

java -classpath .:classes:/opt/pi4j/lib/'*' SerialExample

ผลการรัน

SerialExample

SerialExample

USB2Uart

เมื่อจำนวนของ Uart  พอร์ตบน Raspberry Pi ไม่พอต่อการใช้งานทางหนึ่งเท่าที่ค้นพบคือใช้วิธีการเปลี่ยนจาก usb เป็น serial หรือที่เรียกคุ้นๆกันคือ USB2Uart อุปกรณ์ตัวนี้หาซื้อได้ตามท้องตลาดทั่วไป ผมใช้ของ ETT มีอยู่ 2 ตัว

ET-MINI USB-TTL

ET-MINI USB-TTL

คำสั่งที่ใช้งานเกี่ยวกับอุปกรณ์ usb เช่น

lsusb           แสดงอุปกรณ์ USB ทั้งหมดที่ต่ออยู่

lsusb -v       แสดงรายละเอียดของ usb

ls /dev/ttyUSB*   แสดงอุปกรณ์ ttyUSB ทั้งหมดที่ต่ออยู่

ทดลองใช้คำสั่ง lsusb (เสียบ usb2uart จำนวน 2 ตัว) ผลที่ได้ดังรูปภาพด้าน

lsusb

lsusb

แสดงอุปกรณ์ /dev/ttyUSB ที่ต่อยู่ทั้งหมดใช้สัญลักษณ์ * ดังตัวอย่างคำสั่งด้านล่างนี้

ls /dev/ttyUSB*

ผล

root@raspberrypi: ls /dev/ttyUSB*
/dev/ttyUSB0  /dev/ttyUSB1

ถ้าหากต้องการแสดงรายละเอียดของอุปกรณ์ usb ที่ต่ออยู่ใช้คำสั่ง

 
lsusb –v

แต่เนื่องจากว่าข้อมูลรายละเอียดมีจำนวนมากและไม่สามารถและราลเอียดข้อมูลก่อนหน้านั้นโดยการเลื่อนขึ้นไปดูรายละเอียดก่อนหน้าได้ ดังนั้นจึงส่งข้อมูลต่อให้ less โดยใช้สัญลักษณ์ | เพื่อส่งต่อไปยังปลายทาง ในที่นี่ส่งต่อไปยัง less (ที่บริษัทสอนมาอีกที) กดปุ่มขึ้นหรือลง เพื่อแสดงข้อมูลตามต้องการ

lsusb –v | less

และออกจาก less ให้กดปุ่ม q

ย้อนกลับเพื่อทดสอบการทำงานของ ttyUSB[n] โดยใช้โปรแกรมเดิมเพียงเปลี่ยนจากการเปิดพอร์ต serial.open(Serial.DEFAULT_COM_PORT, 115200); ตามอุปกรณ์ที่พบใน /dev/ttyUSB*

serial.open(“/dev/ttyUSB0”, 115200);
serial.open(“/dev/ttyUSB1”, 115200);

โปรแกรมที่แก้ไขใหม่

import java.util.Date;

import com.pi4j.io.serial.Serial;
import com.pi4j.io.serial.SerialDataEvent;
import com.pi4j.io.serial.SerialDataListener;
import com.pi4j.io.serial.SerialFactory;
import com.pi4j.io.serial.SerialPortException;

/**
 * This example code demonstrates how to perform serial communications using the Raspberry Pi.
 * 
 * @author Robert Savage
 */
public class SerialExample {

    public static void main(String args[]) throws InterruptedException {

	       String msgBlue = "\033[1;34m";
	       String msgReset = "\033[0m";
	       String msgYellow = "\033[1;33m";

        String usbFT232Port = "/dev/ttyUSB0";

        System.out.println(" Serial Communication Example ... started.");
        System.out.println(" ... connect using settings: 115200, N, 8, 1.");
        System.out.println(" ... data received on serial port should be displayed below.");

		System.out.println(" ========================================= ");
		System.out.println(" Use ttyUSB port:"+usbFT232Port);

        // create an instance of the serial communications class
        final Serial serial = SerialFactory.createInstance();

        // create and register the serial data listener
        serial.addListener(new SerialDataListener() {
            @Override
            public void dataReceived(SerialDataEvent event) {
                // print out the data received to the console
                System.out.print(event.getData());
            }            
        });

        try {

            // open the default serial port provided on the GPIO header
            serial.open(usbFT232Port, 115200);

            // continuous loop to keep the program running until the user terminates the program
            for (;;) {
                try {
                    // write a formatted string to the serial transmit buffer
                    //serial.write("\033[01;32mCURRENT TIME: %s", new Date().toString());
					serial.write(msgBlue+"CURRENT TIME: %s", new Date().toString());

                    // write a individual bytes to the serial transmit buffer
                    serial.write((byte) 13);
                    serial.write((byte) 10);

                    // write a simple string to the serial transmit buffer
                    serial.write(msgYellow+"Second Line");

                    // write a individual characters to the serial transmit buffer
                    serial.write('\r');
                    serial.write('\n');

                    // write a string terminating with CR+LF to the serial transmit buffer
                    serial.writeln(msgReset+"Third Line");
                }
                catch(IllegalStateException ex){
                    ex.printStackTrace();                    
                }

                // wait 1 second before continuing
                Thread.sleep(1000);
            }

        }
        catch(SerialPortException ex) {
            System.out.println(" ==>> SERIAL SETUP FAILED : " + ex.getMessage());
            return;
        }
    }
}

ทำการคอมไพล์ใหม่และรันโปรแกรมเหมือนเดิม ผลลัพธ์ที่ได้ดังภาพด้านล่างนี้ครับ

SerialExample

SerialExample

อินเตอร์เฟส Serial ของไลบราลี PI4J มีดังนี้

Interface Serial ใน PI4J

Interface Serial ใน PI4J

สำหรับบทความนี้หวังว่าท่านจะสามารถนำไปประยุกต์ต่อได้ เช่นหากมีอุปกรณ์ใดๆที่ต้องสื่อสารข้อมูลด้วย Serial พอร์ต หรือผ่าน USB2Serial สามารถนำไลบราลีนี้ไปใช้งานได้เลย วิธีอื่นๆก็มีเช่นกัน เท่าที่เห็นเขาจะใช้ python เขียน script และเรียกใช้งานอีกต่อ นั่นก็เป็นอีกวิธีหนึ่งสามารถทำได้เช่นกัน แต่เท่าที่ดูผมงงๆ เพราะไม่เห็นมีสัญลักษณ์ปิดท้ายคำสั่งเลย.. แต่ก็น่าสนใจศึกษาไว้เหมือนกัน

บทความนี้ไว้เพียงเท่านี้ก่อนครั้งหน้าจะว่าด้วยเรื่องอะไรอย่าลืมติดตามน่ะครับบบบบบบ.. ไปเดินเล่นฟอร์จูนดีกว่า...ไปละครับ

by@10

 

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>