วันพฤหัสบดีที่ 21 กุมภาพันธ์ พ.ศ. 2556

OpenWrt Print Server โดยใช้ TP-Link TL-WR703N

วัสดีครับ วันนี้ผมขอนำเสนอโครงงานแนว Embeded Linux ซึ่งก็คือ Open-WRT ซึ่งจะนำมาทำเป็น Wireless Print Server โดยมันช่วยเพิ่มความสะดวกในการใช้เครื่อง Printer เนื่องจากไม่ต้องเชื่อม Printer เข้ากับคอมพิวเตอร์โดยตรง การเชื่อมต่อจะใช้ TL-WR703N เชื่อมกับ Printer ซึ่งผมใช้ Brother HL-2130 มานำเสนอ ในตัวของ TL-WR703N มี Wireless LAN Interface อยู่ ทำให้การเชื่อมต่อเข้าเครือข่ายไม่ต้องใช้สาย
TP-Link TL-WR703N 

Printer Brother HL-2130 ที่นำมาทดสอบเป็นเครื่องพิมพ์แบบ Laser ขาว-ดำ มีพอร์ตเชื่อมต่อแบบ USB ดังรูป
Brother HL-2130
อุปกรณ์ที่ต้องใช้มี 2 อย่างคือ
  • TP-Link TL-WR703N
  • Brother HL-2130

ในส่วนของ Software ที่ต้องใช้มีดังนี้
  • Openwrt Firmware สำหรับ TL-WR703N ผมใช้ตัวนี้ครับ Firmware
  • p910nd Printer Server software
  • usb-printer-support module
ก่อนการทดลองต้องเปลี่ยน firmware และตั้งค่า IP Address ให้กับ WiFi Interface ก่อน สามารถดูรายละเอียดได้ที่เว็บนี้ครับ
ในระหว่าการทดลองจะมีการดาวโหลด Packet มาติดตั้งเสริม ดังนั้นตัว Router ต้องสามารถเชื่อมต่ออินเตอร์เน็ตได้ด้วย

ขั้นตอนการติดตั้ง
  • ต่อสายแลนเข้ากับ Router เพื่อที่จะ Telnet หรือ SSH เข้าไปทดลอง
  • IP address ของ Router คือ 192.168.1.1
  • ทำการ Telnet เข้าไปยัง Router
  • ตั้งค่า WiFi interface โดยทำดังนี้
  • พิมพ์คำสั่ง vi /etc/config/network
  • กดปุ่ม 'i' 1 ครั้งเพื่อเข้าสู่โหมดแก้ไข
  • เพิ่ม ข้อความนี้เข้าไป 
                config interface 'wan'
                           option ifname 'wlan0'    
                           option proto 'dhcp' 
  • กด esc 1 ครั้ง แล้วพิมพ์ :wq กดปุ่ม Enter
  • พิมพ์คำสั่ง vi /etc/config/wireless
  • กดปุ่ม 'i' 1 ครั้งเพื่อเข้าสู่โหมดแก้ไข
  • เพิ่ม ข้อความนี้เข้าไป 
        config wifi-iface
              option device radio0
              option network wan
              option mode sta
              option ssid 'ชื่อของ wifi'
              option encryption psk2
              option key 'รหัสผ่าน'

  • กด esc 1 ครั้ง แล้วพิมพ์ :wq กดปุ่ม Enter
  • พิมพ์ reboot กดปุ่ม enter เราเตอร์จะรีบูตตัวเอง หลังจากเปิดตัวเองขึ้นมาใหม่ก็จะสามารถใช้งาน WiFi ได้เลย
  • เมื่อ boot เสร็จเรียบร้อยก็ให้พิมพ์คำสั่ง opkg update จะได้ผลลัพธ์


Downloading http://downloads.openwrt.org/snapshots/trunk/ar71xx/packages/Packages.gz.
Updated list of available packages in /var/opkg-lists/barrier_breaker.


  • พิมพ์ opkg install kmod-usb-printer ผลลัพธ์จะได้เป็น
Installing kmod-usb-printer (3.7.9-1) to root...
Downloading http://downloads.openwrt.org/snapshots/trunk/ar71xx/packages/kmod-usb-printer_3.7.9-1_ar71xx.ipk.
Configuring kmod-usb-printer.
[  257.810000] usblp 1-1:1.0: usblp0: USB Bidirectional printer dev 2 if 0 alt 0 proto 2 vid 0x04F9 pid 0x003F
[  257.820000] usbcore: registered new interface driver usblp


  • พิมพ์ opkg install p910nd ผลลัพธ์จะเป็น
