Try   HackMD

2021 機器人加課

tags:2020KGHS i2trc2

PWM

Simulating a PWM output

這個練習只是為了幫助你熟悉 C 語言的使用方式,實際上我們不常這樣應用!

現在你已經知道 PWM 就是控制 Duty cycle ,為了更了解運作原理,我們可以用程式模擬硬體電路的運作方式。

策略

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • 設定 number of slots (num)
  • 為每個燈設定亮度 (brightness)
  • 假設有一個 counter 會不斷從 0 數到 num 也就是
    counter=[0,num),counterZ
  • 當 counter 大於 brightness 的時候,輸出 1 ,否則為 0

Blocking v.s. Non-blocking

  • Blocking: 利用 delay() 製造
    ΔT
    的延遲
  • Non-blocking: 如果用 delay() 程式會卡住,因此會被 blockdelay() 。如果要 Non-blocking 有兩種常見的方法:
    • 可以用 millis() 判斷當下時間是否需要更新資料
    • 利用硬體 timer 輔助

Timer interrupt

Why Interrupt Is Necessary?

試想像在煮開水,三不五時總要走過來看一下確定水開了沒,假設我們3分鐘走回來檢查一次,那麼會有二種情況:

  • 走過來時水早已開了。 ← 大部份的情況。
  • 走過來時水剛剛好開了。 ← 機率很低。

若很忙時間被打亂,沒辦法固定時間來檢查怎麼辦?
有沒有什麼更好的做法?

情境

如果在上面 Simulating a PWM output 的例子中, Arduino 不就沒辦法做其他的事情了嗎? 大部分的時間都被困在 delay() 裡面了

What is interrupt?

『處理器接收到來自硬體或軟體的訊號,提示發生了某個事件,應該被注意,這種情況就稱為中斷。』

中斷觸發與執行的流程:

  1. 中斷觸發,暫停目前的Process,並保存執行狀況。
  2. 根據Interrupt Table查詢對應的中斷服務常式(ISR, Interrupt Service Routine)Address。
  3. 跳至該Address(執行)。
  4. ISR執行完畢。
  5. 回到中斷前的Process並繼續執行。

Types of interrupts

硬體中斷 (Hardware Interrupt)

以某個Pin做為外部中斷的觸發,當發生特殊條件時進行中斷。Arduino 328中,具有Interrupt的pin為2、3。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Example:

attachInterrupt(0, functionA, CHANGE);

Note: functionA 是一個自定義 function 的名字,你可以自己設計。

軟體中斷(Software Interrupt)

當發生特殊情況時,E.X.除以零。

Traps in writing ISR functions

在 ISR 函式內部會 改變 其值的變數,在宣告時必須在前面加上 volatile 這個關鍵字。當一個變數加入了 volatile 的宣告,那麼程式在 Compile 時就不會去最佳化與此變數相關的程式碼。

Example:

volatile boolean sw = false;

General OS Usually are Interrupt Driven

由於電腦主要在處理各種 I/O 操作,而 I/O 操作過程往往會因為速度不能相比( I/O 相較於 CPU 慢許多),故會以非同步的方式進行處理,I/O device 會在處理完後產生 Interrupt 告知 CPU 。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

And Timer?

Arduino 利用內部的計數器電路計算 clock 震盪的次數,可以得到規律的時間計數。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Note: 所有的 timer 都會相依於 Arduino 的 system clock 。大部分 Arduino 的 clock 是 16MHz ,但是有些電源使用 3.3V 的 clock 是 8MHz ,所以設定 timer function 時要注意當時的 clock 。

Q: 很多 library 都會使用 timer ,那你也要用的時候怎麼辦?
A: 沒辦法,要不就你換一個 timer 用,要不就你不要用 library

Atmega 328p 有三組 timer 可以用:

  • Timer 0(8bit):像是 delay()millis()micros() 都是使用到 timer 0
  • Timer 1(16bit) :Servo library 使用 timer 1
  • Timer 2(8bit) :tone() 使用到 timer 2

