2015年1月6日 星期二

Arduino power consumption reduction

要試著將我手上的Arduino Pro Mini功耗降到最低,我上網查了一些文章,
也做了一些實驗。結果就是讓板子在進到power down mode時,功耗為
18.7uA/3.3V。如果有那位大大知道如何讓功耗再往下降,請不吝指教。


在一開始我參考下面reference列的那個網址,在進到power down mode
的功耗是112uA,後來去修改register MCUCR去關掉BOD,功耗降到
106uA。後來再去修改register PRR,將Timer0~2,TWI,SPI,USART0,
ADC關掉,才讓功耗降到18uA。此外原本reference code是用函式
sleep_mode()來進到sleep mode,但這個函式會去打開一些前面關掉的
設定,所以要改用函式sleep_cpu()來進sleep mode。

為了去降低功耗,也需要硬體去配合,我將Arduino Pro Mini上的U2
LDO拆掉,還有紅色的LED1也拿掉。另外將INT0 pin接到一個button
,當系統開機後3秒,會自動進到sleep mode,這時再按下button,
就可以觸發 attachInterrupt事件,來喚醒MCU。
#include <avr/sleep.h>
#include <avr/power.h>       
void setup(void)
{
    // the GPIO comprise 3 part, B,C,D.
    DDRD &= B00000011;       // set Arduino pins 2 to 7 as inputs, leaves 0 & 1
    DDRB = B00000000;        // (RX & TX) as is set pins 8 to 13 as inputs
    PORTD = B00000100;      // disable pullups on pins 3 to 7
    PORTB = B00000000;      // disable pullups on pins 8 to 13
    pinMode(13,OUTPUT);      // set pin 13 as an output so we can use LED to monitor
    digitalWrite(13,HIGH);   // turn pin 13 LED on
    Serial.begin(9600); 
}
                //
void loop(void)
{
    // Stay awake for 1 second, then sleep.
    // LED turns off when sleeping, then back on upon wake.
    delay(3000);
    sleepNow();
}
                //
void sleepNow(void)
{
   Serial.println("Go to sleep");
    
    // Set pin 2 as interrupt and attach handler:
    attachInterrupt(0, pinInterrupt, LOW);
    delay(100);
    //
    // Choose our preferred sleep mode:
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    //
    // Set sleep enable (SE) bit:
    sleep_enable();
    digitalWrite(13,LOW);   // turn LED off to indicate sleep
    // Put the device to sleep:
     MCUCR |= bit(BODSE) | bit(BODS); // timed sequence
     MCUCR = (MCUCR & ~bit(BODSE)) | bit(BODS);
  
     ADCSRA &= ~(1 << ADEN);
     PRR = 0xFF;
     sleep_cpu();
    //sleep_mode();

    // Upon waking up, sketch continues from this point.
    sleep_disable();
    Serial.println("sleep disable");
    digitalWrite(13,HIGH);   // turn LED on to indicate awake
    PRR = 0x00;
   //  delay(10000);
}
                //
void pinInterrupt(void)
{
    Serial.println("Interrupt");
    detachInterrupt(0);
}

下表為各個power mode,它有那些block是開著或關掉。


我們利用下面的函式就可以改變sleep mode,在各個sleep mode可以得到不同的功耗。
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
VCC=3.3V
ACTIVE_MODE                         8.0mA
SLEEP_MODE_IDLE                1.56mA
SLEEP_MODE_ADC                1,.02mA
SLEEP_MODE_PWR_SAVE    0.65mA
SLEEP_MODE_STANDBY       0.65mA
SLEEP_MODE_PWR_DOWN  18.7uA.





Reference.
http://www.engblaze.com/hush-little-microprocessor-avr-and-arduino-sleep-mode-basics/

2014年12月21日 星期日

Arduino to Bluetooth module HC-06 for wireless control

Arduino經由BT module就可以做無線控制的功能,可以應用在IOT,遙控車。我在
淘寶買了一個BT module HC-06,花了大約20塊人民幣。我想先做個最簡單的功
能,也就是控制LED。由於還不會寫Android程式,所以先用PC內建的BT來做控
制。我在PC上的終端機,在BT的com port也就是UART,輸入L (light) or D (dark)
字元,然後透過BT傳送到Arduino板子的UART port,當Arduino板子接收到L or D
字元,就會去控制LED的亮暗。

1.由於寫程式需要用到UART port來燒錄,需要先將Arduino UART port接到 USB
   to UART的轉板,然後燒錄下面的程式。BT module對於Arduino的板子來說,
  只是一個UART介面的IC,所以Arduino MCU都是用Serial的函式來與BT module
  溝通。由於HC-06預設的Baud rate是9600bps,所以MUC需要用9600bps來跟
   HC-06來跟它溝通。另外我用到Arduino板子上的綠光LED,當MCU接收到"L"
   就將ledPin設置為1,LED就會亮。當接收到"D",就將ledPin設置為0,LED就會
   暗。

