2017年9月23日 星期六

公司窗外的樹





公司是棟六層樓玻璃帷幕建物,上班日進進出出,不同樓層間上上下下時,不經意都會看到厚片玻璃外有棵美麗的樹。一般來說,我只認為高海拔樹種才是樹(很荒謬的自我催眠)。這種公園中受人悉心照料只是裝飾品。但天天見面,久了有種特別感情。

從三樓看出去,已經是由許多簇枝葉組成的樹冠層,稠密的葉子層層疊疊,陽光照耀下,輕風吹過,葉片翻舞,顏色深淺不一的光反射出不同感受,我總是在盛夏午後,外面熱浪翻騰,樓梯間內是舒適冷氣狀況下,看著這片亮晃晃的光,感受這荒謬世界。

二樓可以看見常綠闊葉樹特有的枝幹,黑夜裏看不清樹葉的形狀,只見崢嶸陰影。一樓外頭是樹冠下的天地,常常會見到白鷺鷥或黑冠麻鷺覓食,但從未見過松鼠行蹤。若參加攀樹活動,藉著繩索拉上滑下,才能看到的風景,就是我每天樓梯外景緻。我也常想像,這樹上某隻松鼠,攀上爬下時,看著玻璃帷幕建物內的我,每日花費大量時間坐在辦公桌和電腦前,那種荒謬的感覺。

四樓、五樓、六樓則是遠離自然,比較偏向登高風景。以前我喜歡高樓層外風景,最近開始會留意這棵樹,也算是某種改變吧。

2017年9月19日 星期二

技術筆記:電路板設計

第一張手繪電路圖 (臨摹自喵喵老師)

這是玩具計劃延伸而來(連結)。印象中電子電路是讀電控或是儀表系才會的東西。對我這讀純軟的人來說,好像天書一般,直到最近玩具計劃進入新階段,不得不研究。下面是些筆記。真有興趣的人可參考kitsprout經驗連結,會有更完整介紹。

PCB LAYOUT

電路設計和LAYOUT是兩回事,電路設計有其學理(有本參考書),但若僅是MAKER,僅將些常用零件組合起來,LAYOUT這部分算是相對簡單。

初入門以EAGLE為主,參考下面書籍,內容淺顯易學值得推薦。當然也可以參考文章1文章2 ,或是kitsprout使用的ALTIUM DESIGNER。

我的第一本電路書

安裝EAGLE後,得先解決中文版問題,到C:\EAGLE 8.3.2 把eagle_zh.qm 移走就可以換成英文版。

file->new->project  給定名子RCfilter (位置在 C:\Users\USER\Documents\eagle\RCfilter)
Lite 板限定Layout面積為 (80x100mm),只支援 最多兩層 (Top and Bottom)
大致上的操作都是,打開或是點選RCfilter右鍵。依照下面三個順序說明。Schematic Editor (類似Pspice)。Layout Editor(真正電路板)。轉出GERBER或是轉入GERBER。

EAGLE 製作schematic


點選RCfilter 打開 右鍵 new->schematic->進入另外的視窗系統
存檔時 可能用同樣名稱 例如 RCfilter.sch

Options->User interface->icon size 24
點左上方的GRID->兩個規格都改成mm
zoom to fit (Alt+F2)或使用放大鏡圖示來調整大小

加入元件
左邊TOOLBAR右邊第二排有個+的元件符號 點下之後會跳出搜尋視窗
搜尋時可善加利用萬用字元*:例如“*555*”可找到所有名稱中有555的元件)
如果已經知道元件名稱,可以直接打入,或是用瀏覽方式
對各元件介紹,如最後

滾動滑鼠的滾輪可以放大/縮小  按滑鼠右鍵可以旋轉
連續點 就是重覆放入
放好後按Esc會跳回元件選擇視窗,可以繼續選擇Add其他元件

移動元件
左邊TOOLBAR右邊第二排第三個Move元件 點元件後可以移動
按住ALT移動會更細密  不然會一格一格跳。群組移動要先用Group把多個元件圈起來–>選擇Move–>按Ctrl和滑鼠右鍵,移動之後按滑鼠左鍵把元件放下。

畫線
左邊TOOLBAR左邊最下面LINE 若碰到元件可以連結。畫線的時候按右鍵可以選擇不同的走線方式,按一下左鍵設定停駐點用來轉折,結束時連按兩下左鍵成為結束端點。兩條線的交會處可以放上Junction標註一下。畫線的時候,要注意連結不同元件時,碰到就好了。

設定資料
1.使用Value來設定電阻值(10k)和電容值(1uF)
2.使用Name來修改連接器的名稱,分別叫做IN和OUT。

