2013年4月4日 星期四

Arduino : PWM 輸出


就像類比輸入一樣,在真正的物理世界中我們經常需要輸出除了01之外的其他數值。例如,除了想用微控制器找開或者關閉電燈之外,我們還會想控制燈光的亮度,這時就需要用到類比輸出。

由於Arduino的微控制器只能產生高電壓(5V)或者低電壓(0V),而不能產生變化的電壓,因此必須採用脈寬度調變技術(PWMPulse Width Modulation)來模仿類比電壓。

脈衝寬度調變 (Pulse Width Modulation,PWM) 是將類比訊號轉換為脈波的一種技術,一般轉換後脈波的週期固定,但脈波的占空比會依類比訊號的大小而改變。PWM的使用隨著數位控制邏輯電路的增加而普及,該技術提供簡單的方法,可讓數位控制邏輯電路建立相當於類比的功能。許多微控制器都內建 PWM功能。PWM同時也可用於通訊系統,因為數位訊號比較穩定,也比較不容易受到雜訊干擾。

555  Duty cycle (PWM) 控制馬達


PWM是一種開關式穩壓電源應用,它是借助微處理器的數位輸出來對類比電路進行控制的一種非常用效的技術,廣泛應用在從測量、通信到功率控制與變換的許多領域中。

簡而言之,PWM是一種對模擬信號位準進行數位編碼的方法,它通過對半導體開關元件的導通和關斷進行控制,使輸出端得到一系列幅值相等但寬度不相等的脈衝,而這些脈衝能夠被用來代替正弦波或其它所需要的波形。

Arduino數未I/O接腳 91011上,我們可以通過analogWrite()函數來產生模擬輸出。該函數有兩個參數,其中第一個參數是要產生模擬信號的引腳(910或者11);第二個參數是用於產生模擬信號的脈衝寬度,取值範圍是0255。脈衝寬度的值取0可以產生0V的模擬電壓,取255則可以產生5V的模擬電壓。不難看出,脈衝寬度的取值變化1,產生的模擬電壓將變化0.0196V5V/255 = 0.0196V)。

本實驗中我們將用類比輸出來調暗發光二極管(LED),由於正常情況下LED對電壓的變化非常敏感,因此當脈衝寬度變化時人眼會感覺到LED實際上是在不斷地熄滅和點亮,而不是逐漸變暗。解決這一問題可以採用濾波電路,它能使有用頻率信號通過而同時抑制(或大大衰減)無用頻率信號。  (R/C 低通)

                 cut frequency = 0.16/ (220*10^-5)= 80Hz

實驗中我們採用的是低通濾波器,它的原理非常簡單,只需要一個電阻和一個電容,能夠很好地過濾掉電路中超過某一頻率的信號。此處給出的電路並不能校平所有脈衝,它之所以被稱為低通濾波是因為它只允許頻率低於某個限度的脈衝通過,對於高於這個限度的脈衝則被平衡為偽類比電壓,濾波的頻率範圍由電阻器和電容器的比值決定。








int potPin = 5;
int ledPin = 11;

byte bright_table[] = {  30,  30,  30,  40,  50,  60,  70,  80,  90, 100,110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100,  90,  80,  70,  60,  50,  40,  30,  30,  30 };
int MAX = 50;
int count = 0;
int val = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  analogWrite(ledPin, bright_table[count]);
  count ++;
  if (count > MAX) {
    count = 0;
  }

  val = analogRead(potPin);
  val = val /4;
  delay(val);
}


本實驗用 analogWrite()函數在數位I/O端口的11號接腳上模仿類比輸出,每產生一次輸出後都設置了相應的延時Delay ,而延時的長度由類比輸入端口5號接腳上的電位器來決定。通過調整電位器的位置,我們可以觀察到LED逐漸變亮後再逐漸變暗的效果。

Arduino : 類比輸入來控制LED 閃爍的頻率


Arduino的優勢在於對數位信號的識別和處理,但我們的真實世界並不是數位(digital)的,簡單到只要用01就能夠表示所有的現象。

例如溫度的變化,它只能在一個範圍之內連續變化,而不可能發生像從01這樣的瞬時跳變,類似這樣的物理量被人們稱為是類比(analog)的。

Arduino是無法理解這些類比量,它們必須在經過類比轉換後變成數位量後(A/D converted),才能被Arduino進一步處理。

像溫度這樣的數據必須先被轉換成微處理器能夠處理的數位形式(比如電壓),才能被Arduino處理,這一任務通常由各類感測器(sensor)來完成的。

