หน้าเว็บ

วันจันทร์ที่ 29 พฤศจิกายน พ.ศ. 2553

คำสั่งเปลี่ยนชื่อ Table ใน MySQL

ตรงตัวครับ คำสั่งเปลี่ยนชื่อ Table ใน MySQL สำหรับเวลาที่สร้าง Table เสร็จแล้วต้องการเปลี่ยนชื่อในภายหลัง

RENAME TABLE oldtablename TO newtablename


ระบบที่ทดสอบ

MySQL: 5.1.49

วันเสาร์ที่ 16 ตุลาคม พ.ศ. 2553

Middle Scrolling ของ Thinkpad บน Ubuntu 10.10 Maverick

ให้ลง package ที่ชื่อว่า gpointing-device-settings

sudo apt-get install gpointing-device-settings

เมื่อลงเสร็จบางคนอาจจะสามารถทำ middle scrolling ได้เลย แต่ถ้าไม่ได้ให้สั่ง

gpointing-device-settings

แล้วให้เลือก Use wheel emulation
แล้วให้อยากให้มัน Scroll แนวตั้งหรือแนวนอนได้ก็ให้เลือก Enable vertical/horizontal scroll ตามต้องการ

เวลาใช้งานก็กดกลางค้างไว้ แล้วลาก track point ขึ้นลงหรือซ้ายขวาตามต้องการ

ระบบที่ทดสอบ
OS: Ubuntu 10.10 Maverick

ที่มา
http://psung.blogspot.com/2010/09/thinkpad-trackpoint-scrolling-in-ubuntu.html

วันอาทิตย์ที่ 10 ตุลาคม พ.ศ. 2553

แก้ปัญหา compile Android Error Debug Certificate Expired

ถ้าใครลง Android แล้วพอคอมไพล์เกิดปัญหาคล้ายๆดังนี้

[2010-10-10 00:07:56 - Test] ERROR: Unable to open class file /path/to/androidproject/gen/com/example/androidproject/R.java: No such file or directory\R.java: No such file or directory
[2010-10-10 00:07:56 - Test] ERROR: Error generating final archive: Debug certificate expired on dd/MM/yyyy


ให้แก้โดยไปที่ ~/.android/ แล้วลบ debug.keystore ทิ้งซะ แล้วให้ทำการสร้างใหม่ด้วยคำสั่ง

%JAVA_HOME%\bin\keytool -genkey -keypass android -keystore debug.keystore -alias androiddebugkey -storepass android -validity 100000 -dname "CN=Android Debug,O=Android,C=US"

โดย %JAVA_HOME% คือ path ชี้ไปยังที่อยู่ของ jdk เช่น /usr/lib/jvm/java-6-sun เป็นต้น

เสร็จแล้วให้ลองปิด eclipse แล้วเปิดใหม่
แล้ว clean project แล้ว build ใหม่

ระบบที่ทดสอบ
OS: Ubuntu 10.04
IDE: Eclipse 3.5.2
AndroidSDK: 7 (2.1)

ที่มา
http://www.board.esanupdate.com/index.php/topic,5308.0.html

วันพุธที่ 11 สิงหาคม พ.ศ. 2553

เปลี่ยนให้ MySQL รองรับ remote connection

โดยค่าปริยาย (default) แล้ว MySQL จะทำการฟังที port 3306 เฉพาะ localhost (127.0.0.1) เท่านั้น ถ้าต้องการให้รองรับ connection จาก host อื่นจะทำไม่ได้

วิธีการคือให้ไปแก้ไฟล์ /etc/mysql/my.cnf แล้วทำการ comment บรรทัด bind-address ทิ้ง

#bind-address = 127.0.0.1

หลังจากนั้นก็ให้ restart MySQL Server

sudo service mysql restart

ระบบที่ทดสอบ
OS: Ubuntu 10.04
MySQL: 5.1.41

ที่มา
http://www.howtogeek.com/howto/mysql/switch-mysql-to-listen-on-tcp/

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

ใช้ printf library กับ TinyOS ผ่าน SerialForwarder

วันนี้ผมลองใช้ MoteLab ของ Harvard เพื่อจะทำการทดลองโปรแกรม TinyOS บนอุปกรณ์จริงจำนวนมาก ซึ่งผมลองดูตัวอย่างโค้ดของทาง MoteLab นั้นจะแสดงวิธีการเรียกค่าเก็บไว้ใน Message ที่ส่งผ่าน Master Serial Port ของทาง MoteLab

แต่ปัญหาต่อมาของผมคือตัวอย่างเหล่านั้นเป็นการส่งค่าประเภทที่เป็นตัวเลข ไม่ใช่ array และไม่ใช่ string ซึ่งที่ผมต้องการนั้นผมอยากจะใช้ library printf ของ TinyOS เพื่อแสดง String (ซึ่งเป็น array ของ char) แล้วส่งผ่านออกมาทาง Serial Port

ดังนั้นวิธีการของผมคือลองแกะโค้ดตัวอย่างของเค้าก่อนว่ามันต้องใช้ utility อะไรมาช่วยบ้าง ซึ่งโค้ดเค้านั้นเป็นภาษา python และมีการเรียกใช้ TestSerialMsg.py ซึ่งเป็น class ที่เก็บโครงสร้าง Message ที่ต้องการเอาไว้ ดังนั้นทำให้ผมพอจะเดาได้ว่าเราต้องมีการสร้าง PrintfMsg.py ขึ้นมาเพื่อใช้จัดการกับ Message ของไลบรารี printf ที่จะถูกส่งออกมา

ผมลองดู TestSerialMsg.py แล้วพบว่า class นั้นถูกสร้างมาจาก MIG ซึ่งใช้ในการ generate คลาสสำหรับโครงสร้าง Message นั้น แต่ว่าที่ผมเคยลองทำคือเอามา generate ออกมาเป็น .class ของภาษา java เท่านั้น ซึ่งตอนนั้นทำใน Makefile

ผมเลยลองสั่ง mig ดิบๆใน shell ดูก็พบว่ามันมี option ที่รองรับภาษา python ด้วย ดังนั้นผมจึงเริ่มไปไฟล์ที่เป็น structure ของ Message เริ่มต้นที่เป็นภาษา nesC ก่อน ก็พบว่ามันอยู่ที่ $(TOSROOT)/tos/lib/printf/printf.h

ดังนั้นก็ให้ไปที่ $(TOSROOT)/tos/lib/printf แล้วสั่งคำสั่งดังนี้

mig python -python-classname=PrintfMsg printf.h printf_msg -o PrintfMsg.py

จะได้ไฟล์ PrintfMsg.py ซึ่งไฟล์คลาสที่เก็บโครงสร้างของ Message แบบภาษา python ออกมา

ซึ่ง String นั้น Message นี้จะเก็บอยู่ตัวแปรอาเรย์ที่ชื่อ buffer ดังนั้นผมจึงลองไปดูที่ฟังก์ชัน getString_buffer() ที่ generate ออกมา และพบว่ามัน generate ผิด ไม่สามารถเรียกใช้ได้เพราะจะเกิด index out of bound นอกจากนั้นค่าที่ได้ยังไม่ใช่ String อีกด้วย โดยผมทำการแก้ไข 3 จุด คือ 1. เปลี่ยนขอบเขตเป็น 28 (จริงๆแล้วขึ้นค่า PRINTF_MSG_LENGTH ที่ define ไว้ใน printf.h) 2. ทำการจัดรูปเป็นเลขฐาน 16 แบบ 2 หลัก 3. ทำการแปลงเลขฐาน 16 ให้เป็น ascii character ซึ่งสุดท้ายแล้วฟังก์ชัน getString_buffer จะได้เป็นแบบนี้