擴充元件
若有找不到的零件,就可以瞭解如何製作擴充元件,這也是比較大型專案的需求。switch-tact
DTSM-6 還有 esp8266modules  ESP12E-SMD  ESP12ESMD (ESP12E)。如何建立擴充元件有兩個方法。
1.自行新建,較複雜,書本第十一章有提到。
2.重覆使用他人lbr檔案,較簡單,拷貝別人資料到 C:\EAGLE 8.3.2\lbr\ 下,打開PANEL,左方的Libraries選單中就會看到放入的LIB。打開,選擇一個元件後,ADD就可以進入電路圖,可是這樣不夠,因為還無法搜尋。進階作法是,拷貝到C:\EAGLE 8.3.2\lbr\ltspice 在PANEL中,找到那個lbr,選擇USE就會進入未來能search的範圍。

電路設計最後步驟是檢查合理性,選擇TOOL->ERC會列出錯誤處。

整個流程如書本P73有很好的說明,先簡單手畫設計圖,新增全部元件,標示名稱和數值,簡單放置在可能地方,啟動ERC。

EAGLE 製作PCB


按下TOOLBAR上面 Generate to board按鈕,會自動產生新的電路板檔案。如果上面電路圖重排,再按一次,下面電路板同樣也會變動。預設是兩層板 Layer 1和16 (免費版本至多是兩層),電路和PCB是兩個不同的APP,兩者間有連動關係。紅線是頂,藍線是底部,綠色是墊片,白色是網版。

用AUTO做出的板子 不過不能用

按Grid圖示將單位調整成mm

用group move把這些元件都移到框框裡面,group move的方式就和schematic一樣,"group",圈選,"move", “Ctrl+滑鼠右鍵",開始移動,"滑鼠左鍵"放下。

Mirror
可把元件放到背面去。

文字資訊
要單獨移動元件的Value的話要按"Smash",然後點在元件的+符號上,這樣他的Name和Value就會和元件分開來,可以單獨移動了。

RATSNEST
讓 EAGLE 重新計算 airwires(尚未真正繞線的線)最適距離。可做DRC check修正各元件至合適距離

Route
有一些地方需要用 ROUTE 這個工具點選未繞線(黃色)的端點, 然後可手工進行繞線,繞線時可選擇寬度、種類等選項。
還沒有真正連線之前應該連線的點會有黃色細線相連,連起來之後他就會消失,這樣可以協助我們認出還有哪些線還沒有畫好。
按Route圖示來接線。
接線的方式是先點選起點,選擇圖層(Select layer),看是要走Top還是Bottom,同時設定線寬(Width),途中按下滑鼠左鍵設定停駐點,按下滑鼠右鍵改變走線方式,換圖層會自動產生灌孔(Via)。
所以灌孔是自動生成的,不是透過ICON加上的。另外上下層線路的顏色不同。

autorouter
自動計算出線路,對話窗,預設參數會產生出 double sided board( 如果希望產生 single-sided board。先設定 preferred direction 中TOP layer 至 NA (Not Applicable.) )。會有幾種方案可選擇。並且顯示最適合項目(未必能完成所有繞線)。很像是水彩教學,很有趣也很舒壓。

鋪銅
線都接好之後,接著要鋪銅,所謂的鋪銅就是把空白的地方用銅鋪滿,可以減少電阻,隔絕干擾。鋪銅是一塊大範圍銅箔,通常是power或ground。在多層板中通常會用一整層做出這樣一個 plane。

單層板鋪銅則有一些優勢:
1) 蝕刻液消耗較少
2) 降低接地電阻(因為 R=ρl/A) l 代表長度, A 代表截面積。若接地的銅片愈大,就可以降低接地電阻,因為作法複雜,短期內不會使用。

按"Polygon"圖示,選擇圖層為"Top",按滑鼠左鍵在整個板材外圍繞一圈(至少不要小於板材),表示要鋪滿整個板材。剛圍好之後會是一圈虛線。接著要決定鋪銅的接點名稱。看一下剛剛連接的那些線都有名子,例如"N$1〃,或是可以用"Name"來設定那些線的名稱,例如"net1〃,"VDD","GND"之類的。我們同樣可以用"Name"來點一下鋪銅虛線,設定鋪銅的名稱,這樣等一下他會將整個鋪銅和同名子的線接起來。在PCB這邊修改/設定接線的名稱會同步改變schematic那邊的名稱。
按一下"Ratsnest"圖示,他就會幫忙把整個圖層鋪滿。
polygon指令。做法是在text command area。例如要產生 polygon 對應到 signal named ‘gnd’,輸入 “poly gnd “ polygon會自動連結到該訊號。然後可拉出一個長方型自動鋪銅(按下RATNEST可檢視成果)

電源
PCB板須有地方讓POWER輸入。
加入Vias:在Text Command 中輸入“via ‘gnd’” (注意訊號需要括號,和鋪銅時不同!) 可以調整drill size 和 via shape然後將其擺至適當地方。

EAGLE 產生GERBER


點選RCfilter 打開 右鍵
在這下面產生一個目錄 GBR(  可以產生GBR檔案 )

第一組 使用CAM

必須要先下載範例CAM,下載點。在PCB Layout上方點選"CAM Processor"圖示,打開File–>Open–>Job…選擇 PCB–>cam裡面找到custom_gerber.cam檔案 ( 設定已經完成 )
確認所有輸出圖層的File都是輸出到%P\GBR\%N.***,這個GBR就是我們一開始產生的那個檔案夾。

