上課日期:10/14(3D列印)
這堂課我們運用了3D繪圖軟體製作了簡單的3D模型(小雪人),並且透過3D列印機給打印出來。這堂課所學的內容比以往的實驗課還來的有趣且有印象,我們可以發揮自己的創意去創造屬於自己的作品,這堂課的內容也相對的簡單易懂且彈性。雖然我們的作品都印壞了,但我還是很期待之後的上課內容。
上課日期:10/21(練習)
今天我們學到了一些簡單的程式語言和接線,將電線、LED燈泡和電阻插在麵包板與UNO板上,再寫一些簡單的腳本進去,使得兩個LED燈泡會做周期性的交替發亮,完成第一次的簡單練習。
程式:
int GLED=10;//根據要儲存的資料種類不同,C++變數有許多型態,int在這裡可以定義為整數,也代表定義角位的Pin角,畢竟 Pin角就是以整數做代表的,在Arduino這塊板子中。
int RLED=8;
//只做一次事情
void setup() {
}
//一直做某件事
void loop()
{
pinMode(10, OUTPUT);
pinMode(8, OUTPUT);
digitalWrite(10, HIGH);
digitalWrite(8, LOW);
delay(1000);
digitalWrite(10, LOW);
digitalWrite(8, HIGH);
delay(1000);
}
上課日期:11/11(按鈕)
這次的課程我們學到了按鈕的運作邏輯,當按鈕按下時線路會接通,知道按鈕的邏輯後我們可以製作一個簡易的燈泡開關,當按鈕按下時燈泡發亮,放開時燈泡熄滅,但當我把線路和程式都寫好後發現一個問題,燈泡並會出現忽亮忽暗的情況,所以這時必須在程式上加入input_pullup,並且在按鈕的另外一端接上G N D,才能讓燈泡持續維持一定的亮度。這次課蠻簡單的,希望之後會學到越來越進階的東西。
程式:
int buttonState = 0;
void setup()
{
pinMode(8, OUTPUT);
pinMode(7, INPUT_PULLUP);
}
void loop()
{
buttonState = digitalRead(7);
if (buttonState == 0)
{
digitalWrite(8, HIGH);
}
else
{
digitalWrite(8, LOW);
}
}
上方影片為操作畫面
上課日期:11/18(時鐘)
今天教的是時鐘,首先幫Arduino下載模組,因為Arduino本身是沒有時間功能的,所以我們需要在函式庫裡幫它加上DS1302這個模組,讓他實現時間的功能。今天第一個程式是直接運用序列阜監控視窗看時間,第二個程式則是在額外加1個螢幕(需加上螢幕的模組),利用螢幕實現顯示時間的功能。
程式:
第一個:(序列阜監控視窗看時間)
#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(伺服馬達)
今天教的是如何運用光敏電阻來驅動伺服馬達,光敏電阻會因為受到不同的光亮程度,而產生不同的訊號,我們可以利用不同的訊號來讓伺服馬達轉動。做好之後,我們可以利用成品來破解小恐龍,來完成小時候根本達不到的分數。
程式:
#include <Servo.h>
Servo myservo;
int r = A0 ;
int sensorValue;
void setup() {
Serial.begin(9600);
myservo.attach(9);
myservo.write(0);
// put your setup code here, to run once:
}
void loop() {
sensorValue = analogRead(r);
Serial.println(sensorValue);
if(sensorValue <= 80){
myservo.write(10);
delay(200);
myservo.write(170);
delay(200);
}
else{
myservo.write(90);
delay(15);
}
}
成品:
上課日期:12/02(濕度溫度感測器、倒車雷達)
今天教的是濕度溫度感測器的運用和如何運用聲波感測器來做出倒車雷達,我覺得今天的內容都還蠻簡單的,而且都很生活化與多變,可以利用它們來做出很多奇怪的東西。
濕度溫度感測器程式:
//使用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秒顯示一次
}
倒車雷達程式:
#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); //避免收到更早發出的聲音脈衝 回音
}
成品: