前言
大學(xué)專業(yè)是能源相關(guān),對太陽能等新能源比較感興趣,一直好奇太陽能電池板是如何跟蹤陽光的。直到最近在油管上看到一個視頻,根據(jù)光敏電阻追蹤光源,才恍然大悟。趁著回揚州,用了一個晚上和一個上午做了這件比較有趣的裝置。

組成簡介
主要組成部分如下,Arduino Nano ,四個光敏電阻,四個12KΩ的電阻,太陽能電池板,兩個sg90舵機。制作框架的塑料管是折騰機箱水冷時剩下的邊角料,放了一年多居然派上用場了。

使用的光敏電阻型號為5516,用萬用表測試,正常光照下,電阻為1.6KΩ 左右;用手遮擋光源后,阻值趨于無窮大。
光敏電阻(photoresistor or light-dependent resistor,后者縮寫為ldr),常用的制作材料為硫化鎘,另外還有硒、硫化鋁、硫化鉛和硫化鉍等材料。其工作原理是基于內(nèi)光電效應(yīng)。光照愈強,阻值就愈低,隨著光照強度的升高,電阻值迅速降低,亮電阻值可小至1KΩ以下。光敏電阻對光線十分敏感,其在無光照時,呈高阻狀態(tài),暗電阻一般可達1.5MΩ。
正面并聯(lián)放置了三塊5V,200mA輸出的太陽能電池板,5V電壓可以給手機平板等好多設(shè)備充電。選擇12KΩ的電阻,是綜合考慮了模擬口取樣的平滑和靈敏。下圖是選擇四種不同阻值的電阻時,中間電壓值的變化。(5V供電時)根據(jù)上文對光敏電阻的描述,x(光敏電阻的阻值,單位KΩ)的取值范圍在1到1500之間,由圖像可以看出在該范圍內(nèi),選取串聯(lián)的電阻阻值越大,曲線越平滑,同時靈敏度下降。所以折中選擇10KΩ左右的電阻比較合適。
[站外圖片上傳中...(image-b66bf9-1559452162883)]
考慮了兩種可行的方案,第一種方案即上述的選擇四個12KΩ的電阻與四個光敏電阻串聯(lián),分別讀取四個中間電壓值作比較,進行舵機的角度調(diào)整。
第二種方案是左右兩側(cè)和上下兩側(cè)的光敏電阻分別串聯(lián),只需要讀取兩個中間電壓值,就可以做出相應(yīng)的控制。第一種方案接線麻煩些,但是可以實現(xiàn)更多的控制方式。(比如說夜晚中間電壓值均小于給定值時,恢復(fù)初始狀態(tài)待機)
方案一接線

方案一代碼
#include <Servo.h>
Servo servo1;
Servo servo2;
int initial1 = 90;
int initial2 = 90; //舵機初始角度
int LDR1 = A0;
int LDR2 = A2;
int LDR3 = A4;
int LDR4 = A6;
int error = 10;
int servoPin1 = 9;
int servoPin2 = 10; //舵機接口
void setup() {
servo1.attach(servoPin1);
servo2.attach(servoPin2);
pinMode(LDR1, INPUT);
pinMode(LDR2, INPUT);
pinMode(LDR3, INPUT);
pinMode(LDR4, INPUT);
servo1.write(initial1);
servo2.write(initial2);
delay(2000);
}
void loop() {
int R1 = analogRead(LDR1);
int R2 = analogRead(LDR2);
int R3 = analogRead(LDR3);
int R4 = analogRead(LDR4); //讀取四個中間電壓值
int diff1= abs(R1 - R2);
int diff2= abs(R2 - R1);
int diff3= abs(R3 - R4);
int diff4= abs(R4 - R3);
if((diff1 <= error) || (diff2 <= error)||(diff3 <= error)||(diff4 <= error)) {
} //設(shè)置死區(qū)
else
{
if(R1 > R2){
initial1 = --initial1;
}
if(R1 < R2){
initial1 = ++initial1;
}
if(R3 > R4){
initial2 = --initial2;
}
if(R3 < R4){
initial2 = ++initial2;
}
}
servo1.write(initial1);
servo2.write(initial2);
delay(100);
}
方案二接線

方案二代碼
#include <Servo.h>
Servo servo1;
Servo servo2;
int initial1 = 90;
int initial2 = 90; //舵機初始角度
int LDR1 = A0;
int LDR2 = A2;
int servoPin1 = 9;
int servoPin2 = 10; //舵機接口
void setup() {
servo1.attach(servoPin1);
servo2.attach(servoPin2);
pinMode(LDR1, INPUT);
pinMode(LDR2, INPUT);
servo1.write(initial1);
servo2.write(initial2);
delay(2000);
}
void loop() {
int R1 = analogRead(LDR1);
int R2 = analogRead(LDR2); //讀取兩個中間電壓值
if(R1 > 400){
initial1 = ++initial1;
}
if(R1 < 250){
initial1 = --initial1;
}
if(R2 > 400){
initial2 = ++initial2;
}
if(R2 < 250){
initial2 = --initial2;
} //該處設(shè)置的數(shù)值是3.3V的數(shù)值,5V供電可改成600和400
servo1.write(initial1);
servo2.write(initial2);
delay(300);
}
測試時用的方案二,圖的接線方便。沒有理線,看著很亂,本來是想用跳線焊接的,可是焊接水平太差,嘗試后選擇放棄。

演示視頻
演示視頻上傳在B站上,向日葵
本人菜鳥,如有錯誤,歡迎指出,謝謝大家。