直接按"Process Job"。然後應該可以在GBR檔案夾裡面看到8個產生的檔案。


第二組 鑽孔檔案

繼續在CAM Processor中,打開File–>Open–>Job…選擇安裝路徑下的cam檔案夾中的excellon.cam,修改File輸出到%P\GBR\%N.drd,按下"Process Job",GBR中會多出兩個檔案,".drd"和".dri"。

在PCB layout視窗點選File–>"Run ULP",或直接點選按鈕,在安裝路徑下找ulp–>drillcfg.ulp。開啟之後選擇單位。 eagle_drl按OK,再按OK。選擇輸出到GBR檔案夾中。總共有三個,這樣總共就有11個檔案在GBR檔案夾中。


第三組 BOM

需要的元件列表可以在schematic那邊選擇File–>Export–>BOM來產生。可以輸出成文字檔,CSV或是HTML格式,然後列印出來到電子材料行選購。

這裡還有些未完成項目

看輸出圖層檔案的軟體gerbv.exe,檢視輸出圖檔有沒有錯誤或是輸出成影像檔用來製作板子,或是製作錫膏圖層自己上件。生成GERBER檔案,連結。然後就可以把整個GBR打包起來送給板廠製作PCB了。

另外一個方向是從GERBER IMPORT成EAGLE專用檔案 說明如連結

實作

坐而言不如起而行,尤其是PCB這種操作型的事物,網路課程連結

1 MicroPython on ESP8266。這是喵喵老師在高雄的範例,喵喵老師CHRIS,由linray轉記兩篇詳細筆記。 安裝系統  APP應用  目前會以實做此PCB為主,在PCB出現前,先放上linray照片和EAGLE檔案互相參考。

ESP8266可能型式

2 簡單電路,連結。優點是沒有MCU和SMT。容易驗證。

JLCPCB

