之前以可變電阻控制呼吸燈的循環時間,這篇要以光敏電阻(photo resistor、photocell、light dependent resistor)控制LED的明滅。
電路圖(Fritzing格式)與程式原始碼,可在此下載。
電路圖:
LED,長腳接腳位13,短腳接GND。
光敏電阻,一腳接5V,另一腳接到腳位A0與10k ohm電阻,電阻的另一腳接地。
// 從腳位A0讀取光敏電阻的值。
// 以腳位13控制LED。
void setup(){
Serial.begin(115200);
pinMode(A0, INPUT);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
}
int pr_min = 400;
void loop(){
// 以analogRead()讀取光敏電阻的值,會回傳0~1023之間的值。
int pr = analogRead(A0);
// 並且把值輸出到序列埠,請用手遮蔽光敏電阻,看看變化。
Serial.println(pr);
// 若大於這個值,熄滅LED,若小於就點亮。
// 請視需求修改pr_min。
digitalWrite(13, pr > pr_min ? LOW : HIGH);
delay(1000);
}
完成後,當外界光線強時,光敏電阻會讀到較大的值,LED就會熄滅;外界光線弱時,會讀到較小的值,LED就會亮起。
參考資料:
請問有沒有什麼方法能利用取樣的方式(比如說每十秒取一次),然後再把讀取出來的a0數據全部加起來呢?
ReplyDelete就照你說的寫成程式。
Delete以millis()或某計時器程式庫來取出10秒時間間隔,讀取數據後加總存在全域變數。大概是這樣吧,有什麼問題嗎?
葉前輩 您好:
ReplyDelete請問您,如果我只想在低於pr設定值時,讓LED發光只維持3秒鐘,然後自動熄滅,
一直維持到下一次的pr低於設定值事件發生,才重新觸發LED發光3秒鐘的這個動作,
要如何做比較好呢?
我已經可以在低於pr設定值時,將LED發光並且設定為3秒鐘後熄滅,但是熄滅之後又重新跑loop點亮...而不是一直維持熄滅狀態...
我一直試一直想,想到現在還是想不出來...T_T,都快凌晨4點了...
總覺得有甚麼指令可以簡單達成這樣的要求...
大致寫法如下 請自行補上其他部分
Deleteint led_stauts = LOW; // LOW代表led熄滅 此時應偵測pr值
unsigned long time_old; // 記錄點亮led時的時間
void loop(){
if(led_status == LOW && analogRead(A0) < PR_MIN)
digitalWrite(LED_PIN, HIGH);
led_status = HIGH;
time_old = millis();
}
if(led_status == HIGH && millis() - time_old > 3000){
digitalWrite(LED_PIN, LOW);
led_status = LOW;
}
}
大概如此 沒真的測試過
謝謝葉前輩的協助,我試了前輩的寫法,
Delete產生的結果是當A0 < pr_min時,LED持續亮著,沒有變化
我猜測是程式又重新發現第一個if成立,所以繼續讓LED亮著,
於是我拿掉最後一行led_status = LOW;去避掉第一個if,
結果變成:在 A0 < pr_min 狀態時只亮3秒,雖然達到我想要的,但是之後的 A0 < pr_min 就無法再觸發任何動作了
LED永遠是暗的...(附帶一提:前輩寫的第一行stauts拼錯我已經修改好)
我有查到pulseIn()這個指令,但不太會使用,不知道能不能應用在這上面?
下面是我重新用的,但結果還是一樣,我有增加了delay()讓我觀察狀態...實在很苦手~~"
int led = 3;
void setup(){
Serial.begin(115200);
pinMode(A0, INPUT);
pinMode(3, OUTPUT);
analogWrite(led,0);
}
int pr_min = 600;
int led_status = LOW; // LOW代表led熄滅 此時應偵測pr值
unsigned long time_old; // 記錄點亮led時的時間
unsigned long duration; // 記錄點亮led時的時間
void loop(){
if(led_status == LOW && analogRead(A0) < pr_min){
digitalWrite(led, HIGH);
led_status = HIGH;
time_old = millis();
//duration = pulseIn(led, HIGH);//計算HIGH的時間(可否應用這個指令達成目的?)
//Serial.println(time_old);
delay(1000);
}
if(led_status == HIGH && millis()-time_old>3000 ){
Serial.println(time_old);
digitalWrite(led, LOW);
//time_old = 0;
led_status = LOW;//當我移除這段時,LED如我所願只維持3秒鐘HIGH,但是之後永遠都LOW了,即使我重新遮蔽光敏電阻也沒動作
//但我希望的是每次環境由"亮"-->"暗"時,觸發一次LED HIGH,然後永遠維持LOW。(直到下一次的環境由"亮"-->"暗"再重新只亮LED3秒)
delay(1000);
}
/*if(analogRead(A0) >= pr_min){
time_old = 0;
}*/
}
> 但我希望的是每次環境由"亮"-->"暗"時,觸發一次LED HIGH
Delete你之前的描述 並沒有說出這點
藉由修改 我之前寫的程式 也可以改出你想要的行為 不過我不想改了 orz
請參考拙作<> 裏頭有解釋何謂 有限狀態機
可運用此種程式設計技巧 解決你的問題
哈哈~好的
Delete十分感謝葉前輩!
葉前輩您好:
ReplyDelete我想用可變電阻控制一整排串聯的led(約70顆),是否要多加模組?程式該如何寫?
葉前輩您好:
ReplyDelete我想用可變電阻控制一整排串聯的led(約70顆),是否要多加模組?程式該如何寫?
哪種led?
Delete控制?要控制什麼?
> 程式該如何寫?
這問題太大了,無從回答。就跟問王建民如何贏球一樣。
控制明亮,V3 LED
Delete首先,你說的是需求,不是問題。需求的答案會是一篇文章或一本書。
Delete什麼是V3 LED?
難道是要串聯70個3V LED,那不就要準備近140 V的電源?
我沒看過接這麼多的,而且你要怎麼控制每一顆的明亮?
我認為該使用WS2812之類的LED吧。
你好,我想要做光敏電阻結合馬達的裝置,就是LED燈亮的同時馬達會轉,
ReplyDelete這是我寫的程式碼,不知道哪裡出了問題,可以請你幫我看看嗎,謝謝。
const int analogPin = A0;
int Vin = 0;
const int presetVal = 400;
const int ledPin = 8;
const int motorpin = 7;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
Vin = analogRead(analogPin);
if (Vin < presetVal) {
digitalWrite(ledPin, HIGH);
digitalWrite(motorpin,HIGH);
}
if (Vin > presetVal) {
digitalWrite(ledPin, LOW);
digitalWrite(motorpin,LOW);
}
}
看不出問題。
Delete什麼馬達?
電路圖?
DC N20 小馬達
Delete直流馬達,不能直接接到arduino的腳位,
Delete你有接電晶體 or H橋電路 or 馬達驅動模組嗎?
請教這光敏開關如果要接6-8.4v的電器,只能接繼電器來做嗎?
ReplyDelete直流電的話,可以用電晶體。
Delete交流電,用繼電器。
另外還有固態繼電器,但我沒用過。
是直流電的,但是不知道相關電晶體的資料要怎麼找?
Delete看電壓、電流囉,以及控制電晶體的電壓,
Delete小一點的用PN2222,大一點的用TIP120
fuckkkkkkkkkkkkkkkkkk
ReplyDeleteGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
ReplyDelete附中 素質
ReplyDelete大安素質
ReplyDelete大安比附中棒你們說=*= 對不對
ReplyDelete附中不就好棒棒
ReplyDelete加個變數就可以
ReplyDelete葉前輩您好
ReplyDelete如果想用開關控制光敏電阻運作的話
就是在外界光線弱的時候
按一下開關使燈泡保持不會亮
再按一下又使燈泡維持亮的狀態
該怎麼做?
請指點一下 謝謝前輩!!