可以在其他晶片上還有更多 timer。E.X. Arduino mega Board(Atmega 2560)

  • Timer 3,4,5(16bit):

How to configure a timer?

Atmega 328p 上的三個 timer 都不太一樣,大家一定要習慣查表,不要一直複製貼上不知道自己在寫什麼,核心概念都是一樣的,這邊有一個很完整的 資料 ,甚至有人做出 計算機

接下來以 timer2 舉例:

下面是存放各種 timer 資料的 Registers:

  • TCCRx - Timer/Counter Control Register. The prescaler can be configured here.
    用來設定 timer 工作模式的 register ,例如說如果要 timer 工作在 CTC mode 表示要讓 register 中 WGM21 的地方為 1 其他為 0。
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

    如果要設定 prescaler:
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • TCNTx - Timer/Counter Register. The actual timer value is stored here.
  • OCRx - Output Compare Register (Trigger Value)
  • ICRx - Input Capture Register (only for 16bit timer)
  • TIMSKx - Timer/Counter Interrupt Mask Register. To enable/disable timer interrupts.
  • TIFRx - Timer/Counter Interrupt Flag Register. Indicates a pending timer interrupt.

Example:

// this code sets up timer2 for a 250us @ 16Mhz Clock // cited from: https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-atmega328 #include <avr/io.h> #include <avr/interrupt.h> int main(void) { OCR2A = 62; TCCR2A |= (1 << WGM21); // Set to CTC Mode TIMSK2 |= (1 << OCIE2A); //Set interrupt on compare match TCCR2B |= (1 << CS21); // set prescaler to 64 and starts PWM sei(); // enable interrupts while (1) { // Main loop } } ISR (TIMER2_COMPA_vect) { // action to be done every 250 usec }

Create your own library

Steps:

  1. Create an INTERFACE to your library: mylib.h
  2. Create an IMPLEMENTATION of your library: mylib.c
  3. Create a LIBRARY OBJECT FILE that can be linked with programs that want to use our library code (Compiler 會幫你做這件事)
  4. USE the library in other C code: #include “mylib.h”

將介面 (INTERFACE) 與實作 (IMPLEMENTATION) 分開,Why?

Create a .h file

在 header file 內宣告函式介面 (Interface)

#ifndef _MYLIB_H #define _MYLIB_H // write your code (interface) here // ... // write your code (interface) here #endif

P.S. #開頭的敘述是給編譯器的指示

為了防止編譯器重複宣告及定義(每當include header file就會讀到這段程式碼)所以需要用 if 來判斷是否已經執行。

Create a .cpp file

Cpp file,Arduino IDE 會自動編譯並 link ,不需要手動操作。

Include the header file

在程式碼中,用include將建立的header file include進來。

#include <FILE NAME> // 從預設的lib路徑尋找 #include ”FILE NAME” // 從專案目錄中尋找

Declare a Global Variable in Your Library

若要定義全域變數,需在宣告的型態前面加上 extern 關鍵字,表示該變數的宣告會在某個 include 該 header file 的檔案中。

Overloading in Arduino

Learning to use third party library

不要再只會複製貼上了!

如果今天,你要用一個全新的 library 或是很少人在用,沒有什麼文獻資料,怎麼辦?

學會看懂別人在寫什麼,別人想要表達什麼!

舉例:
Servo Library

移位暫存器 (Shift Register)

Arduino 上面的 pin 不夠多怎麼辦 ?

A: 將序列 (serial) 資料轉成 並列 (parallel) 資料

功能

移位暫存器 74595 的內部構造,包含

  • Shift register
  • storage register
  • 3 state output (control)

74HC595

74595 datasheet


74575 Name Description Arduino
ST_CP Latch latch 10
SH_CP Shift Clock clock 13
DS Data In 資料(data) 11
Output Enable OE Enable (negative logic) GND
RESET MR 重置 (negtive logic) +5
SQH Q7' Serial Data Out X