2015年12月7日 星期一

GPIO Open Drain?






GPIO 表示此pin可設定為 output 或 input。

GPIO 設為output mode


若設為output 表示此pin有 source或sink 電流的能力 。表示若pin設成High,可以成為電流輸出的來源端(Source); 若pin設成Low,可以成為電流流入的汲端(sink)。

GPIO的邏輯方塊圖 (內部由兩顆電晶體來控制High或Low)


2015年12月3日 星期四

ARM Cortex MCU 開發環境建置


開發...最麻煩的就是把環境弄好, 才能開始研究,做更深入的研究



 以新唐Nuvton 的IC而言, 目前它支援的開發IDE有3種

  • Keil RealView MDK V4.12 or higher
  • CooCox CoIDE V1.0.0 or higher
  • IAR Embedded Workbench V5.xx

底下介紹的是使用ARM MDK環境建置的說明:
  1.  安裝Keil MDK (v5.xx) 的IDE工具 (這個基本上一直"下一步"就裝完了)
  2.  安裝NuLink Driver for MDK (Debug 及 線上燒錄) 或使用Jlink 燒錄  

ARM MDK 開發工具


ARM based MCU=ARM Cortex-M + Peripherals。

針對ARM Cortex-M 這種MCU的開發, ARM 原廠提供的是MDK ARM開發工具。



2015年11月25日 星期三

PCB Layout 入門教學(零) ---認識IC零件規格



IC元件主要分為DIP及SMD兩大類, DIP 插件的IC, SMD (Surface Mount Device) 表面黏著元件。



在SMD世界裡,常會聽到 0603, 0805, 1206 指的是什麼? 

指的其實是元件的Package尺寸, 尺寸講的是長(Length)x寬(Width)。使用的單位可以是inch或mm 。一般常講的SMD 的電阻、電容都是用inch來描述元件的尺寸大小。總共4位數表示, 2個位數一組。

0603:  0.06"x0.03", or 60x30 mils, or 1.6x0.8mm   (Note: 1mil=千分之一英寸)
0805:  0.08"x0.05", or 80x50 mils, or 2.0x1.25mm
1206:  0.12"x0.06", or 120x60 mils, or 3.2x1.6mm

2015年11月23日 星期一

PCB Layout 入門教學(三) ---建立Footprint Library


建立Footprint Library


PCB Layout 的工作, 除了佈線以外,另一個工作就是建立元件的footprint。設計footprint在kicad 裡是交由Module Editor這個工具來完成。如果你用了某一個IC或connector , 在既有的kicad 的footprint library 找不到它的footprint話, 那就得自己畫。在kicad裡, 一個footprint也就是一個Module , 一個library 可以包含多個footprint (module)。library 的副檔名為 .mod。
擁有自己Footprint Library很重要, 因為Footprint 涉及PCB board製造, 對於自己常用的IC用料, 你可以很快且很放心的使用你專屬的footprint,這樣做PCB板的速度才會比別人快。

library就是footprint的集合

簡而言之,footprint 主要的設計就是要知道板框及Pad的尺寸, 如下圖所示,你會一直看到 dimension in inch/mm 之類的字眼。pad包含位置,pitch (pad 間距)及pad排列及編號,以及pad是否有鑽孔, 孔徑大小,鍍銅等規格,所以這要配合IC Databook 來做。從這裡你可以明顯看出來,這是一項工藝技術, 尤其在機構工藝上。



管理footprint library


在kicad 軟體,PCB Module Editor 不僅是用來產生footprint 同時也是拿來管理footprint library用。

可以自新建一個footprint 然後存在目前所選擇的active library裡, 也可以另存一個新的library (.mod) 。也可以取出active library 中的某一個footprint 拿來修改再存回或者重新另存一個新的footprint, 但這個新的footprint 要取別的名字, 因為在同一個Library檔,每一個footprint 都有自己唯一命名。



ARM MCU Board


使用Raspberry Pi 的時候, 是不是常常苦惱於缺乏PWM、ADC及DAC的功能? 
而這都卻是在Arduino上所擁有的基本能力。過去, 為了讓Raspberry Pi 補上這些功能,就會開始用麵包板去插上我們需要的IC或者購買一堆的小的模組板,如PCA9685 for PWM,MCP3008 for ADC 這類的模組板來接在Raspberry Pi 。

要讓 Raspberry Pi  的功能更加完美就要加上更好的左右手,所以我們就開發了這一塊板子。
  
  ARM MCU Board提供40 pin GPIO座,故可以直接在插在Raspberry Pi 上面作為擴充PWM與ADC等等功能的擴充。 ARM MCU Board 已提供好韌體,Raspberry Pi 可以透過UART、I2C、SPI 界面,就可以實現ADC, PWM的功能。同時,這片板子本身是可以stand alone 運作, 因為它本身就具有一顆ARM Cortex-M0 的晶片 (使用的是新唐的Nano130SD2BN) ,你也可以拿 Keil MDK 來撰寫其上的韌體程式。







2015年11月19日 星期四

PCB Layout 入門教學(四) ---以階層式的架構繪製電路圖


以階層式的架構繪製電路圖