import tinyos.message.Message
import binascii
...
...
def getString_buffer(self):
carr = "";
#for i in range(0, 4000):
for i in range(0, 28):
if self.getElement_buffer(i) == chr(0):
break
c = "%x" % (self.getElement_buffer(i) & 0xFF)
if (len(c) < 2):
carr += "0" + c
else:
carr += c
return binascii.unhexlify(carr)

*หมายเหตุ blog ผม indent มันเพี้ยน เวลาใช้จริงอย่าลืมจัด indent ให้ถูกต้อง

คราวนี้เวลานำไปใช้ก็ให้ลองดูตามตัวอย่าง TestSerial.py ของเค้า แล้วให้เพ่ิม

import PrintfMsg

แล้วเพิ่ม

self.mif.addListener(self, PrintfMsg.PrintfMsg)

และเวลาเรียกค่าออกมาให้ใช้

s = m.getString_buffer()

ก็จะได้ String ที่เกิดจากไลบรารี printf แล้วครับ แต่ว่าจะมีปัญหาเล็กน้อยคือถึงแม้เรา printf ออกมาเป็น String ยาวๆ แต่ว่าการส่งข้อมูลออกมาแต่ละครั้งจะเท่ากับความยาวที่กำหนดไว้เท่านั้น (ค่า default คือ 28) ดังนั้นมันจะตัดส่งออกมาทีละ 28 ตัวอักษร ถ้าต้องการให้มากกว่านั้นก็ลองไป compile ไลบรารี Printf กันใหม่ได้ครับ

ถ้าใครยังไม่เคยใช้ MoteLab เดี๋ยวว่างๆผมจะมาเขียนวิธีไว้ด้วยครับ

ระบบที่ทดสอบ
OS: Ubuntu 10.04
TinyOS: 2.1.1
Device: Harvard MoteLab

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

เพิ่ม System Call ใน Linux Kernel

อันนี้เป็นวิธีจากตำราเลยครับ แต่ว่าปรับให้ใช้กับ Kernel 2.6.34.1
(blog นี้ assume ว่าสามารถ compile kernel เป็นแล้ว)

สมมติว่าจะเพิ่ม system call ที่ชื่อ hellokernel ซึ่งทำหน้าที่ print คำว่า "hello kernel!" ออกมาเก็บใน log ไฟล์
1. สร้างไฟล์ hellokernel.c ไว้ใน /usr/src/linux-2.6.34.1/kernel
#include <linux/linkage.h>
#include <linux/kernel.h>
asmlinkage int sys_hellokernel() {
printk(KERN_EMERG "hello kernel!");
return 1;
}


2. เพิ่มเลขของ system call ใหม่ในไฟล์ /usr/src/linux-2.6.34.1/include/asm-generic/unistd.h
- ให้ค้นหาคำว่า "#undef __NR_syscalls" แล้วบรรทัดก่อนบรรทัดนี้ให้เติม
#define __NR_hellokernel 244
__SYSCALL(__NR_hellokernel, sys_hellokernel)

โดยตัวเลข 244 นั้นให้ดูว่า system call ตัวก่อนหน้านั้นเป็นเบอร์อะไร (ของผมเป็น __NR_recvmmsg 243) ก็ให้เอาเลขนั้นบวก 1
- และบรรทัดต่อจากนั้น #define __NR_syscalls นั้นให้บวก 1 เข้าไป (ของเดิมของผมเป็น 244 ก็เปลี่ยนเป็น 245)

3. แก้ไขไฟล์ /usr/src/linux-2.6.34.1/arch/x86/kernel/syscall_table_32.S (สำหรับกรณีเครื่อง x86 ถ้าเป็นเครื่องอื่นก็แก้ที่โฟลเดอร์ของ arch นั้นๆ)
- เพิ่ม .long sys_hellokernel ไว้ที่ท้ายสุดของไฟล์ต่อลงมา

4. แก้ไข Makefile ใน /usr/src/linux-2.6.34.1/kernel
- เพิ่ม hellokernel.o ให้กับ obj-y (ต่อท้ายสุดก็ได้)
เรียบร้อยแล้วให้ทำการคอมไพล์ Kernel ใหม่ แล้ว boot เข้า kernel ที่ใหม่นี้ แล้วทดสอบโดยการสร้างไฟล์ test.c ขึ้นมา
#include <linux/unistd.h>
#define __NR_hellokernel 244 // 244 แทนเลขของ system call ที่ประกาศไว้ข้างบน

main() {
syscall(__NR_hellokernel);
}

เสร็จแล้วก็ลอง compile แล้ว run ดู ถ้าสำเร็จจะมีข้อความ "hello kernel!" ปรากฏอยู่ใน log file ของ kernel ที่ /var/log/kernel/warnings

ระบบที่ทดสอบ
OS: Ubuntu 10.04
Kernel: Linux Kernel 2.6.34.1

อ้างอิงหนังสือ Operating System Concepts 8th Edition, A. Silberschatz, P. B. Galvin, and G. Gagne

วันเสาร์ที่ 31 กรกฎาคม พ.ศ. 2553

วิธี Compile Linux kernel 2.6 บน Ubuntu 10.04

ในบางคราวเราอาจจะต้องคอมไพล์ Linux Kernel เพื่อเพิ่มฟังก์ชันอะไรบางอย่าง หรือเพื่ออยากรู้อยากลองก็มีวิธีการดังต่อไปนี้ครับ (ผมทำบน Ubuntu 10.04)
1. ดาวน์โหลด source code ของ kernel มาก่อน โดยสามารถดาวน์โหลดได้ที่ http://www.kernel.org/ โดยที่ผมทำจะใช้เป็นรุ่น 2.6.34.1 ครับ
แตกไฟล์แล้วเอาโฟลเดอร์ linux-2.6.34.1 ไปไว้ใน /usr/src ซึ่งเป็นโฟลเดอร์ที่นิยมใช้เก็บ source ของ kernel

2. เตรียมเครื่องมือ ได้แก่ kernel-package, fakeroot, ncurses (อันไหนมีแล้วก็ไม่ต้องโหลดเพิ่ม แต่ถ้าอันไหนมันฟ้องว่ายังขาดก็โหลดเพิ่มนะครับ :P)
sudo apt-get install kernel-package fakeroot libncurses5-dev

3. ทำการ configure kernel
ไปที่โฟลเดอร์ source ของเรา /usr/src/linux-2.6.34.1 แล้วสั่ง configure โดยสั่งได้ 3 รูปแบบ
วิธีแรกเป็นแบบ text-based
make menuconfig

วิธีที่สองถ้ามี Qt
make xconfig

วิธีที่สามถ้ามี Gtk
make gconfig

ก็เลือกตามสะดวกครับ ถ้าคิดไม่ออกก็เลือกวิธีแรกก็ได้
โดยใน menu สำหรับ configure นั้นจะมีอะไรให้เราเลือกมากมายครับก็เลือกตามที่ต้องการ แต่ถ้าไม่แน่ใจว่าคืออะไรก็ปล่อยเป็นค่า default ก็ได้ครับ

4. Compile Kernel
ในกรณีถ้าเครื่องมีหลาย cpu และต้องการให้คอมไพล์เร็วขึ้นให้สั่ง
export CONCURRENCY_LEVEL=3
โดยตัวเลขให้ใช้ จำนวนcpuที่มี + 1 (ในกรณีนี้ผมมี 2 cpu (2 core) เลยเป็น 3)

แล้วสั่ง
make-kpkg clean
fakeroot make-kpkg --initrd --append-to-version=-some-string-here kernel-image kernel-headers

โดย -some-string-here ใส่เป็นอะไรก็ได้เพื่อบอก version ของเรา เช่นของผมจะใส่ว่า -ping2p (ต้องขึ้นต้นด้วยเครื่องหมาย - และห้ามมีเว้นวรรค)

