วันอังคารที่ 29 ธันวาคม พ.ศ. 2558

Tutorial - How to give your Raspberry Pi a Static IP Address

To log in to your Raspberry Pi remotely, you'll need the IP of the Raspberry Pi – this is basically like your house address and tells the host computer where to look for it on the network. By default, the Raspberry Pi will be given an IP automatically by the router (called Dynamic IP and denoted by DHCP) when you connect to a network. However, this can change whenever you remove the Pi from the network e.g. turn it off.
Having a static IP isn't essential, however it will make repeated access to the Raspberry Pi via SSH much simpler, as you'll always know that the Raspberry Pi has the same address. Imagine how much trouble your postman would have if your house constantly changed location :)
This task assumes that you have the official Raspian OS release installed. This is available in the NOOBS distribution and can be downloaded from http://www.raspberrypi.org/downloads. This guide also assumes that you've connected your Pi to a network via Ethernet. If you're going to be logging into your Pi remotely for most tasks, then I recommend it's easiest and fastest to plonk it next to your router, and use ethernet to access the internet anway!
A. Checking Set Up
Boot into Raspian and log in (Username. pi, Password. raspberry), this will all be command line stuff, so no need to log in to the GUI.
First, we need to list the network interface we currently have available:
cat /etc/network/interfaces

The line . . . .
iface eth0 inet dhcp
Implies that we're currently getting out IP address via DHCP, meaning it's being dynamically registered by the router. This is what we want to change!
B. Gathering Information
Fist of all we need to grab some information from our router and Pi. There's a couple of command we need to run to get this info. Have a pen and paper handy! . . .
ifconfig

This reveals your router information, the bit you want is after eth0 (the ethernet connection). . . .
eth0      Link encap:Ethernet  HWaddr b8:27:eb:b3:fc:2c
               inet addr:192.168.1.81  Bcast:192.168.1.255  Mask:255.255.255.0
