顯示包含「Arduino」標籤的文章。顯示所有文章
顯示包含「Arduino」標籤的文章。顯示所有文章

2022年6月10日星期五

[Ameba] 使用Arduino Wire 基本函式存取 24C02 EEPROM / I2C

什麼是 EEPROM ?

EEPROM 代表電子可擦除式可做讀寫的存儲器。它允許在使用非常少的功率的情況下長時間寫入和存儲值。大多數微控制器甚至在其電路中直接有 EEPROM,例如 ATmega328P(Arduino Uno 芯片),它有 1KB。但如果這還不夠呢?SD 卡具有更大的存儲容量,但也更複雜、體積更大且耗電量更大。

這次的範例使用 Arduino 的 Wire 基本函式, 不套用現成 Library 。從實做中理解控制原理。這次選用型號為 AT24C02B / 儲存空間 2Kbit

Datasheet ( https://ww1.microchip.com/downloads/en/DeviceDoc/doc5126.pdf)

輸出腳位

24C02,Arduino

開發板

此次使用的是 自行開發的 A1 Lite / Realtek RL8720DN 。連結在此 (連結) ,在這就不多做介紹。
在 A1 Lite 使用 I2C 前先將預裝的提升電阻用焊接的方式將 JP2 , JP3 短接起來

A1 Lite,Arduino,RTL8720DN,BW16

接線

AT24C02ConnectA1 Lite
A0GND 
A1GND 
A2GND 
GNDGNDGND
SDA 8
SCL 7
WPGND 
VCC3V33V3

EEPROM I2C 位址

位址為 7-bit 規則 , A0 ~ A2 均接地。 所以位址為 0x50

 

寫入資料

Ameba,I2C

我們要先確認 WP 是否接入 GND。首先送出 EEPROM 的設備位址,0x50 ~ 0x57 之間。根據接線需送出 0x50 (若設備得到正確位址會有 NACK/ACK 反饋)。接著送出數據位址,再送出資料,最後發出 STOP 訊號 endTransmission() 告知 EEPROM 不再繼續。

程式碼


void WriteByte(uint8_t data_addr, uint8_t data)
{
 
  Wire.beginTransmission(EEPROM_ADDRESS);
  Wire.write(data_addr);
  Wire.write(data);
  Wire.endTransmission();
}

讀取資料

Ameba,I2C

首先要先送出 EEPROM 設備位址 及 數據位址。接下來再送出 設備位址,EEPROM 會反饋 1 組(Byte)資料。

程式碼


uint8_t ReadByte(uint8_t data_addr)
{
  uint8_t data;
  Wire.beginTransmission(EEPROM_ADDRESS);
  Wire.write(data_addr);
  Wire.endTransmission();
  Wire.requestFrom(EEPROM_ADDRESS,1);


  if(Wire.available())
  {
    data = Wire.read(); 
  }
  Wire.endTransmission();
 
  return data;
}

綜合以上,組成


  WriteByte(1,0x5A);
  delay(10);
  
  Serial.println(ReadByte(1),HEX);

輸出結果

進階

以 AT24C02 來說, 它是由 8 bytes 組成 一個 page, 以這個型號有 32 page。它可以一次寫入讀取最多 8 bytes 的資料, 我們將改寫程式

寫入資料



void WriteBytes(uint8_t data_addr, uint8_t *data,uint8_t len)
{


  uint8_t x;
  Wire.beginTransmission(EEPROM_ADDRESS);
  Wire.write(data_addr);
  for(x = 0; x < len; x++)
  {
    Wire.write(data[x]);  
  }
  
  Wire.endTransmission();
}

讀取資料


void ReadBytes(uint8_t data_addr,uint8_t *data, int len)
{
  uint8_t x;
  Wire.beginTransmission(EEPROM_ADDRESS);
  Wire.write(data_addr);
  Wire.endTransmission();
  Wire.requestFrom(EEPROM_ADDRESS,len);


  if(Wire.available())
  {
    for(x = 0; x < len;x++)
    {
      data[x] = Wire.read();    
    }
    
  }
  Wire.endTransmission();
  
}

輸出結果

Ameba,I2C

 

 

GitHub 完整程式碼

連結 ( https://github.com/cold63/Arduino_Code/tree/main/I2C_EEPROM )

其他參考

TI 應用手冊 Understanding the I2C Bus (SLVA704 )
連結 ( https://www.ti.com/lit/an/slva704/slva704.pdf )

 

2022年1月25日星期二

[Ameba] A1 Lite / RTL8720DN (BW16) 開發板 與 Arduino IDE

關於 A1 Lite

A1 Lite 是基於 RTL8720DN (BW16 Module) 所設計的開發板,而 RTL8720DN 具有 WIFI 4G/5G 及低功耗 BLE 5 的無線功能。與前版本 A1 Pico (點這裡)所使用的 BW16 Module 相同

A1 Lite 設計特色

  • 內建 USB/Ext 5V 可自復式保險絲。
  • I2C 介面預裝提升電阻。
  • 使用 CP2102N UART 晶片。
  • 支援 Auto flash 功能。
  • 簡化腳位,並使用單排半圓孔,可使用排針 或配合電路直接焊接 PCB 上

電路圖

Arduino BW16

腳位連接圖

Arduino BW16

孔位尺寸圖

單位:mm

RTL8720DN BW16

背面 JUMP 說明

NUM用途預設
JP1USER LEDON
JP2I2C 提升電阻OFF
JP3I2C 提升電阻OFF

準備

先安裝 CP2102N 的驅動程式。

連結在這裡
https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers

Windows 系統請下載 CP210x Windows Drivers,會得到一個壓縮檔,依據您的電腦系統 選擇 x64 或是 x86 安裝執行檔。 安裝步驟這裡就不贅述。

RTL8720DN 加入 Arduino
首先將這個網址複製起來 https://github.com/ambiot/ambd_arduino/raw/master/Arduino_package/package_realtek.com_amebad_index.json

打開 Arduino IDE , 點開 File / Preferences

BW16 Arduno

將網址貼上 紅框 處 , 然後點 OK 儲存。

接著在 Tools / Board: / Boards Manager...

在 搜尋列直接輸入" ameba " 就會出現開發板資訊 , 在右側會有 Install 的 按鈕。 因為我的 Arduino IDE 安裝完成,所以出現不一樣字樣。 點 " Install " 開始安裝 會需要等待一些時間, 可以先去泡一杯咖啡再回來。

BW16 Arduino

稍待片刻後,系統就會自動安裝完成。
在 Tools / Board: / Amaba ARM (32bit) Boards 裡, 應該會找到 RTL8720DN (BW16) 這個選項。
到這裡 安裝 RTL8720DN(BW16) 到 Arduino IDE 的部分已經做完了。

置換 upload_image_tool_windows.exe

預設安裝是沒有支援 Auto Flash 功能的,必須手動更新

首先 到 Ameba 的 Github https://github.com/ambiot/ambd_arduino/blob/dev/Ameba_misc/Autoflash_patch/ameba_d_tools_windows/upload_image_tool_windows.exe

BW16

右下角 Download , 就可以下載。如果您是不同於 Windows 系統,則回到上一層選擇適合的平台

置換的方法

開啟檔案總管, 到這個位置。

C:\Users\%USER%\AppData\Local\Arduino15\packages\realtek\tools\ameba_d_tools\1.0.7

您會看到很多檔案在其中 , 一定會有 upload_image_tool_windows.exe 這個檔案

可以先行 備份 再將 剛剛下載的 upload_image_tool_windows.exe 做覆蓋置換過去就可以。

測試 Blink 程式

將開發板連接電腦 USB 並開啟 Arduino IDE 並選好 開發板名稱 及 COM Port 位置

Arduino BW16

程式碼


int YelloLED = 9; //PA15

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(YelloLED, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(YelloLED, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(YelloLED, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

然後點選上傳 , 在訊息欄出現以下。自動上傳並自動 RESET。完成



實際測試結果



技術連結


購買 A1 Lite 開發板

蝦皮購物 


官方程式範例

https://bit.ly/bw16_example

官方論壇

https://bit.ly/amebaiot

Ameba Iot Facebook 開發社群

https://bit.ly/amebaiot_groups

2021年11月18日星期四

[Arduino] analogRead應用-使用熱敏電阻量測溫度-查表法

Arduino NTC

什麼是熱敏電阻?

熱敏電阻是個傳感器,特性是電阻值會隨著溫度變化而改變。這個元件其實很古老了,早期在電源類的產品中常用的元件之一,最主要的運用是用來偵測元件運作溫度。現在大部分設計為了要求精密度更高,新設計通常會使用晶片的形式來偵測溫度。

熱敏電阻大致分為兩種,

電阻值隨溫度上升而增加,為正溫度係數 (Positive Temperature Coefficient,簡稱 PTC)
電阻值隨溫度上升而減少,為負溫度係數 (Negative Temperature Coefficient,簡稱 NTC)

PTC 型的熱敏電阻,通常應用在電路保護的 可復式保險絲。例如:PolySwitch,如果發生電路過流現象會依據設計範圍內,使得溫度上升而阻抗變高,最後形成斷路現象。

這次應用的是 NTC的熱敏電阻用來檢測溫度。使用時必須固定在要檢測的會發熱的元件目標物上。

實體元件

Arduino NTC

規格 : 25度常溫 10KOhm ,誤差:正負 1% ,通常需要廠家提供參數值。

紅色框是溫度,藍色框是該溫度時的電阻值。左右兩邊是誤差範圍,我取的是中間值

電路設計

電路由電阻分壓方式組成,產生分壓電壓後再利用公式推算目前溫度所在。

Arduino NTC


程式碼


#define THSourceVoltage 5.0
#define THRES       7500


const int analogPin = A0;
int value;


unsigned int temptable[] = {8019,7679,7356,7048,6754,6475,6209,5956,5714,5484,
                                    5264,5055,4855,4664,4482,4308,4143,3984,3833,3688,
                                    3549,3417,3291,3170,3054,2943,2837,2735,2637,2544,
                                    2455,2369,2286,2207,2132,2059,1989,1922,1858,1796,
                                    1736,1679,1624,1571,1521,1472,1425,1379,1336,1294,
                                    1253,1214,1176,1140,1105,1072,1039,1008,977,948,
                                    920,893,867,841,817,793,770,748,727,706,
                                    686,667,649,631,613,596};


unsigned char temp;
                                    
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}


void loop() {
  // put your main code here, to run repeatedly:
  value = analogRead(analogPin);
  temp = calTemp((THSourceVoltage * value)/1023);
  Serial.print("NTC temp: ");
  Serial.println(temp);
  Serial.println("");  
  delay(1000);
}




float calVoltage(unsigned int value)
{
  return THSourceVoltage * value/(value + THRES);
}


unsigned char calTemp(float value)
{
  unsigned char x,res;
  float xc;
  for(x = 0; x < sizeof(temptable)/sizeof(unsigned int); x++)
  {
    xc = calVoltage(temptable[x]);
    if(xc <= value)
    {
      res = 1;
      break;
    }
  }


  if(res)
    return (30 + x);


  return 0;  
}

temptable 陣列的範圍是 30度 到最高溫度 105 度。透過 calVoltage function 及 for 迴圈比對,就可以順利得知溫度了

我用手指緊捏 NTC 的 顯示結果

Arduino NTC

目前手指溫度 35 度哦。用分壓電路組成的電路大概會有約 2%~3%的誤差範圍 ,這個結果其實也不差。 用在允許有誤差溫度範圍及低成本下,也是可以使用選擇的方式之一。

原始碼連結

https://github.com/cold63/Arduino_Code/tree/main/NTCTemp

相關參考

使用熱敏電阻量測溫度 -斯坦哈特-哈特公式
https://www.makdev.net/2021/11/arduino-analogread-model-func.html

analogRead 基礎
https://www.makdev.net/2020/12/arduino-analogread.html

Voltage Divider Calculator 電阻分壓計算
https://www.makdev.net/p/voltage-divider-calculator.html

[Arduino] analogRead應用-使用熱敏電阻量測溫度 -斯坦哈特-哈特公式

前提概要

前次使用 使用熱敏電阻量測溫度 - 查表法... 測量熱敏電阻溫度,這次使用同樣的熱敏電阻及電路,使用 Steinhart–Hart equation (斯坦哈特-哈特公式) 計算熱敏電阻所得到的溫度。
Steinhart–Hart 是兩個人 ,John S. Steinhart 及 Stanley R. Hart。他們利用 NTC 測量海洋溫度時所提出的公式。等式為

1/T = A+Bln R+ C(ln R)^3

T 是溫度 ,單位是 kelvin
R 是電阻值
A,B,C 常數

要利用這個推導公式最少需要 3 組已知的電阻值,這在後面會提到。
詳細內容可參考 wiki (https://en.wikipedia.org/wiki/Steinhart-Hart_equation)

另位,會使用一個溫度單位 kelvin 。它是一種溫度的國際單位,表示符號為 K 。有些量測溫度功能的晶片也會使用這個國際單位。
詳細內容可參考 wiki (https://en.wikipedia.org/wiki/Kelvin)

同樣我們要拿出廠家提供的表格,找3個電阻值

RT0 : 常溫 25 度時的電阻值。
RT1 : 0 度時的電阻值。
RT2 : 105度時的電阻值。

所以,這次量測範圍是 0 ~ 105 度間。

Arduino NTC
Arduino NTC

同樣我們需要相對應的 K 值

T0 = 298.15 : 常溫 25度時的 Kelvin 值
T1 = 273.15 : 0度時的 Kelvin 值
T2 = 378.15 : 105度時的 Kelvin 值

這個可以利用 線上計算器 (https://www.rapidtables.com/convert/temperature/celsius-to-kelvin.html)


電路圖

一樣和使用查表法的電路相同

Arduino NTC

程式碼


#define THSourceVoltage 5.0
#define THRES       7500
#define RT0         10000  // 常溫 25度時的 NTC 電阻值
#define RT1         35563  // 0度時的 NTC 電阻值
#define RT2         596    // 105度時的 NTC 電阻值
#define T0          298.15 // 常溫 25度時的 Kelvin 值
#define T1          273.15 // 0度時的 Kelvin 值
#define T2          378.15 // 105度時的 Kelvin 值


const int analogPin = A0;
int value;
float VoltageOut;
float ROut;
float beta;
float Rx;
float KelvinValue;
                                   
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);


  beta = (log(RT1/RT2))/((1/T1)-(1/T2));
  Rx = RT0 * exp(-beta/T0);
}


void loop() {
  // put your main code here, to run repeatedly:
  value = analogRead(analogPin);


  Serial.print("NTC Temp: ");
  
  VoltageOut = (THSourceVoltage * value)/1023;
  ROut = THRES * VoltageOut/ (THSourceVoltage - VoltageOut); //目前 NTC 電阻值
  KelvinValue=(beta/log(ROut/Rx));
  
  Serial.println(KelvinValue - 273.15); //Kelvin 轉 溫度C
  Serial.println("");  
  delay(1000);
}

同樣,我用手指緊捏 NTC 的 顯示結果

Arduino NTC

結果和查表法一樣是 35 度,這個方式更接近物理特性。後面再用軟體過濾器,數值就會更穩定及精確。

原始碼連結

https://github.com/cold63/Arduino_Code/tree/main/NTCTemp_modfunc

相關參考

使用熱敏電阻量測溫度-查表法
https://www.makdev.net/2021/11/arduino-analogread-lookup-table.html

analogRead 基礎
https://www.makdev.net/2020/12/arduino-analogread.html

Voltage Divider Calculator 電阻分壓計算
https://www.makdev.net/p/voltage-divider-calculator.html

2021年9月16日星期四

[Ameba] A1 PICO / RTL8720DN (BW16) 開發板 與 Arduino IDE

緣起

Realtek RTL8720DN 是一個具有 Wifi + Bluetooth 無線晶片, Wifi 且支援雙模 (802.11 a/b/g/n 1x1, 2.4GHz & 5GHz ) 和低功耗的 BLE 5。處理器內核採用 Dual processor core 設計 集成 ARM V8M Cortex-M33 (指令集相容於 Cortex-M4F) 及 ARM V8M Cortex-M23 (相容於 Cortex-M0+) 。 Wi-Fi 及 BT 是共用一組天線,所以在硬體設計上更為簡便。而 BW16 為 基於 RTL8720DN 所設計的 SOC 模組,將常用的引腳連接出來, 並使用 PCB 天線。使開發輕鬆。

小結

內核組成 KM4 Arm Cortex-M4 core @ 200 MHz 及  KM0 Arm Cortex-M0 core @ 20 MHz

 WiFi 2.4G 及 WiFi 5G 協定  802.11 a/b/g/n 頻寬範圍 : 2.412-2.484GHz & 5.180-5.825GHz

  • 支援 HT20/HT40 模式
  • 支援低功耗式
  • 支援 Bluetooth 5.0 LE , 頻寬範圍 :2.402GHz – 2.480GHz
  • 工作模式 : AP , Station, AP/ Client
  • WiFi 與 BT 共用一組天線
  • 1 個 ADC
  • 2 UART 介面
  • 1 個 I2C
  • 1 個 SPI
  • 4 個 PWM
  • 全部接腳都可成為 GPIO


為了更方便使用 RTL8720DN (BW16),因此我設計了 A1 PICO 開發版。

開發重點

1. 內建 USB 5V 可自複式保險絲。
因為做實驗難免會有誤接短路的問題,尤其是 USB 是直接連接電腦。雖然 USB Hub 也有相對應的保護,多層保護可以減少發生意外機率。

2. 電池連接口 JST 2.00mm 。
在很多應用是不方便連接固定電源,在應用上會更方便。若同時接入 USB 5V 會自動切換 USB 做為主要電源。

3. 因為要使用電池應用, 所以也特別挑選工作效率好的 LDO。使電池發揮最大的效能。預設電壓區間是 3.6V ~ 4.2V

4. 預裝 I2C 提升電阻,在應用於 I2C 時都需要提升電阻,有時臨時還真找不到 。現在只要將短路 pin 接上就好。

5. 支援 Auto flash 功能也是這次修改的重點, 感謝 jojoling 提供好用的程式,讓我可以搭順風車。

連接圖

RTL8720DN,BW16

UART 驅動程式

CH9102F

https://www.wch.cn/products/CH9102.html

CH9102F (本站下載點,不會更新)

Google driver dwonload.

電路圖

RTL8720DN,BW16


RTL8720DN(BW16) 加入 Arduino IDE

首先先將這個網址複製起來
https://github.com/ambiot/ambd_arduino/raw/master/Arduino_package/package_realtek.com_amebad_index.json

打開 Arduino IDE , 點開 File / Preferences

RTL8720DN,BW16

將網址貼上 紅框 處 , 然後點 OK 儲存

接著在 Tools / Board: / Boards Manager...

RTL8720DN,BW16

在 搜尋列直接輸入" ameba " 就會出現開發板資訊 , 在右側會有 Install 的 按鈕。 因為我的 Arduino IDE 安裝完成,所以出現不一樣字樣。 點 " Install " 開始安裝 會需要等待一些時間, 可以先去泡一杯咖啡再回來。

RTL8720DN,BW16

稍待片刻後,系統就會自動安裝完成。
在 Tools / Board: / Amaba ARM (32bit) Boards 裡, 應該會找到 RTL8720DN (BW16) 這個選項。
到這裡 安裝 RTL8720DN(BW16) 到 Arduino IDE 的部分已經做完了。

將開發板連接電腦 USB 並開啟 Arduino IDE 並選好 開發板名稱 及 COM Port 位置

RTL8720DN,BW16

溫馨提醒:

本開發板有 Auto flash 自動上傳功能, 請將 Auto Upload mode 設定為 Enable

RTL8720DN,BW16


測試 Blink 程式


int YelloLED = 9; //PA15

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(YelloLED, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(YelloLED, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(YelloLED, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

示範影片



如何購買 A1 Pico 開發板

Buy A1 Pico Board.

開發資源

2020年12月8日星期二

[Arduino] analogRead 基礎

 Arduino UNO 具有多通道 10-bit 類比轉換數位功能(analog to digital converter 簡稱: ADC)。範圍介於 0 ~ 工作電壓 (5V 或是 3.3V),而 10 bit 意味著是解析度。和大部分的 ADC 功能晶片一樣,都會需要參考基準電壓。以 UNO 板來說,沒有特別指定就會以輸入電壓為準 (AVCC / 5V)。所以 每單位是 5V / 1024 = 0.0049V(4.9mV)。

既然運算時會用到  參考基準電壓 做為基礎,所以這個電壓值會影響到後面運算結果,例如: 5.1V  和 5.5V 的運算結果肯定會不一樣 。如果您對輸出精準度非常在意,就會需要使用 UNO 板上的 AREF 外接準確的電壓值做為參考電壓,例如: 完美的 5.0V 或是 完美的 3.3V。不過,這裡先敘述基本概念。往後如果有機會再做延伸。

做個簡單測試:

用一條導線連接 A0 與 3V3

Arduino 教學

程式碼:



const int analogPin = A0;
int value;

void setup() {
  Serial.begin(9600);
}

void loop() {
  value = analogRead(analogPin);
  Serial.print("val:");
  Serial.println(value);
  delay(1000);
}

開啟 Tool / Serial Montior  看會出現甚麼數值

這個數值是原生數位資料,代表3.3V呈現出來的資料。那如果是接 5V 是多少數值?

(切記!  不要連接超過 5V以上的電壓)

如果要轉換成實質電壓,可以套這個公式:


5.0 * value/1023
所以,可以將上一個程式改成


const int analogPin = A0;
int value;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  value = analogRead(analogPin);
  Serial.print("Value:");
  Serial.println(value);

  Serial.print("Voltage:");
  Serial.print((5.0 * value)/1023);
  Serial.println(" V");
  Serial.println("");
  delay(1000);
}

輸出顯示
analogRead



這裡顯示輸出的值,會是實際量測到的"接近值"。這個小小程式碼在類比應用除錯時會時常使用到,當找不出問題時。量測原生資料是不錯的方法之一。

量測電壓 可以在 電阻分壓電路 (Voltage Divider Calculator) 上可以做更多的應用,例如: NTC 感測器可以量測溫度,CDS 光敏電阻 可以量測光線明暗度,或是直接量測電池電壓.... 等。

原始碼連結:

相關連結

analogRead應用-使用熱敏電阻量測溫度 -斯坦哈特-哈特公式

analogRead應用-使用熱敏電阻量測溫度-查表法

2020年11月25日星期三

[Arduino] LED Bar 顯示

在 Arduino 有個範例是 LED Bar Graph ,使用 LED Bar 來模擬音頻信號的顯示器。當音量低的時候顯示些許格數的 LED ,音量大的時候顯示接近滿格的 LED。今天,修改一下這個範例。
這裡來個學習提示。因為朋友的小孩在學習上遇到一些問題後的感覺。主要用來理解 數位系統的表示方法,透過這個方式,方便好理解 二進制、16 進制與硬體之間的關係。在早期要做這個實驗,整個麵包板是插滿整個 TTL IC。因為是初學剛理解,有些同學光是 DEBUG 線路就花費好多時間,只是為了要理解及驗證書本上的數位知識。在更進階一點,這個練習還可以做基本運算的驗證,例如: 左移 , 右移 , OR 及 AND 運算

所需材料

  • Arduino UNO     x  1
  • RED LED           x  8
  • 330 ohm 電阻    x   8
  • 些許導線及跳線

參考電路

麵包板


byte value;

void setup() {

DDRD = B11111111;

value = B01010000; //  給於 0x50 值


PORTD = value;


}

void loop() {

}

顯示甚麼?
如果加個 OR 運算

byte value;

void setup() {

DDRD = B11111111;

value = B01010000; // 0x50

PORTD = value | 0x3;


}

void loop() {

}


換個 AND 運算

byte value;

void setup() {

DDRD = B11111111;

value = B01010000; // 0x50

PORTD = value & 0x10; // AND 運算


}

void loop() {

}


有時候在做比較複雜的情境時,用 Windows 小算盤 的程式設計師 模式 可以幫助驗算。


如果要左移,右移 跑馬燈 要如何做呢?

void setup() {
DDRD = B11111111;
PORTD = B10000000; //0x80
}

void loop() {

for(byte x = 0; x <7 portd="" x="">>= 1;  //右移1個位元
 delay(500); 
}

for(byte x = 0; x <7 1="" code="" delay="" portd="" x="">

這是直接使用 PORT 的做法,當然也可以使用 74HC595。這裡只是方便好理解位元的操作

這裡注意一下: 因為 D0 腳有接線出來,所以可能在上傳程式時會出現問題。只要上傳前先移走D0 的導線再上傳,上傳完畢後再接回來即可


2020年11月17日星期二

[Arduino] Blink LED

 Blink LED / 閃爍 LED 通常是初學者的第一個應用,其實即使是老手在拿到未曾使用過的 MCU 或是新板子時也會從這裡開始。通常會先了解基本的 I/O 驅動能力 及 I/O 在 Timing 的表現如何。所以, 這個是常用的例子。

I/O 輸出有分兩種方式, Sink current 及 Source current 。區別是 電流流動方向的不同,Sink current 是電源電流經過負載流向 MCU, Source current 是MCU 輸出電流經過負載流向接地。需要注意地方是兩者的邏輯剛好是相反。

Sink Current:

Arduino sink current 教學

Source Current:



Arduino source current 教學

在這裡只要注意官方的參數。 官方的建議是 電流均不要超過 20 mA (UNO 版本),如果預期可能超出的情況則會需要連接 Driver 輸出電路。

在 Arduino 裡,通常我們會使用 File / Examples / 01.Basics / Blink 做為範本,當中會使用 delay() 函式做為延遲的主要方法。delay() 的特性是停止一段時間不做任何事,然後時間到之後就繼續走。如果電路的控制項目不多,使用 delay() 倒是沒甚麼大問題。但如果同時有其他不同應用的 I/O 時就不太適用了,例如,當有 INPUT (按鍵) / OUTPUT (LED) 同時應用時,會遇到跳過按鍵有時沒反應的問題,就是因為 delay() 剛好跳過 INPUT 的程式段。


int ledPin = 13;             

void setup() {
  pinMode(ledPin, OUTPUT); //將 pin 13設定輸出模式
}

void loop() {
  digitalWrite(ledPin, HIGH);
  delay(1000);       //延遲 1 秒        
  digitalWrite(ledPin, LOW); 
  delay(1000);       //延遲 1 秒 
}


我們可以使用 File / Examples / 02.Digital / BlinkWithoutDelay 的範例,可能在思路上可能會不習慣。但在基礎邏輯上會很有幫助。尤其在中大型的 Project 時,會需要使用類似的方法。

所需材料

  1. Arduino UNO      x  1
  2. 電阻: 330 ohm     x  1
  3. 麵包板                 x   1

參考連接

Arduino LED 教學


程式碼 

採 Source current 連接LED 及 連接 Arduino UNO 的 PIN 12 腳位




/*const 常數 */
/* I/O Pin 選擇使用 12*/
const int ledPin = 12;
/*間隔 1000ms / 1秒*/
const long interval = 1000;
/*LED I/O 狀態,等於是 ledPin 的I/O狀態*/
int ledState = LOW;

/*儲存下次的 clock cycle 時間*/
unsigned long previousMillis = 0;


void setup() {
  // put your setup code here, to run once:
  
  pinMode(ledPin,OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  
  //儲存目前的 clock cycle 時間
  unsigned long currentMillis = millis();

  //確認是否已經到預期時間
  if(currentMillis - previousMillis >= interval ){
    /*儲存下次的 clock cycle 時間*/
     previousMillis = currentMillis;
  
     ledState == LOW ? ledState = HIGH : ledState = LOW;

     digitalWrite(ledPin,ledState);
  }
}