// 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)














