Write down the following information. . .
inet addr – 192.168.1.81 (Pi's Current IP Address)
Bcast –  192.168.1.255 (The Broadcast IP Range)
Mask –  255.255.255.0 (Subnet Mask Address)
We need a little more information before we proceed. Use the command. . .
netstat -nr
(route -n will give you the same info.)

We need:
'Gateway' Address – 192.168.1.254
'Destination' Address – 192.168.1.0
C. Editing Network Configuration
We now need to plug this information into the Pi's network configuration file using a text editor. I always use nano text editor. . .
sudo nano /etc/network/interfaces

Simply change the line that reads:
iface eth0 inet dhcp
to
iface eth0 inet static
Then directly below this line enter the following (Please Note. You will need your own addresses we gathered in Part B, more details below). . . .
address 192.168.1.81
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.254
To clarify what each part means. . . .
address – The address you want to give your Pi, this can be any IP in the network range, but it's usually advisable to go higher rather than lower, or you could end up logging different devices to the same IP! I've selected 192.168.1.81, as we're already registered to that address (denoted by 'inet addr'), but this can be any IP address from the range192.168.1.1 to 192.168.1.255.
netmask – The 'Mask' address we wrote down earlier.
network – The router IP address, this is the 'Destination' Address was found earlier. You can also grab this off your router, it will say on the side somewhere.
broadcast – The 'Bcast' address we wrote down earlier.
gateway – This is the 'Gateway' address we found earlier.

So, it should look something like the above, but with your values! Remember to save before exit, CTRL+X (exit) then yes to save changes!
D. Re-check Static IP Configuration
UPDATE: Remove any existing leases
sudo rm /var/lib/dhcp/*
Then we'll need to reboot and check your changes. . .
sudo reboot
Log back in and run
ifconfig
Which should reveal your new settings. .

To double checks all is working as it should, ping your 'Gateway' Address. . .
ping 192.168.1.254 -c 10
(the -c 10 command simply denotes that you want to ping it 10 times, if you forget to add this, it will ping the address continuosly. To stop it press CTRL+C)

This should ping successfully and all packets should be recieved. If something's not right double check through all your IP addresses, and make sure you're pinging the right address too. Remember you can always revert back to DHCP by reversing the steps. The 'network' router IP address is sometimes a little fiddly, so check that if you're still having issues!
Hopefully however, your Raspberry Pi is now set up with a static IP address!

  Raspberry Pi การตั้งค่า IP Address แบบคงที่ Static

การตั้งค่า Config IP Address ให้ Raspberry Pi แบบคงที่ Static เพื่อให้ง่ายสำหรับการ Config เข้าไปใช้งาน Raspberry pi หรือเชื่อมการใช้งานเข้าในเครือข่ายของเรา

ต่อสาย HDMI จอภาพ, เมาส์ USB, คีย์บอร์ด USB, สาย LAN เชื่อมเครือข่ายและอินเตอร์เน็ต และเสียบสายไฟ 5V Micro USB

ค่า IP เริ่มต้น ของ Rspberry Pi จะเป็นแบบ dhcp (เปลี่ยนค่าอัตโนมัติตาม Router Domain) เราต้องเข้าไปใน Raspi เพื่อตั้งค่าให้เป็นแบบไอพีคงที่ static

@ ใช้คำสั่งเข้าไปตั้้งค่าเน็ตเวิร์กให้ Raspberry pi
sudo nano /etc/network/interfaces   

ตั้งค่า IP Address ให้คงที่ static

โดยใส่ค่า
================================

auto lo
iface lo inet loopback
iface eth0 inet staticaddress 192.168.1.81
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.254=================================

เปลี่ยน
iface eth0 inet dhcp (ค่าตาม Router)

เป็น
iface eth0 inet static  (คงที่)

แล้วกดปุ่ม Ctrl+x แล้วกดปุ่ม y (save) แล้วกดปุ่ม Enter

 @ คำสั่งการตั้งค่า domain , nameserver
sudo nano /etc/resolv.conf

ใช้สำหรับตั้งค่า Domain เชื่อมต่ออินเตอร์เน็ตในเครือข่ายท่าน
ใช้ในกรณีเป็น eth0 inet static แบบไอพีคงที่ เท่านั้น
ถ้าตั้งค่าเป็น dhcp จะทำให้ค่า domain , nameserver ในฟล์ resolv.conf
เปลี่ยนไปตาม Router แบบ dhcp (Auto IP)
      
 ใส่ค่า domain , nameserver ในเครือข่ายเรา (ตัวอย่างนี้เป็นเครือข่ายในสำนักงาน)
เมื่อเราตั้งเป็นคงที่ static แล้ว ไฟล์ revolv.conf จะมีค่านี้ตลอดไป

ทดลอง PuTTY เข้าสู่ Raspberry Pi โดยป้อน IP Host เป็น 192.168.149.106

จะเชื่อมต่อ Raspberry Pi ได้ ดังภาพ แสดงว่าเชื่อมต่อเข้าไปได้แล้ว     

ทดสอบการ Ping เข้าสู่อินเตอร์เน็ต โดยทดลองเชื่อมเข้าเว็บ google.com

@ ใช้คำสั่ง
ping google.com

จากรูป แสดงว่าเชื่อมต่ออินเตอร์เน็ตได้สำเร็จ

เมื่อท่านรู้ IP Address ของ Raspi ก็สามารถต่อตรง Direct LAN ได้แล้ว

เปิดดูขั้นตอนได้ตามลิงค์นี้
http://dtv.mcot.net/data/up_show.php?id=1452754995&web=epost 

@ คำสั่ง ตรวจสอบดู ip network
ifconfig
   

@ คำสั่ง ตรวจสอบดู Active connection
netstat –nr    

@ คำสั่ง ตรวจสอบดู IP routing
route -n

@ คำสั่ง ตรวจสอบดู domain และ nameserver
cat /etc/resolv.conf

@ คำสั่ง ตรวจสอบดู IP และ Netmask
cat /etc/network/interfaces


ตอนบูต Raspi เราสามารถมองเห็นค่า IP ที่เชื่อมเครือข่าย ได้ที่หน้าจอ HDMI

วันจันทร์ที่ 28 ธันวาคม พ.ศ. 2558

การ Login เข้า Raspberry Pi ผ่านพอร์ต UART

การ Login เข้า Raspberry Pi ผ่านพอร์ต UART

ช่วงนี้มีเวลาทดลองและเล่นอุปกรณ์อิเล็กทรอนิกส์หลายตัว ซึ่งจริงๆตัวเองก็จบอิเล็กทรอนิกส์มาแต่ก็ไม่ได้เล่นมาหลายปี พอกลับมาเล่นอีกทีก็ต้องรื้อฟื้นกันเยอะหน่อย ทุกวันนี้อุปกรณ์อิเล็กทรอนิกส์ราคาถูกมากๆ เมื่อเทียบกับ 10 ปีที่แล้วนี้คนละเรื่องเลย วันนี้เริ่มที่การ login เข้าใช้งานตัว Raspberry-Pi กันก่อน ปกติถ้าเราจะทำการ login เข้าไปยัง Raspberry-Pi เราจะต้องต่อจอ หรือไม่ก็ต้องทราบ IP Address เพื่อจะได้ทำการ SSH เข้าไปได้ แต่วันนี้เราจะลองทำการ login ผ่านทางพอร์ต UART ของเจ้า Raspberry-Pi กันดู พอร์ตของ Raspberry-Pi ที่มีให้เราใช้งานจะมีอยู่ 2 ขาที่ทำหน้าที่เป็น Tx กับ Rx คือขาที่ 8 และ 10

จากรูปจะเห็นว่าขาที่ 8 จะทำหน้าที่เป็น Tx และขาที่ 10 จะทำหน้าที่เป็น Rx

สิ่งที่เราต้องมีในการทดลองนี้คือ Raspberry-Pi และสาย USB To UART ถ้าไม่มีก็ต้องไปหามาก่อนนะ ไม่งั้นเล่นไม่ได้และผมก็ไม่ให้ยืมด้วย ถ้าจะซื้อก็ที่นี้เลยครับ http://www.arduino.in.th/product/151/usb-to-uart-cable-pl-2303hx (ผมไม่เกียวอะไรกับเขานะ แต่ก็ซื้อมาจากที่นี้เหมือนกัน)

1. เริ่มจากทำการต่อสาย USB To UART ระหว่าง Raspberry-Pi กับ Computer โดยต่อสายแต่ละเส้นดังนี้
– สายสีแดง ต่อเข้ากับขา 2 ซึ่งจะเป็นขาจ่ายไฟ 5V จากเครื่องคอมฯ ให้ Raspberry-Pi แต่ถ้าเราต่อสายเพาเวอร์ให้ Raspberry-Pi อยู่แล้ว สายเส้นนี้ลอยไว้ไม่ต้องต่อก็ได้ครับ
– สายสีดำ ต่อเข้ากับขา 6 เป็น Ground ของระบบ
– สายสีขาว ต่อเข้ากับขา 8
– สายสีเขียว ต่อเข้ากับขา 10

2. ทำการเปิด Device Manager ขึ้นมาดูก่อนครับว่าสาย USB TO UART มันใช้พอร์ต COM หมายเลขเท่าไร ในตัวอย่างของผมเป็น COM8

3. เปิดโปรแกรม PuTTY ขึ้นมาโดยกำหนดค่าต่างๆ ดังนี้
– Connection type = Serial
– Serial line = COM8 (ถ้าของคุณเป็นพอร์ตอื่นก็ไม่ต้องใส่ตามผมนะ)
– Speed = 115200

4. เมื่อกรอกข้อมูลต่างๆเรียบร้อยและคลิก Open เราก็จะมาเจอกับหน้าล๊อกอินของ Raspberry-Pi
วิธีการติดตั้ง Qt5 บน Raspberry Pi (Jessie)
01 1
1. ติดตั้ง OS ให้กับบอร์ด Raspberry Pi
2. เชื่อมต่อบอร์ดให้สามารถเชื่อมต่อกับ Internet ได้
3. เปิดโปรแกรม Terminal บนบอร์ด Raspberry Pi ขึ้นมา
01
4. พิมพ์คำสั่ง sudo apt-get update เพื่ออัพเดทรายการสารบัญที่อยู่ของซอฟท์แวร์จาก Repository จากนั้นรอสักครู่ให้การอัพเดทเสร็จสิ้น
02
5. พิมพ์คำสั่ง sudo apt-get install qt5-default เพื่อติดตั้ง Qt 5 packet
03
6. พิมพ์คำสั่ง sudo apt-get install qtcreator เพื่อติดตั้ง Qt Creator
04
7. พิมพ์คำสั่ง sudo apt-get install build-essential g++ เพื่อติดตั้ง build-essential และ g++
05
8. พิมพ์คำสั่ง sudo apt-get install libqt5serialport5-dev เพื่อติดตั้ง Library QSerialPort สำหรับผู้ที่ต้องการใช้งาน Serial Port
06
9. เนื่องจาก Qt creator มีปัญหาบางอย่างเกี่ยวกับหน้า Welcome กับ Jessie ให้ Run โปรแกรมในครั้งแรกโดย โดยใช้คำสั่ง qtcreator -noload Welcome
07
(ขอบคุณคำแนะนำจากคุณ Sarawut Phetsilp กลุ่ม Raspberry Pi Thailand ในการแก้ปัญหาไม่สามารถ Run Qtcreator บน Jessie)
10. เข้าไปปิด ไม่ให้มีการโหลดหน้า Welcome ตอนเปิดโปรแกรม
>> เข้าไปที่ Menu Help >> About Plugins…
08
>> ค้นหาหัวข้อ Qt Creator แล้วเอาเครื่องหมายถูกออกจาก Welcome
09
>> กด Button Close แล้วปิดโปรแกรม
11. ทดลอง Run Qt Creator โดยพิมพ์ qtcreator
10
12. Add Compiler
>> หลังจากเข้าโปรแกรม Qt Creator มาแล้วให้ไปที่ Menu Tools >> Options
11
>> เลือกหัวข้อ Build & Run และเลือกที่ tab Compiler
12
>> คลิกที่ Button Add เลือก GCC
13
>> ตั้งค่า Compiler path โดยกด Button Browser และเลือก Browse ไปที่ File System >> /usr/bin/arm-linux-gnueabihf-gcc-4.9
14
>> กด Button Apply
15
>> ไปที่ Tab Kits แล้วเลือกที่ Desktop(default) ตั้งค่า Compiler เป็น GCC
16
>> คลิก Apply และ OK
13. ทดลอง สร้าง Application
>> ไปที่ Menu File >> New File or Project…
17
>> เลือก Qt Widgets Application และ คลิก Button Choose
18
>> ตั้งชื่อ Project และ เลือก path ที่เก็บ Project
19
>> เลือก Kit
20
>> ตั้งค่า class
21
>> ตั้งค่า Project Management
22
>> ทดลองสร้าง UI โดยไปที่ หน้า Design
23
>> ทดลอง นำเอา Dial และ LCD Number มาวาง
24
>> คลิกเลือก menu Edit Signals /Slots หรือ กด F4
25
>> drag mouse ลาก Signal ของ Dial ไปยัง Slot ของ LCD Number
26
>> ตั้งค่า ให้นำเอา Signal ValueChange(int) จาก Dial ส่งไปยัง Slot display(int ) ของ LCD Number แล้วกด Button OK
27
>> ทดลอง Run Program
28
>> ทดลองหมุน Dial จะทำให้ค่า value ไปปรากฏที่ LCD Number
29

Remote Desktop on Raspberry pi with xrdp



 จะดีแค่ไหนถ้าสามารถ Login เข้า Raspberry Pi ผ่านทางโปรแกรม Remote Desktop ของ Windows ได้  มาเริ่มติดตั้งแพคเกจต่างๆ กันครับ.
 

1. ติดตั้ง Remote Desktop ด้วย xrdp

    
          1.1 เริ่มต้นติดตั้ง xrdp
 
            
                      sudo apt-get install xrdp
 
เมื่อติดตั้งเสร็จแล้วสามารถ เข้าไปตั้งค่าได้ที่ ไฟล์ /etc/xrdp/xrdp.ini โดยใช้คำสั่ง


                    sudo nano /etc/xrdp/xrdp.ini

 หลังจากที่เราติดตั้งเสร็จแล้วเราควรที่จะ Fixed IP ด้วยเพื่อที่ไม่ให้ IP เราเปลี่ยนไปมาครับ
 และถ้าเราต้องการจะ Remote จากข้างนอกได้แต่ internet เราเป็น ADSL ที่มี IP จริง เปลี่ยนไปมา เราสามารถแก้ไขปัญหาได้โดยการทำ DDNS ครับ
 
          1.2 ทดสอบการ Remote
 
รันโปรแกรม Remote Desktop Connection ที่มีใน Windows
 
ทดสอบการ Remote Desktop
 
เมื่อเข้าหน้าจอ Remote แล้วให้ ใส่ User และ Password โดยค่า Default ของ บอร์ด Raspberry pi    User:pi  Password:raspberry
 
xrdp remote x windows
 
กดปุ่ม OK จะเข้าสู่หน้าจอ X window ของ Debian Linux บนบอร์ด Raspberry

วันอังคารที่ 17 พฤศจิกายน พ.ศ. 2558

ตอนที่ 8 ตัวอย่างการเขียนโปรแกรมรับ-ส่งข้อมูลผ่านทาง SPI

ตอนที่ 8 ตัวอย่างการเขียนโปรแกรมรับ-ส่งข้อมูลผ่านทาง SPI
         0145
         SPI (Serial Peripheral Interface) เป็น การเชื่อมต่อสื่อสารแบบอนุกรมโดยอาศัยสัญญาณนาฬิกาเป็นตัวกำหนดจังหวะการรับ ส่งข้อมูล (Synchronous) ที่สามารถส่งข้อมูลไปยังปลายทางและรับข้อมูลจากปลายทางกลับมาในครั้งเดียว กัน (Full Duplex)
         SPI แบ่งอุปกรณ์ออกเป็น 2 ฝั่ง คือ Master เป็นตัวควบคุมการรับส่งข้อมูลโดยในที่นี้คือไมโครคอนโทรลเลอร์ กับ Slave เป็นอุปกรณ์ที่รอรับคำสั่งจาก Master โดย Slave มีได้มากกว่า 1 ตัว
SPI ใช้สายสัญญาณทั้งหมด 4 เส้นดังนี้
         1. MOSI (Master Out Slave In)      Master -> Slave           Shared
         2. MISO (Master In Slave Out)      Slave -> Master           Shared
         3. SCLK (Clock)                           Master -> Slave           Shared
         4. CS (Chip Select)                      Master -> Slave           Not Shared

0131
            Master สามารถเชื่อมต่อกับ Slave ได้มากกว่า 1 ตัว โดยทุกตัวจะใช้ขา MOSI MISO และ SCLK ร่วมกัน แล้ว Master จะส่งสัญญาณที่ขา CS เพื่อเลือกว่าในขณะนั้น Master ติดต่อกับ Slave ตัวใด
รูปแบบสัญญาณใน SPI BUS
รูปแบบสัญญาณ SPI มี 4 รูปแบบ แตกต่างกันที่ขอบสัญญาณนาฬิกา (Clock Polarity) และเฟส (Phase)
0132
          - เมื่อ CPHA=0 และ CPOL=0 สัญญาณนาฬิกา (Clock) ในสถานะปกติจะเป็น Low และจะรับ-ส่งข้อมูลที่ขอบขาขึ้นของสัญญาณนาฬิกา (Rising Edge Clock)
          - เมื่อ CPHA=0 และ CPOL=1 สัญญาณนาฬิกา (Clock) ในสถานะปกติจะเป็น High และจะรับ-ส่งข้อมูลที่ขอบขาลงของสัญญาณนาฬิกา (Falling Edge Clock)
          - เมื่อ CPHA=1 และ CPOL=0 สัญญาณนาฬิกา (Clock) ในสถานะปกติจะเป็น Low และจะรับ-ส่งข้อมูลที่ขอบขาลงของสัญญาณนาฬิกา (Falling Edge Clock)
          - เมื่อ CPHA=1 และ CPOL=1 สัญญาณนาฬิกา (Clock) ในสถานะปกติจะเป็น High และจะรับ-ส่งข้อมูลที่ขอบขาขึ้นของสัญญาณนาฬิกา (Rising Edge Clock)
ดังนั้น จึงกำหนดเป็น Mode การทำงานได้ 4 โหมด คือ
          o Mode 0 = CPOL=0 และ CPHA=0
          o Mode 1 = CPOL=0 และ CPHA=1
          o Mode 2 = CPOL=1 และ CPHA=0
          o Mode 3 = CPOL=1 และ CPHA=1
ทดสอบใช้งาน SPI Driver บนบอร์ด Raspberry Pi
          ในการทดสอบนี้เป็นการทดสอบรับ-ส่งข้อมูลผ่าน SPI โดย Loopback ส่งข้อมูลออกจากขา MOSI และรับข้อมูลเข้ามาทางขา MISO
- เปิดโปรแกรม LXTerminal
- ดาวน์โหลดซอร์สโค้ดโปรแกรมทดสอบ Loopback พิมพ์คำสั่ง
wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.10.y /Documentation /spi/spidev_test.c
0134
- คอมไพล์โปรแกรม พิมพ์คำสั่ง gcc -o spidev_test spidev_test.c
0135
- ทดสอบ Run โปรแกรม พิมพ์คำสั่ง ./spidev_test -D /dev/spidev0.0
0136
            โปรแกรมจะแสดงรายละเอียดที่ตั้งค่า SPI และแสดงข้อมูลที่ได้รับจากขา MOSI จากรูปพบว่า Data ทั้งหมดเป็น 0 ทั้งหมดหรืออาจเป็น FF ทั้งหมดเนื่องจากขาของ MOSI ยังไม่ได้ต่อกับอุปกรณ์ใดๆ
- ต่อสัญญาณขา MOSI เข้ากับขา MISO
0137
- ทดสอบ Run โปรแกรมใหม่อีกครั้ง พิมพ์คำสั่ง ./spidev_test -D /dev/spidev0.0
0138
จะมีข้อมูลที่อ่านได้จากขา MOSI ซึ่งตรงกับที่กำหนดไว้ในโค้ดโปรแกรม
0139 1
- ในโปรแกรมตัวอย่างนี้ สามารถทดสอบกำหนดตั้งค่าต่างๆให้กับ SPI ได้โดยกำหนดพารามิเตอร์ซึ่งสามารถดูเมนูวิธีการตั้งค่าโดย พิมพ์คำสั่ง ./spidev_test -x (โดย x คือ ตัวอักษรอะไรก็ได้ที่ไม่มีอยู่ในลิสต์คำสั่ง)
0139
- ทดสอบงาน SPI0 กำหนด Max Speed เป็น 1 MHz เปลี่ยน Mode SPI เป็นโหมด 3 พิมพ์คำสั่ง ./spidev_test -D /dev/spidev0.0 –s 1000000 – H –O
0140
ทดลองใช้งาน SPI กับไลบรารี่ WiringPi บน Qt
            ในการทดลองนี้เป็นการนำโมดูล ADXL345 Digital Accelerometer (ESEN067 Triple Axis Accelerometer Breakout - ADXL345) สำหรับวัดค่าความเร่งมาทดลองเขียนโปรแกรมผ่าน SPI ไปสั่งงานและอ่านค่าความเร่งจาก ADXL345
            ก่อนทำการทดลองมาทำความรู้จัก ADXL345 สักเล็กน้อยเพื่อให้เข้าใจความหมายของข้อมูลที่รับส่งกับตัวโมดูล โดยเราสามารถติดต่อสื่อสารกับ ADXL345 ได้ 2 รูปแบบ คือ SPI กับ I2C แต่ในการทดลองนี้เลือกใช้แบบ SPI โดยในคู่มือของ ADXL345 ระบุว่าสามารถใช้สัญญาณนาฬิกาเพื่อรับ-ส่งข้อมูลแบบ SPI ได้สูงสุด 5 MHz และใช้ CPOL =1 และ CPHA = 1 คือ Mode 3 นั่นเอง
รูปแบบ Protocol ที่ใช้ใน ADXL 345
            เราสามารถสั่งงาน ADXL345 ได้ โดยการระบุตำแหน่งของรีจิสเตอร์ภายในที่เราต้องการเข้าไปเขียนหรืออ่าน ข้อมูลออกมาโดยส่งไปทางขา MOSI โดยข้อมูลไบต์แรกใช้เพื่อระบุว่าเป็นการอ่านหรือเขียนและตำแหน่งที่ต้องการ เข้าถึง หากเป็นการเขียนข้อมูลลงไปในตำแหน่งนั้นไบต์ต่อไปที่ส่งจะเป็นข้อมูลที่ต้อง การเขียน แต่หากเป็นการอ่านข้อมูล ไบต์ของข้อมูลจะถูกส่งออกจากทางขา MISO
0141
ความหมายของข้อมูลไบต์แรกที่ถูกส่งออกไปเพื่อควบคุมการอ่านหรือเขียนและกำหนดตำแหน่ง
0142
           - บิตที่ 0 ถึงบิตที่ 5 (A0 - A5) คือ บิตที่ใช้ระบุตำแหน่งรีจิสเตอร์ของ ADXL345 ซึ่งมีขนาด 5 บิต ตั้งแต่ตำแหน่งที่ 0x00 จนถึง 0x39
           - บิตที่ 6 คือ MB (Multiple Byte) ให้กำหนดเป็น 1 (High) เมื่อต้องการรับ-ส่งข้อมูลหลายๆ ไบต์ในการรับ-ส่งครั้งเดียว
           - บิตที่ 7 (MSB) คือ R/W (Read/Write) หากกำหนดเป็น 0 หมายถึงต้องการเขียนข้อมูลลงไปในตำแหน่งที่ระบุไว้ใน A0 – A5 แต่หากกำหนดเป็น 1 หมายถึงต้องการอ่านข้อมูลจากตำแหน่งนั้น
รีจิสเตอร์ที่ใช้งานในการทดลองนี้
- DATA_FORMAT (Address 0x31)
0143
             ในการทดลองนี้กำหนดค่าให้ DATA_FORMAT = 0x01 (ให้ D0 เป็น1) คือ ให้ ADXL345 อ่านค่าที่ + 4g
- POWER_CTL (Address 0x2D)
0144
             ในการทดลองนี้กำหนดค่าให้ Address POWER_CTL = 0x08 (ให้ D3 เป็น 1) คือ ให้ทำงานในโหมดการวัดค่า (Measure)
- DATAx0 DATAx1 DATAy0 DATAy1 DATAz0 DATAz1 (Address 0x32 - 0x37)
             ตำแหน่ง 0x32 – 0x37 เป็นตำแหน่งที่เก็บค่าความเร่งที่วัดได้แต่ละค่าตามลำดับ
ทดลองเขียนโปรแกรมอ่านค่า ADXL345 ผ่าน SPI
- ต่อโมดูล ADXL345 เข้ากับบอร์ด Raspberry Pi ดังภาพ
0145- เปิดโปรแกรม LXTerminal และเปิดโปรแกรม Qt Creator พิมพ์คำสั่ง sudo qtcreator
- สร้าง Project ใหม่ชื่อ adxl_345
- เปิดไฟล์ adxl_345.pro แล้วเพิ่มโค้ดลงไปดังนี้
LIBS += -L/usr/local/lib -lwiringPi -lwiringPiDev
INCLUDEPATH += /usr/local/include
0146
- ออกแบบหน้าตาโปรแกรมโดยมี Widget ดังนี้
         o Pushbutton 3 อัน โดยแสดงข้อความบนปุ่มดังนี้
                “INIT SPI”
                “Start”
                “Stop”
         คลิกขวาที่ PushButton ทีละอัน แล้วสร้าง Slot เลือก Signal = clicked ให้ครบทั้ง 3 อัน
0147
         o Text Edit
         หน้าตาโปรแกรมที่ออกแบบควรจะมีรูปแบบประมาณนี้
0148- ไปที่ไฟล์ mainwindows.cpp แล้วเพิ่มไลบรารี่ ประกาศตัวแปร และกำหนดค่าต่างๆ ดังนี้
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <QTimer>
#include <sys/ioctrl.h>
#include <linux/spi/spidev.h>
int fd;
Qtimer *timer;
#define DEVID 0x00
#define POWER_CTRL 0x2D
#define DATA_FORMAT 0x31
#define DATA_X 0x32
#define DATA_Y 0x34
#define DATA_Z 0x36
#define CMD_READ 0x80
#define CMD_MB 0x40
#define CMD_WRITE 0x00
0149
- เพิ่มโค้ดลงในฟังก์ชั่น void MainWindow::on_pushButton_clicked() ดังนี้
0150
             บรรทัดที่ 36 เปิดใช้งาน SPI ช่อง 0 และกำหนดความเร็วสัญญาณนาฬิกาที่ 4 MHz
             บรรทัดที่ 38 หากเปิดใช้งานไม่สำเร็จให้แสดงข้อความใน Text Edit
             บรรทัดที่ 44 เนื่องจากไลบรารี่ WiringPi ไม่ได้ทำฟังก์ชั่นให้เข้าไปปรับ SPI Mode ได้ เราจึงต้องใช้ฟังก์ชั่น ioctrl เข้าไปปรับให้ใช้ SPI ใน Mode 3 ได้
             บรรทัดที่ 45 หากตั้งค่า SPI Mode ไม่สำเร็จให้แสดงข้อความใน Text Edit
             บรรทัดที่ 51 ฟังก์ชั่น ioctrl อ่านค่า Speed Clock ที่ตั้งเอาไว้มาแสดงใน Text Edit
             บรรทัดที่ 53 ฟังก์ชั่น ioctrl อ่านค่า SPI Mode ที่ตั้งเอาไว้มาแสดงใน Text Edit
             บรรทัดที่ 55 สืบทอดคลาส Qtimer
             บรรทัดที่ 56 สร้าง Slot และ Signal ให้กับ Timer
- สร้างฟังก์ชั่น void write_register(unsigned char reg,unsigned char data) ดังนี้
0151
             บรรทัดที่ 63 ประกาศตัวแปร Array unsigned char เพื่อเก็บข้อมูลที่ต้องการส่งให้ ADXL345
             บรรทัดที่ 65 นำตำแหน่งของรีจิสเตอร์ที่ต้องการเขียนไปเก็บใน data_out ไบต์ที่ 0 และเนื่องจากคำสั่ง Write ในบิตที่ 7 เป็น 0 อยู่แล้วจึงไม่ต้องกำหนด
             บรรทัดที่ 66 นำข้อมูลที่ต้องการเขียนลงรีจิสเตอร์มาเก็บใน data_out ไบต์ที่ 1
             บรรทัดที่ 67 ส่งข้อมูลออกไปทาง SPI ด้วยฟังก์ชั่น wiringPiSPIDataRW(int channel , unsigned char *data , int len)
                    o int channel คือ ช่อง SPI ที่ใช้งาน
                    o unsigned char *data คือ pointer ของข้อมูลที่ต้องการรับ-ส่ง
                    o int len คือ จำนวนไบต์ทั้งหมดที่รับ-ส่ง
- สร้างฟังก์ชั่น QByteArray read_register(unsigned char reg , int len) ดังนี้
0152
             บรรทัดที่ 73 ประกาศตัวแปร QByteArray dat; เพื่อเก็บข้อมูลสำหรับส่งออกไปเมื่อทำงานจบฟังก์ชั่น
             บรรทัดที่ 74 ประกาศตัวแปร Array unsigned char เพื่อเก็บข้อมูลที่ต้องการส่งให้ ADXL345
             บรรทัดที่ 75 ตรวจเช็คว่าจำนวนไบต์ของข้อมูลที่ต้องการอ่านกลับมาว่ามีค่ามากกว่า 1 ไบต์หรือไม่
             บรรทัดที่ 76 หากจำนวนข้อมูลที่ต้องการอ่านมากกว่า 1 ไบต์ให้เก็บค่าตำแหน่งของรีจิสเตอร์ลงในไบต์ที่ 0 ของ data_out กำหนดบิตที่ 7 เป็น 1 (อ่านข้อมูลจากรีจิสเตอร์) และบิตที่ 6 เป็น 1 (อ่านแบบ Multiple Byte) จาก reg|CMD_READ|CMD_MB หรือ 0xXX|0x80|0x40 ทำให้ data_out[0] มีค่าเท่ากับ 0b11xxxxxx
             บรรทัดที่ 78 หากอ่านค่ากลับมาแค่ 1 ไบต์ให้เก็บค่าตำแหน่งของรีจิสเตอร์ลงในไบต์ที่ 0 ของ data_out กำหนดบิตที่ 7 เป็น 1 (อ่านข้อมูลจากรีจิสเตอร์)
             บรรทัดที่ 80 ส่งข้อมูลใน data_out ออกไปทาง SPI ด้วยฟังก์ชั่น wiringPiSPIDataRW ซึ่ง ADXL345 จะส่งข้อมูลจากรีจิสเตอร์ที่เราต้องการอ่านค่ากลับมา โดยฟังก์ชั่น wiringPiSPIDataRW จะเขียนข้อมูลที่ได้รับจาก ADXL345 มาเก็บในตัวแปร data_out ต่อจากเดิมที่เราใช้ส่งคำสั่งอ่านข้อมูลออกไป ในที่นี้ เราส่งข้อมูลไปเพียง 1 ไบต์ที่ data_out[0] ดังนั้นข้อมูลที่ ADXL345 ส่งกลับมาจะถูกเก็บตั้งแต่ใน data_out[1] เป็นต้นไป
             บรรทัดที่ 81 นำ Data จาก data_out ไปเก็บในตัวแปร QByteArray dat โดยไม่เก็บ data_out[0] ลงไปใน dat ด้วย
             บรรทัดที่ 85 ส่งค่า return ตัวแปร dat ออกไป
- ไปที่ไฟล์ mainwindows.h
- ประกาศชื่อฟังก์ชั่น interval() ภายใต้ private slot และฟังก์ชั่น write_register กับ read_register ภายใต้ private
0153
- ไปที่ไฟล์ mainwindows.cpp เพิ่มโค้ดลงในฟังก์ชั่น
void MainWindow::on_pushButton_2_clicked() ดังนี้
0154
             บรรทัดที่ 92 เขียนค่า 0x01 ลงในรีจิสเตอร์ DATA_FORMAT เพื่อกำหนดให้ ADXL345อ่านค่าที่ + 4g
             บรรทัดที่ 92 อ่านค่ารีจิสเตอร์ DATA_FORMAT ออกมาแสดงใน Text Edit
             บรรทัดที่ 95 เขียนค่า 0x08 ลงไปในรีจิสเตอร์ POWER_CTL เพื่อกำหนดให้ADXL ทำงานในโหมดการวัด (Measure)
             บรรทัดที่ 96 อ่านค่ารีจิสเตอร์ POWER_CTL ออกมาแสดงใน Text Edit
             บรรทัดที่ 99 สั่งให้ Timer ทำงาน มี interval ทุก 200 ms
- เพิ่มโค้ดลงในฟังก์ชั่น void MainWindow::on_pushButton_3_clicked() ดังนี้
0155
             บรรทัดที่ 104 สั่งให้ Timer หยุดทำงาน
- สร้างฟังก์ชั่น interval() ดังนี้
0156
             บรรทัดที่ 110 เคลียร์ข้อความใน Text Edit
             บรรทัดที่ 111 อ่านข้อมูลจากรีจิสเตอร์ตั้งแต่ 0x32 (DATAx0) จำนวน 6 ไบต์หมายถึง การอ่านค่า ADXL345 จาก DATAx0 จนถึง DATAz1 ในครั้งเดียว
             บรรทัดที่ 112 ประกาศตัวแปร int ขนาด 16 บิต มาเก็บค่าที่อ่านได้จาก ADXL345
             บรรทัดที่ 114 เนื่องจากค่าความเร่งที่อ่านได้ในแต่ละแกนมีขนาด 10 บิต แยกเก็บในตัวแปรขนาด 8 บิต 2 ตัว ก่อนนำไปใช้งานจึงต้องนำข้อมูล 8 บิตทั้ง 2 อันมาเก็บรวมกันก่อนโดย Datax0 จะเป็น LSB และ Datax1 เป็น MSB และทำเช่นเดียวกันกับ Data ของทุกแกน
             บรรทัดที่ 118 สร้างตัวแปรแบบ float มาเก็บค่าที่ได้จากทั้ง 3 แกนเมื่อคำนวณเป็นแรง g
             บรรทัดที่ 120 ในตอนแรกกำหนดให้รีจิสเตอร์ DATA_FORMAT = 0x01 ทำให้ ADXL345 อ่านค่าที่ +4g และ ADXL345 มีค่าความละเอียด 10 บิท คือ ตั้งแต่ 0 ถึง 1023 ดังนั้นที่ -4g ค่าที่อ่านได้จะเท่ากับ 0 และที่ +4g ค่าที่อ่านได้เท่ากับ 1023 ดังนั้น ถ้าอ่านค่าได้ 1 จะมีค่าเท่ากับ 8/1023 = 0.0078g หากนำค่าในแต่ละแกนที่ ADXL345 อ่านได้มาคูณกับ 0.0078 ก็จะได้ค่าแรง g ที่กระทำต่อแกนนั้นๆ
             บรรทัดที่ 124 นำค่า g ที่คำนวณได้มาแสดงใน Text Edit
- ทดลอง Run โปรแกรม
0157ทดสอบวาง ADXL345 ในทิศทางต่าง
0158ทดลองนำค่า g ที่วัดได้ในแกน x y z มาคำนวณเป็นค่ามุม Roll / Pitch
- เพิ่ม #include <qmath.h> ใน mainwindows.cpp
0160
- เพิ่มโค้ดลงไปในฟังก์ชั่น interval() ดังนี้
0161
- ทดลอง Run โปรแกรม