Installing p910nd (0.95-3) to root...
Downloading http://downloads.openwrt.org/snapshots/trunk/ar71xx/packages/p910nd_0.95-3_ar71xx.ipk.
Configuring p910nd.



  • พิมพ์คำสั่งดังนี้
    • /etc/init.d/p910nd enable
    • /etc/init.d/p910nd start
  • พิมพ์คำสั่ง vi /etc/hotplug.d/usb/20-printer
  • กดปุ่ม 'i' 1 ครั้งเพื่อเข้าสู่โหมดแก้ไข
  • เพิ่ม ข้อความนี้เข้าไป 
#!bin/sh
if [ "$PRODUCT" = "4f9/3f/100" ]
then
case "$ACTION" in
        add)
        /etc/init.d/p910nd stop
        echo "`date` : Brother HL-2130 add" >> /tmp/hl-2130
        /etc/init.d/p910nd start >> /tmp/hl-2130
        echo "Done." >> /tmp/hl-2130
        ;;
        remove)
        echo "`date` : Brother HL-2130 removed" >> /tmp/hl-2130
        /etc/init.d/p910nd stop >> /tmp/hl-2130
        echo "Done." >> /tmp/hl-2130
        ;;
esac
fi



  • กด esc 1 ครั้ง แล้วพิมพ์ :wq กดปุ่ม Enter
  • ลองเสียบสาย USB ของ Printer แล้วถอดออก
  • เมื่อพิมพ์คำสั่ง  cat /tmp/hl-2130 ผลลัพธ์จะเป็น

Wed Feb 20 17:07:06 UTC 2013 : Brother HL-2130 removed
Done.
Wed Feb 20 17:07:06 UTC 2013 : Brother HL-2130 removed
Done.
Wed Feb 20 17:07:11 UTC 2013 : Brother HL-2130 add
Done.
Wed Feb 20 17:07:12 UTC 2013 : Brother HL-2130 add
Done.

  •  พิมพ์ชุดคำสั่งต่อไปนี้ลงไป
