การติดตั้ง GPS U-blox Neo 6M บน Raspberry PI

เป็นภาคเสริมเรื่องการถ่ายภาพ NDVI ครับ คือว่าต้องการให้ระบบบันทึกข้อมูลระบุตำแหน่ง (latitude, longitude) และเวลาทีถ่ายภาพไว้ด้วย เพื่อประโยชน์ในการอ้างอิงเมื่อต้องการกลับมาถ่ายภาพครั้งต่อ ๆ ไป นอกจากนี้เรายังสามารถเอาไปทำงานร่วมกับระบบแผนที่ได้อีกด้วย

อุปกรณ์

1. Raspberry Pi B+
2. Neo-6m-0-001 U-blox GPS Module





3. ระบบปฏิบัติการ คือ Raspbian Wheezy kernel 3.18 Released 2015-05-05  ที่ใช้รุ่นนี้เพราะ Raspberry Pi  ที่ใช้เป็น B+ ครับ เคยทดลองกับ Jessie แล้วมีปัญหากับการใช้ Camera Module ครับ

Wiring





Raspberry PiNeo-6-M
VCCPin 1 (3.3 V)
GNDPin 6 (9, 14, 20, 25, 30, 34, 39)
TxGPIO 15 (Pin 10)
RxGPIO 14 (Pin 8)

ติดตั้ง Softwares

 1. gpsd เป็น daemon หรือ service ใช้สำหรับสื่อสารกับ GPS Module
 2. gpsd-clients เป็นตัวที่รับค่ามาจาก gpsd แล้วแสดงข้อมูลบนหน้าจอ
 3. python-gps เป็น python library ใช้สื่อสารกับ gpsd สำหรับการพัฒนาซอฟต์แวร์ของเราเอง

ติดตั้งโดยใช้คำสั่ง

$sudo apt-get install gpsd gpsd-clients python-gpsd



แก้ไข configuration file 

ในการใช้งานกับ Raspbian Wheezy เราต้องแก้ไข configuration file สองแห่งคือ

1. /boot/cmdline.txt

ข้อความเดิม

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

แก้เป็น

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait


2. /etc/inittab

ข้อความเดิม


#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

แก้เป็น

#Spawn a getty on Raspberry Pi serial line
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100


3. reboot


 ทดสอบการใช้งาน


1.  GPS Module จะสื่อสารกับ Raspberry Pi ผ่าน /dev/ttyAMA0 เราต้องกำหนด bautrate ให้กับ port ดังกล่าวก่อน แม้จะมีการแนะนำว่า GPS ส่วนใหญ่จะใช้ 4800 ก็ตาม แต่มาใช้กับสภาพแวดล้อมนี้แล้วไม่ได้ผลครับ ผมเลยใช้เป็น 9600 แทน ซึ่งก็ได้ผล

$ sudo killall gpsd
$ sudo stty -F /dev/ttyAMA0 9600


2. ทดลองดูด้วยคำสั่ง
$ cat < /dev/ttyAMA0

ควรจะได้เห็นอะไรวุ่นวายแบบในภาพ



เรียก gpsd ขึ้นมาทำงาน โดยให้รับค่าจาก port สื่อสาร /dev/ttyAMA0

$ sudo gpsd /dev/ttyAMA0 -F /var/run/gpsd.sock

$ sudo cgps -s ก็ควรจะได้เห็นอะไรที่ดูรู้เรื่องแบบในภาพ



 หมายเหตุ

1. เป็นไปได้ว่าการเรียกใช้งานอาจจะพบแต่ข้อความ Status : NO FIX และ cgps timeout   อาจมาจากสาเหตุที่ตำแหน่งนั้นอาจไม่ได้รับสัญญาณ GPS หรือการทำงานของ gpsd เอง หรือ ตัว GPS Module เองมีปัญหา ฯล ขอให้ทำซ้ำขั้นตอนการทดสอบใหม่ หรือสังเกตุดูที่ GPG Module ว่ามีไฟสีเขียวกระพริบอยู่หรือไม่




2. ข้อมูลจากผู้ขายจะบอกว่า GPS Module รุ่นนี้ใช้ 3.3 v - 5.0 v แต่จากการทดสอบพบว่า ถ้าใช้ที่ 5.0 V จะได้ผลการทำงานที่แน่นอนกว่า 3.3 v (พบอาการ GPS timeout บ่อยกว่าเยอะเลย) ดังนั้นหากเราใช้แรงดันไฟฟ้าที่ 5.0 V ก็ควรติดตั้ง Logic level convertor  คั่นระหว่าง Raspberry Pi กับ GPS Module ด้วย

การเขียนภาษา Python เพื่อรับค่าจาก GPS Module

เราได้ติดตั้ง python-gps ไปแล้วในขั้นตอนก่อนหน้านี้ โดยไปรับข้อมูลมาจาก gpsd อีกทีหนึ่ง ดังนั้นก่อนการใช้งาน python เราต้องเรียกใช้งาน gpsd ก่อนเสมอ

เนื่องจากเอกสารประกอบมีน้อยมาก ต้องหาจากตัวอย่างที่คนอื่นเขาทำไว้ แต่ก็ไม่ตรงกับความต้องการของเรา ดังนั้นเราไปดูที่ source code เลยครับ อยู่ที่ /usr/lib/python2.7/dist-packages/gps/gps.py จะได้ทราบวิธีการทำงาน ตัวอย่าง code ข้างล่างนี้สมมุติว่าเก็บไว้ในไฟล์ชื่อ gps-test.py ก็แล้วกันนะ


import gps
import time
import threading
import os

class GPS_Poller(threading.Thread):
   def __init__(self):
      threading.Thread.__init__(self)    
      global session
      # Listen on port 2947 (gpsd) of localhost
      self.session = gps.gps(host="127.0.0.1",port="2947")
      self.session.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE)
      self.stop_flag = False

   def get_speed(self):
      return self.session.fix.speed

   def get_location(self):
      return (self.session.fix.latitude,self.session.fix.longitude)

   def get_time(self):
      return self.session.utc

   def get_altitude(self):
      return self.session.fix.altitude

   def get_climb(self):
      return self.session.fix.climb

   def get_satellites(self):
      return self.session.satellites

   def run(self):
      global session
      while not self.stop_flag :
         try:
           self.session.next()
           #if you want to see how gpsd data look like uncomment 2 statements below and comment out a statement above.
           #report = self.session.next()
           #print report
         except KeyError:
           pass #nothing to do here
         except KeyboardInterrupt:
            self.session = None
            self.stop_flag = True
         except StopIteration:
            self.session = None
            print "GPSD has terminated"
            self.stop_flag = True


if __name__ == "__main__" :
   gps_th = GPS_Poller()
   try :
      gps_th.start()
      while True :
         os.system('clear') #clear screen
         print 'Location ',gps_th.get_location()
         print 'Time ',gps_th.get_time()
         print 'Altitude ',gps_th.get_altitude()
         print 'Climb ',gps_th.get_climb()
         print 'Speed (m/s) ',gps_th.get_speed()
         print 'Satellites ',gps_th.get_satellites()
         time.sleep(2)
   except (KeyboardInterrupt, SystemExit):
      gps_th.stop_flag = True
      gps_th.join() # wait for the thread to finish it's job


ทดสอบการทำงานด้วยคำสั่ง
$ python  gps-test.py

กด Ctrl-c เพื่อหยุดการ
Previous
Next Post »