顯示包含「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 天線。使開發輕鬆。

Ameba BW16



總結

內核組成 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 提供好用的程式,讓我可以搭順風車。

連接圖

CP2102N 版本
A1 PICO ,BW16


FTDI 版本
Ameba BW16



電路圖

rtl8720dn bw16


實體照

A1 PICO,BW16


RTL8720DN(BW16) 加入 Arduino IDE


現在官方已經正式將 RTL8720DN(BW16) 納入 Arduino,按照以下步驟就可以將開發版加入您的 Arduino IDE。


打開 Arduino IDE , 點開 File / Preferences

Ameba BW16



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

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

Ameba BW16



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

Ameba BW16



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


我們知道 Ameba 的開發板要上傳程式到開發版之前,必需要先按開發板上的 Dwonload  按鈕 再按 RESET 按鈕才能順利上傳成功到板子上來。在前面所述 Auto Flash 功能就是我所設計的 RTL8720DN(BW16) 可以簡化必需要事先按鈕的步驟, 不過要啟用這個功能必需先更替 系統原安裝的 "upload_image_tool_windows.exe" 程式。

下載 "upload_image_tool_windows.exe"


Ameba BW16



因為我的環境是 windows 所以選擇 amaba_d_tools_windows 。
您會看到 upload_image_tool_windows.exe 的連結 , 再點開它。 


Ameba BW16



再右下角 "Download" , 先下載下來。
在這裡 感謝 jojoling 製作那麼美妙的程式, 讓大家更方便使用 Ameba。

好 , 接下來就是要 置換這個程式了。

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

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

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

Ameba BW16




這時候您有 2 個選擇 。
1.是直接將剛下載的 upload_image_tool_windows.exe 直接覆蓋置換就好。
2.先將原來的程式做備份。建新的資料夾丟進去。再將 upload_image_tool_windows.exe 拷貝過來。

就看個人的習慣嘍。

到這裡算是完成所有安裝步驟了。

開發板上預留 PA15(9) 連接 LED , 用它來做 blank 基本的程式。不過, 預設連接是斷開的。必須焊接短接


Ameba BW16



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

Ameba 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
}

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




購買 A1 Pico 開發板


官方程式範例


官方論壇連結


Ameba Iot Facebook 開發社群



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);
  }
}