uci set p910nd.cfg1=p910nd
uci set p910nd.cfg1.device=/dev/usb/lp0
uci set p910nd.cfg1.port=0
uci set p910nd.cfg1.bidirectional=1
uci set p910nd.cfg1.enabled=1
uci commit p910nd
/etc/init.d/p910nd restart

  •  พิมพ์ vi /etc/config/firewall 
  • กดปุ่ม 'i' 1 ครั้งเพื่อเข้าสู่โหมดแก้ไข
  • เพิ่ม ข้อความนี้เข้าไป 
    #Open Port For Network Printer
    config 'rule'
            option 'src' 'lan'
            option 'proto' 'tcp'
            option 'desc_port' '9100'
            option 'target' 'ACCEPT'
    config 'rule'
            option 'src' 'wan'
            option 'proto' 'tcp'
            option 'desc_port' '9100'
            option 'target' 'ACCEPT'

    • กด esc 1 ครั้ง แล้วพิมพ์ :wq กดปุ่ม Enter
    • พิมพ์ reboot เพื่อรีบูตตัวเอง
    หลังจากทำการตั้งค่าฝั่ง Server เสร็จก็สามารถใช้งาน Print-Server ได้ โดยมีขั้นตอนดังนี้


    ขั้นตอนการ Add Printer 

    ในที่นี้จะแสดงตัวอย่างของ Windows 8 ซึ่งสามารถนำไปประยุกต์ใช้กับ  Windows รุ่นอื่นๆ ได้เช่นกัน โดยขั้นตอนมีดังนี้

    • เข้าไปยัง Devices and Printers ที่อยู่ใน Control Panel



    • กดที่ Add a Printer





    • คลิกที่ The printer that I want isn't listed



    • คลิกตัวเลือกล่างสุด แล้วคลิก Next




    • คลิกตัวเลือกล่างและตั้งค่าเป็น Standard TCP/IP Port แล้วคลิก Next



    • ที่ช่อง Hostname ให้ใส่หมายเลขไอพี Wireless ของ Router ช่อง Port name ใส่เป็นอะไรก็ได้ ส่วนที่ check box ให้ติ๊กออกแล้วคลิก Next


    • จะพบกับหน้า Detecting TCP/IP port ให้รอจนมันเปลี่ยนเป็นหน้าถัดไป



    • เมื่อเข้าสู้หน้า addination port information required ให้เลือก Custom แล้วคลิก Settings



    • จะปรากฎหน้าตั้งค่า คลิก OK แล้วคลิก Next

    • เลือก Driver ให้ตรงรุ่นกับ Printer แล้วคลิก Next
    • คลิก Next
    • ตั้งชื่อเครื่องพิมพ์แล้วคลิก Next
    • คลิก Next
    • คลิก Finish
    • จะปรากฎเครื่องพิมพ์รูปขวาสุด สามารถสั่งงานได้แบบปกติ

    แหล่งข้อมูล


    แหล่ง Firmware






                          วันเสาร์ที่ 2 กุมภาพันธ์ พ.ศ. 2556

                          ออกแบบวงจร PCB ของโมดูล GPS HOLUX M-9129

                          Holux M-9129 เป็นโมดูล GPS ที่น่าสนใจ มีราคาไม่แพงประมาณ 500 กว่าบาทอ้างอิงจากเว็บ es.co.th รูปร่างของโมดูลเป็นดังนี้
                          รูปจริงของโมดูล
                          ตัวโมดูลมีขนาดเล็ก มีขา 22 ขา แต่ใช้งานจริงไม่กี่ขา ได้แก่ 
                          • VCC(13) ต่อกับไฟ +3.3V
                          • V_BAT(12) ต่อกับถ่ายกระดุม 3V
                          • GND(7,17,20,22)
                          • TXDA(4) ต่อกับพอร์ต Serial หรือ UART
                          • RXDA(5)
                          • RF_IN(21) ต่อกับเสาอากาศ
                          • GPIO5(8) ต่อกับ LED เพื่อบอกสถานะการ Fix ของ GPS
                          รายละเอียดขาต่างๆ ของโมดูลเป็นดังนี้

                          ชื่อ Pin ต่างๆ

                          ตารางอธิบายรายละเอียดขาต่างๆ
                          ตารางรายละเอียดขา

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

                          Schematic
                          หลังจากนั้นนำไปสร้าง PCB ออกมา
                          PCB Top Layer
                          PCB Top overlay

                          หลังจากออกแบบ PCB เรียบร้อยก็จะเข้าสู่ขั้นตอนการกัด PCB โดยใช้กรรมวิธี Toner Transfer ผ่านทางแผ่นใส แล้วทำการเจาะรูจะได้แผ่น PCB ดังนี้

                          PCB ของโมดูล GPS

                          บอร์ด GPS เมื่อประกอบเสร็จ

                          ทำการบัดกรีอุปกรณ์ต่างๆเสร็จ ก็ทำการทดสอบ โดยต่อเชื่อมอุปกรณ์ดังนี้


                          การเชื่อมต่ออุปกรณ์
                          ในที่นี้เชื่อม GPS กับคอมพิวเตอร์โดยผ่านทางบอร์ดแปลง USB to Serial

                          ต่อ บอร์ด GPS เข้ากับบอร์ด

                          GPS&GSM Antenna

                          บอร์ดแปลง USB to Serial Port
                          จากการทดสอบ GPS สามารถ Fix ตำแหน่งแบบ 3D โดยใช้เวลาประมาณ 38 วินาที ซึ่งก็ถือว่าเร็วทันใจดีมาก

                          รายการอุปกรณ์ที่ใช้(ไม่รวมบอร์ด USB to Serial)
                            • ตัวต้านทานขนาด 240 โอห์ม                                                       1 ตัว
                            • ตัวต้านทานขนาด 1000 โอห์ม                                                     1 ตัว
                            • LED สีเขียว                                                                                  1 ตัว
                            • LED สีแดง                                                                                   1 ตัว
                            • รางถ่านกระดุมแบบยืน                                                                 1 ตัว
                            • Holux M-9129                                                                             1 ตัว
                            • Pin Header                                                                                 22 ขา
                            • GPS Antenna พร้อม Connector                                                    1 ชุด

                          แหล่งข้อมูลที่ใช้

                          วันพฤหัสบดีที่ 15 พฤศจิกายน พ.ศ. 2555

                          test script

                          $(document).bind('click', function(e) {
                          
                                      var $clicked = $(e.target);
                                      if (! $clicked.parents().hasClass("staticMenu")){
                                          $(".staticMenu dd ul").hide();
                                          $(".staticMenu dt a").removeClass("selected");
                                      }        });
                          
                          
                          #define r  3
                          #define g  5
                          #define b  6
                          
                          unsigned char va;
                          unsigned char vb;
                          unsigned char vc;
                          
                          void setup()
                          {
                            pinMode(r, OUTPUT);
                            pinMode(g, OUTPUT);
                            pinMode(b, OUTPUT);
                            Serial.begin(9600);  
                          }
                          
                          
                          void loop()
                          {
                            va = (unsigned char)micros();
                            delay(50);
                            vb = (unsigned char)micros();
                            delay(50);
                            vc = (unsigned char)micros();
                            delay(50);
                            analogWrite(r, va);
                            analogWrite(g, vb);
                            analogWrite(b, vc);
                            delay(200);
                            
                          }
                          
                          ทดสอบๆ

                          โดย

                          SyntaxHighlighter


                          วิธีการทำเอาจากหน้านี้ครับ


                          ใช้ Arduino รับค่าจาก PS/2 Keyboard

                          หลังจากที่ผมได้อ่านตามเว็บต่างๆ พบมีการใช้ไมโครคอนโทรลเลอร์มารับค่าจาก keyboard แบบ PS/2 ที่ใช้ในคอมพิวเตอร์รุ่นเก่าๆ จึงอยากลองเขียนดูบ้าง ตัว keyboard ได้ของเก่าจากห้องเก็บของซึ่งก็เก่ามากยี่ห้อ Sony แต่ยังใช้งานได้ดีอยู่เลย



                          รูปที่ 1 Keyboard ที่นำมาทดลอง


                          ในการทดลองผมได้ทำตัวแปลงหัวพอร์ตของ Keyboard เป็นขาแบบ SIP จำนวน 6 ขา เพื่อความสะดวกในการต่อกับบอร์ด Arduino โดยออกแบบวงจรอย่างง่ายด้วยโปรแกรม Protel99se

                          รูปที่ 2 ตัวแปลงพอร์ต PS/2 มุมมองด้านล่าง

                          รูปที่ 3 ตัวแปลงพอร์ต PS/2 มุมมองด้านหน้า

                          บอร์ด Arduino ที่ใช้คือ Arudino Mega 2560 แต่ก็สามารถใช้ Arduino รุ่นอื่นได้เนื่องจาก Code ที่เขียนมีขนาดเล็ก

                          รูปที่ 4 บอร์ด Arduino Mega2560

                          จอแสดงผลผมใช้จอของ SILA รุ่น TLCD-164 เป็นบอร์ด Graphic LCD แบบสำเร็จรูปสามารถที่จะแสดงผลภาษาไทย อังกฤษ และรูปภาพต่างๆ ได้ โดยมี interface 3 แบบ คือ TTL Serial, RS-232 Serial, SPI ในการทดลองนี้ได้เลือกใช้ interface แบบ TTL Serial เนื่องจากสามารถต่อกับ Arduino ได้ตรงๆ และง่าย ในการทดลองนี้ได้ใช้งาน 4 คำสั่ง คือ

                          • Set charactor Row & Column (:1RCC<CR>) 
                          • Set Character (:2XX...X<CR>) 
                          • Clear LCD (:5<CR>)
                          • Backlight ON (:9<CR>)


                          รูปที่ 5 บอร์ดจอ SILA TLCD-164

                          หลักการรับค่าจาก Keyboard จะทำโดยผ่านทางสายสัญญาณ 2 เส้น และไฟเลี้ยง 2 เส้น ดังนี้

                          • CLOCK (ขาที่ 5) 
                          • DATA (ขาที่ 1) 
                          • ไฟเลี้ยง +5V (ขาที่ 4) 
                          • Ground (ขาที่ 3) 

                          รูปที่ 6 ขาของพอร์ต PS/2
                          ขาแต่ละขาของพอร์ต PS/2 มีหน้าที่ดังนี้

                          1. Data
                          2. ไม่ใช้งาน
                          3. ไฟเลี้ยง +5V
                          4. GND
                          5. Clock
                          6. ไม่ใช้งาน

                          บัสของ Keyboard จะเป็นมาตรฐาน TTL 5V โหมดของบัส PS/2 มี 3 โหมด ดังนี้

                          1. Data = high, Clock = high:  Idle state. บัสว่าง ไม่มีการกดปุ่มที่ Keyboard
                          2. Data = high, Clock = low:  Communication Inhibited. เป็นการสั่งหยุดการส่งข้อมูลจาก Keyboard เพื่อที่ทำการส่งคำสั่งควบคุมไปยัง Keyboard เช่น สั่งเปิด LED ปุ่ม Numlock
                          3. Data = low, Clock = high:  Host Request-to-Send เป็นการร้องขอการส่งข้อมูลจาก Keyboard
                          โหมดหลักๆ ที่เราใช้จะเป็นโหมดที่ 3 เพื่อที่จะรอรับค่าที่ Keyboard ส่งมาหา Arduino เมื่อมีการกดปุ่มใดๆ โดย ทั้งสัญญาณ Data และ Clock จะถูกควบควบคุมโดย Keyboard ทั้งหมด เราทำแค่อ่านค่าบิตข้อมูลทุกๆ ขอบขาลงของสัญญาณ Clock

                          เมื่อมีการกดปุ่มที่ Keyboard บัสของระบบจากที่อยู่สถานะ Idle จะเปลี่ยนเป็นสถานะ Host-Request-to_Send โดย Keyboard จะให้สัญญาณ Data เป็น LOW บ่งบอกถึงการเริ่มการส่งข้อมูล รูปแบบของข้อมูลที่ Keyboard ส่งไปจะมีขนาด 11 บิต ดังรูปที่ 7

                          รูปที่ 7 รูปแบบการส่งข้อมูลของ Keyboard
                          ข้อมูลทั้ง 11 บิต ประกอบด้วย
                          • Start bit มีขนาด 1 บิต
                          • Data bit มีขนาด 8 บิต
                          • Parity bit มีขนาด 1 บิต (Odd Parity)
                          • Stop bit มีขนาด 1 บิต

                          เมื่อ Data = 0 เป็นการเริ่มการส่งข้อมูล ให้รอจน Clock = 0 ต่อไปก็ให้รอขอบขาลงของ Clock ลูกถัดไป แล้วทำการอ่านค่าสัญญาณของ Data เก้บไว้ในตัวแปร เก็บจนครบ 8 บิตข้อมูล 2 บิตสุดท้ายคือ Parity และ Stop bit ไม่ต้องสนใจก็ได้

                          ข้อมูลที่ได้จะเป็นค่า Scan code ของแต่ละปุ่มซึ่งต้องนำมาแปลค่าอีกที


                          รูปที่ 8 รูปสัญญาณที่ได้จากการดักจับสัญญาณ
                          จากรูปที่ 8 เราค่าที่ส่งมาคือ 0x15 เมื่อเปิดตารางแปลจะมีความหมายเป็นตัว Q ส่วนค่าประจำตัวของตัวอื่นๆ สามารถดูได้จากลิงค์ต่อไปนี้
                          1 2

                          เมื่อมีการกดปุ่มจะมีค่าส่งออกมา 2 แบบ คือ ค่าเมื่อกดปุ่มลงไป เช่น ตัว Q คือ 0x15 อีกค่าที่ออกมาจะออกเมื่อปล่อยปุ่ม Q คือ 0xF0 0x15 ทำให้เราสามารถรู้ได้ว่าผู้ใช้ที่กดปุ่มได้ปล่อยปุ่มหรือยัง ตัวค่าที่ออกมาเมื่อปล่อยปุ่มส่วนใหญ่มีขนาด 2 byte โดย byte แรกจะเป็นค่า 0xF0 ตัวถัดมาเป็นค่าประจำตำแหน่งของปุ่มนั้นๆ

                          ในส่วนของ Sourcecode เขียนด้วย Arduino version 1.0 โดยต่อขา Data เข้ากับขา Digital 2, Clock เข้ากับขา Digital 3 ของ Arduino มีการแสดงผลออก 2 ทาง คือ จอแอลซีดี และทาง Serial Port รองรับการพิมพ์อักษรภาษาอังกฤษทั้งพิมฑ์เล็ก พิมพ์ใหญ่ อักขระพิเศษ ปุ่ม Tab, Caps lock, Shift 


                          1:  #define dat 2  
                          2:  #define clk 3  
                          3:  #define led 13  
                          4:  #define clk_low()  digitalWrite(clk,LOW)  
                          5:  #define clk_high() digitalWrite(clk,HIGH)  
                          6:  #define read_dat() digitalRead(dat)  
                          7:  #define read_clk() digitalRead(clk)  
                          8:  #define ps2_delay() delayMicroseconds(39)  
                          9:  unsigned char shift, caplock;  
                          10:  int idx=0;  
                          11:  unsigned char arr[10] = {0};  
                          12:  unsigned long wait_time;  
                          13:  char in_transmit = 0,timeout=0;  
                          14:  void setup()  
                          15:  {  
                          16:   Serial.begin(9600);  
                          17:   Serial.print(":5\r");  
                          18:   delay(100);  
                          19:   Serial.print(":9\r");  
                          20:   delay(10);  
                          21:   Serial.print(":2PS2 Keyboard\r");  
                          22:   delay(100);  
                          23:   Serial.print(":1100\r");  
                          24:   delay(10);  
                          25:   pinMode(dat,INPUT);  
                          26:   pinMode(clk,INPUT);  
                          27:   pinMode(led,OUTPUT);  
                          28:   digitalWrite(clk,HIGH);  
                          29:   digitalWrite(dat,HIGH);  
                          30:  }  
                          31:  void print_arr(unsigned char *p,int len)  
                          32:  {  
                          33:   int i;  
                          34:   for(i=0;i < len;i++)  
                          35:   {  
                          36:    print_hex(p[i]);  
                          37:    Serial.write(' ');  
                          38:   }  
                          39:  }  
                          40:  void decode_key(char c)  
                          41:  {  
                          42:   Serial.print(":2");  
                          43:   switch(c)  
                          44:   {  
                          45:    case 0x76: Serial.write(0x1b);break; //esc  
                          46:    case 0x05: Serial.write(0x1b);break; //f1  
                          47:    case 0x06: Serial.write(0x1b);break; //f2  
                          48:    case 0x04: Serial.write(0x1b);break; //f3  
                          49:    case 0x0c: Serial.write(0x1b);break; //f4  
                          50:    case 0x03: Serial.write(0x1b);break; //f5  
                          51:    case 0x0b: Serial.write(0x1b);break; //f6  
                          52:    case 0x83: Serial.write(0x1b);break; //f7  
                          53:    case 0x0a: Serial.write(0x1b);break; //f8  
                          54:    case 0x01: Serial.write(0x1b);break; //f9  
                          55:    case 0x09: Serial.write(0x1b);break; //f10  
                          56:    case 0x78: Serial.write(0x1b);break; //f11  
                          57:    case 0x07: Serial.write(0x1b);break; //f12  
                          58:    case 0x0e:   
                          59:          if(shift == 0)Serial.write('`');  
                          60:          else Serial.write('~');  
                          61:          break;  
                          62:    case 0x16:   
                          63:          if(shift == 0)Serial.write('1');  
                          64:          else Serial.write('!');  
                          65:          break;  
                          66:    case 0x1e:   
                          67:          if(shift == 0)Serial.write('2');  
                          68:          else Serial.write('@');  
                          69:          break;  
                          70:    case 0x26:   
                          71:          if(shift == 0)Serial.write('3');  
                          72:          else Serial.write('#');  
                          73:          break;  
                          74:    case 0x25:   
                          75:          if(shift == 0)Serial.write('4');  
                          76:          else Serial.write('$');  
                          77:          break;  
                          78:    case 0x2e:   
                          79:          if(shift == 0)Serial.write('5');  
                          80:          else Serial.write('%');  
                          81:          break;  
                          82:    case 0x36:   
                          83:          if(shift == 0)Serial.write('6');  
                          84:          else Serial.write('^');  
                          85:          break;  
                          86:    case 0x3d:   
                          87:          if(shift == 0)Serial.write('7');  
                          88:          else Serial.write('&');  
                          89:          break;  
                          90:    case 0x3e:   
                          91:          if(shift == 0)Serial.write('8');  
                          92:          else Serial.write('*');  
                          93:          break;  
                          94:    case 0x46:   
                          95:          if(shift == 0)Serial.write('9');  
                          96:          else Serial.write('(');  
                          97:          break;  
                          98:    case 0x45:   
                          99:          if(shift == 0)Serial.write('0');  
                          100:          else Serial.write(')');  
                          101:          break;  
                          102:    case 0x4e:   
                          103:          if(shift == 0)Serial.write('-');  
                          104:          else Serial.write('_');  
                          105:          break;  
                          106:    case 0x55:   
                          107:          if(shift == 0)Serial.write('=');  
                          108:          else Serial.write('+');  
                          109:          break;  
                          110:    case 0x66:   
                          111:          Serial.write(0x08); //backspace  
                          112:          Serial.write(' ' );  
                          113:          Serial.write(0x08);  
                          114:          break;  
                          115:    case 0x0d:   
                          116:          if(shift == 0)Serial.write(0x09); //tab  
                          117:          break;  
                          118:    case 0x15:   
                          119:          if(shift == 0 && caplock == 0)Serial.write('q');  
                          120:          else Serial.write('Q');  
                          121:          break;  
                          122:    case 0x1d:   
                          123:          if(shift == 0 && caplock == 0)Serial.write('w');  
                          124:          else Serial.write('W');  
                          125:          break;  
                          126:    case 0x24:   
                          127:          if(shift == 0 && caplock == 0)Serial.write('e');  
                          128:          else Serial.write('E');  
                          129:          break;  
                          130:    case 0x2d:   
                          131:          if(shift == 0 && caplock == 0)Serial.write('r');  
                          132:          else Serial.write('R');  
                          133:          break;  
                          134:    case 0x2c:   
                          135:          if(shift == 0 && caplock == 0)Serial.write('t');  
                          136:          else Serial.write('T');  
                          137:          break;  
                          138:    case 0x35:   
                          139:          if(shift == 0 && caplock == 0)Serial.write('y');  
                          140:          else Serial.write('Y');  
                          141:          break;  
                          142:    case 0x3c:   
                          143:          if(shift == 0 && caplock == 0)Serial.write('u');  
                          144:          else Serial.write('U');  
                          145:          break;  
                          146:    case 0x43:   
                          147:          if(shift == 0 && caplock == 0)Serial.write('i');  
                          148:          else Serial.write('I');  
                          149:          break;  
                          150:    case 0x44:   
                          151:          if(shift == 0 && caplock == 0)Serial.write('o');  
                          152:          else Serial.write('O');  
                          153:          break;  
                          154:    case 0x4d:   
                          155:          if(shift == 0 && caplock == 0)Serial.write('p');  
                          156:          else Serial.write('P');  
                          157:          break;  
                          158:    case 0x54:   
                          159:          if(shift == 0)Serial.write('[');  
                          160:          else Serial.write('{');  
                          161:          break;  
                          162:    case 0x5b:   
                          163:          if(shift == 0)Serial.write(']');  
                          164:          else Serial.write('}');  
                          165:          break;  
                          166:    case 0x5d:   
                          167:          if(shift == 0)Serial.write('\\');  
                          168:          else Serial.write('|');  
                          169:          break;  
                          170:    case 0x1c:   
                          171:          if(shift == 0 && caplock == 0)Serial.write('a');  
                          172:          else Serial.write('A');  
                          173:          break;  
                          174:    case 0x1b:   
                          175:          if(shift == 0 && caplock == 0)Serial.write('s');  
                          176:          else Serial.write('S');  
                          177:          break;  
                          178:    case 0x23:   
                          179:          if(shift == 0 && caplock == 0)Serial.write('d');  
                          180:          else Serial.write('D');  
                          181:          break;  
                          182:    case 0x2b:   
                          183:          if(shift == 0 && caplock == 0)Serial.write('f');  
                          184:          else Serial.write('F');  
                          185:          break;  
                          186:    case 0x34:   
                          187:          if(shift == 0 && caplock == 0)Serial.write('g');  
                          188:          else Serial.write('G');  
                          189:          break;  
                          190:    case 0x33:   
                          191:          if(shift == 0 && caplock == 0)Serial.write('h');  
                          192:          else Serial.write('H');  
                          193:          break;  
                          194:    case 0x3b:   
                          195:          if(shift == 0 && caplock == 0)Serial.write('j');  
                          196:          else Serial.write('J');  
                          197:          break;  
                          198:    case 0x42:   
                          199:          if(shift == 0 && caplock == 0)Serial.write('k');  
                          200:          else Serial.write('K');  
                          201:          break;  
                          202:    case 0x4b:   
                          203:          if(shift == 0 && caplock == 0)Serial.write('l');  
                          204:          else Serial.write('L');  
                          205:          break;  
                          206:    case 0x4c:   
                          207:          if(shift == 0)Serial.write(':');  
                          208:          else Serial.write(';');  
                          209:          break;  
                          210:    case 0x52:   
                          211:          if(shift == 0)Serial.write('\'');  
                          212:          else Serial.write('"');  
                          213:          break;  
                          214:    case 0x5a:   
                          215:          Serial.println("");  
                          216:          break;  
                          217:    case 0x1a:   
                          218:          if(shift == 0 && caplock == 0)Serial.write('z');  
                          219:          else Serial.write('Z');  
                          220:          break;  
                          221:    case 0x22:   
                          222:          if(shift == 0 && caplock == 0)Serial.write('x');  
                          223:          else Serial.write('X');  
                          224:          break;  
                          225:    case 0x21:   
                          226:          if(shift == 0 && caplock == 0)Serial.write('c');  
                          227:          else Serial.write('C');  
                          228:          break;  
                          229:    case 0x2a:   
                          230:          if(shift == 0 && caplock == 0)Serial.write('v');  
                          231:          else Serial.write('V');  
                          232:          break;  
                          233:    case 0x32:   
                          234:          if(shift == 0 && caplock == 0)Serial.write('b');  
                          235:          else Serial.write('B');  
                          236:          break;  
                          237:    case 0x31:   
                          238:          if(shift == 0 && caplock == 0)Serial.write('n');  
                          239:          else Serial.write('N');  
                          240:          break;  
                          241:    case 0x3a:   
                          242:          if(shift == 0 && caplock == 0)Serial.write('m');  
                          243:          else Serial.write('M');  
                          244:          break;  
                          245:    case 0x41:   
                          246:          if(shift == 0)Serial.write(',');  
                          247:          else Serial.write('<');  
                          248:          break;  
                          249:    case 0x49:   
                          250:          if(shift == 0)Serial.write('.');  
                          251:          else Serial.write('>');  
                          252:          break;  
                          253:    case 0x4a:   
                          254:          if(shift == 0)Serial.write('/');  
                          255:          else Serial.write('?');  
                          256:          break;  
                          257:    case 0x29:   
                          258:          Serial.write(' '); //space  
                          259:          break;  
                          260:    //default: print_hex(c);  
                          261:   }  
                          262:   Serial.print("\r");  
                          263:  }  
                          264:  void print_hex(unsigned char a)  
                          265:  {  
                          266:   unsigned char t;  
                          267:   t = (a >> 4) & 0x0f;  
                          268:   if(t <10)Serial.write(t + '0');  
                          269:   else   
                          270:   {  
                          271:    t = t - 10;  
                          272:    Serial.write(t + 'A');  
                          273:   }  
                          274:   t = a & 0x0f;  
                          275:   if(t <10)Serial.write(t + '0');  
                          276:   else   
                          277:   {  
                          278:    t = t - 10;  
                          279:    Serial.write(t + 'A');  
                          280:   }  
                          281:   //Serial.println("");  
                          282:  }  
                          283:  void loop()  
                          284:  {  
                          285:   if((millis() - wait_time > 10) && in_transmit == 1)  
                          286:   {  
                          287:    in_transmit = 0;  
                          288:    timeout = 1;  
                          289:   }  
                          290:   if(timeout == 1)  
                          291:   {  
                          292:    timeout = 0;  
                          293:    if((idx == 1) && ((arr[0] == 0x12) || (arr[0] == 0x59)))  
                          294:    {  
                          295:     shift = 1;  
                          296:     //Serial.println("Shift key DOWN");  
                          297:    }  
                          298:    if((idx == 2) && (arr[0] == 0xf0) && ((arr[1] == 0x12) || (arr[1] == 0x59)))  
                          299:    {  
                          300:     shift = 0;  
                          301:     //Serial.println("Shift key UP");  
                          302:    }  
                          303:    if((idx == 1) && (arr[0] == 0x58))  
                          304:    {  
                          305:     caplock = ~caplock;  
                          306:    }    
                          307:    if(idx == 1)decode_key(arr[0]);  
                          308:    else{  }  
                          309:    /*Serial.print(" [");  
                          310:    print_arr(arr,idx);  
                          311:    Serial.print(", ");  
                          312:    Serial.print(idx);  
                          313:    Serial.print("] ");  
                          314:   */  
                          315:    //Serial.print(arr[0],HEX);  
                          316:    idx = 0;  
                          317:   }  
                          318:   if(read_dat() == LOW)  
                          319:   {  
                          320:    in_transmit = 1;  
                          321:    //Start bit  
                          322:    while(read_clk() == HIGH);  
                          323:    while(read_clk() == LOW);  
                          324:    //Read 8 bit data  
                          325:    int i=0;  
                          326:    char mdat=0;  
                          327:    for(i = 0;i <= 7;i++)  
                          328:    {  
                          329:     while(read_clk() == HIGH);  
                          330:     if(read_dat() == HIGH)mdat = (mdat | (1 << i));  
                          331:     while(read_clk() == LOW);  
                          332:    }  
                          333:    //Parity bit  
                          334:    while(read_clk() == HIGH);  
                          335:    while(read_clk() == LOW);  
                          336:    //Stop bit   
                          337:    while(read_clk() == HIGH);  
                          338:    while(read_clk() == LOW);  
                          339:    //print_hex(mdat);  
                          340:    arr[idx] = mdat;  
                          341:    idx++;  
                          342:    in_transmit = 1;  
                          343:    wait_time = millis();  
                          344:   }  
                          345:  }  

                          Source code File ครับ

                          หวังบทความนี้คงพอช่วยให้ท่านสนุกกับการเล่นนะครับ

                          แหล่งข้อมูล

                          http://en.wikipedia.org/wiki/PS/2_connector
                          http://www.computer-engineering.org/ps2protocol/
                          http://www.pyroelectro.com/tutorials/ps2_keyboard_interface/theory.html

                          วันพฤหัสบดีที่ 6 กันยายน พ.ศ. 2555

                          ทดสอบครับ

                          เพิ่งลองเขียนครั้งแรก ยังไม่รู้จะเขียนเรื่องอะไรเลยครับ