若電路圖一張圖紙畫不下,一種方法就是調整Paper大小,如調到A3大小, 把線路全部畫在同一頁。另一種方式是將電路以階層式的架構來畫,從最上層(Root層)一直畫到最內層。每一層就是一個sheet, 把相關的電路都畫在同一張sheet,如此就是一個電路模組化的一個概念。對一個複雜的電路,看整個電路就更有結構性並且具有層次感。

從軟體程式設計角度來看, 一個IC元件就是一個函數。一群IC元件的集合就是一個Library檔案。寫C程式,你可以全部程式碼存在一個.c 檔,也可以按功能分別存在不同的.c檔。雖然功能上也許都對, 但只是結構性好不好的問題而已。畫電路和寫程式的概念一樣, 你可以全部畫在同一張sheet (.sch), 也可以按功能分別畫在不同的sheet。


2015年11月18日 星期三

PCB Layout 入門教學(二) ---建立元件library


建立自己元件library


一個schematics component library (xxx.lib)底下會有很多component (schematics symbol).

 library 包含多個component (schematics symbol).

2015年11月16日 星期一

PCB Layout 入門教學(六) ---產生 Gerber File



PCB Layout 入門教學(六) --- 產生 Gerber File

從 CAD 到 CAM

Gerber File是PCB板廠用來製作一片PCB所需要的檔案, 也就是要給CAM (電腦輔助製造) 要吃的檔案格式。Gerber格式是一種二維向量圖像文件格式。它是印刷線路板行業軟體中用於描述印刷線路板圖像的標準格式。 

要製作一個PCB板, 必須提供板廠Gerber檔案。所謂Gerber檔,其實是包含一群檔案 (如下圖所示),如包含正反面銅箔層 F.Cu B.Cu.,正反面文字面 F.Silkscreen ,B.Silkscreen,防焊層 SolderMask、板邊裁切Edge.Cuts 等。另外,還要給鑽孔Drill (.drl)及 Drill Map (.map) 的Gerber 檔案,此會描述此PCB所用到的鑽孔的孔徑尺寸及鑽孔位置。

  • Cu (銅箔層/線路層)
  • Silk Screen(文字層): 主要的功能是在電路板上標註各零件的名稱、位置框,方便組裝後維修及辨識用。
  • Solder Mask: 防焊層(綠油層) :並非全部的銅面都要吃錫上零件,因此非吃錫的區域,會印一層隔絕銅面吃錫的物質(通常為環氧樹脂),避免非吃錫的線路間短路。根據不同的工藝,分為綠油、紅油、藍油、黑油、白油等顏色
  • Drill Map : 描述 PCB 有鑽孔位置及孔徑。

    2層板的話, 有正面(Front)及背面(Back). 故會有F.Cu或 B.Cu
  • ----------------
  • Paste Mask: 製作鋼板用的圖層。鋼膜上的孔就對應著電路板上的SMD 器件的焊點。(該層的尺寸與實際SMD焊盤的尺寸相同)
  • Edge.Cuts,: PCB板框裁切用的檔案。
  • Dwgs.User : User Drawing 的部份,可以用來描述板框尺寸(用量測工具)或文字說明的地方。或用來描繪Edge.Cuts以外的部份。這一層完全不影響生產。


2015年11月15日 星期日

PCB Layout 入門教學(一) ---PCB Layout 設計流程









先有一些基本PCB概念, 再開始進行軟體上教學。首先要有個觀念, PCB談的是製作工藝, 不是電路設計。所以即使你不太懂什麼叫電路設計,只要確定有一個可正常工作的電路圖 , 基本上也就可以做出一個PCB板。如果你是Maker (創客),只要你掌握了一些的Design Rule,你也可以出自己板子。不過, 你要先確定有一個可"工作" 的電路圖。你可以先用洞洞板手銲驗證一下電路或用麵包板插一插,先確定一下這是可工作的。到時Layout PCB時, IC零件可以再選擇SMD的版本,因為量產時加工費會比較便直。

要完成一個PCB電路板,基本上可分為三個階段,其實也是工作流程。 第一個階段電路圖繪製,第二個階段電路佈局, 第三階段為建立BOM表以及備料、手銲樣品。不過,第一個階段的電路圖繪製工作,很少是由PCB Layout 工程師自己來完成,而是由電路設計RD工程師完成。Layout的工作是由電路路轉成Netlist 之後才動工。電路圖頂多也只有拿到PDF檔而已。

如果你是Maker (創客),你的PCB 需要layout到4層板以上或者高速,RF, 天線這種高頻的東西, 這已經屬pro專業等級了, 沒有經過專家指導並不容易,再加上你沒有太多量測儀器, 有些也不太可能自己做, 這已經是另一個level了, 建議找具相關設計專長領域的Layout House 代工,因為可能後續還有EMI, FCC,CE, NCC規範要過。


階段1: 電路圖繪製


2015年11月10日 星期二

用 Python 寫程式控制 WiFi 無線遙控車實作


用 Python 寫程式控制 WiFi 無線遙控車實作

根據前幾篇文章的內容,已經可以簡單而初步地實作一台 WiFi 無線遙控車。基本上所有的事情都是在 Raspberry Pi 的系統上實作出來的。

材料

  • motoduino 車子套件(板子需已燒錄 motoduino 的 firmware)
  • ESP8266 模組
  • 9V 方塊電池 x 3
  • Raspberry Pi
  • 區域網路

設置 WiFi 模組

