永成的學習部落格

這裡會記錄永成學習的一部分

0%

勤益(二上)課程-上課筆記 Arduino 程式設計

這裡記錄著我在課堂中的學習

⬇⬇⬇文章開始⬇⬇⬇

請至 Tinkercad 註冊帳號。
若已經有Autodesk的帳號,就不用在註冊一次,使用原本註冊的帳號密碼登入即可。
登入後,點選左上就LOGO,找到Circuits(電路)的按鈕,再建立新電路,即可在網站模擬Arduino的實體樣子。


2019年10月24日

傳資料到 PC

1
2
3
4
5
6
7
8
9
10
11
const byte ledPin = 13;

void setup(){
Serial.begin(9600); // 初始化序列埠,以9600bps速率連線
Serial.println("Hello," ); // ln換行
Serial.print("\tLED pin is: ");
Serial.print(ledPin);
Serial.print("\nBYE!");
}
void loop(){
}
  • 執行後,結果為
    1
    2
    3
    Hello,
    LED pin is: 13
    BYE!

更改內容test

1
2
3
4
5
6
7
8
9
10
11
const long ledPin = 525566;

void setup(){
Serial.begin(9600); // 初始化序列埠,以9600bps速率連線
Serial.println("Hello," ); // ln換行
Serial.print("\tYongCheng: ");
Serial.print(ledPin);
Serial.print("\nBYE!");
}
void loop(){
}
  • 執行後,結果為
    1
    2
    3
    Hello,
    YongCheng: 525566
    BYE!

顯示正弦波

1
2
3
4
5
6
7
8
9
10
11
12
13
void setup(){
Serial.begin(9600); // 初始化序列埠,以9600bps速率連線
}

void loop(){
float angle = 0;float sineData;
for (angle = 0.0; angle <= 90; angle += 0.1)
{
sineData = sin(angle);
Serial.println(sineData);
delay(1);
}
}
  • 執行後,顯示為

串列監視器畫出心形

這裡可以參考一下上一篇顯示正弦波
我自己Google到的心形公式

