身為一個奉公守法的飆車族,
能夠知道自己真正的車速是一件很重要的事情,
而你永遠不會知道自己的儀表板的快樂程度,
所以就用GPS測定自己的車速了。
在露天上面可以找到許多UART界面的GPS模組,
上電之後,接收器就會自動連上衛星,並且透過Serial Port不斷的傳回數據,
這些數據為NMEA所制定的訊息格式,
因此直接使用TinyGPS++這個Arduino的函式庫來解讀GPS接收器所傳回來的訊息。
GPS除了可以讀回車速,也可傳回許多其他的相關資訊,
而這邊我總共抓取了車速、UTC時間、航向、HDOP(水平2D坐標精度因子) 以及所連接的衛星數量這五個參數。
為了易於判讀資訊以及減小體積,這邊只用一個四位數的七段顯示器來顯示資訊,
搭配Atmega8l上的兩個外部中斷,來調整顯示模式以及顯示亮度。
目前Atmega8l幾乎是市面上最便宜的Atmega系列晶片,甚至比有些attiny還來的便宜,
但也因為8k的flash,所以必須想盡辦法降低程式碼的體積,
因此使用了AVR-GCC直接對IO PORT存取的語法來點亮七段顯示器,
這邊把原本用來接外部振盪器的PB6,PB7也作為GPIO使用。
也為了搭配車上的12V電源,或者9V電池,所以另外規劃了一個5伏特的穩壓。
正面左邊為GPS模組,中間是共陽四位七段顯示器,
右邊兩個中斷的按鈕、2.1DC座以及開關。
背面分別為穩壓IC、Atmega8l以及GPS的陶瓷天線。
為了減小體積,Atmega8l直接焊死到板子上,
所以另外拉出了ICSP腳位方便之後修改程式碼。
顯示時間八點整,靠近七段顯示器的按鈕為中斷1(PD3,arduino pin3),調整亮度用。
另一個按鈕則為中斷0(PD2, arduino pin2),用來改變顯示模式。
Ublox neo 6m GPS module
程式碼:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <TinyGPS++.h> | |
byte displayMode=1; //(mode 1~mode 5) | |
int displayNum; | |
byte pointDigit; | |
byte brightness=205;//the lower, the more bright | |
byte numPattern[10]={ | |
B11000000,//0 | |
B11111001,//1 | |
B10100100,//2 | |
B10110000,//3 | |
B10011001,//4 | |
B10010010,//5 | |
B10000010,//6 | |
B11011000,//7 | |
B10000000,//8 | |
B10010000,//9 | |
}; | |
TinyGPSPlus gps; | |
void setup() { | |
DDRB = B11111111; | |
DDRC = B1111; | |
pinMode(2,INPUT_PULLUP); | |
pinMode(3,INPUT_PULLUP); | |
attachInterrupt(1, brightnessISR, RISING); | |
attachInterrupt(0, nextModeISR, RISING); | |
Serial.begin(9600);//GPS receiver's baud rate | |
} | |
void loop() { | |
lightUp(displayNum,pointDigit); | |
} | |
void lightUp(int num, byte point){ | |
PORTC=B0001;//LSB | |
if(point==0)PORTB=numPattern[num%10]&127; | |
else PORTB=numPattern[num%10]; | |
lightPeroid(); | |
PORTC=B0010; | |
if(point==1)PORTB=numPattern[(num/10)%10]&127; | |
else PORTB=numPattern[(num/10)%10]; | |
lightPeroid(); | |
PORTC=B0100; | |
if(point==2)PORTB=numPattern[(num/100)%10]&127; | |
else PORTB=numPattern[(num/100)%10]; | |
lightPeroid(); | |
PORTC=B1000;//MSB | |
if(point==3)PORTB=numPattern[(num/1000)%10]&127; | |
else PORTB=numPattern[(num/1000)%10]; | |
lightPeroid(); | |
} | |
void lightPeroid(){ | |
int t=1000;//digit period:1000us | |
delayMicroseconds(t-brightness*4); | |
PORTC=B0000; | |
PORTB=B11111111; | |
delayMicroseconds(brightness*4); | |
} | |
void serialEvent(){ | |
double kmhr; | |
while(Serial.available()){ | |
if(gps.encode(Serial.read())){ | |
switch(displayMode){ | |
case 1://UTC time(+8 in Taiwan) | |
displayNum=((gps.time.hour()+8)%24)*100+gps.time.minute(); | |
pointDigit=2; | |
break; | |
case 2: //speed(kilometer per hour) | |
kmhr=gps.speed.kmph(); | |
displayNum=(byte)(kmhr*10); | |
pointDigit=1; | |
break; | |
case 3: //heading course degree (0~360 degree) | |
displayNum=gps.course.deg(); | |
pointDigit=0; | |
break; | |
case 4://GPS accuracy(HDOP:0.00~99.99) | |
displayNum=gps.hdop.value(); | |
pointDigit=2; | |
break; | |
case 5://number of connected satellite(0~12) | |
displayNum=gps.satellites.value(); | |
pointDigit=0; | |
break; | |
} | |
} | |
} | |
} | |
void nextModeISR(){ | |
static unsigned long last_interrupt_time = 0; | |
unsigned long interrupt_time = millis(); | |
if (interrupt_time - last_interrupt_time > 150){ | |
displayMode++; | |
if(displayMode==6)displayMode=1; | |
} | |
last_interrupt_time = interrupt_time; | |
} | |
void brightnessISR(){ | |
static unsigned long last_interrupt_time = 0; | |
unsigned long interrupt_time = millis(); | |
if (interrupt_time - last_interrupt_time > 300) { | |
brightness-=25; | |
if(brightness<=60)brightness=205; | |
} | |
last_interrupt_time = interrupt_time; | |
} | |
compile後的大小
測試影片:
--------------------
GPS模組-----------------690
Atmega8l---------------39 共陽四位七段顯示器--50
按鈕
開關
穩壓IC7805
電容104
2.1mm DC jack
洞洞板
接線
-----------------
TinyGPS++
NMEA Reference Manual
u - blox 6 GPS Modules
Atmega8
Arduino IDE 1.0.1 and ATmega8 running at 8MHz with Optiboot
有沒有詳細製作過程?很想做做看!
回覆刪除電路圖以及程式碼都已經附上。
刪除比較麻煩的是要先利用USBASP將atmega8l燒入bootloader,
接著燒入上面的程式碼之後,依照電路圖接線接好,
就可以運作了。
而燒bootloader的作法在文章下方有連結可參考。
當然,這個作品也可以直接用Arduino UNO來作,但需要修改一點點程式碼。
若有問題歡迎盡量提出:)
如果使用Arduino UNO連接GPS不知道程式應該如何撰寫
刪除請求大大提供程式碼 只需要有經緯度就可以了!! 感謝!
我來試試
回覆刪除可以請問一下Atmega8l要怎麼燒錄嗎?要用專用燒錄器和程式編輯器嗎??還有上面我有看到兩張程式碼,一張很大張,後面那張小張的是甚麼呢?
回覆刪除利用USBAPS透過SPI燒錄,露天上可以找的到。
刪除再燒錄程式之前要先燒入bootloader,文章後有我使用的bootloader的連結。
程式碼後面的截圖只是要表示這些程式碼編譯之後的大小,
因為atmega8只有8k的flash,因此要盡量用少量的程式碼做出需要的功能。
喔~!!好的謝謝~找時間試試囉~!!有問題再麻煩你解惑囉~!!!
刪除GPS用這種可以嗎?http://goods.ruten.com.tw/item/show?21310172254121
回覆刪除只要是透過UART界面,以NMEA標準格式輸出訊息的GPS模組都可以喔!
刪除http://goods.ruten.com.tw/item/show?21308054716524
回覆刪除如果使用Arduino UNO連接GPS不知道程式應該如何撰寫
回覆刪除請求大大提供程式碼 只需要有經緯度就可以了!! 感謝!
想請問一下
回覆刪除如果透過ISP用Progisp進行燒錄
這樣還需要燒錄bootloader嗎?
我並沒有使用Progisp的經驗,
刪除但以Arduino語言為基礎,我想bootloader是需要的。
參考 http://diveduino.blogspot.tw/2012/11/usbasp-progisp-arduino.html
不好意思,再請問一下
回覆刪除影片中u-blox的模組在動作時亮紅燈
是因為有用整體電路(加上ATMEGA8的程式)
完成後啟動才亮嗎?
因為自己用電腦跑u-center連接測試時GPS模組並沒有亮燈
所以有點擔心是不是模組不小心弄壞了
在我印象中影片內的紅燈應該是GPS模組的電源,
刪除(因為在某次的測試時被我摔壞了,所以沒辦法再確認一次)
即使所使用的晶片是同一個,每個下游廠商Lay出來的PCB電路也都不盡相同,
因此每個元件的用處還是要回去找Datasheet才準確。
想問一下,如果沒有接上GPS時,以IC接上七段顯示器,這樣七段顯示器會有動作嗎(想以這樣確認程式是否有燒完整)
回覆刪除會的,依照程式的邏輯會顯示「0000.」
回覆刪除不好意思,在請問一下,新的GPS買來後有需要另外燒程式,還是能直接使用呢?
回覆刪除只要上電就會以預設模式輸出GPS的訊息喔。
刪除請問tiny GPS函式庫的用意,只是讓他在Arduino IDE中能成功編譯程式嗎?
回覆刪除透過另外一種方法燒錄程式,是有成功顯示"0000.",但按鈕按下去後並無反應
且行進間也不會有任何變化,還是維持"0000."
請問如影片的gps 測速器願意割愛嗎
回覆刪除抱歉,該測速器在某次使用時不慎飛出摔落,並且徹底損壞。
刪除若您有需求,可以自己依照上述步驟製作一個,或者再來信詢問,感謝!
太酷了,有沒有開班授課的打算~~~有的話,通知一下,我想報名。
回覆刪除想請問大大有在販賣嗎?
回覆刪除最近把他改成能在uno上運行,用byte強制轉型之後會有overflow的問題
回覆刪除不同變數需要依照不同場合之需求來宣告型態,
刪除此處為使用成本低廉的ATMEGA8,因此程式碼盡可能精簡。
若需要移植到ARDUINO UNO上,稍作修改應該就能正常運行。
作者已經移除這則留言。
回覆刪除請問一下 您的七段顯示器是用哪一種的呀?
回覆刪除此處七段顯示器為電子材料行選購而來,僅知此為共陽四位七段顯示器,並不清楚詳細型號。
刪除但七段顯示器操作方法大同小異,惟須注意若需要使用高亮度的顯示器,此例使用Microcontroller直接輸出的方式可能會有電流不足之情形,需要加掛Buffer電路以供給足夠電流,並且避免控制器損壞。
請問最後需要接石英振盪器嗎?? 因為PB6、PB7要接七段
回覆刪除此例並無外掛石英震盪器,ATMEG8若無外接外部震盪器,則可以內部獨立震盪器運行。
刪除此時PB6、PB7即可當成GPIO使用。
請問一下 上方的程式碼 中文也是包含在程式碼裡面的東西嗎
回覆刪除大大您好,我最近也買Ublox neo 6m GPS來玩,但是我的模組一直收不到衛星訊號(模組上有LED指示燈都不會亮),就單純使用範例程式也是如此,請問您有遇到同樣的狀況嗎?我在懷疑是不是板子玩壞了。
回覆刪除我的測試環境有室內室外
感謝您
刪除你好,最近照著線路圖做了成品出來,不過上電後,GPS接收燈號正常,但七段顯示器顯示8888,中斷1亮度調整感覺有作用,但不明顯。中斷2不知有無作用。請問是那個部份的問題比較大。IC透過UNO燒錄BOOTLOADER,再上傳BLINK測試OK。ARDUINO IDE 版本是1.87
回覆刪除請教大大,如果我想偵測測速照相機,我該追加什麼模組,又該怎麼讓它抓圖資呢?謝謝。
回覆刪除