10/14
上課內容:利用tinkercad繪圖再進行3D列印
這次的課程跟3D列印有關,我們使用tinkercad這個程式進行繪圖,繪製完成後再上傳到Snapmaker Luban上切層並選擇STL檔匯出,在列印之前要記得先校正列印機。這堂課畫的是一隻雪人,我覺得繪圖最難的部分是要讓每個物件貼合在一起,我畫的雪人手臂沒有貼合在身上,導致3D列印時印不出來。如過下次還有繪圖的機會,我會記得帶滑鼠,有滑鼠繪圖會更方便,畫出來的圖也會更好看。
10/21
上課內容:運用Arduino點亮兩個LED燈泡,並讓兩個燈泡能夠輪流閃爍,控制閃爍的頻率在兩秒一次
這次的課程主要在介紹基本的電子元件,並運用Arduino點亮兩個LED燈泡,並讓兩個燈泡能夠輪流閃爍,控制閃爍的頻率在兩秒一次。我照著自己編輯的程式碼接線,很快就接成功了,如左圖展示的紅色和白色LED燈泡兩秒一次輪流閃爍。透過程式設定燈泡的閃爍頻率,我認識到延遲函數,也因為自己能夠撰寫程式碼並控制LED燈閃爍時間而得到成就感。
以下為程式碼:
// 定義LED燈的接腳
const int led1 = 9; // 第一顆LED接在數位腳位9
const int led2 = 10; // 第二顆LED接在數位腳位10
// 設定閃爍的延遲時間 (毫秒)
const int delayTime = 1000; // 1秒
void setup() {
// 設定腳位為輸出
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
}
void loop() {
// 開啟LED1,關閉LED2
digitalWrite(led1, HIGH);
digitalWrite(led2, LOW);
delay(delayTime); // 延遲1秒
// 開啟LED2,關閉LED1
digitalWrite(led1, LOW);
digitalWrite(led2, HIGH);
delay(delayTime); // 延遲1秒
}
11/11
上課內容:利用按鈕接收訊號使發光二極體亮起(按下按鈕亮燈)
在這堂課上,我學習到鮑率Serial.begin 和腳位DigitalRead。鮑率是指每秒傳輸的符號數,用於設定資料傳輸速率,如 Arduino 與電腦的串行通信,常見值為 9600 或 115200 。腳位是指Arduino板上的金屬接腳,用來連接外部元件並進行訊號傳輸或控制。 在按下按鈕使發光二極體亮起的同時,可以在序列阜監控視窗裡面看到正在抖動的按鈕訊號因為按下按鈕而停止抖動。
以下為程式碼:
// 定義按鈕和LED的腳位
const int buttonPin = 2; // 按鈕接在數位腳位2
const int ledPin = 9; // LED接在數位腳位9
// 變數儲存按鈕狀態
int buttonState = 0;
void setup() {
// 設定按鈕腳位為輸入
pinMode(buttonPin, INPUT);
// 設定LED腳位為輸出
pinMode(ledPin, OUTPUT);
}
void loop() {
// 讀取按鈕狀態
buttonState = digitalRead(buttonPin);
// 如果按鈕被按下,點亮LED
if (buttonState == HIGH) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
}
11/18
上課內容:利用Arduino來記錄時間
需要先下載DS1302跟TM1637這兩個函數,DS1302利用arduino程式庫管理員找到,內管理程式庫Rtc by Makuna 直接在Arduino程式管理員下載就可以了,TM1637在Arduino程式管理員上沒有所以要自己下載並且安裝。
以下為程式碼:
#include <Wire.h>
#include <ThreeWire.h>
#include <RtcDS1302.h>
ThreeWire myWire(A6, A5, A7); //接腳: DAT/IO, SCLK/CLK, RST/CE (DS1302的接線自行更改)
RtcDS1302<ThreeWire> Rtc(myWire);
void setup ()
{
Serial.begin(9600);
Serial.print("compiled: ");
Serial.print(__DATE__);
Serial.println(__TIME__);
Rtc.Begin();
//__DATE__,__TIME__,是程式碼編譯時的日期和時間
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
printDateTime(compiled);
Serial.println();
//判斷DS1302是否接好
if (!Rtc.IsDateTimeValid())
{
// Common Causes:
// 1) first time you ran and the device wasn't running yet
// 2) the battery on the device is low or even missing
Serial.println("RTC lost confidence in the DateTime!");
Rtc.SetDateTime(compiled);
}
if (Rtc.GetIsWriteProtected())
{
Serial.println("RTC was write protected, enabling writing now");
Rtc.SetIsWriteProtected(false);
}
if (!Rtc.GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc.SetIsRunning(true);
}
//判斷DS1302上紀綠的時間和編譯時的時間,哪個比較新
//如果編譯時間比較新,就進行設定,把DS1302上的時間改成新的時間
//now:DS1302上紀綠的時間,compiled:編譯時的時間
RtcDateTime now = Rtc.GetDateTime();
if (now < compiled)
{
Serial.println("RTC is older than compile time! (Updating DateTime)");
//編譯時間比較新,把DS1302上的時間改成編譯的時間
Rtc.SetDateTime(compiled);
}
else if (now > compiled)
{
Serial.println("RTC is newer than compile time. (this is expected)");
}
else if (now == compiled)
{
Serial.println("RTC is the same as compile time! (not expected but all is fine)");
}
}
void loop ()
{
RtcDateTime now = Rtc.GetDateTime();
printDateTime(now);
Serial.println();
//判斷DS1302是否正常,如果不正常,一般是線沒接好,或是電池沒電了
if (!now.IsValid())
{
Serial.println("RTC lost confidence in the DateTime!");
}
delay(10000); // 10秒更新一次
}
#define countof(a) (sizeof(a) / sizeof(a[0]))
//顯示完整年月日時間的副程式
void printDateTime(const RtcDateTime& dt)
{
char datestring[20];
snprintf_P(datestring,
countof(datestring),
PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
dt.Month(),
dt.Day(),
dt.Year(),
dt.Hour(),
dt.Minute(),
dt.Second() );
Serial.print(datestring);
}
#include <ThreeWire.h>
#include <RtcDS1302.h>
#include <TM1637Display.h>
#define countof(a) (sizeof(a) / sizeof(a[0]))
#define CLK 11
#define DIO 12
TM1637Display display(CLK, DIO);
ThreeWire myWire(7, 6, 5); //接腳: DAT/IO, SCLK/CLK, RST/CE (DS1302的接線自行更改)
RtcDS1302<ThreeWire> Rtc(myWire);
void setup()
{
Serial.begin(9600);//鮑率57600
display.setBrightness(7);
Serial.print("compiled: ");
Serial.print(__DATE__);
Serial.println(__TIME__);
Rtc.Begin();
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
printDateTime(compiled);
Serial.println();
if (!Rtc.IsDateTimeValid())
{
// Common Causes:
// 1) 第一次使用但設備還沒跑好
// 2) 電池電量低
Serial.println("RTC lost confidence in the DateTime!");
Rtc.SetDateTime(compiled);
}
if (Rtc.GetIsWriteProtected())
{
Serial.println("RTC was write protected, enabling writing now");
Rtc.SetIsWriteProtected(false);
}
if (!Rtc.GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc.SetIsRunning(true);
}
//判斷DS1302上紀綠的時間和編譯時的時間,哪個比較新
//如果編譯時間比較新,就進行設定,把DS1302上的時間改成新的時間
//now:DS1302上紀綠的時間,compiled:編譯時的時間
RtcDateTime now = Rtc.GetDateTime();
if (now < compiled)
{
Serial.println("RTC is older than compile time! (Updating DateTime)");
Rtc.SetDateTime(compiled);
}
else if (now > compiled)
{
Serial.println("RTC is newer than compile time. (this is expected)");
}
else if (now == compiled)
{
Serial.println("RTC is the same as compile time! (not expected but all is fine)");
}
}
void loop()
{
RtcDateTime now = Rtc.GetDateTime();
printDateTime(now);//呼叫副函數
Serial.println();
if (!now.IsValid())
{
// Common Causes:
// 1) the battery on the device is low or even missing and the power line was disconnected
Serial.println("RTC lost confidence in the DateTime!");
}
}
void printDateTime(const RtcDateTime &dt)
{
char datestring[20];
snprintf_P(datestring,
countof(datestring),
PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
dt.Month(),//月
dt.Day(),//日
dt.Year(),//年
dt.Hour(),//小時
dt.Minute(),//分鐘
dt.Second());//秒
Serial.println(dt.Minute());
display.showNumberDecEx(dt.Hour(), 0b11100000, 2, 2); //前兩位數設定為小時
display.showNumberDecEx(dt.Minute(), 0b11100000, true, 2, 2); //後兩位數設定為分鐘
delay(1000);
}
11/25
上課內容:利用伺服馬達和光敏電阻來製造小恐龍的自動破解裝置
小恐龍遊戲是 Google Chrome 瀏覽器內建的一款簡單且經典的離線遊戲。當網頁無法連線時,瀏覽器會顯示一隻小恐龍以及「無法連線」的訊息,按下空白鍵即可啟動遊戲。 光敏電阻是一種能根據光線強弱改變自身電阻值的被動電子元件。它的主要特性是當光線強度增加時,電阻值減小;當光線變弱時,電阻值增大,因此常用於測量光線強度或作為光感應元件。
這次的目標是以伺服馬達當手、光敏電阻當眼睛,做出Google離線小恐龍的簡易自動破解器。我覺得這次的題目很有趣,但要成功地讓小恐龍跨越障礙物並不簡單,需要自行調整光敏電阻的數值,當數值越大,光敏電阻就越敏感;且伺服馬達沒有辦法很好的按下空白鍵讓小恐龍跳過障礙物。
以下為程式碼:
#include <Servo.h> //載入函式庫,這是內建的,不用安裝
Servo myservo; // 建立SERVO物件
int r = A0 ; //假設一個字母R代替A0的孔洞
int sensorValue;
void setup() {
Serial.begin(9600);
myservo.attach(9); // 設定要將伺服馬達接到哪一個PIN腳
myservo.write(0); //歸零
// put your setup code here, to run once:
}
void loop() {
sensorValue = analogRead(r);
Serial.println(sensorValue);
if(sensorValue <= 0){ //如果光敏電阻的數值小於或大於某一數值時,則伺服馬達轉動。
myservo.write(30); //旋轉到30度
delay(100); //延遲0.5秒
myservo.write(0); //旋轉到0度
delay(100 ); //延遲0.5秒 可自行更改
12/02
上課內容:DHT11數位式的溫度溼度感測器、過超聲波感測器和、LED和蜂鳴器來模擬倒車雷達
DHT11 是一種數位式的溫度溼度感測器。它的測量範圍從 0°C 到 50°C,濕度從 20% 到 90%。溫度測量精度為正負2°C,濕度測量精度為正負 5%。每次讀取訊號時間,必須間隔2秒以上。量測濕度的原理是當環境中的溼度發生變化,感濕元件會吸收或釋放濕氣,讓感測器的電容值發生變化,通過測量電容值變化,DHT11可以透過先前校準的數值,判斷出當前的溼度值。
以下為DHT11數位式的溫度溼度感測器的程式碼:
//使用DHT11函式庫
#include <SimpleDHT.h>
//定義腳位自行更改
int pinDHT11 = 18;
//建立DHT11函式庫物件
SimpleDHT11 dht11;
void setup() {
Serial.begin(9600);
}
void loop() {
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
// start working...
Serial.println("=================================");
if ((err = dht11.read(pinDHT11, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);
return;
}
Serial.print("Humidity = ");
Serial.print((int)humidity);
Serial.print("% , ");
Serial.print("Temperature = ");
Serial.print((int)temperature);
Serial.println("C ");
delay(1000); //每1秒顯示一次
}
超音波感測器利用超音波測距,有效感測距離為2cm-200cm透過發射超音波並計算回波時間來測量距離,基本運作方式類似於蝙蝠在飛行中利用回聲定位找尋昆蟲。發射器會發射高頻聲波的短突波,稱為「啁啾」,涵蓋 23 kHz 至 40 kHz 的頻率。當此聲音脈衝撞擊物體,部分聲波會反射回到接收器。
蜂鳴器是產生聲音的信號裝置,分為"有源蜂鳴器"與"無源蜂鳴器",有源蜂鳴器僅能發出單一頻率的聲音,而無源蜂鳴器則可根據不同頻率發出不同的聲音。
以下為倒車雷達的程式碼:
#define m1 294 //頻率1
#define m5 440 //頻率2
#define h5 880 //頻率3
int red = 2;
int yellow = 3;
int green = 4;
int v=5; //蜂鳴器輸出
int trigPin = 12; //定義 觸發輸出腳位 Trig Pin
int echoPin = 11; //定義 回音接收腳位 Echo Pin
float duration, distance; //定義 時間長度duration 與 距離distance 格式為 浮點數
void setup(){
Serial.begin(9600); //設定 序列埠 鮑率
while (!Serial){ ;} //等待序列埠接通
pinMode(red, OUTPUT);
pinMode(yellow, OUTPUT);
pinMode(green, OUTPUT);
pinMode(v, OUTPUT);
pinMode(trigPin, OUTPUT); //設定 觸發輸出腳位(trigPin)的功能為 輸出(OUTPUT)
pinMode(echoPin, INPUT); //設定 回音接收腳位(echoPin)的功能為 輸入(INPUT)
}
void loop(){
//於 觸發輸出腳位 Trig Pin 產生觸發脈衝(應大於 10微秒)
digitalWrite(trigPin, LOW); // 讓觸發腳位trigPin 確實降回低電位,持續 20微秒 (us)
delayMicroseconds(20);
digitalWrite(trigPin, HIGH); // 觸發腳位trigPin 變成高電位,持續 20微秒 (us)
delayMicroseconds(20);
digitalWrite(trigPin, LOW); // 觸發腳位trigPin 再降回低電位,完成脈衝,使HC-SR04產生聲音脈衝出去
duration = pulseIn(echoPin, HIGH); // 於回音接收腳位(Echo Pin) 收到高電位(High) 的時間 (微秒 us)
distance = duration*0.0170; // 將聲音 "來回" 時間(us) 換算成距離 (cm) [ 假設聲波速率為 340 m/s ]
if (distance >= 25 ){
digitalWrite(green, HIGH);
digitalWrite(yellow, LOW); digitalWrite(red, LOW);
tone(v, m1, 200);
delay(250);
}
else if (distance >= 10 and distance <= 25){
digitalWrite(yellow, HIGH);
digitalWrite(green, LOW); digitalWrite(red, LOW);
tone(v, m5, 150);
delay(200);
}
else {
digitalWrite(red, HIGH);
digitalWrite(green, LOW); digitalWrite(yellow, LOW);
tone(v, h5, 100);
delay(150);
}
//Serial.println(distance); // 將 距離distance 傳送到序列埠暫存器
Serial.flush(); // 等待序列埠暫存器中的數據傳送至電腦完畢
delayMicroseconds(duration*1.5); //避免收到更早發出的聲音脈衝 回音
}