// Created by vince // Copyright (c) 2014年 vince. All rights reserved. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace delegate_test { //delegate type delegate void myDelegate(string name); class Program { static void Main(string[] args) { invokeDelegate(man, "vince"); invokeDelegate(lady, "Apple"); } //using delegate to call method static void invokeDelegate(myDelegate hello, string name) { hello(name); } //method static void man(string name) { Console.WriteLine("Hi, Mr."+name); } static void lady(string name) { Console.WriteLine("Hey, Ms."+name); } } }
Google Code Prettify
2014年11月7日 星期五
C# delegate(委派) 使用教學
2014年11月4日 星期二
繼電器(relay)原理
一般的繼電器,又稱作relay,是由一組電磁鐵、彈簧及簧片所組成,
利用電磁鐵的啟動,產生磁力吸引彈簧來控制迴路的導通。
通常會在relay上看到幾個縮寫:
COM(common):一般這邊是接地
NO(normal open):迴路接這裡處於導通狀態(電磁鐵未通電)
NC(normal close):迴路接這裡處與不倒通狀態,直到電磁鐵通電後才導通
如下圖所示,利用relay控制兩個燈泡
線圈未導通,NO迴路開啟
線圈導通,NC迴路開啟
通常選用relay要確認電壓適用範圍、電流供應大小,
電壓電流選用不當會導致relay切換不順(親身經驗orz)
圖片來源:PLC lecture01
2014年8月29日 星期五
搜尋PTT全部版的文章
2014年3月27日 星期四
windows 使用 winmm.lib 錄音(windows sound recording using winmm.lib)
在windows 下有一個 winAPI library 可以實現錄音的功能
API 說明可以參考 MSDN 網站:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd743833(v=vs.85).aspx
這裡主要是介紹如何將電腦麥克風的聲音錄起來,
並存成 wav 檔
1.Audio 結構
在聲音的格式中,定義在 WAVEFORMATEX 這個結構中:
typedef struct { WORD wFormatTag; //audio format,這裡使用WAVE_FORMAT_PCM WORD nChannels; //1為單聲道,2為雙聲道 DWORD nSamplesPerSec; //每秒採集的聲音sample數量 DWORD nAvgBytesPerSec; //每秒傳送byte數量 WORD nBlockAlign; //nBlockAlign = (nChannels*wBitsPerSample)/8; WORD wBitsPerSample; //每個sample儲存多少bit的資料,一般為8bit or 16bit WORD cbSize; //額外資訊的大小,通常是non-PCM時,才會用到,這裡設0 } WAVEFORMATEX;
聲音的採集資料,定義在 WAVEHDR 這個結構中:
typedef struct { LPSTR lpData; //buffer的資料 DWORD dwBufferLength; //buffer的長度 DWORD dwBytesRecorded; //buffer的資料大小(bytes) DWORD dwUser; //通常為0 DWORD dwFlags; //描述額外的資料 DWORD dwLoops; //在播放的時候使用 struct wavehdr_tag* lpNext;//應該給link list用 DWORD reserved; //保留 } WAVEHDR;
2.使用API
使用windows API錄音 主要利用到下面函式:
waveInOpen() //開啟錄音裝置 waveInPrepareHeader() //buffer header 準備 waveInAddBuffer() //輸入buffer waveInStart() //開始錄音 waveInStop() //停止錄音 waveInUnprepareHeader() //buffer header 清空 waveInClose() //關閉錄音裝置
3.code ( 含儲存成wav檔 )
#include "stdafx.h" #include "windows.h" #pragma comment(lib, "winmm.lib") //windows API library for wave #define DATASIZE 22050*2*5 //SamplesPerSec * byte per sample * duration time int _tmain(int argc, _TCHAR* argv[]) { HWAVEIN audio_in; WAVEFORMATEX audio_format; //structure of wave format WAVEHDR audio_header; int log; char* soundBuffer[DATASIZE]; audio_format.wFormatTag=WAVE_FORMAT_PCM; audio_format.nChannels=1; audio_format.nSamplesPerSec=22050; audio_format.wBitsPerSample=16; audio_format.cbSize=0; audio_format.nBlockAlign = (audio_format.nChannels * audio_format.wBitsPerSample)/8; audio_format.nAvgBytesPerSec = (audio_format.nSamplesPerSec*audio_format.nBlockAlign); log = waveInOpen(&audio_in,WAVE_MAPPER,&audio_format,NULL,NULL,NULL); //open input device if (log == MMSYSERR_NOERROR) printf("waveInOpen success\n"); else printf("waveInOpen fail\n"); audio_header.dwFlags=0; audio_header.dwUser=0; audio_header.dwLoops=0; audio_header.dwBytesRecorded=0; audio_header.lpData = (LPSTR)soundBuffer; audio_header.dwBufferLength = DATASIZE; //prepare buffer header log = waveInPrepareHeader( audio_in, &audio_header, sizeof(WAVEHDR) ); if (log == MMSYSERR_NOERROR) printf("waveInPrepareHeader success\n"); else printf("waveInPrepareHeader fail\n"); //send buffer to input device log = waveInAddBuffer( audio_in, &audio_header, sizeof(WAVEHDR) ); if (log == MMSYSERR_NOERROR) printf("waveInAddBuffer success\n"); else printf("waveInAddBuffer fail\n"); if (! waveInStart(audio_in) ) //start recording printf("recording start for 5 sec...\nenter any char to stop\n"); else printf("recording fail...\n"); getchar(); if (! waveInStop(audio_in) ) //stop recording printf("recording stop\n"); else printf("recording stop fail\n"); //clean buffer header if(waveInUnprepareHeader(audio_in, &audio_header, sizeof(WAVEHDR))) printf("UnPrepare Header fail\n"); else printf("UnPrepare Header success\n"); Sleep(500); if (waveInClose(audio_in)==MMSYSERR_NOERROR) printf("waveInClose success\n"); else printf("waveInClose fail\n"); //saving as wave file MMCKINFO wav_file_header1; MMCKINFO wav_file_header2; HMMIO wav_file; MMRESULT result; long wav_log; //create wav file wav_file = mmioOpen(L"wavfile.wav",NULL,MMIO_CREATE|MMIO_WRITE|MMIO_EXCLUSIVE | MMIO_ALLOCBUF); if(wav_file == NULL) printf("mmioOpen fail\n"); ZeroMemory(&wav_file_header1, sizeof(MMCKINFO)); wav_file_header1.fccType=mmioFOURCC('W', 'A', 'V', 'E'); result = mmioCreateChunk(wav_file ,&wav_file_header1, MMIO_CREATERIFF); //create RIFF chunk if (result==MMSYSERR_NOERROR) printf("mmioCreateChunk: wav_file_header1 %s ok\n",result); else printf("mmioCreateChunk: wav_file_header1 fail\n"); ZeroMemory(&wav_file_header2, sizeof(MMCKINFO)); wav_file_header2.ckid=mmioFOURCC('f', 'm', 't', ' '); wav_file_header2.cksize=sizeof(WAVEFORMATEX)+audio_format.cbSize; //create fmt chunk result = mmioCreateChunk(wav_file ,&wav_file_header2, 0); if (result==MMSYSERR_NOERROR) printf("mmioCreateChunk wav_file_header2 %s ok\n",result); else printf("mmioCreateChunk wav_file_header2 fail\n"); //輸入fmt chunk的data wav_log = mmioWrite(wav_file ,(char*)&audio_format,sizeof(WAVEFORMATEX)+audio_format.cbSize); if(wav_log==-1) printf( "mmioWrite audio_format fail\n"); else printf( "mmioWrite write %d bytes\n",wav_log); //跳出fmt chunk result = mmioAscend(wav_file,&wav_file_header2,0); if (result==MMSYSERR_NOERROR ) printf( "mmioAscend wav_file_header2 %s ok\n",result); else printf( "mmioAscend wav_file_header2 %s fail\n",result); wav_file_header2.ckid=mmioFOURCC('d', 'a', 't', 'a'); //create data Chunk result = mmioCreateChunk(wav_file ,&wav_file_header2,0); if (result==MMSYSERR_NOERROR) printf( "mmioCreateChunk wav_file_header2 %s ok\n",result); else printf( "mmioCreateChunk wav_file_header2 %s fail\n",result); printf("audio_header %d BytesRecorded\n",audio_header.dwBytesRecorded); //輸入audio data wav_log = mmioWrite(wav_file,(char*)audio_header.lpData,DATASIZE); if(wav_log==-1) printf( "mmioWrite audio data fail\n"); else printf( "mmioWrite success : write %d bytes\n",wav_log); //跳出data chunk result = mmioAscend(wav_file,&wav_file_header2,0); if (result==MMSYSERR_NOERROR) printf( "mmioAscend wav_file_header2 %s ok\n",result); else printf( "mmioAscend wav_file_header2 %s fail\n",result); //跳出RIFF chunk result = mmioAscend(wav_file,&wav_file_header1,0); if (result==MMSYSERR_NOERROR) printf( "mmioAscend wav_file_header1 %s ok\n",result); else printf( "mmioAscend wav_file_header1 %s fail\n",result); result = mmioClose(wav_file,0); //close the wav file if (result==MMIOERR_CANNOTWRITE){ printf( "mmioClose fail\n"); } return 0; }可以看到儲存下來的wav檔
2014年3月17日 星期一
OpenCV 2.4.8 + mac Xcode 5.1 安裝教學
這次更新成OpenCV 2.4.8,發現跟之前的 OpenCV 2.4.6 + mac Xcode 4.6 安裝教學
安裝方法幾乎99%一樣,這次使用的Mac air是最近才換的,Xcode首灌就獻給這篇了XD
安裝環境:
MAC OSX 10.9
OpenCV 2.4.8
Xcode 5.1
1.下載opencv: http://opencv.org/
右邊有一個opencv for linux/mac
點下去就會自動下載了
2.安裝homebrew: http://brew.sh/
這是一個很好用的mac安裝許多程式的軟體
只要在終端機上輸入
ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
就會自動下載安裝了
終端機可以在下圖找到
3.安裝cmake: http://www.cmake.org/
在終端機輸入
brew install cmake
就會自動下載安裝了
4.安裝Xcode:
直接去App Store 下載安裝,Xcode是免費的
5.安裝opencv:
將下載回來的opencv壓縮檔解壓縮會跑出資料夾
使用終端機進入解壓縮後的資料夾
比較不熟linux指令的人
可以先用在終端機輸入 => ls ,看現在位置的資料夾
再終端機依序輸入 => cd 資料夾名稱 ,進入壓縮的資料夾中
可以在終端機輸入 => pwd ,確認當前位置
接著依序輸入
mkdir release
cd release
cmake -G "Unix Makefiles" ..
make
sudo make install
依序完成以上步驟就全都安裝好囉
接下來是新建opencv project
6.建立opencv project:
開啟Xcode 建立專案
建立名稱後 下面type選擇 c++
建立後到build setting -> All
到search paths中設定路徑
library search paths 中 輸入 /usr/local/lib
header search paths 中輸入 /usr/local/include /usr/local/include/opencv
7.include lib:
在專案名稱上面按右鍵
選擇add files to.....
進入後直接按下 / 就會跳出go to the folder 再輸入 /usr/local/lib
接著把所有的有xxx.2.4.8.dylib檔案都加進去
以上所有環境都設定好囉
可以開始試試看程式了!!!
8.final test:
貼上以下code
// // main.cpp // tutorial_opencv2.4.8 // // Created by Vince on 2014/3/17. // Copyright (c) 2014年 vince. All rights reserved. // #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" using namespace cv; using namespace std; int main(int argc, char *argv[]) { cv::Mat src; src=cv::imread("/Users/Vince/Documents/MyPictures/apple logo.jpeg", -1); //上面的路徑為圖片路徑 cv::imshow("show image",src); //這邊會show圖出來 cv::waitKey(0); return 0; }
如果看得到圖片就大功告成囉~~
2014年3月16日 星期日
Sublime text Package for Arduino
最近發現一個Arduino的Package Stino
它是一個Open Source的專案,
可以直接透過Sublime text 編譯Arduino程式,
最讓我覺得實用的功能是他有Key word Highlight 和 Auto pop,
這樣就不用每次打code時還要把完整的keyword打完
效率增加不少喔~
1.準備工具
Sublime Text 2 or 3
Arduino主程式
2.安裝套件
有兩種安裝方式,Console下指令安裝或下載檔案安裝
//------------------------------------------------------------------------------------------------------------
Console下指令安裝:
開啓Sublime text -> view ->show console
依自己安裝的版本貼上
Subtext text2:
import urllib2,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404' + 'e330c659d4bb41d3bdf022e94cab3cd0'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); os.makedirs( ipp ) if not os.path.exists(ipp) else None; urllib2.install_opener( urllib2.build_opener( urllib2.ProxyHandler()) ); by = urllib2.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); open( os.path.join( ipp, pf), 'wb' ).write(by) if dh == h else None; print('Error validating download (got %s instead of %s), please try manual install' % (dh, h) if dh != h else 'Please restart Sublime Text to finish installation')
Sublime text3:
import urllib.request,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404' + 'e330c659d4bb41d3bdf022e94cab3cd0'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)
完成後將Sublime text關掉後重開
重新開啟後,Preferences->Package Control
輸入 Package Control: Install Package
接著輸入 Arduino-like IDE 安裝套件
//-----------------------------------------------------------------------------------------------------------------
下載檔案安裝:
Preferences -> Browse packages
將剛剛下載的 Stino-master 解壓縮到資料夾中就完成囉!
3.設定Arduino編譯器
開啟Arduino標頭列
這時候會發現標頭列已經有Arduino的選項出現
Arduino->Preferences->Select Arduino Application Folder
找到你的Arduino.app的安裝路徑
看到這個就代表安裝編譯器設定完成了
Arduino -> New Sketch
可以看到keyword 會auto pop
打完就可以編譯和燒錄板子囉!!
2014年3月7日 星期五
Sublime Text for Verilog Plugin in MAC
1.到官網下載verilog package
http://sublimetextinfo.sourceforge.net/pages/Verilog.html
2.找到sublime text 的安裝目錄
進入資料夾 Contents —> MacOS —> Packages
將下載的 Verilog.sublime-package 放入資料夾內重新開啓sublime text 就可以了
3.結果測試
2014年3月4日 星期二
Altera DDR2 Controller Tutorial
1.使用Altera
DDR2 IP
2.IP訊號定義
local_addr[23:0]
|
input
|
DDR2儲存位置,每個記憶體位置儲存32個bit資料
|
local_be[15:0]
|
input
|
寫入資料用,每筆資料全部寫入下16'hFFFF
|
local_burstbegin
|
input
|
For
write req and read req,每筆資料拉high做讀或寫
|
local_read_req
|
input
|
讀取資料訊號
|
local_write_req
|
input
|
寫入資料訊號
|
local_size[]
|
input
|
Size
= 2 for DDR2
|
local_wdata[]
|
input
|
寫入資料,這裡為128bit,寫入4個記憶體位置,每32bit一筆
|
local_rdata[]
|
output
|
讀出資料,這裡為128bit,讀出4個記憶體位置,每32bit一筆
|
local_init_done
|
output
|
DDR2初始化完成訊號
|
local_rdata_valid
|
output
|
可以開始接收讀出的資料
|
local_ready
|
output
|
Pull
high時burstbegin才有效
|
3.IP訊號
Write:
在ready
pull high時,burstbegin每pull
high一次,寫入2
(local_size) 筆資料,
記憶體位置則增加8
Read:
在ready
pull high時,burstbegin就pull
high,請求讀2
(local_size) 筆資料,
記憶體位置則增加8,read_req則pull
high到請求讀出的資料位置最末筆。
當local_valid訊號pull
high時,開始讀出資料,每筆資料有4個記憶體位置,
pull
low時讀取結束
2014年3月3日 星期一
Altera ModelSim Tutorial
1.下載檔案
Altera
官網下載最新的ModelSim
(http://www.altera.com/products/software/quartus-ii/modelsim/qts-modelsim-index.html)
2.建立ModelSim
專案
註:路徑和檔名最好以英文命名才不會發生錯誤
3.增加編譯好的 .V檔(包括testbench的檔案)
選擇Copy
to project directory 後按OK
4.編譯檔案
選擇Compile All,檔案編譯完成後status會從" ? " 變成 "√"
5.選擇模擬檔案
在路徑work裡選擇testbench檔
6.執行結果
在view
→ 勾選
Objects
和
Wave
將要顯示的input 或 output Pin拖曳到 wave 視窗
選擇模擬時間,按下Run(F9)開始模擬,
訂閱:
文章 (Atom)