原本的連線方式是用USB線連接motoduino 和 Scratch,所以這邊要使用ESP8266模組把這個連線切換成WiFi連線。因為不想更動到motoduino 裡面的firmware 所以我們要把ESP8266模組變成可以把motoduino 透過UART 的 tx/rx (pin腳1,2)傳出來的封包用WiFi 無線傳輸的方式傳到指定的網站,也就是Raspberry Pi 所架的網站,這邊假設 Raspberry Pi 的 IP 為 192.168.0.1。
要達到這個需求的一個方法就是去把 ESP8266 的 firmware 刷成 nodeMCU 之後再寫入lua script ,使其在開機之後自動連線到指定的AP上,並將 motoduino 的 UART 和 Raspberry Pi 的 UDP socket 連線。簡易的架構圖如下:
-------------------------      ------------       ---------------
Rapsberry Pi UDP Socket | <==>|ESP8266 tx | ----> | rx motoduino|
                        |     |        rx | <---- | tx          |
-------------------------     -------------       ---------------
ESP8266 刷成 nodeMCU 的方式可以參考之前的文章 :
ESP8266 wifi 通訊模組韌體燒錄簡介
ESP8266 NodeMCU 使用 ESPLorer 寫入 Lua Script
ESP8266 NodeMCU 使用 Lua 自動連網
而自動連線的 Lua Script 如下:
print("ESP8266 START")

ssid = "My_AP"
passwd = "12345678"
scratch_ip = "192.168.0.1"
scratch_port = 12345

wifi.setmode(wifi.STATION)
wifi.sta.config(ssid,passwd,1)

tmr.alarm(1,1000, 1, function()
    if wifi.sta.getip()==nil then
        print(" Wait to IP address! for " .. ssid)
    else
        print("New IP address is "..wifi.sta.getip())
        tmr.stop(1)
        sck = net.createConnection(net.UDP)
        sck:on('receive', function(sck,pl) uart.write(0,pl) end)
        uart.on('data',0, function(data) sck:send(data) end,0)
        sck:connect(scratch_port,scratch_ip)
        sck:send("START UART Tunnel\n")
        uart.setup(0,38400,8,0,1,0)
    end
end)

print(wifi.sta.getip())
其中的 ssid = "MyAP" 為要連線的 AP SSID, passwd = "12345678" 為AP密碼。
scratch
ip = "192.168.0.1" 為 Raspberry Pi 的 IP 位址。而 scratch_port 為 Raspberry Pi 的 UDP socket 的 port number 。
所以在 Raspberry Pi 上可以寫一個 Python script 來接收 motoduino 所傳送過來的封包。
#!/usr/bin/env python3
import socket

def s4aDecode(data):
    dev_id = (data[0] & 0b01111000) >> 3
    dev_val = ((data[0] & 0b00000111 ) << 7) | (data[1] & 0b01111111)
    return (dev_id, dev_val)

def handle_data(data):
    i= 0
    length = len(data)
    if(data[i] & 0b10000000):
        pass
    else:
        i+=1
    while(i<length):
        try:
            print(s4aDecode(data[i:i+2]))
            i+=2
        except:
            break

address = ('',12345)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(address)

while(True):
    print('--')
    data, addr = s.recvfrom(1024)
    handle_data(data)
詳細的s4a protocol 格式設定可以看之前寫的文章:
Python 操控 S4A 透過通訊協定來下手
這樣就可以大概了解如何去用Python 來操控 motoduino 的車子了。我們寫了一些簡單的範例碼放在github之上。


2015年10月28日 星期三

ESP8266 NodeMCU 使用 Lua 自動連網

ESP8266 NodeMCU 使用 Lua 自動連網

在使用Arduino的時候,有時候會需要將TxRx的連線訊息透過 WiFi 傳送到一個指定的網站。這時就可以使用 ESP8266 with nodeMCU 來達成。
在ESP8266裡面刷 nodeMCU 來跑 lua script 的方式可以參考之前的文章。
所以這邊就直接把範例程式碼寫出來如下:
ssid = "My_AP"
passwd = "12345678"
scratch_ip = "192.168.0.1"
scratch_port = 12345
wifi.setmode(wifi.STATION)
wifi.sta.config(ssid,passwd,1)

tmr.alarm(1,1000, 1, function() 
    if wifi.sta.getip()==nil then 
        print(" Wait to IP address! for " .. ssid) 
    else 
        print("New IP address is "..wifi.sta.getip())
        tmr.stop(1)
        sck = net.createConnection(net.UDP)
        sck:on('receive', function(sck,pl) uart.write(0,pl) end)
        uart.on('data',0, function(data) sck:send(data) end,0)
        sck:connect(scratch_port,scratch_ip)
        sck:send("START UART Tunnel\n")
        uart.setup(0,38400,8,0,1,0)
    end 
end)
將這個 script 用 "init.lua" 的檔名存到 ESP8266 晶片之中之後,之後 ESP8266 開機就會自動去和指定的無線 AP 連線,然後把從 UART port 所收到的訊息用 UDP Socket 的方式送到指定的 ip 位置裡的指定port。
其中 ssid 變數指定無線 AP 的 SSID ,passwd 變數為 AP 登入密碼。 scratch_ip 和 scratch_port 則是連線之後 UART 訊息要收發的伺服器位置和 port。
其中 tmr.alarm() 函示用來設定 timer 每隔 1 秒就執行一次 wifi.sta.getip() 確認是否有正確取得IP位置。如果確認取得IP位置就執行另一段程式碼將timer 關掉,並且和伺服器建立一個 UDP 的 socket ,將UART收到的封包傳送到伺服器,並將伺服器傳送過來的封包透過 UART 發送出去。
該段程式碼是用來把 S4A 的板子所發出來的封包透過 wifi 連線和指定的伺服器做連線。