(sqrt(cos(x))*cos(200*x)+sqrt(abs(x))-0.7)*(4-x^2)^0.01)
由於Arduino不支援上面打法,所必須改為:(pow的意思可以參考這邊連結
(sqrt(cos(x))*cos(200*x)+sqrt(abs(x))-0.7)*pow((4-x^2),0.01)

1
2
3
4
5
6
7
8
9
10
11
void setup(){
Serial.begin(9600); // 初始化序列埠,以9600bps速率連線
double angle = 0;float sineData;
for (angle = -4.5; angle <= 4.5; angle += 0.008){
double x=angle;
Serial.println(sqrt(cos(x))*cos(200*x)+sqrt(abs(x))-0.7)*pow((4-x*x),0.01);
}
}

void loop(){
}
  • 執行後,顯示為

老師找到的心形公式

(sqrt(cos(x))*cos(300*x)+sqrt(abs(x))-0.2)*pow((4-x*x),0.01)

1
2
3
4
5
6
7
8
9
10
11
void setup(){
Serial.begin(9600); // 初始化序列埠,以9600bps速率連線
double angle = 0;float sineData;
for (angle = -4.5; angle <= 4.5; angle += 0.008){
double x=angle;
Serial.println(sqrt(cos(x))*cos(300*x)+sqrt(abs(x))-0.2)*pow((4-x*x),0.01); //
}
}

void loop(){
}
  • 執行後,顯示為

試做一個電壓調節器

新建一個電路專案,新建一個Arduino Uno R3電位器
程式碼新增:

1
2
3
4
5
6
7
8
9
10
11
12
// 詳細的程式說明,請參閱第六章,6-4頁。
const byte potPin = A0;
int val; // 接收類比輸入值的變數,類型為整數。

void setup(){
Serial.begin(9600); // 初始化序列埠,以9600bps速率連線
}
void loop(){
val = analogRead(potPin);
Serial.println(val);
delay(500);
}
  • 執行後,顯示為

更改內容test

設置一個LED接收到512值以上,燈亮;
反之,接收到512值以下,燈滅。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const byte potPin = A0;
int val; // 接收類比輸入值的變數,類型為整數。

void setup(){
Serial.begin(9600); // 初始化序列埠,以9600bps速率連線
pinMode(13,OUTPUT);
}
void loop(){
val = analogRead(potPin);
Serial.println(val);
if(val>512){
digitalWrite(13,HIGH);
}
else
{
digitalWrite(13,LOW);
}
}
  • 執行後,顯示為

2019年10月28日

使用光敏電阻控制LED

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const byte LED = 13;
const byte CdS = A0;

void setup()
{
Serial.begin(9600); // 以 9600bps 速率初始化序列埠
pinMode(13, OUTPUT);
}

void loop(){
int val; // 接收類比輸入值的變數,類型為整數
val = analogRead(CdS);
Serial.println(val); // 印val數值
if(val>=700){
digitalWrite(13,HIGH);
}
else{
digitalWrite(13,LOW);
}
}
  • 執行後,顯示為

74HC595控制「七段顯示器」

讓七段顯示器,顯示0~9。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
const byte datePin = 2;  // 74HC595 序列輸入腳接「數位2」
const byte latchPin = 3; // 74HC595 暫存器時脈腳接「數位3」
const byte clockPin = 4; // 74HC595 序列時脈腳接「數位4」

byte index = 0;

const byte LEDs[10] = { // 七段顯示器索引
B01111110, // 0
B00110000, // 1
B01101101, // 2
B01111001, // 3
B00110011, // 4
B01011011, // 5
B01011111, // 6
B01110000, // 7
B01111111, // 8
B01110011}; // 9

void setup()
{
pinMode(datePin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}

void loop()
{
digitalWrite(latchPin, LOW); // 關閉閘門
// 底下的函數將從 LEDs 陣列取出一個位元組資料(從 0 的元素開始取)
// 並以序列方式傳入 74595 IC
shiftOut(datePin,clockPin, LSBFIRST, LEDs[index]);
digitalWrite(latchPin, HIGH); // 開啟閘門
delay(1000); // 暫停一秒

index ++;
if (index == 10){ // 10個數字
index = 0;
}
}
  • 執行後,顯示為

更改TEST

將七段顯示器顯示為「9、7、5、3、1」
(電路與上者相同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
const byte datePin = 2;
const byte latchPin = 3;
const byte clockPin = 4;

byte index = 0;

const byte LEDs[5] = {
B01110011, // 9
B01110000, // 7
B01011011, // 5
B01111001, // 3
B00110000}; // 1

void setup()
{
pinMode(datePin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}

void loop()
{
digitalWrite(latchPin, LOW);
shiftOut(datePin,clockPin, LSBFIRST, LEDs[index]);
digitalWrite(latchPin, HIGH);
delay(1000); // Wait for 1000 millisecond(s)

index ++;
if (index == 5){ // 5個數字
index = 0;
}
}
  • 顯示結果為,依序「9、7、5、3、1」循環。

2019年11月11日

超音波

課本範例(9-29)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const byte trigPin = 10;  // 超音波模組的觸發腳
const int echoPin = 9; // 超音波模組的接收腳
unsigned long d; // 儲存高脈衝的持續時間

// 自訂 ping()函數將傳回 unsigned long 類型的數值
unsigned long ping(){
digitalWrite(trigPin, HIGH); // 觸發腳設定成高電位
microseconds(10); // 持續 10 毫秒
digitalWrite(trigPin, LOW); // 觸發腳設定成低電位
return pulseIn(echoPin, HIGH); //傳回高脈衝的持續時間
}
void setup()
{
pinMode(trigPin, OUTPUT); // 觸發腳設定成[輸出]
pinMode(echoPin, INPUT); // 接收腳設定成[輸入]

Serial.begin(9600); //初始化序列埠
}

void loop()
{
d = ping() /58; // 把高脈衝時間值換算成公分單位

Serial.print(d); // 顯示距離
Serial.print("cm");
Serial.println();

delay(1000); // 等待一秒鐘(每隔一秒量測一次)
}

test更改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
const int pingPin = 7;
const int ledPin = 13;

void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}

void loop()
{
long duration, cm;
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);
cm = microsecondestToCentimeters(duration);
Serial.print("Distance: ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
if (cm < 100){
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
delay(100);
}
long microsecondestToCentimeters(long microseconds){
return microseconds / 29 / 2;
}
  • 依此配置,執行後,結果為

電壓輸出

1
2
3
4
void setup(){
analogWrite(10,102);} // 指定10腳位輸出電壓為2v
void loop(){
}
  • 電路依此配置,執行後,結果為

變頻控制LED燈光和馬達


2019年11月18日

傳值、傳址、傳參考

  1. call by ralue 傳值
  2. call by adress 傳址
  3. call by reference 傳參考
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void swap(int* x,int* y){
int temp = *x;
*x = *y;
*y = temp;
}
void setup(){
int a=10, b=20;
Serial.begin(9600);
// 交換之前的a和b值
Serial.println(String("Before swap: ")+ "\t" + a + "\t" +b);
swap(&a,&b);
// 交換之後
Serial.println(String("After swap: ")+ "\t" + a + "\t" +b);
}
void loop(){
// 這裡沒有程式
}
  • 顯示如下:
    1
    2
    Before swap: 	10	20
    After swap: 20 10

8-1 函數

1
2
3
4
5
6
7
8
9
10
11
12
coid cirArea(){  // cirArea 為自定義函數名稱
int r=5;
float area = 3.14 *r *r;
Serial.println(area);
}
void setup(){
Serial.begin(9600);
}
void loop(){
cirArea(); //執行函數
delay(2000);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 動手做8-1:建立自訂函數
// 詳細的程式說明,請參閱第八章,8-5頁。

float ans; // 接收運算結果的變數

float cirArea(int r) {
float area = 3.14 * r * r;
return area;
}

void setup() {
Serial.begin(9600);
ans = cirArea(10); // 計算半徑 10 的圓面積
Serial.println(ans); // 顯示結果
ans = cirArea(20); // 計算半徑 20 的圓面積
Serial.println(ans); // 顯示結果
}
void loop() {
}
  • 執行結果如下
    1
    2
    314.00
    1256.00
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
double result = 0;
double i;
double SumCC()
{
double SumC=0;
for (int n=1; n<101;n++){
SumC=(n*5/3)+SumC;
}
return SumC;
}
void setup()
{
Serial.begin(9600);
for( i=0 ; i<300 ; i++){
result=SumCC()+result;
}
Serial.println(result);
}

void loop(){

}

2019年12月02日

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
double fun(double t)
{
double A=2;
double f=60;
double result;
double pi=3.1415926;

result = A*sin(2*pi*f*t);

return result;
}

void setup()
{
Serial.begin(9600);
for(double t=0;t<=(1);t=t+0.001)
{
double result = fun(t);
Serial.println(result);
}
}

void loop()
{
}
  • 執行後,結果為

&ensp;


t = 0 度 ~ 360 度
x = A sin ( 2 π f t ) + B cos ( 2 π f t )
A = 0.2
B = 0.3
f = 60

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
double fun(double t)
{
double A=0.2;
double B=0.3;
double f=60;
double result;
double pi=3.1415926;

result = A*sin(2*pi*f*t) + B*cos(2*pi*f*t);

return result;
}

void setup()
{
Serial.begin(9600); // 初始化序列埠,以9600bps速率連線
for(double t=0;t<=(1);t=t+0.001)
{
double result = fun(t);
Serial.println(result);
}
}

void loop()
{
}
  • 執行後,結果為

老師上課補充

中斷 ➜ 最高權限

中斷

  • 線路配置圖

程式內容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int pbInt = 0; // 定義中斷引腳為0,也就是D2引腳
int ledOut = A0; // 定義輸出指示燈引腳
volatile int state = LOW; // 定義默認輸入狀態

void setup()
{
pinMode(ledOut, OUTPUT); // 置ledOut引腳為輸出狀態
attachInterrupt(pbInt, stateChange, CHANGE); // 監視中斷輸入引腳的變化
}
void loop()
{
for (int i = 0; i < 100; i++)
{
delay(100); // 什麼都不做,等待10毫秒
} // 模擬長時間運行的進程或複雜的任務
}

void stateChange()
{
state = !state;
digitalWrite(ledOut, state);
}

2019年12月09日

斜率

  1. x^2+5
1

2019年12月16日

外部中斷(FALLING)

線路布線圖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
ShakeSwitch
中斷檢測振動感測器,控制LED燈亮滅
*/
int SensorLED = 9; //定義LED為數字引腳9
int SensorINPUT = 2; //連線震動開關到中斷0,也就是數字引腳2
char state = LOW;

void setup() {

pinMode(SensorLED, OUTPUT); //LED為輸出模式
pinMode(SensorINPUT, INPUT_PULLUP); //震動開關為輸入模式

//下降沿觸發,觸發中斷0,呼叫blink函式
attachInterrupt(0, blink, FALLING);
}

void loop() {

if (state == HIGH) { // 如果state為HIGH
state = LOW;
digitalWrite(SensorLED, HIGH); // 亮燈
delay(500); //延時500ms
}
else {
digitalWrite(SensorLED, LOW); // 否則,關燈
}
}
void blink() { //中斷函式blink()
state = !state; //一旦中斷觸發,state狀態反轉
}

進階(CHANGE)

線路布線圖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
ShakeSwitch
中斷檢測振動感測器,控制LED燈亮滅
*/
int SensorLED = 9; //定義LED為數字引腳9
int SensorINPUT = 2; //連線震動開關到中斷0,也就是數字引腳2
char state = LOW;

void setup() {

pinMode(SensorLED, OUTPUT); //LED為輸出模式
pinMode(SensorINPUT, INPUT_PULLUP); //震動開關為輸入模式

//下降沿觸發,觸發中斷0,呼叫blink函式
attachInterrupt(0, blink, CHANGE);
}

void loop() {

if (state == HIGH) { // 如果state為HIGH
state = LOW;
digitalWrite(SensorLED, HIGH); // 亮燈
delay(500); //延時500ms
}
else {
digitalWrite(SensorLED, LOW); // 否則,關燈
}
}
void blink() { //中斷函式blink()
state = !state; //一旦中斷觸發,state狀態反轉
}