[Netduino Plus 2 & 3]_在Netduino上面使用UART相機PTC06拍照

用UART拍照?

老實說先前不知道可以這麼厲害透過UART拍照…

 

這次來解決像便宜版adafruit VC0706稱的PTC06無法正常使用netduino helpers中的lib驅動的問題~(真是饒舌)

 

WP_20150613_003

WP_20150613_004

WP_20150613_005

I. 硬體配置

首先,硬體接線很簡單,這塊相機模組有5隻接腳,分別為:

  1. GND
  2. RX
  3. TX
  4. 3.3V(事實上建議運作在5V)
  5. 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才能保證每次拍照順利成功。

 

否則圖片會長的像(下方灰色色塊是沒有寫入資料的部分):

test59

 

而在下方的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).

 

 

來張成功的範例吧~

10

 

另外,若有水波紋,成因不知道是不是光線太暗…但已經排除供電的原因

推測是光線的問題,換一塊新的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上面的相關文章:

https://fabienroyer.wordpress.com/2011/08/12/driving-an-adafruit-vc0706-ttl-serial-jpeg-camera-with-a-netduino/

 

以上~

 

Leave a comment

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料