例如,電路中的溫度感測器能夠將溫度值轉換成0V5V間的某個電壓,比如 0.3V 、 3.27V 4.99V等。由於感器輸出的是類比信號,它不會像數位信號那樣只有簡單的Hi 和 Lo,而有可能是在這兩者之間的任何一個數值。至於到底有多少可能的值則取決於類比轉換(ADC)的精度,精度越高能夠得到的值就會越多。

Arduino所採用的ATmega8微處理器一其有6個模數轉換器(ADCAnalog to Digital Converter),每一個模數轉換器的精度都是10bit,也就是說能夠讀取10242^10 = 1024)個狀態。

Arduino的每一個類比輸入接腳上,電壓的變化範疇是從0V5V,因此Arduino能夠感知到的最小電壓變化是4.8毫伏(5V/1024 = 4.8mV)。

電位計(potentiometer)是一種最簡單的類比輸入設備,它實際上就是一個可變電阻,通過控制滑稈所在的位置我們可以得到不同的電壓值,而輸入信號正是從滑稈所在的位置接入到電路中的。


這一實驗我們將通過改變電位計的值來控制發光二極管閃爍的頻率。電位計上一共有三個接腳,分別連接到Arduino的電源、地和類比輸入的5號接腳上,LED則連接到數位I/O的7到14號接腳上,原理圖如下所示:




int BASE = 2;
int NUM = 8;
int index = 0;
int potPin = 5;  //analog input
int val=0;

void setup()
{
  for (int i = BASE; i < BASE + NUM; i ++) {
    pinMode(i, OUTPUT);
  }
 }

void loop()
{
  val= analogRead(potPin); 

   for (int i = BASE; i < BASE + NUM; i ++) {
       digitalWrite(i, HIGH);  }
   delay(val);
   for (int i = BASE; i < BASE + NUM; i ++) {
       digitalWrite(i, LOW);  }
   delay(val);
 }



Arduino中,對類比輸入口不需要用 pinMode()函數 將其指定為輸入或者是輸出模式,這點同數位I/O口是有所不同的。

通過旋轉電位計的軸,我們能改變電位計中間那根連線同地之間的電阻量,從而也就能改變從類比輸入的5號管腳上所讀入的模擬量的值。當電位計完全旋轉到頭時,輸入到類比輸入接腳上的電壓為0V,用analogRead()函數讀出的值為0;當電位計完全旋轉到另一頭時,輸入到類比輸入接上的電壓為5V,此時用analogRead()函數讀出的值為1023

當電位計旋轉到中間的某個位置時,輸入到模擬輸入管腳上的電壓是0V5V之間的某個值,而用analogRead()函數讀出的則是位於01023之間的某個對應值。

讀出的類比輸入量在我們的實驗中被用來確定LED點亮和熄滅的時間,以反映類比量的變化。



2013年4月3日 星期三

Arduino : Digital Input



在數位電路中開關(switch)是一種基本的輸入形式,它的作用是保持電路的連接或者斷開。
Arduino從數I/O pin接腳上只能讀出高電平(5V)或者低電平(0V),因此我們首先面臨到的一個問題就是如何將開關的開/斷狀態轉變成Arduino能夠讀取的高/低電平。解決的辦法是通過上/下拉電阻,按照電路的不同通常又可以分為正邏輯(Positive Logic)和負邏輯(Inverted Logic)兩種。

在正邏輯電路中,開關一端接電源,另一端則通過一個10K的下拉電阻接地,輸入信號從開關和電阻間引出。當開關斷開的時候,輸入信號被電阻向地,形成低電平(0V);當開關接通的時候,輸入信號直接與電源相連,形成高電平。對於經常用到的按壓式開關來講,就是按下為高,抬起為低。




在負邏輯電路中,開關一端接地,另一端則通過一個10K的上拉電阻接電源,輸入信號同樣也是從開關和電阻間引出。當開關斷開時,輸入信號被電阻向電源,形成高電平(5V);當開關接通的時候,輸入信號直接與地相連,形成低電平。對於經常用到的按壓式開關來講,就是按下為低,抬起為高。



為了驗證Arduino數位I/O的輸入功能,我們可以將開關接在Arduino的任意一個數字I/O接上(13除外),並通過讀取它的接通或者斷開狀態,來控制其它數I/O接腳的高低。

本實驗採用的原理圖如下所示,其中開關接在數I/O的12號腳上,被控的發光二極管接腳在數I/O的7到14號腳上:







// I/O Pin12 = High   8 LED Flashing (all on , all off)
// I/O Pin12 = LOW    8 LED Alternately flashing 1 by 1


int BASE = 2;
int NUM = 8;
int index = 0;
int inpin=12;
int val;

void setup()
{
  for (int i = BASE; i < BASE + NUM; i ++) {
    pinMode(i, OUTPUT);
  }
  pinMode(inpin,INPUT);

}

void loop()
{
val=digitalRead(inpin); 
if(val==LOW) 
{  for (int i = BASE; i < BASE + NUM; i ++) {
   digitalWrite(i, LOW);
  }
  digitalWrite(BASE + index, HIGH);
  index = (index + 1) % NUM;
  delay(100);
}
else
  for (int i = BASE; i < BASE + NUM; i ++) {
   digitalWrite(i, HIGH);
  }
   delay(100);
   for (int i = BASE; i < BASE + NUM; i ++) {
   digitalWrite(i, LOW);
  }
   delay(100);
}
  
}












Arduino : digital output 8 LED


Arduino的數位I/O被分成兩個部分,其中每個部分都包含有6個可用的I/O管腳,即pin2到pin7 和 pin8到pin13除了pin13上接了一個1K的電阻之外,其他各個管腳都直接連接到ATmega上。

我們可以利用一個6(8)位的digital跑馬燈,來對Arduino數字I/O的輸出功能進行驗證,以下是相應的原理圖:

電路中在每個I/O PIN上加的那個1K限流電阻阻,由於LED在電路中沒有等效電阻值,使用限流電阻可以使元件上通過的電流不至於過大,能夠起保護作用。
程式如下:




int BASE = 2;
int NUM = 8;
int index = 0;

void setup()
{
  for (int i = BASE; i < BASE + NUM; i ++) {
    pinMode(i, OUTPUT);
  }
}

void loop()
{
  for (int i = BASE; i < BASE + NUM; i ++) {
    digitalWrite(i, LOW);
  }
  digitalWrite(BASE + index, HIGH);
  index = (index + 1) % NUM;
  delay(100);
}



2013年3月29日 星期五

Arduino 入門 LED 閃爍實驗






int ledPin = 10; //定義數位 pin 10 介面

void setup()
{
pinMode(ledPin, OUTPUT);//定義LED為輸出介面
}

void loop()
{
digitalWrite(ledPin, HIGH); //ON LED
delay(1000); //延時1

digitalWrite(ledPin, LOW); //OFF LED
delay(1000); // 延時1
}

Arduino 入門 Hello World!




int val;     //定義變數val
int ledpin=13;   //定義數位介面pin 13

void setup()

Serial.begin(9600);  //設定串列傳輸速率為9600

pinMode(ledpin,OUTPUT);//設定數位13 為輸出介面
}


void loop()
{
val=Serial.read();   //讀取PC 發送給Arduino 的指令或字元
                         //並將該指令或字元賦予val

if(val=='R')   //判斷接收到的指令或字元是否是R

{  //如果接收到是R

digitalWrite(ledpin,HIGH); //ON 數位13 的LED。
delay(500);
digitalWrite(ledpin,LOW);  //OFF 數位13 的LED。
delay(500);
Serial.println("Hello World!"); //顯示「Hello World!」字串
                                      //於Serial Port Monitor 上

}     //end if   

Arduino Uno安裝設定















Arduino Uno板子正面照。















背面上印有"R3"。

USB cable連接板子與電腦後,Windows會出現新增硬體視窗
因為要自行指定驅動程式,所以選「不,現在不要」。


然後選從清單或特定位置安裝(進階)


只勾選「搜尋時包含這個位置」,按下「瀏覽」,

指向Arduino軟體解壓縮後的目錄下的drivers目錄。


然後就會開始安裝了。


安裝時,你可能要按下「繼續安裝」。


DRIVER安裝完成。


接下來,要找出Arduino板子被接到哪一個序列埠上。

雖然用的是USB連接線,其實是將USB模擬成序列埠。


首先到「Tools」-「Board」設定你用的是哪塊板子。
Arduino UNO

然後到「Tools」-「Serial Port」設定的com port 。
COMX

Arduino軟體提供一些寫好的程式範例,我們可以拿來測試看看。
請選「File」-「Examples」-「1.Basics」-「Blink」。



Node-Red --> MQTT --> Fuxa

Node-Red --> MQTT --> Fuxa      FUXA(一個開源的 Web HMI / SCADA 自動化監控軟體)的專案設定檔 。 這份設定檔完整定義了 HMI 監控畫面的 後端通訊(MQTT 連線、點位標籤) 與 前端網頁圖形介面(SVG 畫布...