這篇文章是來解釋USB PD在TypeC是如何來進行的。TypeC與Type A/B在流程
上不同的是,Type-C需要先建透過CC pin去建立兩端DFP與UFP。而TypeA/B
的角色從Connector的公母端,就已經確定的,而TypeAB則是用ID pin來判斷
誰是DFP或UFP。當DFP與UFP透過Type-C連接,會先進行下面四點,這個在
我的另一篇網誌有解釋過了。
1. Detect attach of USB ports, e.g. a DFP to a UFP
2. Resolve cable orientation and twist connections to establish USB data
bus routing
3. Establish DFP and UFP roles between two attached ports
4. Configure VBUS: USB Type-C Current modes
在上面四點完成後,便開始進行USB PD的連接與溝通,這時VBUS電壓是5V,
電流是依照Type-C current mode,再來便是進行Power Negotiation
(PD spec 8.3.2.3)。
1.Power Source會周期性的持續送Source Capabilities messages,
2.當Source收到SINK送出的GoodCRC,表示兩端PD已連接。
3. 連接後,SINK會送出Request message,裡面包括
4.Source認可SINK的Request後,發Accept給UFP。
5.Source轉換到SINK Request的電壓後,發PS_RDY給SINK。。
6.Power Negotiation完成,SINK開始依照新的供電來運作。
PD Negotiation的第3個動作,如果Source的Capabilities不能滿走SINK在電壓
或電流的需求,SINK送出的Request message (Table 6-13)便會設置Capability
Mismatch bit。Source端在接收到後,Source端可以送出Get Sink Capabilities
,來得到SINK再回Sink Capabilities。之後Source再去確認,是否它可以得到更
大的供電能力來提供SINK。
希望透過這個blog,分享軔硬體之間的動作,用到Python、Arduino。另外會分享新的USB PD Type-C Spec。 By this blog, I want to share the interaction of Firmware and Hardware. And some of the latest USB spec. If you have question, please don't hesitate to contact with me. My e-mail address: zsnes631@yahoo.com.tw
2015年4月16日 星期四
2015年1月6日 星期二
Arduino power consumption reduction
要試著將我手上的Arduino Pro Mini功耗降到最低,我上網查了一些文章,
也做了一些實驗。結果就是讓板子在進到power down mode時,功耗為
18.7uA/3.3V。如果有那位大大知道如何讓功耗再往下降,請不吝指教。
#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
Reference.
http://www.engblaze.com/hush-little-microprocessor-avr-and-arduino-sleep-mode-basics/
也做了一些實驗。結果就是讓板子在進到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/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);
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.SLEEP_MODE_PWR_SAVE 0.65mA
SLEEP_MODE_STANDBY 0.65mA
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也可以修改。
Reference:
1.http://wiki.mikrokopter.de/en/HC-06
淘寶買了一個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
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
訂閱:
文章 (Atom)