前進校園計畫投影片-- 用Raspberry Pi 結合 Arduino 實現 Wi-Fi 遙控車 -- 用 Python 玩 WiFi + S4A







投影片中用到的 Code 都放在 GitHub 上面:

https://github.com/itrobotics/Python_Control_Motoduino




ESP8266 NodeMCU 使用 ESPLorer 寫入 Lua Script

ESP8266 NodeMCU 韌體設計 Lua Script

上一篇文章中有提到刷新 ESP8266 韌體的做法,這次說明的是使用開發工具 ESPlorer 來寫入Lua Script 進去ESP8266(NodeMCU)的做法。
而nodeMCU所提供了API查詢網頁可以查詢其中所支援的 API 與其定義。

ESPlorer

ESPLorer 是一款用 java 寫的開發工具(for ESP8266)。在 mac os x 或 Linux 底下需先安裝 JDK 套件之後才能執行它。打開 command line 之後,跑到 ESPLorer 的目錄底下鍵入:
$> java -jar ESPlorer.jar
之後就會出現ESPlorer的使用者介面如下:

和 ESP8266 連線

ESP8266 連線時的 pin 腳連線設置有兩個模式,一個是燒錄模式,另一個是一般模式。

燒錄模式接線接法

  • CH_PD --> 3.3v
  • VCC --> 3.3V
  • UTXD --> RXD (白色線)
  • URXD --> TXD (綠色線)
  • GPIO0 --> GND <重點>
  • GND --> GND

一般模式接線接法

  • CH_PD --> 3.3v
  • VCC --> 3.3V
  • UTXD --> RXD (USB-TTL 轉接線:白色線)
  • URXD --> TXD (USB-TTL 轉接線:綠色線)
  • GPIO0 --> 不要接 <重點>
  • GND --> GND
在燒錄 lua script 進去 ESP8266 的時候是使用一般模式的接線法。pin 設置做好之後就可以準備開始和 ESP8266 連線了。
nodeMCU 預設連線的UART設定是 9600,8,N,1 ,使用 ESPlorer 的時候要設定畫面右半邊的連線區域上的 Baudrate 選項設定為 9600 ,然後指定連線設備為 "/dev/tty.usbserial" (在 Linux 系統上應該是 "/dev/ttyUSB0")
設置完按下 "Open" 按鍵就開始連線。這時如果把ESP8266重新上電的話應該會看到類似下面的訊息:
NodeMCU custom build by frightanic.com
branch: master
commit: bb9dd62882b89d40f5d0df2c009c972f64b7f965
SSL: false
modules: node,file,gpio,wifi,net,tmr,uart
built on: 2015-09-18 02:26
powered by Lua 5.1.4

編輯 Lua Script 檔 & 燒錄 Lua Script

開發工具的左半邊是 Lua script 的程式碼編輯區,在此區編輯要燒入ESP8266模組的Lua script檔。要在連線的狀態之下才能燒入 Lua Script。
假設我們先寫了一個印出 "hello world" 的程式碼:
print("hello world")
然後按下編輯區下方的 "Send to ESP" 按鈕,會看到開發工具會把該行程式碼傳送給ESP後馬上執行。如果有程式碼不只一行的話會看到,傳一行執行一行,結束後才執行下一行的動作狀況。
開發工具也支援將lua script 用檔案的形式儲存在晶片之中,之後再呼叫出來運行的方式。做法是先在編輯區之中把程式碼打好,然後按上面的 "Save" -> 指定存檔檔名(副檔名要為.lua)。最後再按下下方的 "Save to ESP" 按鈕,就會看到開發工具會用 lua 的 file open 的方式來把程式碼檔案寫入晶片之中的檔案系統,並且用剛剛存檔的檔名。之後就可以使用 lua 的 dofile("檔名") 來執行已存在晶片之中的 lua script檔。
dofile("script.lua")

開機後執行的第一個lua script檔

nodeMCU的韌體預設在晶片開機的時候,會先自動呼叫 "init.lua" 這個檔案來執行。 如果要有開機後執行初始化設定的需求的時候,就把初始化動作寫好之後存指定檔名為 "init.lua" 之後,再按 "Save to ESP"。

2015年10月18日 星期日

使用 Google fusion tables

存取google 的服務,都會用到OAuth 的認證機制,所以使用 Google fusion tables當然也不例外,底下說明的使用的是OAuth 2.0 for Devices過程,一旦取得Access Token,就可以對Google fusion tables 執行新增資料、查詢資料、刪除資料等操作。


OAuth 2.0 for Devices的認證流程
The user logs in on a separate device that has a browser.

使用 OAuth 2.0 , 必須先到Google Developers Console 建立一個專案以取得client ID及client secret. 註: 須於建立用戶端ID頁面, [已安裝的應用程式類型]請選擇"其他"

注意:curl 必須支援HTTPS (安裝說明)

取得Authorization Code