const int ledPin = 13; 
int incomingByte = 0;
void setup() 
{
  // open a serial connection
  pinMode(ledPin, OUTPUT); 
  Serial.begin(9600); 
 Serial.println("Control start, please press L or D");
}
void loop()
{
while (Serial.available()) 
{
  incomingByte=Serial.read();
if ( incomingByte=='L')
{
  digitalWrite(ledPin, 1);
  Serial.println("Turn on LED");
}
else if ( incomingByte=='D')
 {
   Serial.println("Turn off LED");
   digitalWrite(ledPin, 0);
 }
else
{
  Serial.println("Wrong input");
}
}
}

2.程式燒錄完後,就可以連接Arduino板子與HC-05,這時你的Arduino板子已經脫離
   你的PC了。我們只需要接VCC,GND,TXD,RXD 4條線,注意module的TXD要接到
    Arduino板子的RXD,module的RXD要接到Arduino板子的TXD。最後再供外部電
    源5V或3.3V給VCC pin,等於是同時供電給Arduino板子與HC-06。










3.最後我們打開電腦的BT,可以看到您附近有那些BT device,我們選擇連接到
    HC-06後,開啟終端機,就可以看到有一個Bluetooth serial port的選項,點選
    "OK"後,就會出現終端機畫面,這時你輸入keyboard的L或D會出現訊息,而
    LED也會隨著亮或暗。






















注:如果要修改BT module的設定,需要用AT command。我們用USB to UART轉板
        連接到BT module,只需要VCC,GND,TXD,RXD四條線,然後進到終端機模式
        輸入左邊第一排的command就可以來修改BT module的設定。例如輸入"
        AT+PIN1234"就是設定BT module的密碼為"1234",Baud rate也可以修改。
     
command
response
effect

AT+VERSION
OKlinvorV1.6
Gets the version info, no changes

AT+NAMExyz
OKsetname
Sets the module name to "xyz"

AT+PIN1234
OKsetPIN
Sets the module PIN to 1234

AT+BAUD7
OK57600
Sets the baud rate to 57600


Reference:
1.http://wiki.mikrokopter.de/en/HC-06

2014年12月12日 星期五

Arduino to Compass GY-273/HMC5883L 三軸電子羅盤

要在Arduino開發版載入電子羅盤很容易,在網路上有很多相關的網站提供Library與函式,減少入門者開發的時程。下面便是利用網路上的範例程式來驗証HMC5883L三軸電子羅盤。  


1.將Adruino的I2C pin A4,A5接到GY-273的SDA,SCL。GY-273的VCC可以直接接Arduino上的   5V,GY-273支援5~3V輸入。再連接上兩塊板子的GND,硬體設置便完成了。


2.找個blog[1]下載的Library,
3.在壓縮檔內還有一個範例程式HMC5883L_Example.ino,我們可以先用這個程式來驗証GY-273的功能。
4. 當你把程式成功upload到Arduino的板子後,再打開Serial Monitor視窗,就可以看到Arduino從HMC5883L讀到的數值。最左邊是三個軸的Raw data,中間的scaled是將Raw data轉成磁場強度,最右邊這排,便是將Raw data轉成磁角度。



在驗証Library的過程中,如果出現下面編輯的錯誤訊息
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp: In member function 'void HMC5883L::Write(int, int)':
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp:110: error: 'class TwoWire' has no member named 'send'
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp:111: error: 'class TwoWire' has no member named 'send'
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp: In member function 'uint8_t* HMC5883L::Read(int, int)':
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp:118: error: 'class TwoWire' has no member named 'send'
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp:129: error: 'class TwoWire' has no member named 'receive'
這是因為Arduino版本的問題,在舊版的arduino,Wire的函式是用send,receive指令來收發資料,但新的Arduino是用write,read。要修正這個問題,只要將  HMC5883L.cpp內的head檔
#include <WProgram.h>
改成下面這行, 就可以解決這個問題了。
#include <Arduino.h>




Reference
[1] http://bluelemonlabs.blogspot.tw/2013/08/arduino-simple-compass-with-hmc5883l.html

2014年10月31日 星期五

Arduino first step (by Arduino PRO Mini)


1.到Arduino官網下載IDE 程式編輯器,並安裝。
    http://arduino.cc/en/Main/Software
2. 確認您的Arduino編輯器是如何下載image到你的板子。我在淘寶買了CP2102 7.5塊人民幣,
    還有Arduino Pro Mini 15塊人民幣。由電腦的USB port接到CP2102,轉成UART訊號後燒
    錄到Arduino Pro Mini。


