這一篇以「Arduino練習:以開關切換LED明滅狀態」為基礎,但功能改成:按一下開關,LED開始閃爍,再按一下開關,LED熄滅,依此類推。
這一篇不會有太多說明,若對Arduino、程式庫、開關bounce問題等等不熟悉的話,還請參考我其他的文章:Arduino文章列表,或是參考我寫的Arduino入門書:Arduino輕鬆入門:範例分析與實作設計。
我的環境:Windows XP、Arduino 1.0.5、板子是Arduino Uno R3。
電路圖很簡單,就是一個LED與一個開關而已。
首先是使用millis記錄時間的版本,程式碼可到這裡下載;使用millis記錄時間,比較上次與這次的時間後,決定做什麼事情。注意,程式內沒有使用delay函式。
#define LED_PIN 13
#define SWITCH_PIN 12
#define DEBOUNCE_DELAY 200
unsigned long lastDebounceTime;
int ledBlinkStatus;
#define LED_BLINK_TIME 300
unsigned long lastUpdateLedTime;
int ledStatus = LOW;
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(SWITCH_PIN, INPUT);
}
void updateLedBlinkStatus(){
unsigned long currentTime = millis();
if((currentTime - lastDebounceTime) > DEBOUNCE_DELAY){
lastDebounceTime = currentTime;
ledBlinkStatus = !ledBlinkStatus;
}
}
void updateLed(){
if(ledBlinkStatus){
unsigned long currentTime = millis();
if((currentTime - lastUpdateLedTime) > LED_BLINK_TIME){
lastUpdateLedTime = currentTime;
ledStatus = !ledStatus;
}
}
else{
ledStatus = LOW;
}
digitalWrite(LED_PIN, ledStatus);
}
void loop() {
int switchStatus = digitalRead(SWITCH_PIN);
if(switchStatus == HIGH){
updateLedBlinkStatus();
}
updateLed();
}
另一個則是使用程式庫Timer與Bounce的版本,程式碼可到這裡下載,程式庫Timer的用法請參考這篇,程式庫Bounce的用法請看這篇。
#include <Bounce.h>
#include <Timer.h>
#define LED_PIN 13
#define SWITCH_PIN 12
#define DEBOUNCE_DELAY 50
int ledBlinkStatus = 0;
Bounce bouncer = Bounce(SWITCH_PIN, DEBOUNCE_DELAY);
#define LED_BLINK_TIME 300
Timer timer;
int8_t timer_id;
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(SWITCH_PIN, INPUT);
}
void loop() {
if(bouncer.update() == true && bouncer.read() == HIGH){
ledBlinkStatus = !ledBlinkStatus;
if(ledBlinkStatus){
timer_id = timer.oscillate(LED_PIN, LED_BLINK_TIME, HIGH);
}
else{
timer.stop(timer_id);
digitalWrite(LED_PIN, LOW);
}
}
timer.update();
}
使用程式庫後,程式碼變短許多。
想不到老師寫出來了 受益良多 謝謝
ReplyDelete想請問老師
ReplyDelete我在序列埠上輸入的10進位數字與下方顯示的數字不相同?請問是在輸入10進位要加上什麼符號還是我的程式有問題
例如輸入6 顯示74
> 輸入6 顯示74
Delete嗯,猜不出來。
你呼叫什麼函式?
> 下方顯示的數字
下方是什麼?
我是在練習一個Making a Binary Quiz Game的練習題
Delete原始碼如下
//Project 17 - Making a Binary Quiz Game
#define DATA 6 // connect to pin 14 on the 74HC595
#define LATCH 8 // connect to pin 12 on the 74HC595
#define CLOCK 10 // connect to pin 11 on the 74HC595
int number = 0;
int answer = 0;
void setup()
{
pinMode(LATCH, OUTPUT); //set up the 74HC595
pinMode(CLOCK, OUTPUT);
pinMode(DATA, OUTPUT);
Serial.begin(9600);
randomSeed(analogRead(0));
displayNumber(0);
}
void displayNumber(byte a)
{
//send byte to be displayed on the LEDs
digitalWrite(LATCH, LOW);
shiftOut(DATA, CLOCK, MSBFIRST, a);
digitalWrite(LATCH,HIGH);
}
void getAnswer()
{
//receive the answer from the player
int z = 0;
Serial.flush();
while (Serial.available() == 0 );
{
//do nothing until someting comes into the serial buffer
}
while ( Serial.available() > 0 )
{
//move any previous digit to the next column on the left; in
//other words, 1 becomes 10 while thers is data in the buffer answer = anser * 10;
// red the next number in the buffer and subtract the character '0'
z = Serial.read() - '0';
//ass this digit into the accumulating value
answer = answer + z;
//allow a short delay for any more numbers to come into Serial.vaailable
delay(5);
}
Serial.print("you entered:");
Serial.println(answer);
}
void checkAnswer()
{
//check the answer form the player and show the results
if ( answer == number ) //Correct!
{
Serial.print("Correct!");
Serial.print(answer,BIN);
Serial.print(" equals ");
Serial.print(number);
Serial.println();
}
else //Incorrect
{
Serial.print("Incorrect,");
Serial.print(number,BIN);
Serial.print(" equals ");
Serial.print(number);
Serial.println();
}
answer = 0;
delay(10000); //give the player time to rrview his or her answer
}
void loop()
{
number = random(256);
displayNumber(number);
Serial.println("What is the binary number in base-10?");
getAnswer();
checkAnswer();
}
我要在序列埠上輸入監控視窗中用十進位輸入電路板顯示的二進位數值
我輸入的數值在視窗上顯示看起來像是總和
輸入0-9 視窗顯示都能正常顯示0-9
輸入11 視窗顯示2
輸入123 視窗顯示6
請問老師這樣是我的原始碼有問題還是我的開發環境設定有問題?
把
Deleteanswer = answer + z;
改成
answer = answer * 10 + z;
謝謝老師我找到問題了
Delete我在Serial port 輸入文字
arduino顯示的文字看起來像是數字總和
後來發現原始碼裡面忘記每個數字要*10
void getAnswer()
{
//receive the answer from the player
int z = 0;
Serial.flush();
while (Serial.available() == 0 );
{
//do nothing until someting comes into the serial buffer
}
while ( Serial.available() > 0 )
{
//move any previous digit to the next column on the left; in
//other words, 1 becomes 10 while thers is data in the buffer
answer = answer * 10;
// red the next number in the buffer and subtract the character '0'
//from it to convert it to the actual integer number
z = Serial.read() - '0';
//ass this digit into the accumulating value
answer = answer + z;
//allow a short delay for any more numbers to come into Serial.vaailable
delay(5);
}
Serial.print("you entered:");
Serial.println(answer);
}
來獲得10進位