root@raspberrypi:~# curl -d "client_id=530304002742-55mhfghci5o59tur1tgt183p38ceh08t.apps.googleusercontent.com&scope=https://www.googleapis.com/auth/fusiontables" https://accounts.google.com/o/oauth2/device/code
{
  "device_code" : "ZMUM-BZYM4/b1grhomQLBtifJxKrATFJ-m8AoYV7tr3RfN1BLvOTlo",
  "user_code" : "ZMUM-BZYM",
  "verification_url" : "https://www.google.com/device",
  "expires_in" : 1800,
  "interval" : 5
  
} 
  
The user_code and verification_url from the JSON object should be shown to your user. The idea is to ask the user to go to a browser, navigate to the verification_url URL, and enter the user_code. The user_code is case sensitive, so the user will need to enter the code exactly as it appears in the response.



  
=======================================

獲得access tokens

code為上一個請求所傳回的device code

root@raspberrypi:~# curl -d "client_id=530304002742-55mhfghci5o59tur1tgt183p38ceh08t.apps.googleusercontent.com&client_secret=xtogS1gi_MSl_7apvzfrsvmK&code=ZMUM-BZYM4/b1grhomQLBtifJxKrATFJ-m8AoYV7tr3RfN1BLvOTlo&grant_type=http://oauth.net/grant_type/device/1.0" https://www.googleapis.com/oauth2/v3/token




{
 "access_token": "ya29.tAH13KudNYGAmG9rtdXLJjO_QNPjbJcvEkJEeG_C3MxqWh5T9sFbbrguWh77llT6JbVL",
 "token_type": "Bearer",
 "expires_in": 3600,
 "refresh_token": "1/97_rdY40n2PusItQPVPENp5ECTZYqFvUobJZB09nOxlIgOrJDtdun6zK6XiATCKT"
}

==================================

#Access Token 過期時, 出現 401 "Invalid Credentials" 錯誤

root@raspberrypi:~# curl -H "Authorization: Bearer ya29.tAH13KudNYGAmG9rtdXLJjO_QNPjbJcvEkJEeG_C3MxqWh5T9sFbbrguWh77llT6JbVL" -d "sql=SELECT * FROM 1fV5mXuKgG5cCck1cAVQX0G7HVTjfdm1SqeYSdmXU WHERE number=43" "https://www.googleapis.com/fusiontables/v2/query" { "error": { "errors": [ { "domain": "global", "reason": "authError", "message": "Invalid Credentials", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Invalid Credentials" } } =======================================

# Refresh Token

root@raspberrypi:~# curl -d "client_id=530304002742-55mhfghci5o59tur1tgt183p38ceh08t.apps.googleusercontent.com&client_secret=xtogS1gi_MSl_7apvzfrsvmK&refresh_token=1/97_rdY40n2PusItQPVPENp5ECTZYqFvUobJZB09nOxlIgOrJDtdun6zK6XiATCKT&grant_type=refresh_token" https://www.googleapis.com/oauth2/v3/token
{
 "access_token": "ya29.tAHsfamfZ4CUSiMwXG0TztY9DYkcj3Zs988p9Wr_GrZz5vRbxkGHFoQiHxDMNsuEZf8-",
 "token_type": "Bearer",
 "expires_in": 3600
}


一旦取得Access Token並知道過期後如何更新Access Token, 接下接下來就是對Google fusion tables 執行新增資料、查詢資料、刪除資料對表格的操作。使用的方式使用HTTP POST,但必須在每一次的HTTPS請求,在Header中加入Access Token

#新增 "sql=INSERT INTO {table} (number,Address)VALUES(43,'IT robotics lab')"

root@raspberrypi:~# curl  -H "Authorization: Bearer ya29.tAH13KudNYGAmG9rtdXLJjO_QNPjbJcvEkJEeG_C3MxqWh5T9sFbbrguWh77llT6JbVL" -d "sql=INSERT INTO 1fV5mXuKgG5cCck1cAVQX0G7HVTjfdm1SqeYSdmXU (number,Address)VALUES(43,'IT robotics lab')" "https://www.googleapis.com/fusiontables/v2/query"
{
 "kind": "fusiontables#sqlresponse",
 "columns": [
  "rowid"
 ],
 "rows": [
  [
   "5002"
  ]
 ]
}
==================================

#查詢 "sql=SELECT * FROM {table} WHERE number=43"

root@raspberrypi:~# curl  -H "Authorization: Bearer ya29.tAH13KudNYGAmG9rtdXLJjO_QNPjbJcvEkJEeG_C3MxqWh5T9sFbbrguWh77llT6JbVL" -d "sql=SELECT * FROM 1fV5mXuKgG5cCck1cAVQX0G7HVTjfdm1SqeYSdmXU WHERE number=43" "https://www.googleapis.com/fusiontables/v2/query"
{
 "kind": "fusiontables#sqlresponse",
 "columns": [
  "Date",
  "Time",
  "number",
  "Location",
  "Address"
 ],
 "rows": [
  [
   "",
   "",
   "43",
   "",
   "IT robotics lab"
  ]
 ]
}
==================================

#查詢ROWID SELECT ROWID FROM {table} WHERE number=43

root@raspberrypi:~# curl -H "Authorization: Bearer ya29.tAHsfamfZ4CUSiMwXG0TztY9DYkcj3Zs988p9Wr_GrZz5vRbxkGHFoQiHxDMNsuEZf8-" -d "sql=SELECT ROWID FROM 1fV5mXuKgG5cCck1cAVQX0G7HVTjfdm1SqeYSdmXU WHERE number=43" "https://www.googleapis.com/fusiontables/v2/query"
{
 "kind": "fusiontables#sqlresponse",
 "columns": [
  "rowid"
 ],
 "rows": [
  [
   "5002"
  ]
 ]
}
==================================

#更新 sql=Update {table} Set Address='ittraining' WHERE ROWID='5002'

root@raspberrypi:~# curl -H "Authorization: Bearer ya29.tAH13KudNYGAmG9rtdXLJjO_QNPjbJcvEkJEeG_C3MxqWh5T9sFbbrguWh77llT6JbVL" -d "sql=Update 1fV5mXuKgG5cCck1cAVQX0G7HVTjfdm1SqeYSdmXU Set Address='ittraining' WHERE ROWID='5002'" "https://www.googleapis.com/fusiontables/v2/query"


{
 "kind": "fusiontables#sqlresponse",
 "columns": [
  "affected_rows"
 ],
 "rows": [
  [
   "1"
  ]
 ]
}
==================================

#再查詢一次

root@raspberrypi:~# curl -H "Authorization: Bearer ya29.tAH13KudNYGAmG9rtdXLJjO_QNPjbJcvEkJEeG_C3MxqWh5T9sFbbrguWh77llT6JbVL" -d "sql=SELECT * FROM 1fV5mXuKgG5cCck1cAVQX0G7HVTjfdm1SqeYSdmXU WHERE number=43" "https://www.googleapis.com/fusiontables/v2/query"
{
 "kind": "fusiontables#sqlresponse",
 "columns": [
  "Date",
  "Time",
  "number",
  "Location",
  "Address"
 ],
 "rows": [
  [
   "",
   "",
   "43",
   "",
   "ittraining"
  ]
 ]
}

#刪除 sql=Delete {table} WHERE ROWID='5002'

root@raspberrypi:~# curl -H "Authorization: Bearer ya29.tAHsfamfZ4CUSiMwXG0TztY9DYkcj3Zs988p9Wr_GrZz5vRbxkGHFoQiHxDMNsuEZf8-" -d "sql=Delete from 1fV5mXuKgG5cCck1cAVQX0G7HVTjfdm1SqeYSdmXU WHERE ROWID='5002'" "https://www.googleapis.com/fusiontables/v2/query"
{
 "kind": "fusiontables#sqlresponse",
 "columns": [
  "affected_rows"
 ],
 "rows": [
  [
   "1"
  ]
 ]
}

#確認該筆資料(number=43)已刪除

root@raspberrypi:~# curl -H "Authorization: Bearer ya29.tAHsfamfZ4CUSiMwXG0TztY9DYkcj3Zs988p9Wr_GrZz5vRbxkGHFoQiHxDMNsuEZf8-" -d "sql=SELECT ROWID FROM 1fV5mXuKgG5cCck1cAVQX0G7HVTjfdm1SqeYSdmXU WHERE number=43" "https://www.googleapis.com/fusiontables/v2/query"
{
 "kind": "fusiontables#sqlresponse",
 "columns": [
  "rowid"
 ]
}

Access VBA: 查詢方式有3種方式



進入Access 查詢[設計模式]下, 可以設定查詢的連接屬性, 如下。 預設是1:  查詢結果是當兩個個資料表都必須要有記錄才算. 另外2種就是看要以那一個表格為主去查詢另外一個表的記錄, 也就是通常有些記錄,只存在於其中一個表格而已。





Access VBA表單傳遞資料的方式


 Method 1: 從表單找到控制項,取值
  Forms("資料表單").Controls("StudentNo").Value 

 Method 2: 使用Form.OpenArg

  開智表單並傳傳參數
  DoCmd.OpenForm stDocName, , , stLinkCriteria, , , StudentNo

  被開智的表單,利用Form.OpenArgs 取得傳入的參數
   lbl_studentNo.Caption = Me.OpenArgs    ' set studentNo to correct data




2015年9月30日 星期三

ARM MCU Board (ARM Cortex-M0)

 
這塊板子MCU採用的是新唐科技的NANO130低功耗系列晶片(NANO130SC2BN) , 其相關規格如下:
  • I2C延伸腳座x2
  • UART延伸腳座
  • DAC延伸腳座x2
  • ADC延伸腳座x7
  • PWM延伸腳座x7
  • ICE燒入腳座
  • GPIO發光二極體x1
  • GPIO按鈕x1
  • USB 2.0 Port
  • ADC可變電阻
  • Reset 按鈕開關
  • External Power Supply延伸腳座
  • OPT INT Power Jump 腳座
  • External Power Supply 穩定電容座
  • 三色led判斷Power Source狀態(紅:ICE 綠:PI 2 藍:USB)
  • 40 pin Head ( for raspberry Pi )



2015年9月27日 星期日

MX25L4005A SPI NOR Flash的使用方式



Raspberry Pi I/O Shield 上的MX25L4005A  SPI NOR Flash的使用方式


相關規格如下:
Flash size: 4Mbit (512KB), 其內部記憶體的組織結構為
  1. 64K Block size (for Block Erase) 
  2. 4K Sector size (for Sector Erase) 
  3. 256 Byte Page size (for Page Program) 



工作電壓為 .7 to 3.6 volt for read, erase, and program 操作
SPI 工作模式為 : Mode 0 & Mode 1

操作的相關注意事項: 
1.Flash 要寫入page之前,要先Erase
2.執行Page Program動作,byte 寫入"0", 無法寫入"1", 要執行Erase指令才能 將byte 設回"1"
3.資料送出的順序為 MSB First

執行動作

SE, BE, CE, and WRSR 會改變Flash內容的Command, 都要先設定WEL bit=1 (in RDSR bit 1), 一旦操作完成後, 它會自動reset (將WEL bit設回0)

操作方法: 

CS# goes low
     sending WREN (0x6); // set WEL=1
CS# goes high

CS# goes low
     sending <CMD>+{Flash Address}+{Data}//see command table
CS# goes high

CS# goes low
  deadline = jiffies + MAX_READY_WAIT_JIFFIES;
   do {
           status=sending RDSR(0x5) ;
            if (!(status & WIP) ) return 0;   //判斷是否操作完成
              cond_resched();                   // 再排程
        } while (!time_after_eq(jiffies, deadline));
CS# goes high 


Flash Address 的定址方法

NOR Flash 定址方法和一般SRAM,ROM, EEPROM 的定址方址相同,容量有多大,位址線就有多少條。容量有512 Kbyte 表示存取某一位置為需要19條位址線來定址。一般Parallel NOR Flash 介面,就會在IC元件上看到位址線 A0~A18的pin腳。但若為使用較少Pin count 以縮小IC 大小, 使用serial  Flash 是另一種解決方案。MX25L4005A  即是採用serial 的 SPI 介面。在送出位址時得用到3個byte ,也才足以表示這19條位址訊號。

位址結構:

位址用以定址到某一個block下的某一個sector, 再到某一個sector下的某一個page, 再到該page 內的offset。

若要進行Flash Block Erase (BE) 時, 描述Flash Addr [18:16] 。
若要進行Flash Sector Erase (SE)時, 描述Flash Addr [18:12]。
若要進行Flash 讀取(READ)時, 描述Flash Addr [18:0]。
若要進行Flash 寫入(WRITE)時, 描述Flash Addr [18:0]。
(每次寫入都是基於某一個page #內寫入)




2015年9月21日 星期一

ESP8266 wifi 通訊模組韌體燒錄簡介


ESP8266 wifi 通訊模組韌體燒錄簡介

ESP8266是一款UART轉WiFi的SoC晶片,被拿來組合成各種五花八門的擴充板,其中最常見也最容易買到的模組型號就 ESP-01,尺寸迷你價格便宜。
此篇文章進行燒錄 ESP模組是使用mac os x 平台,但是如果是使用Linux平台的話做法應該是一樣。

pin 腳定義

買到手的時候會發現,模組上有八根沒有標示的 pin 腳。上網查了一下,可以知道pin 腳配置如下:


UART介面的 wifi 模組

ESP8266模組到手的時候,就可以透過模組上的 Tx/Rx (UART 介面)的 pin腳來下AT command 進行簡單的 WiFi 連線。本身支援AP模式(無線網路基地台)和一般模式。通訊協定上支援 TCP 和 UDP,可在無線區域網路中扮演伺服器(Server)等候連入,或扮演客戶端(Client)去與Server連線。
我一般使用可以簡單買到的 USB-UART 轉接線和ESP模組連接。而接法如下:
ESP8266 pin:
GND
UTxD ----> RxD (USB-UART 轉接線)
GPIO_2 --> 不用接
CH_PD ---> 3.3V (電源,不能接5V!會燒掉)
GPIO_0 --> 不要接!!
RST -----> 不用接
URxD ----> TxD (USB-UART 轉接線)
VCC -----> 3.3V (電源,不能接5V!會燒掉)

電流需求 : 200 ~ 300 mA
ESP8266對於電源電流供應會有一些要求,如果電源不夠力的話,會導致模組運作不穩定。
使用UART 做通訊的時候記得要設定連線設定如下: (115200 8N1)
  • Baudrate:115200
  • byte size: 8
  • Parity: None
  • Stop Bit: 1
UART連線下指令的時候換行符號是 "\r\n" ,換行符號要下對指令才會被接受,不然是不會動的。連線之後可以先傳送指令 "AT\r\n" 看看 ESP 模組是否會回傳 "OK" 的訊息。如果成功了就表示模組可正常運作。

使用UART 介面進行韌體更新

ESP8266是可程式化的通用微控制器(具有WiFi功能),具有少數的 GPIO。ESP-01模組上只拉出兩根。而從拍賣網站上買到手的時候,裡面其實已經燒好最新版本的韌體來支援 AT command。網路上也流傳著許多其他版本的韌體來支援其他功能,像是較為知名的支援可在模組上執行 Lua 程式語言的韌體(nodeMCU),其原始碼就放在github上。不過要自行編譯原始碼的話會是一項大工程,所幸的是,有網站提供客製化的 nodeMCU 韌體線上編譯的免費服務,網址為
http://frightanic.com/nodemcu-custom-build/
編譯好的韌體會傳送到網頁上要求輸入的 email 位址,筆者收到了兩個檔案:
nodemcu-master-7-modules-2015-09-18-02-26-58-float.bin
nodemcu-master-7-modules-2015-09-18-02-26-58-integer.bin
燒錄的時候,我是選檔案大小比較小的那個。拿到韌體之後,我們還需要一個燒錄程式,在這邊我是使用 esptool.py 這個指令工具,下載安裝之後。就可以準備開始燒錄韌體了。
進行燒錄時使用下面所示的接線配置,可以使ESP模組進入燒錄模式,
  • CH_PD --> 3.3v
  • VCC --> 3.3V
  • UTXD --> RXD (USB-UART 轉接線)
  • URXD --> TXD (USB-UART 轉接線)
  • GPIO0 --> GND <重點>
  • GND --> GND
接好線之,把 USB-UART 轉接線接上mac os x 系統會自動跳出裝置檔檔名
/dev/tty.usbserial
如果是 Linux 系統的話則是出現
/dev/ttyUSB0
然後打開 command-line ,然後使用esptool.py指令:
esptool.py --port /dev/tty.usbserial write_flash 0x000000 nodemcu-master-7-modules-2015-09-18-02-26-58-integer.bin
如果是 Linux 系統的話則是
esptool.py --port /dev/ttyUSB0 write_flash 0x000000 nodemcu-master-7-modules-2015-09-18-02-26-58-integer.bin
接著就會出現燒錄中的訊息,等到燒錄完成後畫面是如下所示
onionys$ esptool.py --port /dev/tty.usbserial write_flash 0x000000 nodemcu-master-7-modules-2015-09-18-02-26-58-integer.bin
Connecting...
Erasing flash...
Wrote 354304 bytes at 0x00000000 in 34.6 seconds (82.0 kbit/s)...

Leaving...
onionys$
如此一來,就完成燒錄的工作了。重新接線後,會發現AT command 已經不能使用了。之後,我們會再介紹如何在 nodeMCU 的韌體下使用 Lua 語言控制 ESP8266 模組。


2015年9月14日 星期一

救援隨身碟各種遺失的資料,誤刪了怎麼辦呢?要如何把檔案救回來。

  相信各位也跟我們一樣都常常使用到隨身碟, 隨身碟的便利性從128M小型資料的時代,到目前已把32G隨身碟普遍使用了,相信也帶給大家很大的方便性,讓使用者可以隨身攜帶自己的資料,同樣的,有時候也因為方便而導致隨身碟搞丟,或者是不小心的把資料給誤刪了!

  當下一定會很惱羞慘了資料不見了,只好拍拍屁股在重新的做一份了!
在這邊就是要大家不需要再重新做一份了,只需要再把檔案從新救援出來就好,可是到底為什麼可以把一個刪掉的資料救回來呢?

為什麼已刪除的檔案可以救回?


   Windows儲存檔案時,每一個檔案有分為檔案的檔頭,以及真正儲存的資料內容兩個部分。檔頭的作用是用來記錄檔案名稱,以及資料內容儲存在哪些磁碟空間中的資訊。而系統是靠檔頭的資訊,才知道檔案的資料內容要去哪裡找。而當Windows刪除檔案時,事實上是將檔頭的資訊修改,將檔案標記為刪除。這個動作可以視為是將原本這個檔案佔用硬碟的空間釋放出來,讓日後其他要儲存進硬碟的檔案,可以取用。

  因此,如果你刪除檔案之後,沒有放進其他的檔案到硬碟中,那麼這些空間所儲存原先檔案的資料內容是仍然存在的。你只要找到原先記錄檔案的檔頭,把資訊修補回來,就可以把檔案拯救回來,這就是檔案救援的原理。
硬碟裡面的資料並沒有被完全刪除,而只是檔案標頭被刪除,檔案的位子被釋放出來。


  回到本題重點,今天要在這邊分享的是我們所遇到的,當我隨身碟一插上電腦上的USB傳輸孔,突然看到我的隨身碟裡面居然是空白而且無資料,當下我心想慘了,隨身碟有32G裡面的東西全部都消失了,在裡面放了好多重要的資料,而且沒有備份一份在電腦中,要怎麼辦呢?




  馬上看一下是否是我帶錯隨身碟還是電腦抓錯呢?當我把下又插上去的時候我突然發現這個隨身硬碟是我原本的沒錯阿!可是怎會32G記憶體有8M是被佔用的呢?接下來就使用了以下的軟體去做救援了,真的所有的資料都救回來了,在救援之後我也做了一些小實驗,想說那只是把資料釋放而已,那要如何真的完全都刪除呢?不然哪一天把自己的隨身碟借給別人的時候,不小心的就把個人所有的資料都送出去給別人了呢~~~

推薦的免費檔案救援軟體


Recuva







 一、選擇要救援的檔案類型。
  

 二、選擇儲存媒體,如記憶卡、隨身碟等。



三、按下開始,開始搜尋中。

相片救援Recuva-5



硬碟格式化之後檔案可以救回嗎?

  Windows的格式化有兩種,一種是快速格式化,一種是完整格式化。快速格式化的原理其實與前述的檔案刪除原理類似,他只是修改了硬碟用來管理所有檔案的檔案配置表,讓系統檢查的時候,顯示並沒有檔案在硬碟中。但是事實上資料還是保存在原本硬碟的位置上,只是整顆硬碟所有的空間都被釋放出來而已。在這種情況下,資料救回來的機率是很大的。



預設是快速格式化,而並非真正的清除唷!