[Netduino Plus 2 & 3]_在Netduino上面使用UART相機PTC06拍照
用UART拍照?
老實說先前不知道可以這麼厲害透過UART拍照…
這次來解決像便宜版adafruit VC0706稱的PTC06無法正常使用netduino helpers中的lib驅動的問題~(真是饒舌)
I. 硬體配置
首先,硬體接線很簡單,這塊相機模組有5隻接腳,分別為:
- GND
- RX
- TX
- 3.3V(事實上建議運作在5V)
- CVBS(電視訊號)
只需用到1~4的腳位
對應在Netduino上頭,有四組UART(其中COM4跟I2C共用)
以下都用COM1做解釋,COM1 RX,TX在DIGITAL 0,1上
所以模組Rx接在Netduino Tx上,Tx接在Netduino Rx上。
ok之後,請記得放一張2G以下的Micro SD卡,否則等等照片會沒地方存
II. Code解說
本人修改過來自netduino helpers的專案(http://netduinohelpers.codeplex.com/),調整AdaFruitVC0706.cs來適合PTC06使用。
修改過的專案放置在我的bitbucket上頭:
https://bitbucket.org/thkaw/netduino-ptc06
首先先解釋一下主程式的部分,在Main內,會有個初始化的程式碼如下:
Camera.Initialize(SerialPorts.COM1, AdaFruitVC0706.PortSpeed.Baud115200, AdaFruitVC0706.ImageSize.Res640x480);
需要注意的是,你的PTC06可能預設速率不會是115200,這邊可以做調整,像我預設就是38400,如果調整為115200就不會運作下面自動掃描Baud Rate的功能。
或者可以在我的專案內附上的公用程式透過USB TTL線接上電腦,修改PTC06預設的baud rate,我有測過115200是可以使用的,且讀取圖片也會快一些。
不過其實還是會跑自動掃描Baud rate的程式,如果出現下列output訊息,很有可能是你接線錯誤或者PTC06壞掉了(手邊就壞一顆):
Hello A first chance exception of type 'System.ApplicationException' occurred in NetduinoApplication1.exe AutoDetect failed @ 115200. Exception: Timeout The thread '<No Name>' (0x4) has exited with code 0 (0x0). A first chance exception of type 'System.ApplicationException' occurred in NetduinoApplication1.exe AutoDetect failed @ 57600. Exception: Timeout A first chance exception of type 'System.ApplicationException' occurred in NetduinoApplication1.exe AutoDetect failed @ 38400. Exception: Timeout A first chance exception of type 'System.ApplicationException' occurred in NetduinoApplication1.exe AutoDetect failed @ 19200. Exception: Timeout A first chance exception of type 'System.ApplicationException' occurred in NetduinoApplication1.exe AutoDetect failed @ 9600. Exception: Timeout A first chance exception of type 'System.ApplicationException' occurred in NetduinoApplication1.exe The program '[4] Micro Framework application: Managed' has exited with code 0 (0x0).
最後一個可以調解析度,建議一開始測試時,先用較低的解析度,這樣照相讀取時比較不會等待這麼久的時間。
注意一下,我在拍攝照片檔名上面沒有防呆,所以如果有拍出例如1.jpg,程式碼需要手動改2.jpg,否則會有IOException的問題
Camera.TakePicture(@"SD\1.jpg");
其他的片段就自行trace,沒有特別需要提的
我做的trace以及更改在AdaFruitVC0706.cs裏頭
在TakePicture()中
public void TakePicture(string path) { FreezeFrame(); var frameAddress = 0; var frameLength = GetFrameLength(); Debug.Print("Frame length: " + frameLength.ToString()); using (var picFile = new FileStream(path, FileMode.Create, FileAccess.Write)) { var totalBytesRead = 0; while (frameLength > 0) { var segmentLength = System.Math.Min(frameLength, _frameBuffer.Length); totalBytesRead += ReadFrameSegment(segmentLength, _frameBuffer, frameAddress); picFile.Write(_frameBuffer, 0, segmentLength); frameLength -= segmentLength; frameAddress += segmentLength; } Debug.Print("Total bytes read: " + totalBytesRead.ToString()); // TODO: IF IMAGE INCOMPLETE, INCRESED THIS DELAY Thread.Sleep(2000); picFile.Flush(); picFile.Close(); } // Thread.Sleep(200); ReadResponse(5); Thread.Sleep(200); ResumeFrame(); }
加了一些delay,原因是因為可能檔案還沒有完全寫入sd卡,程式就結束了,所以才關閉影像串流之前,先讓thread停止一下,這是因為netduino目前還不支援非同步操作的解法,可以自行拿掉這邊兩處delay或者縮短時間,若正常寫入就恭喜你~,我這裡測試是必須要加一點delay才能保證每次拍照順利成功。
否則圖片會長的像(下方灰色色塊是沒有寫入資料的部分):
而在下方的ReadFrameSegment()
我也放了Thread.Sleep
protected int ReadFrameSegment(int segmentLength, byte[] frameBuffer, int frameAddress) { RunCommand(Command.READ_FBUF, new byte[] { 0x0, 0x0A, (byte)((frameAddress >> 24) & 0xFF), (byte)((frameAddress >> 16) & 0xFF), (byte)((frameAddress >> 8) & 0xFF), (byte)(frameAddress & 0xFF), (byte)((segmentLength >> 24) & 0xFF), (byte)((segmentLength >> 16) & 0xFF), (byte)((segmentLength >> 8) & 0xFF), (byte)(segmentLength & 0xFF), (byte)((CameraDelayMilliSec >> 8) & 0xFF), (byte)(CameraDelayMilliSec & 0xFF) }, 5); var totalBytesRead = 0; while (segmentLength > 0) { if (WaitForIncomingData(GetTimeoutMilliSec(segmentLength)) == false) throw new ApplicationException("Timeout"); // TODO: NEED ADJUST, TOO SHORT WILL CAUSE Timeout EXCEPTION OR WILL TRUCATED IMAGE(WON'T READ IMAGE)! //38400 delay 30, 115200 delay around 11~14(14 better) Thread.Sleep(14); var bytesToRead = System.Math.Min(_comPort.BytesToRead, segmentLength); var bytesRead = _comPort.Read(frameBuffer, 0, bytesToRead); segmentLength -= bytesRead; totalBytesRead += bytesRead; } return totalBytesRead; }
在這裡放Sleep的原因是因為從UART讀取資料過來,可能還沒有這麼快讀取到,若不放Sleep,可能會讀取不完全…這邊的Sleep影響到讀取圖片的速度,我的建議是若為38400 Baud rate,不要低於30ms,而如果是115200,則可以到10,但有幾次沒讀取成功所以14ms會比較保險些。
如果這邊不delay,可能會出現timout的錯誤。
如果這邊設定的不理想,sd卡會寫入一張有size但是不能檢視的圖片,依照官方文件有提到
注意:完整的 JPEG 图片文件一定是以 FF D8 开始,FF D9 结束。
所以你可以用hex editor去開圖片檔,能夠檢視的圖片會符合這個條件。
有可能拍成功的output訊息會大概長這樣:(因為如果delay太短,有可能會儲存錯誤的位元到圖片中導致無法檢視圖片)
Hello Camera version: VC0703 1.00 Compression: 53 Image size: 0 Motion detection activation: False PTZ width: 640 PTZ height: 480 PTZ zoomWidth: 640 PTZ zoomHeight: 480 PTZ pan: 0 PTZ tilt: 0 Color status showMode: 0 Color control currentColor: 0 Frame length: 47688 The thread '<No Name>' (0x4) has exited with code 0 (0x0). Total bytes read: 47688 The thread '<No Name>' (0x1) has exited with code 0 (0x0). Done. Waiting for debug commands... The program '[2] Micro Framework application: Managed' has exited with code 0 (0x0).
來張成功的範例吧~
另外,若有水波紋,成因不知道是不是光線太暗…但已經排除供電的原因
推測是光線的問題,換一塊新的cam才知道…手邊的cam已經被凌遲太多次了XD
III. 補充
可以參考PTC的Document,裡面有提到要傳什麼16進位資料去操作相機,很清楚
另外工具也都在裡面了,VC0706CommTool比較不好使用,但算是我第一套找到在電腦端可以透過USB TTL線材連線CAM並且照相的程式。
使用方式提供下面兩個連結:
http://blog.csdn.net/xiaodao1986/article/details/40021959
http://www.geek-workshop.com/thread-2644-1-1.html
第二套工具是ptc test tool 1.01,這個程式比較好用,可以調整解析度跟壓縮程度還有baud rate,但記得調整完後要按下保存才算數,保存之後會把設定存在ptc06裡面,所以到netduino上記得用對應調整的baud rate做傳輸溝通喔~
來源來自:
http://download.csdn.net/detail/putal/7587349
最後附上用adafruit vc0706做在netduino上面的相關文章:
以上~
Leave a comment
很抱歉,必須登入網站才能發佈留言。