JLCPCB:中國一調龍式公司(連結),前幾年廣告打很大,這兩年比較沉寂。連結 連結 連結對應的製作工具是EASYEDA(連結)。
如果以ATMEGA328P-PU PDIP-28為範例,參考資料
  • 中文介紹  連結 連結
  • 可能製作過程 連結 連結   連結1 連結2 連結3 連結4
  • 其他

    目前PCB沒有防呆很容易靜電打壞,花了些功夫把板子隔離開 
    某種PCB製作方式 化學溶液
    打件SMD和焊接:手工焊接是OK但手不巧,太忙只能找EMILY幫忙 

    電路板:中國PCB生產介紹(連結) 

    WAVE  連結

    2017年9月15日 星期五

    技術筆記Dither

    拍攝自當代館展場 很有Dither的感覺

    這是玩具計劃延伸來與演算法有關筆記,原始連結

    Dither及做法


    This printer is not capable of printing anything but black or white pixels. The best way to give the illusion of grayscale is to “dither”. In image processing, dithering is a method of giving something the appearance of grayscale by alternating black and white.

    Dither
    熱感應噴頭,因為每個點只有1與0兩種選擇,沒有灰階的概念。直覺上就是用比較密的點表示黑,而比較稀鬆的點就是淺。(同樣技術可套用在EINK上)。要如何表示呢,這時讀過書就有用啦,誤差擴散演算法,能以學理的角度,看待和解決這個問題。

    學理上來說,透過這個方式,可以降低圖像色彩的深度,顧名思義, 誤差擴散, 就是將色彩深度降低時, 將像素顏色的變化誤差, 擴散開去. 這使得肉眼在觀察圖片的時候, 相鄰的像素點集合整體 的誤差變小。

    先以較多級度來當範例。256級灰度圖象上有一個點,灰度值是 120 (0~255),如果我們要將這張圖轉換成 16 級灰度,最簡單的方法是將每個像素點除以最簡單的方法是將每個像素點除以 16。那麼轉換后的值就是那麼轉換后的值就是 120/16=7.5。如果我們採取直接捨去,保留整數位后就是 7,誤差值0.5跑去哪裡了呢?

    最簡單的誤差擴散方法是將這 0.5 的誤差放到這個點右邊/下邊的點上,我們可以按 3:2:3 的比例把它分配到右邊, 右下, 下邊的點上。即我們把右邊和下邊的點加上 (0.5*16)*3/8=3,把右下的點加上 (0.5*16)*2/8=2. 這樣處理完整個圖形,要比直接截尾的效果要好的多。實際上, 3:2:3 的誤差分配方案 並不算好。還可以試不同分法例如7:3:5:1

      X 7
    3 5 1

    更或者 42 分:

        X 8 4
    2 4 8 4 2
    1 2 4 2 1

    如果每個點只有0或是1兩階怎麼辦呢?ch00ftech的範例認為小於128(256/2)的變成0,大於128的變成1,被捨棄的就依照模式分出去,有欠的,也依照同樣方式扣回來。(不論哪種方式,到邊界後都會忽略)

    範例如下

                 86     90    97
         82    90    102  117
         95    106  122  137

                 0      126    97
         97    116  107  117
         95    106  122  137


                 0      0      152
         97    131  146  125
         95    106  122  137

                 0      0      255
         97    131  127   93
         95    106  122  137

    參考1
    參考2

    其他技巧


    原始影像,處理時,是每8X8進行處理。原因是原本專案使用F107,記憶體較小,且配合JPEG decoder,所以影像切割成8×8 pixel blocks進行處理。程式較複雜,邊界部分也有些誤差。在F429上應該都很容易解決。

      每個點的顏色經過GRAYSCALE變成256階的灰階R*210+G*720+B*70
      (因為整數系統,所以都放大成INT)
      The first step to getting a full color image through a black and white printer is to convert it to grayscale.
      每個PIXEL包含RGB顏色 標準方式是
        ditheredImage[i][j] = *(pSrcR++)*210 + *(pSrcG++)*720 + *(pSrcB++)*70;


      如果這個點,位置在邊界,要從上次的結果中,取得數值加回來
      然後對這64個點中各個項目進行dithering
         如果小於80000就是0,不然就是255000
         然後把多餘的數值,向右、右下、下、左下進行加總
      這就是上面的Dither動作

      最後將目前結果存入整體暫存區
          bmpBlock[(colcount/40)][319-by-((colcount%40)*8)]|=(1<<(7-bx));
      數字有點奇怪,必須要用張圖解釋



    rescale
    dest[dx,dy] = src[dx*src_width/dest_width,dy*src_height/dest_height]
    初次實驗是  240(30) : 320  配合列印頭最大數據是 384(48) : 512
    除了影像調整外,送到印表機時,因為那需要批次處理,也跟著做了改變

    右邊是原始大小,中間和左邊已經放大

    GAMMA亮度調整

    Convolution
    簡易又有效,連結位置

    2017年9月14日 星期四

    技術筆記各種螢幕


    LCD設備

    • 4" otm8009  800X480:F429。特別提到 FSMC 專門控制LCD?? 流程
      • R61581_Config(); 設定FSMC 和GPIO所有PIN腳 和R61581_BLigConfig
      • R61581_Init();
      • LCD_WriteCmd(0xD0);
      • LCD_WriteData(0x07); 都是這種型式,將指令寫入LCD
      • ( 檔案還包括了畫各種樣式 例如 LCD_DrawLineY )
    • 3.5" R61581:F407
    • ILI9341 STM32開發板內建螢幕:240 x 320 pixels resolution and 16bit or 18bit color depth, what gives you 65536 or 262144 different colors. 因為有開發板那篇,就不拍畫面了。
    • 20*4, 有點像小型跑馬燈範例,實體不知道在哪,但確定3D列印上面很多。


    • 還有個不知道做什麼的
    上面還附著SD卡


    • 樹梅有個專屬螢幕,以及ARDUINO的SHIELD

    LCD使用方式

    1. SPI 一般做法  範例 (可以顯示出方型 圓形 和文字 因為用了font lib )
    2. SPI DMA 架構在SPI上面更進一步
    3. LTDC 高階 範例 you can actually display movies, because it uses parallel communication and support 2 layers simultaneously what gives you a high refresh rate. 範例 過程有點複雜 重新開了一個專案, 內包括sdram/dma/2d等 提供結果是畫面快速閃動

    OLED使用方式

    1. 手邊有個小OLED SSD1306_128X64_NONAME_F_HW_I2C,百年有賣(連結連結)。
      Part No: 119671   Product No: 0.96寸-OLED-IIC-白色。

    EINK

    EINK測試元件

    EINK特性是節電不傷眼,缺點是單色(或說彩度很低),呈現方式與熱感應印表機相似,可以提供很棒的應用。
    從MCUAPPS購買了一組2.7的Repaper 2.7"實驗。其通訊方式是SPI,程式上可以參考這裡。當腳位對應好,啟動EPD_INIT。
    後面的對應指令EPD_POWERON EPD_POWEROFF EPD_DRAW。繼續將兩張已經事先產生好的圖片BYTE ARRAY放入,aphrodite_1_44.c venus_1_44.c
    因為購買的是2.7所以回到原廠的範例位置。找_2_7.xbm,替換使用。

    技術筆記CAMERA

    印表玩具
       STM32技術

    一般EMBEDDED SYSTEM和CAMERA溝通方式為SPI,缺點是速度太慢。STM32F4之後,提供DCMI加速機制,讀取影像更方便,F7之後,還號稱能同時處理兩個以上CAMERA影像,如果我想用兩顆鏡頭抓空間深度,這會有很幫助。

    網路上搭配STM32開發板的,幾乎都是使用OV。OV有眾多型號,我購買的OV7670只有三十萬畫素,價格僅二百左右,首次Tabbao買的不能用,後來向taiwaniot購買。缺晶振,但由外部XCLK提供也還堪用。

    好歹在相機組裝廠工作過。先來研究一下OV。OV美商OmniVision豪威(台灣有分公司,曾是感光元件巨頭),而OV7670不是想像中僅有sensor,已包含完整影像系統。也就是說,可直接取出經過3A的JPEG、RAW(雖然畫質很糟)。目前使用上就是以RAW為主。


    比較貴的模組,會附上FIFO,就是下圖中那顆CHIP。不帶FIFO的攝像頭和帶FIFO攝像頭的區別:帶FIFO的攝像頭比不帶的多了個3M的緩存,可將採集的數據暫存在這個緩存中,使用時讀取緩存中的圖像數據即可,因此可減少對單片機採集圖像數據時對MCU速度的要求。OV7670 FIFO攝像頭,將圖像傳感器和圖像緩衝器件AL422B有機結合,解決了低端單片機圖像採集的速度瓶頸問題。搭配STM32用不到。另外,圖中還多了個晶振。若無,由STM32從外部XCLK提供也還堪用。


    從影像模組來看其他專案,例如PrintSnap用的是很簡易配Arduino使用的JPEG模組,使用TTL溝通,取回的內容是JPEG要另行Decode,不實用。

    手上的OpenMV也有幾種版本差異

    Raspberry Pi使用特殊的CSI(Camera Serial Interface)也有兩種相機
    V1 OV5647 5百萬像素固定焦點 支持1080p、720p60和VGA90
    V2 Sony IMX219PQ CMOS 八百萬像素固定焦點 支持1080p、720p60和VGA90

    另外,小體積的FPV鏡頭也很。

    回到STM32對OV取得影像部分,目前使用指令並不多,只有寬高、拍攝、取得畫面。依架構可分成三種。

    一堆杜邦線亂纏繞,眼睛都快脫窗( 原本有牛角母啦, 麻煩 ),看到它起動時高興的不得了,覺得前進一大步.

    方式一,DCMI資料進入一般記憶體,處理後再送LCD


    架構簡單也是後續開發基礎。主要參考位置是 範例, 文件 底部有使用的CODE範例,程式流程

    STM_mode = 0;
    btn_pressed = false;
    frame_flag = false;
    // Infinite program loop
    while(1){
    if (btn_pressed == true){
    if (STM_mode == 0){
    // MODE 1 - RUN
    STM_mode = 1;
    開攝影鏡頭
    }
    else{
    if(frame_flag == false){
    // MODE 2 - STOP
    STM_mode = 0;
    停止攝影鏡頭
    }
    }
    btn_pressed = false;
    }
    if( frame_flag == true){
    // Show camera image
    通知LCD顯示畫面
    frame_flag = false;
    畫面沒有更新,不需要再重覆顯示
    }
    }

    當相機收到訊號後,就會送DMA完成的訊號
    void DMA2_Stream1_IRQHandler(void){
    // DMA complete
    if(DMA_GetITStatus(DMA2_Stream1,DMA_IT_TCIF1) != RESET){
    DMA_ClearITPendingBit(DMA2_Stream1,DMA_IT_TCIF1);
    DMA_Cmd(DMA2_Stream1, ENABLE);
    frame_flag = true;
    也就是說 相機會一直送訊號進來,畫面更新的快 就會漏掉一些畫面
    但是如果相機更新比較慢,畫面會等相機
    }
    }

    按下按鈕
    命令取得影像 DCMI_CaptureCmd(ENABLE);
    系統由CAMERA取得影像後觸發 DMA2_Stream1_IRQHandler
      影像會進volatile uint16_t frame_buffer[IMG_ROWS*IMG_COLUMNS];
      因為設定過
      DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)frame_buffer;
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
      DMA_InitStructure.DMA_BufferSize = IMG_ROWS*IMG_COLUMNS*2/4;

    畫出影像LCD_ILI9341_DisplayImage((uint16_t*) frame_buffer);  ( 這和CAMERA無關,只式記錄 )
    void LCD_ILI9341_DisplayImage(uint16_t image[ILI9341_PIXEL]) {
      uint32_t n, i, j;
      LCD_ILI9341_SetCursorPosition(0, 0, ILI9341_Opts.width - 1, ILI9341_Opts.height - 1);
      LCD_ILI9341_SendCommand(ILI9341_GRAM);
      ILI9341_WRX_SET;
      ILI9341_CS_RESET;
      for (n = 0; n < ILI9341_PIXEL; n++) {
        i = image[n] >> 8;
        j = image[n] & 0xFF;
        LCD_SPI_Send(ILI9341_SPI, i);
        LCD_SPI_Send(ILI9341_SPI, j);
      }
      ILI9341_CS_SET;
    }

    OV7670_control.h 最重要參數是
    // Image settings
    #define IMG_ROWS   320
    #define IMG_COLUMNS   240
    決定了影像大小

    方式二,CAMERA內容透過DMA直接映射到LCD記憶體區域

    這種狀況下,DMA更新LCD畫面也立刻更新( CPU不介入 ),好寫也單純,但不能處理影像,不考慮使用。 OV7725:KitSprout  CMOS VGA 640X480  範例

    流程( KitSprout 407 )
      GPIO設定
      RCC_MCO1Config
        啟動 OV7725_Config()
             RCC
             GPIO PIN腳對應
             DCMI_Init
             NVIC_Init
             DMA_Init
                 #define DCMI_DR_ADDRESS        0x50050028
                 #define FSMC_LCD_ADDRESS       0x60020000
                 DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;
                 DMA_InitStructure.DMA_Memory0BaseAddr  = FSMC_LCD_ADDRESS;
                 這裡把CAMERA的內容和LCD連結起來
                 在LCD #define LCD_RAM *(vu16*)((u32)0x60020000)

      OV7725_Init();
    透過OV_WriteReg SCCB_Write 寫入很多REG設定 OV_reg (在H檔案中)
    Camera_Start
      LCD_SetWindow(0, 0, 320 - 1, 240 - 1);
      DMA_Cmd(DMA2_Stream1, ENABLE);
      DCMI_Cmd(ENABLE);
      DCMI_CaptureCmd(ENABLE);

    因為是使用DCMI 每當DCMI收到結果就會發送callback
    void DCMI_IRQHandler( void )
    {
      if(DCMI_GetITStatus(DCMI_IT_FRAME)!= RESET) {
        LCD_SetWindow(0, 0, 320 - 1, 240 - 1);
        DCMI_ClearITPendingBit(DCMI_IT_FRAME);
        將DMA結果對應到LCD記憶體,刷新畫面
      }
    }
    Handler是固定寫法,放在xxx_it中

    方式三,CAMERA內容透過DMA直接映射到 SD RAM記憶體(不是RAM)


    和方式一類似,差別在記憶體使用上,方式一是原生記憶體,方式二是SD RAM。

    PIN對應和範例相同
    SDRAM_Init
    影像和處理和顯示特殊處理方式
    在DCMI回覆時
        LCD_SetWindow(FRAME_W, FRAME_H, FRAME_W + FRAME_W - 1, FRAME_H + FRAME_W - 1);
        for(uint32_t i = 0; i < FRAME_W * FRAME_H; i++) {
          pixel = SDRAM_DATA(uint16_t, (i << 1));
          LCD_RAM = pixel & (~(RED | GREEN)); //將SDRAM每個元素顏色計算,寫回LCD_RAM
        }
    //讀出影像
    OV的資料對應到DMA 不是LCD
      DMA_InitStruct.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;
      DMA_InitStruct.DMA_Memory0BaseAddr    = (uint32_t)SDRAM_BANK_ADDR;//SDRAM_BANK_ADDR;//FSMC_LCD_ADDRESS;
      DMA_InitStruct.DMA_DIR                = DMA_DIR_PeripheralToMemory;
      DMA_InitStruct.DMA_BufferSize         = FRAME_W * FRAME_H >> 1;
    #define SDRAM_BANK_ADDR               ((uint32_t)0xD0000000)
    #define SDRAM_DATA(__TYPE, __INDEX)   *(__IO __TYPE *)(SDRAM_BANK_ADDR + (__INDEX))
    因為OV市直接設定到SDRAM_BANK_ADDR,只要使用SDRAM_DATA就可以讀出畫面結果
    //寫螢幕
    #define LCD_RAM     *(__IO uint16_t *)((uint32_t)0x60020000)
    用這個就可以將資料逐漸寫入
    #define FSMC_LCD_ADDRESS  0x60020000
    DMA_InitStruct.DMA_Memory0BaseAddr    = 0x60020000;

    特殊點
    1.429有加入晶振功能,但407無?
    2.加SDRAM但HEAP沒改變? (比對XXX.s)
    3.影像大小設定
    #ifdef RESOLUTION_VGA
    #define FRAME_W 640
    #define FRAME_H 480
    #else
    #define FRAME_W 320
    #define FRAME_H 240
    #endif
    DMA_InitStruct.DMA_BufferSize = FRAME_W * FRAME_H >> 1;
    static const uint8_t OV_reg[OV_REG_NUM][2] = {
    #ifdef RESOLUTION_VGA
      {0x12,0x06},// VGA RGB565, 640*480
    #else
      {0x12,0x46},// QVGA RGB565, 320*240
    #endif
    #ifdef RESOLUTION_VGA
      {0x29,0xA0},  // VGA
      {0x2C,0xF0},  // VGA
    #else
      {0x29,0x50},  // QVGA
      {0x2C,0x78},  // QVGA
    #endif

    可能的範例如下 範例  範例  範例  範例 範例

    DCMI串接多台Camera


    若要計算立體視覺,需要綜合多台Camera所傳入影像,DCMI可以處理兩組影像嗎?目前查到的資料如下

    文字描述 STM32F7 DCMI
    The cameras additionally need to be set up through the I2C bus before the images can be transfered via DCMI. An example of two camera setups is available in the Board Support Package driver files.
    Other camera types need different setup that users have to extract from their documentation.

    有發出詢問,等待回應。

    技術筆記熱感應印表機



    印表玩具
       STM32技術

    熱感應印表機(thermal printer),已經大量使用於日常生活,舉凡購物時的發票,醫院排隊掛號號碼條或是手搖杯上的標籤貼紙,都是它的應用。使用一種化學原料塗抹在紙上,使得紙張可因受熱而改變顏色,不需要使用墨水或油墨。塗抹固態的染劑與合適的基質,像是熒烷類的隱色染料以及磷酸正十八酯。當基質加熱到其溶點時,染劑會與酸性物質反應,轉換成有色態;而基質很容易快速冷卻,則染劑的有色態會直接被儲存於亞穩定狀態。但一段時間後,顏色仍會逐漸消退,故僅適用於不需長期儲存的用途。

    通常,該塗料在加熱時會轉為黑色,但有時會使用轉為藍色或紅色的塗料。開放的熱源,像是火焰,會改變紙張的顏色;而用指甲快速擦過紙張也可以給予足夠的熱能,產生有顏色的標記。另外就是Multicolored papers,最著名的就是寶麗來的ZINK,很美好,但也很貴。


    最上面照片是我手邊熱感應印表模組和開發板合體的樣子,相關介紹連結 連結購買連結。實際拿到機器比想像的大且重,感覺可以整個拆開移調不需要元件。紙寬是5.7 cm(Paper width: 57mm Print width: 48mm)。一般熱感應紙太大捲,放不進盒子裡,得手動剪掉部分讓它瘦身才塞得進(在販售模組時也有搭配的客製化紙捲是10m)。

    因為需要加熱,裝置對電源的要求也高,需要5-9V。實驗時,可以透過5V/2A電源供應器供電,移動時因為目前USB電池可提供5V,可透過轉接頭使用。一般遙控玩具鋰電池也可使用。

    結構上,著色原理和加熱頭的關聯很大,加熱頭寬度為八個BIT,所以程式中一直會看到8BIT出現。bmpBlock[30][320] 大概的意思則是,紙張寬的這面可以印30組,每組8個點,共240點。長則為320個點。實際上,Resolution ration: 8dots/mm(384dots/line),也就是說若要全部都用上,就是48組資料(目前只佔了30個)。

    從軟體角度看,有兩種連結方式,分別是TTL及直接連結。

    TTL接口


    TXRX部分則是透過轉板拉到開發板。使用上參考

    CODE位置D:\stm\printsnap\Firmware\src ( CAMERA用SPI非DCMI,忽略 )
    進行中CODE位置D:\stm\tm\printer,目前已經可以送入COMMAND,嘗試使用bit image.

    腳位設定在C10 C11 , 使用UART4
    TX RX
        /* Configure Printer UART */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
        //GPIO_PinAFConfig(GPIOC, GPIO_PinSource10,GPIO_AF_UART4);
        //GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,GPIO_AF_UART4);
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        USART_InitTypeDef USART_InitStruct;
        USART_StructInit(&USART_InitStruct);
        USART_InitStruct.USART_BaudRate = 19200;
        USART_Init(UART4, &USART_InitStruct);
        USART_Cmd(UART4, ENABLE);

    init function
    void initThermalPrinter()
    {
        //reset printer to default state
    <10 i="" p="">    send(27);
        send(64);
    }

    //主要送出指令
    send(bmpBlock[px][py]);

    使用的基本功能
    1 void send(uint8_t data) {
        //make sure the last byte made it out
        while(!USART_GetFlagStatus(UART4, USART_FLAG_TXE)){};
        USART_SendData(UART4, data);
    }

    換行
    void feedPrinter(uint8_t x) {
        while(x--) send('\n');
    }
    <10 i="" p="">
    <10 i="" p="">當初參考資料,原始資料
    <10 i="" p="">
    <10 i="" p="">印出品質部分,原始設計建議送出後等待系統回應,自己感覺反而有更多白色空隙
    如果光度低,整張紙面黑色多時,加熱頭要持續加熱,使用很多時間,但MCU卻還是不斷將資料送進來,會造成亂碼。目前作法是,計算每一行中黑色數量,如果數量過多,就啟動wait機制。效果還不錯。

    若考慮TTL控制板部分。熱感應部分,除FUJI、SEIKO外,中國大陸PRT 普瑞特 廈門專門生產熱感應廠商,以PT486F-H違例,包含有詳細說明文件,翻到最後甚至有DEMO電路。控制板編號是PF486F Control Board(網站上原有資料,現無法連結),也是以TTL控制,但有最小購買量拿不到成品。

    TTL轉板

    TaoBao有賣家販賣
    選項1
    富士 FTP-628MCL103
    游艺机 手持终端 刷卡机 卡POS 58MM热敏打印方案 FTP-628+控制板 ¥125.00  已經購買等到貨過程
    廈門 PF486F  零買
    游艺机 手持终端 刷卡机 卡POS 58MM热敏打印方案 PT486 + 控制板 ¥115.00
    整組下來,約600元( 模組價格1650 )
    選單中,還標示可選RS232版本。但在過程中,原本628熱敏售完?改換成SK58TM,但這個零件電壓達12V,無法負荷(或許電壓夠,加熱較快)。下載兩種版本PDF文件。

    選項2 選項3正廠控制板 選項4看起來是自製的,不確定TTL指令相同

    直接連結


    上面的盒子體積實在太大,拿在手上好像抱著120中片幅相機,自己都不好意思帶出門,而且整個模組價格不便宜。最直覺的想法是,能不能只使用噴頭本體呢。經過查詢,本體應該是FUJI FTP-628MCL103元件。也可能是Seiko LTP02-245(台灣找不到類似零件,先擱置)。

    若能連結FUJI元件 可大幅減少體積和成本

    先從台中代理商以賠本價取得成品機,就動手開始拆解( 可惜了一台機器 )。

    RTP58801 12V 3A

    開腸破肚中 軟體工程師做這種是總事不順手

    排線下方就是FUJI熱感應模組
    熱感應頭比TTL模組小許多,若紙張數量不多,整個玩具體積可大幅縮減。熱感應頭拉出來的是30PIN 1.0mm pitch的FPC軟排線,因為我對電子電路不熟悉,開始了一段摸索之旅。排線太密無法拉初電路,有幾種方式可以轉成可測試電路。

    嘗試一:找適當connector(又分成上和下兩種,都可以,只是方向差異),將軟排線轉成許多針腳,接下來就沒有對應這麼細針腳的PCB板。

    嘗試二:百年有賣下面特殊轉板,能夠把小connector連結到一般牛角轉出線路,當然銲接又是一門學問,結果如下。

    軟排線的轉板
    嘗試三:上圖是不能直接連結STM32的。包含了電流供給(因為軟排線太細,必須兩組提供等問題),還有其他設計,要達到上面範例,實在還有很長的路要走。
    可能的電路圖( 未實現 )

    網路範例在此 YOUTUBE影片位置  相關GIT位置 作者是 Romy Bompart
    從程式看來,以STM32F107為主。

    APP應用
    main.c
    Header_Init
    印字 ThermalPrint("        TICKET          \0");
    feed_pitch(150,BACKWARD);

    中間層
    fonts.c
    ThermalPrint(char text[150])
    將字型轉變成dot的形式在這邊送下去
    PrintDots(LinePixels, character-start );

    底層控制印表機硬體
    header_hardware.c
    原本以為是STM提供,看來不是
    Header_Init
    準備好所有的PIN設定

    Control OUTPUT pins configuration Part1: Port E Group
    LATCH_PIN | STB1_PIN | STB2_PIN | STB3_PIN | STB4_PIN | STB5_PIN  | STB6_PIN;
            23          12 13 14 18 19 20

    Control OUTPUT pins configuration Part 2: Port D Group
    PH12_PIN | PH21_PIN | PH22_PIN | ENABLE2_PIN;
    27 28 29 30

    Control OUTPUT pins configuration Part 2: Port C Group
    ENABLE1_PIN | VH_PIN;

    Control OUTPUT pins configuration Part 2: Port B Group
    PH11_PIN;

    Control OUTPUT pins configuration Part1: Port E Group
    PEM_PIN;

    Analogic pin configuration: PORTC
    THERMISTORPIN;

    SPI pins configuration which belows to port B
    HEADER_PIN_MOSI | HEADER_PIN_SCK;

    總共有18個,但是不知道這兩組資料中間是怎麼連接的。先前就是想要直接EMAIL,後來是在YOUTUBE下面留言。

    PrintDots(uint16_t *Array, uint8_t characters)
    會直接操作GPIO的動作
    GPIO_SetBits(HEADER_PORT_GROUP_E,STBx[y]);
    怎麼知道什麼指令會有什麼結果呢? 似乎有其他文件說明

    在電路聯結部分
    可能會需要馬達驅動電路  3相全波非線性馬達驅動系統IC 羅姆BA6849
    還有GPIO擴展方式電路

    其他


    除熱感應著色,網路還有色帶型式微型引表機。不過打點速度太慢,過程中還會發出MODEM的聲音(噪音??),不太實用。

    喵喵機
    最近看到個新產品"喵喵機",是中國大陸廈門喵寶科技出品,看資料就是熱感應盒子加藍芽(或WIFI)功能。影像來源則是手機。使用標準57mm打印機蕊,電池容量1000mAh。網路上有些人討論,但感覺不很熱衷。

    列印紙張
    列印紙張配合機蕊有各種尺寸。目前手邊57mm算常見型號,紙捲也很容易購買(貫峻 03-5226900 03-5229009 地址:新竹市中山路296巷7號1樓),算非常便宜。除了尺寸外,感應紙上還有兩種特色,一是紙張有背景色,這種應用不多。第二是印出感應紙後有自黏貼紙,印出後可隨手貼在醒目處。

    貼紙都是大量生產,所以只有幾種固定裁切版型。最接近57mm可能是55mmX30mm,可能也不是很合適。(熱感貼紙55mm*30mm/66米2000pcs 30捲一箱)。當然,網路上也有許多訂製生產的廠商。配合喵喵機通路,在網路上輕鬆訂購完全沒有裁切過的空白紙,六公尺50元左右,使用起來,沒有想像的有趣,還在觀察中。( 另外可能選項是這個 )

    首次貼紙實驗 貼NB了