แล้วก็รอมันคอมไพล์ไป ระหว่างนี้ก็ไปอาบน้ำ อ่านหนังสือ กินข้าว รอจนกว่ามันจะเสร็จนะครับ ถ้าเสร็จแล้วลองดูที่โฟลเดอร์ /usr/src จะมีไฟล์ 2 ไฟล์คือ linux-image-2.6.34.1-ping2p_2.6.34.1-ping2p-10.00.Custom_i386.deb และ linux-headers-2.6.34.1-ping2p_2.6.34.1-ping2p-10.00.Custom_i386.deb (ในกรณีที่ compile แล้ว error เพราะ permission denied ให้ลองเปลี่ยน permission ของโฟลเดอร์ /usr/src ให้สามารถ write ได้ แล้วลองคอมไพล์ใหม่อีกรอบ (แต่จะใช้เวลาไม่นานเหมือนครั้งแรก เพราะหลายๆอย่างคอมไพล์เสร็จแล้ว))

5. Install
คราวนี้ก็จะทำการ Install kernel ใหม่นี้ โดยทำเป็น Option ให้เลือกตอน boot เผื่อเกิดอะไรผิดพลาดจะได้เรียกของเก่ากลับมาได้
ไปที่โฟลเดอร์ /usr/src จะพบ kernel ใหม่ที่เราคอมไพล์ แล้วให้ทำการติดตั้งดังนี้
sudo dpkg -i linux-image-2.6.34.1-ping2p_2.6.34.1-ping2p-10.00.Custom_i386.deb
sudo dpkg -i linux-headers-2.6.34.1-ping2p_2.6.34.1-ping2p-10.00.Custom_i386.deb


*** ในกรณี Ubuntu 10.04 จะมี bug โดยไม่ยอม initramfs มาให้ ให้สร้างเอง โดยในโฟลเดอร์ /usr/src ให้สั่ง sudo update-initramfs -c -k 2.6.34.1-ping2p (ใส่ version และชื่อตามรุ่นที่เราคอมไพล์และตั้งชื่อไว้ตอนแรก) เสร็จแล้วให้ลองตรวจสอบใน /boot ดูจะมีไฟล์ initrd.img2.6.34.1-ping2p, System.map-2.6.34.1-ping2p และ vmlinuz-2.6.34.1-ping2p ออกมา

6. ตรวจสอบ Bootloader
เพื่อให้แน่ใจว่าตอน boot แล้วจะมี kernel ใหม่ให้เลือก ให้ลองตรวจสอบ bootloader ดู ซึ่งแล้วแต่ว่า bootloader เป็น grub หรือ lilo
ในกรณีของผมเป็น grub2 ก็ไปดูที่ไฟล์ /boot/grub/grub.cfg (แต่ถ้าเป็น grub 1 จะอยู่ใน /boot/grub/menu.lst) จะมี kernel ใหม่อยู่

*** ลองตรวจสอบว่าตรงรายการ kernel ใหม่นั้นมีบรรทัด initrd /boot/initrd.img-2.6.34.1-ping2p อยู่หรือไม่ ถ้าไม่มีให้ใส่เพิ่มเข้าไป (ตัวที่เป็น recovery mode ก็เช่นกันให้ใส่เข้าไปด้วย) ส่วนบรรทัดที่ขึ้นต้นด้วย linux /boot/vmlinuz-2.6.34.1-ping2p ให้ลองเปลี่ยนค่า root=/dev/sda5 เป็น root=UUID=..... โดยค่า UUID ให้ใช้ค่าที่อยู่ใน option --fs-uuid --set .... ที่อยู่ในบรรทัดข้างบน เช่นของผมจะเป็น
menuentry 'Ubuntu, with Linux 2.6.34.1-ping2p' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod ext2
set root='(hd0,5)'
search --no-floppy --fs-uuid --set 54c8e93d-971f-4197-8a08-b9e131d1becf
linux /boot/vmlinuz-2.6.34.1-ping2p root=UUID=54c8e93d-971f-4197-8a08-b9e131d1becf ro quiet splash
initrd /boot/initrd.img-2.6.34.1-ping2p
}


เป็นอันเรียบร้อยครับ ลอง reboot ดู ตัว bootloader ของเราจะมี option kernel ตัวใหม่ของเราอยู่ด้วย

ระบบที่ทดสอบ
OS: Ubuntu 10.04
Kernel: Linux 2.6.34.1


อ้างอิง
http://www.howtoforge.com/kernel_compilation_ubuntu
http://linuxtweaking.blogspot.com/2010/05/how-to-compile-kernel-on-ubuntu-1004.html
http://www.cyberciti.biz/tips/compiling-linux-kernel-26.html

วันศุกร์ที่ 30 กรกฎาคม พ.ศ. 2553

วิธีเขียน PHP เรียกข้อมูลจาก MS Access .mdb บน Ubuntu

การเรียกดูข้อมูลจาก MS Access บน Ubuntu โดยใช้ PHP นั้นสามารถทำได้โดยเรียกผ่าน ODBC (ย่อจาก Open Database Connectivity ซึ่งเป็น API ใช้สำหรับการเชื่อมต่อกับฐานข้อมูลใดๆ โดย ODBC จะทำหน้าที่เป็น Layer กลางแปลงคำสั่ง odbc ไปเป็นคำสั่งของฐานข้อมูลนั้นๆให้)

1. ก่อนอื่นเตรียมอุปกรณ์กันก่อน ดังต่อไปนี้
sudo apt-get install php5-odbc libmdbodbc mdbtools unixodbc-bin

2. หลังจากนั้นทำการสร้าง DSN (Data Source Name) เพื่อให้ ODBC ทำการเชื่อมต่อ
ในขั้นตอนนี้จะเกี่ยวข้องด้วย 2 ไฟล์ด้วยกันคือ
2.1 ไฟล์ /etc/odbcinst.ini ซึ่งเป็นไฟล์ที่ใช้ในการกำหนด Driver ในการเชื่อมต่อ บางกรณีไฟล์นี้อาจถูกเขียนไว้แล้ว แต่ถ้ายังไม่มีหรือมีแล้วแต่ไม่ใช่ Driver ตัวเดียวกันก็ให้เพิ่มเข้าไปดังนี้ (อย่าลืม sudo ด้วย เดี่ยว save ไม่ได้)
[mdbtoolsodbc]
Description = MDB Tools odbc drivers
Driver = /usr/lib/libmdbodbc.so.0
Setup =
FileUsage = 1
CPTimeout =
CPReuse =
UsageCount = 1

- ตรง [mdbtoolsodbc] เป็นชื่อ driver ของเรา ใส่เป็นอะไรก็ได้แต่ห้ามมีเว้นวรรค ไว้ใช้สำหรับการอ้างถึงจากไฟล์อื่น
- ตรง Description ใส่อะไรก็ได้ เป็นแค่คำบรรยายให้เราเข้าใจทีหลังเวลากลับมาอ่าน
- ตรง Driver ลองตรวจสอบดูว่าไฟล์อยู่ที่ /usr/lib หรือไม่ ถ้าไม่อยู่ให้เปลี่ยน path ให้ตรงกับที่อยู่จริง

ขั้นตอนนี้จะเป็นการกำหนด ODBC Driver ให้เป็น mdbtools ซึ่งใช้สำหรับการเชื่อมต่อกับไฟล์ MS Access (.mdb) พอเสร็จแล้ว save และไปขั้นตอนถัดไป

2.2 ไฟล์ /etc/odbc.ini ไฟล์นี้จะเป็นตัวกำหนดการเชื่อมต่อไปยังฐานข้อมูลของเราให้เพิ่มรายละเอียดดังนี้
[TestDatabase]
Description = Miscrosoft Access Database of TestDatabase
Driver = mdbtoolsodbc
Database = /home/supasate/desktop/testdatabase.mdb
Servername = localhost
UserName =
Password =
port = 5432