2.一開始先打開範例程式,在選單中的File -> Open,然後再Arduino的目錄底下,進到目錄              examples\01.basics, 我們先選一個最容易驗証的例子,在Blink目錄底下,選擇blink.ino。
3. 選擇所使用的Arduino硬體裝置,在工具列選Tools -> Board -> "Arduino PRO or Pro Mini                 (5V, 16MHz) w/ATmega328"   ,這關係到你用的是那一塊Arduino版子。
4.在打開程式後,可以發現程式非常的簡單,這是因為Arduino已經幫你把很多硬體相關的
   初始設定做掉了。你只需要偵對要做的功能來設定。
5.再來就是將程式燒錄到板子上,只要選擇File->Upload,就會進行燒錄了,同時板子的LED
   也會閃爍。
6. 燒錄完成後,就可以看到程式運行的結果。blink.ino的功能是讓LED亮暗,由於LED是接到                  MCU的pin 13,所以在程式裡,設定PIN13為output。在迴圈的開始,先設定pin13為 high
     經過1秒後,再設定為low,經過1秒後再重覆廻圈。LED便會每隔1秒改變一次狀態。

Reference
1. http://arduino.cc/en/Guide/Windows

2014年10月21日 星期二

The amplifier and speaker spec impact on audio performance 放大器與喇叭的規格對於音頻訊號的影響

當Codec的DAC轉出音頻訊號後,需要經過放大器來增強訊號,再透過喇叭將電能轉為聲能,才能發出聲音。要有好的聲音品質需要注意放大器與喇叭的規格,下面列出一些要注意的規格。

Class-D amp 放大器
Class-D amplifier給speaker的最大輸出功率計算,當VDD=5V,在最理想的情況下,輸出電壓Vrms= 5Vx0.707= 3.535V ,當speaker阻抗在8ohm的情況下,輸出功率為V²/R=3.535²/8=1.562W。在4ohm的情況下,可以輸出3.124W。下圖為TI AIC3262 Class-D Amp output spec,它的最大輸出Vrms=3.46V,輸出功率為1.41W,這是在失真10%時量到的數據,如果增加amp的輸出功率,失真度就會超過10%。另外還有幾個影響輸出信號品質的數據,SNR 、THD+N、PSRR。

1.SNR :訊號與雜訊的比率,在放大倍率為6dB (Vo/Vi=2, 20log2=6dB)的條件下, 量測SNR數
                值越大,表示音頻的雜訊越小。
2.THD+N:總諧波失真+N,就是總諧波失真加上雜訊後與訊號的比值,等於把SNR也考慮
                 進去。比值會小於1,再取log,所以是負數。
3.PSRR:電源抑制比,當放大器的電源輸入端出現雜訊時,會產生多少比例的雜訊在放大器
                 輸出端,表示這個放大器抗電源雜訊的能力,數值越大越好。
4,Po      :最大輸出功率,這需要考慮量測的條件,尤其是在不同的放大倍率與THD+N數值的
                 情況下。另外在設定放大器的輸出功率時,需要考慮後級speaker的power rating,
                 輸出功率大於後級的power rating時,有可能會燒掉speaker。



Speaker喇叭
Speaker的規格書上,我主要看它的幾個參數,dimension, impedance,Power rating,lowest resonant Frequency, S.P.L, FR , distortion.


1.Dimension:在物理條件的限制下,一個Speaker的尺寸大小直接影響它的聲音表現。小尺寸                                的喇叭,很難在低音方面能有表現。
2.Impedance:P=V²/R, 當放大器輸出電壓固定的情況下,阻抗越低,能產生的功率越大。但
                       相對的,消耗的電流也會增加。
3.Power rating:喇叭能承受的功率,如果輸出過大的功率給喇叭,是會造成喇叭燒掉的。
而且越大功率的喇叭,不代表能產出的聲音比較大
4.Lowest resonant frequency:最低共振頻率點,這表示喇叭的低頻點,在這個頻率點,喇叭的   阻抗最大。
5.Output Sound Pressure:SPL表示聲壓大小,需要參考它的測試條件。在下面規格書的例子
提供1W給speaker,可以在距離0.5m處,量到81dB的聲壓。供不同的瓦
、在不同的距離量測,量到的聲壓也不同。這個數據也表現出這個speaker
電能與聲能的轉換效率。
6.Frequency Range:表示speaker輸出的頻寬,在下面規格書的例子是量測每個頻率點的SPL,                               要能大於Average SPL-10dB,才算是在頻帶內。
7.Distortion  :失真度,下面的例子是供speaker 1W,量測1Khz頻率點,失真最多為5%。如果                                提供超過1W的能量給Speaker,失真度就可能超過5%。

上圖為speaker的頻率響應圖,可以看出在頻帶450~20kHz,SPL都在70dB以上。但由於speaker
最低共振頻率點為900Hz,所以900Hz以下的頻率點,失真度都會過高。

Reference
1.http://www.ti.com/product/tlv320aic3262
2.http://www.endrich.com/es/55825/altavoces+din%C3%A1micos?prodnav=2_55825