- ตรง [TestDatabase] เป็นชื่อฐานข้อมูลที่ใช้ในการเชื่อมต่อ ซึ่งตั้งเป็นอะไรก็ได้ ไว้ใช้อ้างถึงจากที่อื่น (ตั้งให้คล้ายกับชื่อไฟล์ .mdb ก็ดี)
- ตรง Description เช่นเดิมเป็นอะไรก็ได้
- ตรง Driver อ้างอิงชื่อ driver ที่เราสร้างไว้ที่ไฟล์ odbcinst.ini ดังนั้นเขียนให้เหมือนกัน
- ตรง Database ให้ใส่ path ไปยังไฟล์ MS Access (.mdb) ที่เราต้องการเรียกข้อมูล
- ส่วนที่เหลือจริงๆไม่ต้องพิมพ์ก็ได้ แต่เขียนให้ดูเป็นตัวอย่างเผื่อเอาไปใช้กับฐานข้อมูลแบบอื่นที่เป็นแบบ server และมีการยืนยันตัวตน

เท่านี้เราก็พร้อมที่เชื่อมต่อกันแล้ว

3. เขียน PHP เพื่อทำการเชื่อมต่อ ดังตัวอย่างข้างล่าง ผมเขียนไว้ในไฟล์ test.php
if (!($conn = odbc_connect("TestDatabase", "", ""))) {
echo "Connection Falied.";
} else {
echo "Connection Success.";
$query = "SELECT ID, FirstName, LastName From EMPLOYEE";
$result = odbc_exec($conn, $query);
while ($row = odbc_fetch_array($result)) {
print $row['ID'].' '.$row['FirstName'].' '.$row['LastName'].'
';
}

- odbc_connect("ชื่อ db ที่เรากำหนดไว้ในไฟล์ odbc.ini", "username", "password")
- $query ใส่คิวรีที่ต้องการ ในที่นี้คือจะดึง field ID, FirstName, LastName มาจากตาราง EMPLOYEE
- odbc_exe(คอนเน็คชันที่สร้างขึ้น, คิวรีสตริง)
- odbc_fetch_array ดึงข้อมูลมาทีละแถว

ในกรณีที่อยากรู้ว่าฐานข้อมูลเรามีตารางอะไรและ Field อะไรบ้างนั้นให้ใช้ตัว GNOME MDB Viewer ในการดู

ลองทดลองบน Command line ดูก่อน โดยสั่ง
php test.php
ถ้าไม่สำเร็จลองตรวจสอบชื่อ Driver ชื่อ ODBC และ Path ไปยังฐานข้อมูลว่าถูกต้องหรือไม่
ถ้าสำเร็จก็ลองไป run บน server ดู โดยถ้าบน server ไม่สำเร็จอาจเกิดจาก SELinux หรือ Firewall ในกรณีที่ต้องมีการเชื่อมต่อ port

ขอให้โชคดีครับ

ระบบที่ทดสอบ
OS: Ubuntu 10.04

อ้างอิง
http://ubuntuforums.org/showthread.php?t=678690
http://www.infoqu.com/dev/database-management/access-msaccess-via-odbc-from-linux-php-228635-1/

วิธีเรียกดูข้อมูล MS Access .mdb บน Ubuntu

ใช้โปรแกรม GNOME MDB Viwer
sudo apt-get install mdbtools-gmdb
เมื่อลงเสร็จโปรแกรมจะอยู่ใน Applications -> Office -> MDB Viewer
เวลาใช้งานก็ Open ไฟล์สกุล mdb ของเราได้เลย แล้วจะเกิด Table ต่างๆที่มีขึ้นมา อยากดูข้อมูล Table ไหนก็เลือก Table นั้นแล้วเลือก Data

ระบบที่ทดสอบ
OS: Ubuntu 10.04
MDB Viewer: gmdb2 0.6pre1

วันพฤหัสบดีที่ 22 กรกฎาคม พ.ศ. 2553

วิธีสร้างไฟล์ animation จาก Nam (Network animator)

สมมติว่าเรามีไฟล์ .nam ซึ่งสามารถใช้ Nam (Network animator) ในการแสดง Animation ได้ แล้วเราต้องการที่จะทำ Animation นี้เป็น Movie clip แบบ gif animation สามารถทำได้ดังนี้
1. ในโปรแกรม Nam ให้ทำการตั้งค่าต่างๆให้เรียบร้อย เช่น ตำแหน่งการซูม ค่า step การขยับ animation (ในแต่ละ step จะ generator ออกมา 1 frame ดังนั้นถ้า step สั้นไฟล์จะใหญ่ละเอียด แต่ถ้า step ไกลไฟล์จะเล็กแต่ไม่ละเอียด)

2. เมื่อพร้อมแล้วให้เลื่อนแกนเวลาไปตำแหน่งที่เราต้องการจะเริ่มอัด แล้วไปที่ File -> Record Animation

3. กดปุ่ม Play ก็เริ่มทำการอัด Animation (คือจะทำการสร้างไฟล์ .xwd ออกมาทุกๆ frame) ถ้าอยากหยุดให้กดปุ่ม Stop หรือรอจนเล่นไปจนจบก็ได้

4. ในโฟลเดอร์เดียวกับไฟล์ .nam ของเราจะเกิดไฟล์ภาพ .xwd ออกมามากมายเท่ากับจำนวน frame ขั้นตอนต่อไปคือการแปลงจาก .xwd ให้เป็น .gif และทำการ merge .gif ออกมาเป็นไฟล์เดียว

for i in *.xwd; do
xwdtopnm $i | ppmtogif -interlace > `basename $i .xwd`.gif;
done
gifmerge -10 -2 -notransp *.gif > movie.gif

คำสั่ง xwdtopnm บางคนถ้าใช้รุ่นเก่าจะเป็นชื่อว่า xwdtoppm โดยจะหน้าที่แปลงไฟล์ format .ppm ซึ่งในที่เราจะไม่ต้อง save เป็นไฟล์ .ppm ให้เปลืองพื้นที่ก็ทำการ pipe binary ที่ได้ไปแปลงต่อเป็น .gif เลยด้วยคำสั่ง ppmtogif พอเสร็จแล้วจะก็ทำการ merge ไฟล์ .gif ทั้งหมดออกมาเป็นไฟล์ animated gif ไฟล์เดียวชื่อ movie.gif

ถ้าใครไม่มี xwdtopnm กับ ppmtogif ให้ลง netpbm ก่อน (sudo apt-get install netpbm) ถ้าใครไม่มี gifmerge ให้โหลดจาก http://www.the-labs.com/GIFMerge/ แล้วเอามา compile โดยการสั่ง make หลังจากนั้นให้ตั้งค่าให้ execute ได้ด้วย chmod +x gifmerge

ข้อควรระวังเมื่อได้ไฟล์ movie.gif มาแล้ว อย่าเผลอลบไฟล์ .gif ทั้งหมด ด้วย rm *.gif ล่ะ ไม่งั้นได้ทำใหม่

ระบบที่ทดสอบ
OS: Ubuntu 10.04
gifmerge: 1.33

อ้างอิง
http://isi.edu/nsnam/ns/doc/node610.html

วันจันทร์ที่ 12 กรกฎาคม พ.ศ. 2553

วิธี get ค่า local time บน TinyOS

เราสามารถเรียกค่าเวลาของโหนดๆหนึ่งตั้งแต่มันเริ่มทำงานได้โดยใช้ component HilTimerMilliC
component นี้จะ provides interface LocalTime ก็ให้จัดการ wiring ให้เรียบร้อย
เวลาจะเรียกดูค่าก็ให้ใช้คำสั่ง call LocalTime.get()

ระบบที่ทดสอบ
OS: TinyOS 2.1.1

วิธี extract text จากไฟล์ pdf บน Ubuntu

ใช้คำสั่ง
pdftotext filename.pdf
โดย filename.pdf แทนด้วยชื่อไฟล์ที่เราต้องการ แล้วโปรแกรมจะสร้างไฟล์ที่ชื่อเหมือนกันว่า filename.txt ออกมา

ในกรณีที่ต้องการทำหลายๆไฟล์ ให้นำไฟล์ .pdf ทั้งหมดใส่ไว้ในโฟลเดอร์เดียวแล้วสั่ง bash script ดังนี้
$for f in *.pdf
> do
> pdftotext "$f"
>done


ระบบที่ทดสอบ
OS: Ubuntu 10.04

ที่มา:
http://en.wikipedia.org/wiki/Pdftotext วันที่ 12 ก.ค. 53

วันศุกร์ที่ 9 กรกฎาคม พ.ศ. 2553

วิธีเอาจอ Android ขึ้นจอคอม หรือ projector

สิ่งที่ต้องมี
1. Android SDK (ดาวน์โหลดได้ที่ http://developer.android.com/sdk/index.html ) แล้วสั่งเปิด adb server ด้วยคำสั่ง sudo adb start-server (คำสั่ง adb อยู่ใน /path/to/android-sdk-yourversion/tools โดย yourversion แทนด้วย sdk ที่ใช้ เช่นของผมคือ android-sdk-linux_86)
2. ดาวน์โหลดโปรแกรม DroidEx จาก http://groups.google.com/group/cw-android/web/DroidEx.jar

การเรียกใช้โปรแกรม
1. ที่เครื่อง android ไปที่ Settings->Applications->Development เลือก USB Debugging
2. ต่อสาย USB เครื่อง android เข้ากับ PC
3. บน PC ให้ cd ไปที่โฟลเดอร์ที่มีโปรแกรม DroidEx.jar ที่ดาวน์โหลดมา
4. สั่งคำสั่ง java -cp DroidEx.jar:/path/to/android-sdk-yourversion/tools/lib/ddmlib.jar com.commonsware.droidex.DroidEx (หรือถ้าอยากเรียกสั้นๆก็ให้ set classpath ให้มีค่า DroidEx.jar:/path/to/android-sdk-yourversion/tools/lib/ddmlib.jar แล้วเวลาเรียกก็เรียกแค่ java com.commonsware.droidex.DroidEx)

โปรแกรมจะแสดงภาพหน้าจอที่เราใช้งานขึ้นมา คราวนี้เราก็สามารถต่อเครื่อง PC เราออก projector ได้เพื่อให้คนอื่นเห็น

หมายเหตุ โปรแกรมจะทำงานโดยเรียกใช้ Dalvik Debug Monitor อีกทีนึง ดังนั้นสังเกตได้ว่าภาพจะไม่ใช่การ live video แต่เป็นการ capture ภาพแบบต่อเนื่องมาให้ดู จึงมีดีเลย์ระหว่างการ capture แต่ละภาพ

ระบบที่ทดสอบ
Device: Samsung Galaxy S (GT-I9000)
Android OS: 2.1 Eclair
PC OS: Ubuntu 10.04

อ้างอิง:
http://www.androidguys.com/2009/01/30/projecting-android-on-the-big-screen/
http://www.makeuseof.com/tag/how-to-capture-screenshots-with-your-android-mobile-phone/

Root Samsung Galaxy S ด้วย Ubuntu

วิธีการนี้คือวิธีที่ผมใช้ในการ root เครื่อง Samsung Galaxy S (ssgs) โดยใช้ Ubuntu 10.04 ครับ (หมายเหตุ การ root อาจทำให้เครื่องหมดประกัน และถ้าเกิดข้อผิดพลาดขึ้นได้ ข้อให้ทดลองอย่างระมัดระวัง และผู้เขียนไม่รับประกันใดๆครับ) สำหรับใครใช้ Windows ก็คล้ายๆกัน หรือลองไปอ่านในลิงค์อ้างอิงด้านล่างสุดได้ครับ

เครื่องมือที่ต้องใช้ในการ root
1. Android SDK Linux http://developer.android.com/sdk/index.html
2. Update Script http://forum.samdroid.net/attachments/f49/1224d1277452759-superuser-su-busybox-i9000-26-06-2010-update.zip หรือ http://www.deedns.net/update.zip

เตรียมเครื่องมือก่อน
บนเครื่องคอม

1. แตกไฟล์ android sdk สมมติว่าเอาไว้ที่ /path/to/android-sdk-linux_86 ให้เข้าไปที่โฟลเดอร์ tools ตัวที่เราจะใช้คือ adb
2. สั่งคำสั่ง sudo adb start-server

บนมือถือ ssgs
1. ไปที่ Settings->Applications->Development ติ๊กเลือก USB debugging
2. เสียบสาย usb ต่อเข้ากับคอม
3. เลื่อนแถบ notification bar ด้านบนลงมา เลือก USB connected แล้วเลือก Mount

โอเคเตรียมการเรียบร้อย ตอนนี้เครื่องคอมเราจะสามารถเข้าไปยังโฟลเดอร์ของ ssgs ได้ (จะมีของ haddisk 2GB และ SD Card 14GB) และลองทดสอบด้วยคำสั่ง adb devices จะมีรายการอุปกรณ์ขึ้นมาหนึ่งอัน (ในกรณีชื่อเป็น ?????? แสดงว่าตอนสั่ง adb start-server ลืมใส่ sudo ให้แก้ด้วยการสั่ง adb kill-server ก่อน แล้วลอง sudo adb start-server ใหม่อีกครั้ง)

เริ่มทำการ root
1. copy ไฟล์ update.zip ที่ดาวน์โหลดมาข้างต้นไปไว้ด้านนอกสุดของ SD Card
2. สั่งคำสั่ง adb reboot recovery แล้วเครื่อง ssgs จะเข้าสู่ recovery mode
3. พอเครื่อง ssgs เข้าสู่ recovery mode แล้ว ให้เลือก apply sdcard:update.zip (ใช้ปุ่ม volumn ด้านข้างในการเลื่อนขึ้นลง และกดปุ่ม Home ด้านล่างในการเลือก) แล้วเครื่องจะ reboot เป็นอันเสร็จพิธี

ตรวจสอบว่า root สำเร็จ
1. ใน Applications จะมีโปรแกรมชื่อ Superuser Permission โผล่มา
2. ลองโหลดโปรแกรม CacheMate มาติดตั้ง โปรแกรมจะขอสิทธิ root ในการทำงาน ถ้าทำงานได้โปรแกรมจะล้าง cache ของเครื่องทิ้งให้ ทำให้ได้พื้นที่คืนมา (ของผมลองแล้วได้ 14MB)

ระบบที่่ทดสอบ
Device: Samsung Galaxy S (GT-I9000)
Firmware: Android ECLAIR 2.1-update1
Baseband: I9000DXJF4
Kernel: 2.6.29
Ububunt: 10.04

เบื้องหลังการ root
0. ทดสอบว่าเป็น Galaxy 3 (GT-I5800) หรือ Galaxy S (GT-I9000) ก่อน แล้วทำการแตก package ออกมาเพื่อเตรียมใช้
1. ลบ su เดิมทิ้งออกจาก bin และ xbin
2. copy app Superuser, busybox และ su ตัวใหม่เข้าไป
3. สร้าง symlink ของ su และกำหนด permission ให้ su กับ busybox

อ้างอิง
http://pdamobiz.com/forum/forum_posts.asp?TID=321558&PN=1

วันศุกร์ที่ 11 มิถุนายน พ.ศ. 2553

วิธีใช้ vi copy text จาก file หนึ่งไปอีก file หนึ่ง

สมมติว่าต้องการ copy 10 บรรทัดจากไฟล์ที่ชื่อ a.txt ไปยังไฟล์ b.txt ที่อยู่ที่ /path/to/b.txt

สมมติว่าตอนนีี้เปิดไฟล์ a.txt และอยู่บรรทัดเริ่มต้นที่ต้องการ copy แล้วให้ใช้ command ดังนี้
"a10yy
ความหมายคือทำการ copy line (yy) 10 ครั้ง (10 บรรทัด) ไปเก็บไว้ใน buffer ชื่อ a ("a)

หลังจากนั้นให้เปิดอีกไฟล์หนึ่งขึ้นมาในด้วยคำสั่ง
:e /path/to/b.txt
จะเข้ามาสู่ไฟล์ b.txt แล้วให้ไปบรรทัดที่ต้องการจะ paste และทำการสั่ง paste โดย
"ap
ความหมายคือ paste (p) โดยนำค่าจาก buffer a ที่เก็บไว้ ("a)

เสร็จแล้วก็สามารถ save ไฟล์ (:w) แล้วกลับไปยังไฟล์เก่าได้โดยคำสั่ง
:e#

วันอาทิตย์ที่ 6 มิถุนายน พ.ศ. 2553

รับไฟล์ผ่าน Bluetooth บน Mac OSX Snow Leopard

ถ้าต้องการให้เครื่อง Mac OS X Snow Leopard ทำการรับไฟล์ได้นั้น ให้ไปที่ perference ของ bluetooth บนเครื่อง mac โดยคลิกที่ icon รูป Bluetooth ด้านบนขวา แล้วเลือก Open Bluetooth Perference -> Sharing Setup แล้วให้ติ๊กถูกที่ Bluetooth Sharing ซึ่งจะมีเมนูให้ปรับแต่งเพิ่มขึ้นมา เช่น เวลารับไฟล์ให้ถามก่อน หรือว่ารับแล้วเปิดไฟล์ หรือว่ารับแล้วเซฟไฟล์เป็นต้น

เมื่อตั้งค่าเสร็จแล้วก็ทำการ pairing กับเครื่องที่ต้องการ แล้วก็จะสามารถรับไฟล์ได้

ระบบที่ทดสอบ
Mac: Macbook Air
OS: Mac OS X Snow Leopard
เครื่องที่ส่งไฟล์: Nokia E75

รับไฟล์ผ่านทาง Bluetooth บน BlackBerry (Bold)

ผมจะลองส่งไฟล์ภาพจาก Nokia E75 มายังเครื่อง BlackBerry Bold แล้วเกิดปัญหาคือ เมื่อทำการ pairing สำเร็จแล้ว เครื่อง Nokia เลือกส่งไฟล์มา แต่ส่งไม่ได้ โดยขึ้นว่า Unable to connect ก็เลยค้นหาวิธีส่งไฟล์เข้าเครื่อง BlackBerry ได้ดังนี้
(หลังจาก pairing เสร็จ)
1. ที่หน้า Home Screen ไปที่ Media
2. เลือกประเภทที่อยากจะรับ (Picture, Video, Music, ฯลฯ)
3. กดปุ่มเมนู แล้วเลือก Receive using Bluetooth
4. หลังจากนั้นจะขึ้นว่ารอให้ผู้ส่งติดต่อเข้ามา ตอนนี้ก็ให้ใช้เครื่องที่ต้องการจะส่งไฟล์เข้ามาเลือกส่งไฟล์เข้ามาได้ (แต่เครื่องนั้นต้องทำการ paring ก่อน)

เครื่องที่ทดสอบ
เครื่องที่รับ : BlackBerry Bold 9700
เครื่องทีส่ง : Nokia E75

วันศุกร์ที่ 14 พฤษภาคม พ.ศ. 2553

วิธีเรียกดู diff ของ file ใน git

ถ้าต้องการดูว่าไฟล์ที่ถูกแก้ไขไปนั้นแตกต่างกับ revision ก่อนหน้ายังไงบ้าง ให้ใช้ 2 คำสั่ง
1. หาเลข commitid revision ที่ต้องการเปรียบเทียบด้วยคำัส่ง
git log -- filename
2. แสดงผลการเปรียบเทียบ
git diff commitid -- filename
โดย commitid คือเลข commit id ของ revisoin ที่ต้องการที่หาได้จากขั้สตอนที่ 1
filename แทนชื่อไฟล์ที่ต้องการเปรียบเทียบ

ระบบที่ทดสอบ
git: 1.7.0.4
OS: Ubuntu 10.04

วันพฤหัสบดีที่ 13 พฤษภาคม พ.ศ. 2553

แก้ปัญหา Firefox ปิดตัวเองบน Ubuntu 10.04 Lucid Lynx

ขอแชร์ประสบการณ์ครับเผื่อเป็นประโยชน์ เครื่องผม Lenovo Thinkpad X200 ลง Lucid ตัวเต็ม clean install พบปัญหาว่า Firefox มักจะปิดตัวเองลงเมื่อมีการ login เข้าหน้าเว็บพวก Facebook, Google Wave หรือทำการเปิดไฟล์/เมลใน Google Docs, Hotmail

ผมทดลอง run ด้วย safe mode แล้วกลับไม่พบอาการดังกล่าว จึงได้ลอง 2 วิธี 1. สร้าง profile ใหม่ 2. ถอด extension/add-on ทิ้งหมด แต่ปรากฏว่าอาการยังเป็นอยู่ครับ และไม่ได้ลองวิธีอื่นต่อ

ผมตัดสินใจลบ Firefox ทิ้งแล้วลงใหม่ครับ โดยเริ่มจากถอด firefox ออกด้วย
sudo apt-get remove firefox
หลังจากนั้นลบโฟลเดอร์ที่เกี่ยวข้องออกครับ
sudo rm -r /usr/lib/firefox-3.6.3 /usr/lib/firefox-addons ~/.mozilla
หลังจากนั้นลงใหม่ด้วย
sudo apt-get install firefox
ซึ่งทำให้กลับมาใช้ได้ครับ ผมยังไม่ได้ลงไล่ไปลึกกว่านี้ว่าสาเหตุจริงๆคืออะไรกันแน่ครับ

ระบบที่ทดสอบ

OS: Ubuntu 10.04 Lucid Lynx

Firefox: 3.6.3

วันจันทร์ที่ 10 พฤษภาคม พ.ศ. 2553

My Top-10 Favorite Firefox Add-ons

รายการ Add-on ของ Firefox ที่ผมใช้บ่อยๆจนต้องลงแทบทุกครั้งที่ลง firefox ใหม่ครับ
1. Adblock Plus
2. DownThemAll! + DownThemAll AntiContainer
3. WebMail Notifier
4. Delicious Bookmarks
5. Firebug
6. Greasemonkey
7. rikaichan + Word Dict & Names Dict
8. FireFTP
9. FasterFox
10. ScreenGrab

วันเสาร์ที่ 24 เมษายน พ.ศ. 2553

วิธีการชาร์จแบตเตอรี่ Notebook

แต่ไหนแต่ไรไม่เคยสนใจเรื่องแบตเตอรี่เลย แต่มาวันนี้พอแบตเตอรี่มันเสื่อมสภาพ ซึ่งเป็นแบต 6-cell ใช้ไปประมาณ 1 ปีครึ่ง แล้วได้ทำการซื้อใหม่ โดยทำการซื้อแบต 9-cell สำหรับเครื่อง Lenovo Thinkpad x200 มา แต่ด้วยความที่ไม่รู้ข้อมูลเรื่องแบตเลยก็เลยถามคนขายว่าควรชาร์จครั้งแรกทิ้งไว้นานเท่าไหร่ ซึ่งเค้าตอบกลับมาว่าประมาณ 16 ชั่วโมง ด้วยเหตุเหล่านี้เลยเกิดคำถามขึ้นมาในใจหลายคำถาม เช่น
1. ทำไมแบตฯตัวเก่ามันหมดอายุเร็วจัง (ปัจจุบันชาร์จเต็มที่ได้แค่ 15 นาทีบน Ubuntu Linux ถ้าบน Windows อาจได้ประมาณ 40 นาที (ไม่ได้ทดลอง แต่ตอนซื้อมาใหม่ๆ Windows ใช้ได้ 4-5 ชม. ขณะที่ Ubuntu ใช้ได 2-3 ชม.))
2. แบตเมื่อซ์อมาครั้งแรกควรชาร์จยังไงดีเพื่อให้ใช้เต็มประสิทธิภาพ
3. เวลาชาร์จใหม่ ควรใช้แบตไปเยอะๆก่อน หรือว่าอยากชาร์จตอนไหนก็ได้

ก็เลยลองไปค้นๆข้อมูลดูและเอามาเล่า/แปลให้ฟัง

แต่ก่อนที่ควรรู้คือ ประเภทของแบตเตอรี่
แบตเตอรี่ปัจจุบันที่ใช้ใน Notebook มีหลักๆ 3 ประเภท
1. NickelCadmium (NiCd) เป็นแบตที่มีใช้กันเยอะ โดยมีข้อดีคือทำงานในที่อุณหภูมิสูงมากหรือต่ำมากได้ และมีจำนวนรอบของการชาร์จเต็มและใช้จนหมดได้ถึงประมาณ 750 รอบการชาร์จ แต่ข้อเสียคือมี Memory Effect (เดี๋ยวบอกว่าคืออะไร)

2. NickelMetalHydride (NiMH) เป็นตัวที่พัฒนาขึ้นจาก NiCd มีความจุเพิ่มขึ้นประมาณ 40% (โดยใช้ขนาดเท่าๆกัน) ไม่โดนผลกระทบจาก Memory Effect แต่มีรอบการชาร์จอยู่ที่ประมาณ 400 รอบ

3. LithiumIon (LiIon) เป็นตัวใหม่ (ปัจจุบันก็เห็นใช้กันเยอะแล้ว) สามารถทำงานได้นานขึ้นกว่า NiMH และน้ำหนักเบา แต่ราคาแพง และต้องใช้ที่ชาร์จที่ออกแบบเฉพาะสำหรับแบตเตอรี่แต่ละรุ่น มีรอบการชาร์จอยู่ที่ประมาณ 400 รอบเช่นกัน และไม่โดนผลกระทบจาก Memory Effect

มาอธิบาย Memory Effect เล็กน้อย
Memory Effect คืออาการที่แบตเตอรี่ลืมไปว่าตัวมันเองยังมีประจุที่ยังไม่ได้ใช้งานอยู่อีกเท่าไหร่ ซึ่งอาการนี้จะเกิดกับการใช้งานแบตประเภท NiCd ที่ใช้พลังงานไปยังไม่หมดแล้วทำการชาร์จใหม่ทันที เช่น ใช้ไป 50% แล้วทำการชาร์จใหม่จนเต็ม แล้วพอใช้ไปใหม่ได้แค่ 50% แบตก็จะบอกว่ามันหมดแล้ว โดยมันลืมไปว่าจริงๆแล้วยังสามารถคลายประจุได้อีก 50%
วิธีการหลีกเลี่ยงก็คือพยายามใช้ไฟจากแบตประเภท NiCd ให้หมดหรือเกือบหมดแล้วค่อยชาร์จใหม่ หรือทำแบบนี้ทุกๆ 1-3 สัปดาห์ ซึ่งเรียกว่าเป็นการปรับสภาพ (Conditioning)

พอรู้จักประเภทของแบตแล้ว คราวนี้พอซื้อแบตมาครั้งแรกเนี่ยควรชาร์จยังไงดี กี่ชั่วโมง?
จากที่อ่านมาคือถ้าเป็นแบตประเภท NiCd หรือ NiHM เนี่ย ควรชาร์จครั้งแรกประมาณ 16 ชั่วโมง แต่ถ้าเป็น LiIon เนี่ยชาร์จครั้งแรกประมาณ 5-6 ชั่วโมง (นั่นคนขายมั่วใส่เราจริงด้วย เพราะที่เราซื้อเป็น LiIon)
สำหรับ NiCd หรือ NiHM ในการชาร์จครั้งแรกๆควรชาร์จให้เต็ม และใช้ให้หมด แล้วชาร์จให้เต็มใหม่ ประมาณ 2-4 รอบก่อนนำไปใช้งานจริง เพื่อให้ได้ประสิทธิภาพเต็มที่ แต่ขณะที่ LiIon นั้นไม่จำเป็น
เค้าบอกว่าเวลาชาร์จครั้งแรกๆเนี่ยเป็นปกติเลยที่เครื่องมักบอกว่าชาร์จเต็มแล้วทั้งๆที่เพิ่งชาร์จไปได้แค่ 10-15 นาที ก็ไม่ต้องตกใจชาร์จต่อไป แต่บางเครื่องเนี่ยมันจะไม่ยอมชาร์จต่อ ก็ให้ถอดแบตแล้วชาร์จใหม่อีกรอบ เค้าบอกด้วยว่าอาจเกิดขึ้นได้หลายครั้งในการชาร์จครั้งแรก
ถ้าแบตไม่ได้ใช้เป็นเวลานานแล้วก็ควรจะต้องทำกระบวนแบบนี้ใหม่เช่นกัน เรียกว่า re-initialization

คราวนี้พอใช้ปกติควรชาร์จใหม่เมื่อไหร่ดี?
อันนี้จะเกี่ยวกันกับเรื่องรอบการชาร์จ (cycle count) ว่าชาร์จยังไงถึงจะนับเป็น 1 รอบการชาร์จ เพราะว่ารอบการชาร์จก็ส่งผลโดยตรงกับอายุการใช้งานแบตซะด้วย
จากที่อ่านมาคือถ้าเป็นแบตประเภท NiCd เนี่ยไม่ว่ารอบจะใช้ไปเท่าไหร่ ถ้าเริ่มชาร์จปุ๊ปจะนับเป็น 1 cycle ทันที เช่นใช้ไปแค่ 30% แล้วเอาไปชาร์จก็นับเป็น 1 cycle เลย ในขณะที่ถ้าเป็นแบบ LiIon เนี่ยมันจะฉลาดกว่าคือมันจะนับ 1 cycle ถ้ามีการชาร์จรวมกัน(1 หรือหลายครั้ง) คิดเป็นประมาณ 80% ขึ้นไป เช่น ใช้ไป 20% แล้วชาร์จเต็ม แล้วใช้ไปอีก 20% แล้วชาร์จเต็มใหม่ แล้วใช้ไปอีก 50% แล้วชาร์จเต็มใหม่ แบบนี้ถึงจะนับเป็น 1 cycle (แต่ตัวเลข 80% นั้นไม่แน่นอน แต่ราวๆนั้น) ส่วน NiMH ไม่มีข้อมูล (แต่คิดว่าคล้าย NiCd)
ดังนั้นแบตพวก NiCd ควรใช้ไปเยอะๆก่อนแล้วค่อยชาร์จทีเดียว ส่วน LiIon ก็ชาต์จเมื่อไหร่ก็ได้

ต่อมาเรื่องอายุการใช้งาน
อันดับแรกเลยก็คือจำนวนรอบการชาร์จ (cycle count) ที่ได้กล่าวไปแล้ว แต่ตัวเลขที่แสดงให้ดูเป็นแค่การประมาณ อาจมากหรือน้อยกว่านั้นก็ได้ ถ้าใช้จนหมดแล้ว แบตจะเสื่อมและเก็บประจุไม่ค่อยได้แล้ว
นอกจากนั้นก็มีเรื่องการเก็บรักษาคือไม่ควรเก็บแบตไว้ในที่ร้อน เช่น ทิ้งไว้ในรถเวลารถตากแดด (อันนี้ผมทำบ่อยเลย สงสัยเป็นสาเหตุหนึ่งให้แบตเก่าผมเสื่อมเร็ว) และแบตประเภท LiIon เนี่ยไม่ควรปล่อยให้แบตหมดเกลี้ยง เพราะทำให้เสื่อมสภาพเร็วขึ้น และอีกอย่างคือไม่ควรชาร์จจนเต็ม(ล้น)! (อันนี้แปลกดี ไม่รู้จริงรึเปล่า)
ถ้าเกิดว่าต้องไปต่างจังหวัด ต่างประเทศ ทำให้ไม่ได้ใช้งานโน๊ตบุ้คเป็นเวลานานๆ ก็ไม่ควรเสียบแบตฯค้างไว้ในเครื่อง ให้ถอดเก็บรักษาไว้ในที่แห้งและเย็นจะช่วยถนอมอายุการใช้งานได้ดียิ่งขึ้น

ถ้าใครทราบหรือรู้วิธีอะไรเพิ่มเติมสามารถบอกข้อมูลเพิ่มเติมได้ครับ

อ้างอิง

วันอาทิตย์ที่ 7 มีนาคม พ.ศ. 2553

Google มีผล Real-Time Search จาก Twitter


วันนี้บังเอิญลองค้นคำว่า webos บน google.com ดูแล้วปรากฏว่าเจอผลลัพธ์การค้นหาที่มาจาก twitter ติดมาด้วย เลยขอบันทึกเก็บไว้หน่อย

เพิ่มเติม: ไปลองอ่านจากข่าวต่างๆพบว่ามันมีมานานแลว(ประมาณเดือนธันวาปีก่อน) สามารถเลือกให้แสดงได้โดยเลือกที่ Show options แล้วใต้ Any time ให้เลือก Latest แต่ว่ายังไม่รู้สาเหตุว่าทำไมบางครั้งมันไม่ต้องเลือกก็ขึ้นมาในผลลัพธ์เลยและ update อัตโนมัติด้วย (ถ้าใน Show options จะแสดงแบบ static)


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

แก้ค่า auto_increment ใน MySQL

บางครั้งในฐานข้อมูลที่มีการ set ให้มี field ที่เป็น auto_increment แต่บังเอิญเกิดเหตุการณ์ที่เราต้องไปลบ record สุดท้าย เช่น ถ้าค่าวิ่ง 1,2,3,4,5 แล้วเราลบ 5 ออก พอเราใส่อันใหม่เข้าไปมันจะยังนับต่อเนื่องจนกลายเป็น 1,2,3,4,6 ซึ่งเราอยากให้มันเริ่มนับต่อที่ 5 ให้เราแก้ไขโดยใช้คำสั่งดังนี้
ALTER TABLE ชื่อตาราง AUTO_INCREMENT=5
ถ้าต้องการให้เป็นค่าอื่นก็เปลี่ยนเอาตรงตัวเลขหลัง AUTO_INCREMENT= นั่นล่ะครับ

วันพุธที่ 3 มีนาคม พ.ศ. 2553

ความแตกต่างของ struct กับ typedef struct

ในภาษา C นั้นการประกาศ struct เพื่อสร้างประเภทข้อมูลชนิดใหม่โดยทำการนำหลายๆประเภทข้อมูลมาจัดกลุ่มเป็นอันเดียว ซึ่งคล้ายๆกับการสร้าง class ในภาษาแบบ OO(Object Oriented) (แต่มีแค่โครงสร้างข้อมูล ไม่มีคำสั่งสำหรับเรียกใช้)

ซึ่งการประกาศ struct ที่เห็นกันบ่อยๆก็คือ
(1)
struct ABC {
...
};


กับ (2)
typedef struct {
...
} ABC;


และ (3)
typedef struct ABC {
...
} ABC;


ที่สงสัยกันคือแต่ละแบบนั้นแตกต่างกันยังไง? เหตุผลลึกๆเดี๋ยวอธิบายไว้ด้านหลัง เริ่มจากดูวิธีการประกาศใช้ก่อน

ถ้าเกิดเราประกาศ ABC โดยใช้รูปแบบที่ (1) และถ้าเราจะประกาศตัวแปรประเภทนี้ขึ้นมา เราต้องประกาศว่า
struct ABC v;
ถึงจะเรียกใช้งานได้

ถ้าเป็นกรณีที่ (2) ล่ะก็เราจะสามารถประกาศตัวแปรโดยเชียนเพียงแค่
ABC v;

แต่ว่าการประกาศในรูปแบบที่ (1) จะดีกว่าในรูปแบบที่ (2) ก็คือเราสามารถประกาศโครงสร้างล่วงหน้าโดยยังไม่ต้องใส่รายละเอียดของโครงสร้างข้อมูลได้ ซึ่งเรียกว่าการทำ Forward-Declaration เช่น
struct ABC x;
...
struct ABC {
...
};

ในขณะที่แบบที่ (2) ทำไม่ได้

ดังนั้นการที่จะทำให้แบบที่ (2) ทำ Forward-Declaration ได้บ้าง จึงพัฒนามาเป็นการประกาศในแบบที่ (3) ซึ่งเป็นการรวมข้อดีของแบบที่ (1) กับ (2) นั่นคือ เวลาประกาศตัวแปรก็จะเขียนแค่
ABC x;
และสามารถทำ Forward-Declaration ได้(แต่ในส่วน Forward-Declaration ยังต้องประกาศเป็น struct ABC อยู่) เช่น
struct ABC x;
...
typedef struct ABC {
...
} ABC;
// หลังจากนี้จึงเรียกแค่ ABC ได้
ABC y;


ส่วนเหตุผลลึกๆก็คือในภาษา C นั้นจะมีการแบ่ง namespace ของ type ออกเป็น 2 แบบ คือ tag namespace กับ typedef namespace ซึ่งการประกาศแบบที่ (1) นั้นจะเป็นการนำคำว่า ABC เข้าไปอยู่ใน tag namespace เพื่อใช้ในการอ้างถึงของการประกาศตัวแปรแบบ struct เพียงเท่านั้น ดังนั้นเวลาประกาศตัวแปรจึงต้องใช้ struct ABC x; แต่ในขณะที่แบบที่ (2) นั้นเป็นการนำคำว่า ABC เข้าไปอยู่ใน typedef namespace ซึ่ง typedef namespace นี้ให้มองว่าคล้ายการสร้าง map เพื่อจับว่าถ้าเจอคำว่า ABC ให้แทนด้วยคำว่า struct ABC ไปซะ ดังนั้นจึงสามารถประกาศสั้นๆได้ว่า ABC x; ส่วนการประกาศแบบที่ (3) ก็คือการนำคำ ABC ไปใส่ไว้ในทั้ง tag namespace และ typedef namespace เลย

ส่วนการทำ Forward-Declaration นั้นคือต้องมีประเภทตัวแปรที่จะประกาศอยู่ใน tag namespace เสียก่อนจึงจะสามารถทำได้

หลักการของ tag namespace นั้นจะใช้ได้กับทั้ง struct, enum, union (เพราะพวกนี้นับว่าอยู่ใน tag namespace)

แต่ถ้าเป็นภาษา C++ แล้ว แบบที่ (1), (2), (3) ไม่แตกต่างกัน เนื่องจาก การประกาศ struct/enum/union/class ใน C++ นั้นจะเหมือนการถูกทำ typedef ไปเรียบร้อย

อ้างอิง
http://stackoverflow.com/questions/612328/difference-between-struct-and-typedef-struct-in-c
http://www.embedded.com/story/OEG20020926S0059