아두이노 태양 추적기 Arduino Solar Tracker
가상 계측을 갖춘 태양 추적기용 오픈 하드웨어/소프트웨어 테스트 벤치.
구성 요소 및 공급품
저항기 330옴 4개 LDR, 5Mohm 4개 Arduino UNO 미니 태양 전지 패널 SG90 마이크로 서보 모터 2개 회전식 전위계(일반) 푸시버튼 스위치, 푸시버튼 2개
도구 및 기계
PLX-DAQ
프로젝트 설명
이 프로젝트는 태양 추적기용 오픈 하드웨어/소프트웨어 테스트 벤치를 제공합니다. 제안된 프로토타입은 사용하기 쉬운 하드웨어 및 소프트웨어를 기반으로 하는 오픈 소스 프로토타입 플랫폼인 Arduino Uno로 제어되는 듀얼 축 태양 추적기를 기반으로 합니다. 태양 추적기는 LightDependent Resistor(LDR) 센서를 사용하여 자동으로 제어하거나 전위계로 수동으로 제어할 수 있습니다. 또한 이 테스트 벤치는 태양 추적기 데이터를 기록하고 표시할 수 있는 Excel 기반 가상 계측기를 제공합니다. 사용된 하드웨어는 저렴하고 컴팩트하며 다재다능하도록 선택되었습니다. 제안된 테스트 벤치는 학생들이 제어 이론과 그 응용에 대한 이해를 개발하는 데 도움이 되도록 설계되었습니다.
제안된 테스트 벤치는 그림 1에 나와 있습니다. 4개의 LDR 센서와 2개의 서보모터(SM1 및 SM2)의 도움으로 태양을 추적하기 위해 자동으로 회전할 수 있는 태양 추적기를 기반으로 하거나 전위차계를 사용하여 수동으로 회전할 수 있습니다. 두 모드(자동 및 수동) 간에 전환하려면 푸시 버튼을 사용합니다. 또 다른 푸시 버튼은 SM1(상하 서보모터) 또는 SM2(좌우 서보모터)를 전위차계에 연결하여 움직임을 제어하는 데 사용됩니다. 또한 컴퓨터는 MS Excel에서 시간에 따른 PV 패널의 모드와 전류, 전압 및 전력을 시각화하는 가상 계측기로 사용됩니다. Arduino Uno 보드는 시스템의 모든 소프트웨어 요구 사항을 구현하는 데 사용됩니다.
그림 1. 제안된 테스트 벤치의 개략도
기계 설계
그림 2에서 볼 수 있듯이, 태양 추적기의 컴퓨터 지원 설계(CAD) 3D 모델은 CATIA에서 설계되었습니다. PV 패널, 좌우 및 상하 서보 모터, 4개의 LDR 센서로 구성됩니다. 수평 축의 경우, 더 나은 유연성을 위해 상하 서보 모터와 평행하게 베어링이 고정됩니다. 태양 추적기는 좌우 서보 모터로 동쪽에서 서쪽으로, 상하 서보 모터로 남쪽에서 북쪽으로 2자유도를 갖도록 설계되었습니다. LDR 센서는 PV 패널의 네 모서리에 배치되고 상단에 작은 구멍이 있는 어두운 튜브에 넣어 태양의 조명을 감지합니다. 이러한 어두운 튜브는 또한 방사선 집광기로 간주되며 태양 추적기의 견고성을 높이는 데 사용됩니다.
그림 2. CATIA에서 태양 추적기의 CAD 3D 모델
하드웨어 시스템
그림 3은 제안된 테스트벤치의 전자 회로를 보여줍니다. 자동 모드의 경우, 마이크로컨트롤러는 LDR센서(핀 A0~A3)의 아날로그 값을 디지털로 변환합니다. 그런 다음 두 개의 펄스 폭 변조(PWM) 신호(핀 5 및 6)를 사용하여 두 개의 서보모터(상하 및 좌우)를 제어하여 태양을 추적합니다. 회전 운동은 두 축에서 발생하는데, 방위각은 매일 태양의 경로에 따라 동쪽에서 서쪽으로, 고도는 계절별 태양의 경로에 따라 남쪽에서 북쪽으로 발생합니다. 수동 모드의 경우, 전위차계(핀 A4)를 사용하여 두 서보 모터의 움직임을 제어하고, 푸시 버튼(핀 11)을 배치하여 전위차계를 상하 서보모터 또는 좌우 서보모터에 연결합니다. 또한, 또 다른 푸시 버튼(핀 12)을 사용하여 두 모드 사이를 전환합니다. 또한 PV 전압은 Arduino의 아날로그 핀 A5를 통해 측정한 다음 부하의 저항이 이미 알려져 있으므로 PV 전류를 계산합니다. 다음으로 PV 전류, 전압 및 전력 대 시간 및 실제 모드를 컴퓨터로 전송하여 MS Excel에서 실시간으로 표시합니다.
그림 3. 수동 및 자동 모드가 있는 태양 추적기의 전자 회로
LDR 센서 회로는 전압 분배기 회로로 설계되었습니다. 광도의 변화는 분배기 출력 전압의 변화에 비례합니다. 전위 분배기의 상단은 5V이고 접지는 0V이며 전압 분배기의 출력은 마이크로컨트롤러의 아날로그 입력(예: A 0)에 연결됩니다. 그런 다음 마이크로컨트롤러의 아날로그-디지털 변환기(ADC)는 A 0에서 읽은 아날로그 값을 0~1023 사이의 디지털 값으로 변환합니다. ADC는 10비트로 코딩되어 있고 이 값에 따라 광 레벨을 알 수 있기 때문입니다. 전압 분배기에 사용되는 저항기의 값은 330Ω입니다.
두 개의 180도 서보 모터가 사용됩니다. 수직 축에 따라 태양 추적기를 제어하는 서보 모터(MG996R)인 좌우 서보 모터. 수평 축에 따라 태양 추적기를 제어하는 마이크로 서보 모터(SG90)인 상하 서보 모터. 서보 모터의 장점은 드라이버가 필요 없이 마이크로 컨트롤러의 출력에 직접 연결된 단일 저전류 와이어를 사용하여 정지, 실행, 회전 방향 및 속도를 제어할 수 있다는 것입니다. 사용된 서보 모터는 그림 3과 같이 3선 전기 케이블을 통해 Arduino UNO 보드에서 제어되며, 2개의 와이어는 공급용이고 1개의 와이어는 PWM용이며 위치를 제어합니다.
임베디드 소프트웨어 설계
임베디드 소프트웨어는 하드웨어(Arduino Uno)에 임베디드되어 태양 추적기 테스트 벤치를 제어하고 모니터링하는 부분입니다. 임베디드 소프트웨어는 다음 요구 사항을 충족하도록 설계되었습니다.
1. 테스트 벤치에는 수동 및 자동의 두 가지 모드가 있습니다. 푸시 버튼은 핀 12에 연결되어 두 모드 사이를 전환합니다.
2. 수동 모드가 활성화된 경우 전위차계는 좌우 모터의 경우 동쪽에서 서쪽으로, 상하 모터의 경우 남쪽에서 북쪽으로 서보 모터를 제어할 수 있습니다. 푸시 버튼은 핀 11에 연결되어 전위차계를 두 모터 사이에서 전환하여 좌우 서보 모터 또는 상하 서보 모터를 제어합니다.
3. 자동 모드가 활성화된 경우 그림 4에 제시된 알고리즘이 실행됩니다. 후자는 LDR 센서에서 반환된 아날로그 값을 사용합니다. 예를 들어 방위각 또는 수직 축을 고려할 때 두 개의 오른쪽 LDR과 두 개의 왼쪽 LDR의 평균 값을 비교하고 왼쪽 LDR 세트가 더 많은 빛을 받으면 태양 추적기가 좌우 서보 모터를 통해 해당 방향으로 이동합니다. 후자는 차이 결과가 [-10, 10] 범위에 있을 때까지 계속 회전합니다. 이 범위는 컨트롤러를 안정화하는 데 사용되며 태양 추적기가 태양과 수직이 되면 더 이상 제어가 이루어지지 않습니다. 반면, 오른쪽 LDR 세트가 더 많은 빛을 받으면 태양 추적기가 좌우 서보 모터를 통해 해당 방향으로 이동하고 차이 결과가 [-10, 10] 범위에 있을 때까지 계속 회전합니다. 고도 축에도 동일한 방식이 사용됩니다. 게다가, 우리는 또한 4개의 LDR 센서 사이의 평균 복사량을 결정했고 이 값이 작은 값(8: 조정되고 실제적으로 테스트되었으며 복사가 null일 때 반환되는 값)보다 작은지 여부를 결정했습니다. 즉, 밤이 왔습니다. 이 경우 태양 추적기는 태양의 뜨는 위치로 돌아가야 합니다. 예를 들어, 좌우 서보 모터에서 0도, 상하 서보 모터에서 30도를 설정하여 태양의 뜨는 위치에 도달할 수 있는 경우입니다. 이는 Arduino IDE에서 제공하는 C 함수 "servox.write(angle)"을 통해 쉽게 수행할 수 있습니다.
4. 아날로그 핀 A5를 통해 수집된 PV 전압을 처리하여 PV 전류와 전력을 계산하는 데 사용해야 합니다. 그런 다음 이러한 모든 데이터와 실제 모드를 USB 케이블을 통해 컴퓨터로 전송한 다음 MS Excel에 표시해야 합니다.
그림 4. 태양 추적기의 자동 모드 알고리즘
PLX-DAQ Excel 매크로는 Arduino 마이크로컨트롤러에서 Excel 스프레드시트로 데이터를 수집하는 데 사용됩니다. 다운로드만 하면 됩니다. 설치 후 PC에 "PLX-DAQ"라는 폴더가 자동으로 생성되고 그 안에 "PLX-DAQ 스프레드시트"라는 바로 가기가 있습니다. 그런 다음 보드와 Excel 간의 통신을 설정하려면 스프레드시트를 열고 PLX-DAQ 창(그림 5)에서 연결 설정(전송 속도 및 포트)을 정의하기만 하면 됩니다. 그 후, "연결"을 클릭하면 출력 데이터가 수집되어 Excel 스프레드시트에 실시간으로 표시됩니다.
그림 5. PLX-DAQ 스프레드시트 창
프로토타입
그림 6은 분리 및 조립 상태의 태양 추적기를 보여줍니다. 제시된 대로 전체 구조는 나무 판을 사용하여 제조되었으며, 언급된 모든 구성 요소가 수동 및 자동 모드(LDR 센서, Arduino Uno, 서보 모터, 전위차계, 푸시 버튼 및 소형 PV 패널)로 태양 추적기를 만드는 데 사용되었다는 것이 분명합니다.
그림 6. 태양 추적기의 구성
그림 7은 전체 테스트 벤치, 가상 계측기가 있는 태양 추적기 및 태양 추적기를 테스트하기 위해 빛을 노출할 수 있는 인공 램프를 보여줍니다. 태양 추적기와 컴퓨터는 USB 케이블을 통해 연결됩니다. PV 전압이 수집되면 컨트롤러가 이 정보를 처리하여 PV 전류와 전력을 계산합니다. 그런 다음 이러한 모든 데이터를 컴퓨터로 전송하여 MSExcel에 표시합니다. 그림에서 5와 6에서 제안된 테스트 벤치는 작고 유연하며 사용하기 쉽다는 것이 분명합니다. 이를 통해 학생, 연구자 및 엔지니어는 대형 태양 추적 장치의 구현을 진행하기 전에 알고리즘을 쉽게 적용할 수 있습니다.
전체 코드 1
//Servo motor library
#include <Servo.h>
//Initialize variables
int mode = 0;
int axe = 0;
int buttonState1 = 0;
int buttonState2 = 0;
int prevButtonState1 = 0;
int prevButtonState2 = 0;
int ldrtopr= 0; // top-right LDR
int ldrtopl = 1; // top-left LDR
int ldrbotr = 2; // bottom-right LDR
int ldrbotl = 3; // bottom-left LDR
int topl = 0;
int topr = 0;
int botl = 0;
int botr = 0;
//Declare two servos
Servo servo_updown;
Servo servo_rightleft;
int threshold_value=10; //measurement sensitivity
void setup()
{
Serial.begin(9600); //serial connection setup //opens serial port, sets data rate to 9600 bps
Serial.println("CLEARDATA"); //clear all data that’s been place in already
Serial.println("LABEL,t,voltage,current,power,Mode"); //define the column headings (PLX-DAQ command)
pinMode(12, INPUT); //Mode switch Button
pinMode(11, INPUT); //Axis switch
pinMode(A4, INPUT); //Potentiometer for right-left movement and for up-down movement
servo_updown.attach(5); //Servo motor up-down movement
servo_rightleft.attach(6); //Servo motor right-left movement
}
void loop()
{
// pv_power();
char Mode;
float volt = analogRead(A5)*5.0/1023;
float voltage = 2*volt; // Volt=(R1/R1+R2)*Voltage / R1=R2=10Ohms => voltage=2*volt)
float current = voltage/20; // I=voltage/(R1+R2)
float power = voltage*current;
Serial.print("DATA,TIME,"); // PLX-DAQ command
Serial.print(voltage); //send the voltage to serial port
Serial.print(",");
Serial.print(current); //send the current to serial port
Serial.print(",");
Serial.print(power); //send the power to serial port
Serial.print(",");
// Serial.println(Mode);
buttonState1 = digitalRead(12);
if (buttonState1 != prevButtonState1) {
if (buttonState1 == HIGH) {
//Change mode and ligh up the correct indicator
if (mode == 1) {
mode = 0;
} else {
mode = 1;
}
}
}
prevButtonState1 = buttonState1;
delay(50); // Wait for 50 millisecond(s)
if (mode == 0) {
Mode='M';
Serial.println(Mode); //send Mode "Manual" to serial port
manualsolartracker();
} else { // mode automatic
Mode = 'A';
Serial.println(Mode);
automaticsolartracker(); //send Mode "Automatic" to serial port
}
}
void automaticsolartracker(){
//capturing analog values of each LDR
topr= analogRead(ldrtopr); //capturing analog value of top right LDR
topl= analogRead(ldrtopl); //capturing analog value of top left LDR
botr= analogRead(ldrbotr); //capturing analog value of bot right LDR
botl= analogRead(ldrbotl); //capturing analog value of bot left LDR
// calculating average
int avgtop = (topr + topl) / 2; //average of top LDRs
int avgbot = (botr + botl) / 2; //average of bottom LDRs
int avgleft = (topl + botl) / 2; //average of left LDRs
int avgright = (topr + botr) / 2; //average of right LDRs
//Get the different
int diffelev = avgtop - avgbot; //Get the different average betwen LDRs top and LDRs bot
int diffazi = avgright - avgleft; //Get the different average betwen LDRs right and LDRs left
//left-right movement of solar tracker
if (abs(diffazi) >= threshold_value){ //Change position only if light difference is bigger then the threshold_value
if (diffazi > 0) {
if (servo_rightleft.read() < 180) {
servo_rightleft.write((servo_updown.read() + 2));
}
}
if (diffazi < 0) {
if (servo_rightleft.read() > 0) {
servo_rightleft.write((servo_updown.read() - 2));
}
}
}
//up-down movement of solar tracker
if (abs(diffelev) >= threshold_value){ //Change position only if light difference is bigger then thethreshold_value
if (diffelev > 0) {
if (servo_updown.read() < 180) {
servo_updown.write((servo_rightleft.read() - 2));
}
}
if (diffelev < 0) {
if (servo_updown.read() > 0) {
servo_updown.write((servo_rightleft.read() + 2));
}
}
}
}
void manualsolartracker(){
buttonState2 = digitalRead(13);
if (buttonState2 != prevButtonState2) {
if (buttonState2 == HIGH) {
//Change mode and ligh up the correct indicator
if (axe == 1) {
axe = 0;
} else {
axe = 1;
}
}
}
prevButtonState2 = buttonState2;
delay(50); // Wait for 50 millisecond(s)
if (axe == 0) { //control right-left movement
servo_rightleft.write(map(analogRead(A4), 0, 1023, 0, 180));
} else { // //control up-down movement
servo_updown.write(map(analogRead(A4), 0, 1023, 0, 180));
}
}
전체 코드 2
//Servo motor library
#include <Servo.h>
//Initialize variables
int
mode = 0;
int axe = 0;
int buttonState1 = 0;
int buttonState2
= 0;
int prevButtonState1 = 0;
int prevButtonState2 = 0;
int ldrtopr=
0; // top-right LDR
int ldrtopl = 1;
// top-left LDR
int ldrbotr = 2; //
bottom-right LDR
int ldrbotl = 3; // bottom-left
LDR
int topl = 0;
int topr = 0;
int botl = 0;
int
botr = 0;
//Declare two servos
Servo servo_updown;
Servo servo_rightleft;
int
threshold_value=10; //measurement sensitivity
void setup()
{
Serial.begin(9600); //serial connection setup //opens
serial port, sets data rate to 9600 bps
Serial.println("CLEARDATA"); //clear
all data that’s been place in already
Serial.println("LABEL,t,voltage,current,power,Mode");
//define the column headings (PLX-DAQ command)
pinMode(12, INPUT); //Mode
switch Button
pinMode(11, INPUT); //Axis switch
pinMode(A4,
INPUT); //Potentiometer for right-left movement and for up-down movement
servo_updown.attach(5); //Servo motor up-down movement
servo_rightleft.attach(6);
//Servo motor right-left movement
}
void loop()
{
// pv_power();
char
Mode;
float volt = analogRead(A5)*5.0/1023;
float voltage = 2*volt;
// Volt=(R1/R1+R2)*Voltage / R1=R2=10Ohms => voltage=2*volt)
float current = voltage/20; // I=voltage/(R1+R2)
float power
= voltage*current;
Serial.print("DATA,TIME,"); // PLX-DAQ command
Serial.print(voltage);
//send the voltage to serial port
Serial.print(",");
Serial.print(current);
//send the current to serial port
Serial.print(",");
Serial.print(power);
//send the power to serial port
Serial.print(",");
// Serial.println(Mode);
buttonState1 = digitalRead(12);
if (buttonState1 != prevButtonState1)
{
if (buttonState1 == HIGH) {
//Change mode and ligh up the correct
indicator
if (mode == 1) {
mode = 0;
} else {
mode = 1;
}
}
}
prevButtonState1 = buttonState1;
delay(50); // Wait for 50 millisecond(s)
if (mode == 0) {
Mode='M';
Serial.println(Mode); //send Mode "Manual" to serial port
manualsolartracker();
} else { // mode automatic
Mode = 'A';
Serial.println(Mode);
automaticsolartracker(); //send Mode "Automatic" to serial port
}
}
void
automaticsolartracker(){
//capturing analog values of each LDR
topr= analogRead(ldrtopr); //capturing analog value of top right LDR
topl= analogRead(ldrtopl); //capturing analog value of top left LDR
botr= analogRead(ldrbotr); //capturing analog value of bot right LDR
botl= analogRead(ldrbotl); //capturing analog value of bot left LDR
// calculating average
int avgtop = (topr + topl) / 2; //average
of top LDRs
int avgbot = (botr + botl) / 2; //average of bottom LDRs
int avgleft = (topl + botl) / 2; //average of left LDRs
int avgright
= (topr + botr) / 2; //average of right LDRs
//Get the different
int diffelev = avgtop - avgbot; //Get the different average betwen
LDRs top and LDRs bot
int diffazi = avgright - avgleft; //Get the different
average betwen LDRs right and LDRs left
//left-right movement of
solar tracker
if (abs(diffazi) >= threshold_value){ //Change
position only if light difference is bigger then the threshold_value
if
(diffazi > 0) {
if (servo_rightleft.read() < 180) {
servo_rightleft.write((servo_updown.read()
+ 2));
}
}
if (diffazi < 0) {
if (servo_rightleft.read()
> 0) {
servo_rightleft.write((servo_updown.read() - 2));
}
}
}
//up-down movement of solar tracker
if (abs(diffelev) >= threshold_value){ //Change position only if light
difference is bigger then thethreshold_value
if (diffelev > 0) {
if
(servo_updown.read() < 180) {
servo_updown.write((servo_rightleft.read()
- 2));
}
}
if (diffelev < 0) {
if (servo_updown.read()
> 0) {
servo_updown.write((servo_rightleft.read() + 2));
}
}
}
}
void manualsolartracker(){
buttonState2
= digitalRead(13);
if (buttonState2 != prevButtonState2) {
if (buttonState2
== HIGH) {
//Change mode and ligh up the correct indicator
if
(axe == 1) {
axe = 0;
} else {
axe = 1;
}
}
}
prevButtonState2 = buttonState2;
delay(50); // Wait for 50
millisecond(s)
if (axe == 0) { //control right-left movement
servo_rightleft.write(map(analogRead(A4),
0, 1023, 0, 180));
} else { // //control up-down movement
servo_updown.write(map(analogRead(A4),
0, 1023, 0, 180));
}
}
수동 및 자동 모드가 있는 태양광 트래커의 전자 회로
답글에 달린 잘 동작하는 포루투칼어 코드
#include <Servo.h>
// Inicialização de variáveis
int modo = 0; // 0 para manual, 1 para automático
int eixo = 0; // 0 para esquerda-direita, 1 para cima-baixo
int estadoBotaoModo = 0;
int estadoBotaoEixo = 0;
int estadoBotaoAnteriorModo = 0;
int estadoBotaoAnteriorEixo = 0;
// Definição dos pinos dos LDRs
int ldrSuperiorDireito = A0;
int ldrSuperiorEsquerdo = A1;
int ldrInferiorDireito = A2;
int ldrInferiorEsquerdo = A3;
// Leituras dos LDRs
int superiorEsquerdo = 0;
int superiorDireito = 0;
int inferiorEsquerdo = 0;
int inferiorDireito = 0;
// Declaração dos dois servos
Servo servoCimaBaixo;
Servo servoEsquerdaDireita;
int valorLimite = 10; // Sensibilidade da medição
void setup() {
Serial.begin(9600);
Serial.println("CLEARDATA");
Serial.println("LABEL,t,voltage,current,power,Mode");
pinMode(12, INPUT_PULLUP); // Botão de Modo (com pull-up interno)
pinMode(11, INPUT_PULLUP); // Botão de Eixo (com pull-up interno)
pinMode(A4, INPUT); // Potenciômetro para controle manual
servoCimaBaixo.attach(5); // Servo para movimento cima-baixo
servoEsquerdaDireita.attach(6); // Servo para movimento esquerda-direita
Serial.println("Setup completo");
}
void loop() {
float volt = analogRead(A5) * 5.0 / 1023;
float tensao = 2 * volt; // Tensão=(R1/(R1+R2))*Tensão, R1=R2=10Ohms => tensao=2*volt
float corrente = tensao / 20; // I=tensao/(R1+R2)
float potencia = tensao * corrente;
Serial.print("DATA,TIME,"); // Comando PLX-DAQ
Serial.print(tensao);
Serial.print(",");
Serial.print(corrente);
Serial.print(",");
Serial.print(potencia);
Serial.print(",");
// Tratamento do botão de modo
estadoBotaoModo = digitalRead(12);
if (estadoBotaoModo != estadoBotaoAnteriorModo) {
if (estadoBotaoModo == LOW) { // LOW porque o pull-up inverte a lógica
modo = 1 - modo; // Alterna o modo entre 0 e 1
Serial.print("Modo alterado para: ");
Serial.println(modo == 0 ? "Manual" : "Automático");
}
}
estadoBotaoAnteriorModo = estadoBotaoModo;
delay(50); // Atraso para debouncing
if (modo == 0) {
Serial.println('M');
rastreadorSolarManual();
} else {
Serial.println('A');
rastreadorSolarAutomatico();
}
}
void rastreadorSolarAutomatico() {
// Captura dos valores analógicos de cada LDR
superiorDireito = analogRead(ldrSuperiorDireito);
superiorEsquerdo = analogRead(ldrSuperiorEsquerdo);
inferiorDireito = analogRead(ldrInferiorDireito);
inferiorEsquerdo = analogRead(ldrInferiorEsquerdo);
// Calculando a média
int mediaSuperior = (superiorDireito + superiorEsquerdo) / 2;
int mediaInferior = (inferiorDireito + inferiorEsquerdo) / 2;
int mediaEsquerda = (superiorEsquerdo + inferiorEsquerdo) / 2;
int mediaDireita = (superiorDireito + inferiorDireito) / 2;
// Calculando as diferenças
int diferencaElevacao = mediaSuperior - mediaInferior;
int diferencaAzimute = mediaDireita - mediaEsquerda;
// Movimento esquerda-direita do rastreador solar
if (abs(diferencaAzimute) >= valorLimite) {
if (diferencaAzimute > 0 && servoEsquerdaDireita.read() < 180) {
servoEsquerdaDireita.write(servoEsquerdaDireita.read() + 2);
}
if (diferencaAzimute < 0 && servoEsquerdaDireita.read() > 0) {
servoEsquerdaDireita.write(servoEsquerdaDireita.read() - 2);
}
}
// Movimento cima-baixo do rastreador solar
if (abs(diferencaElevacao) >= valorLimite) {
if (diferencaElevacao > 0 && servoCimaBaixo.read() < 180) {
servoCimaBaixo.write(servoCimaBaixo.read() + 2);
}
if (diferencaElevacao < 0 && servoCimaBaixo.read() > 0) {
servoCimaBaixo.write(servoCimaBaixo.read() - 2);
}
}
}
void rastreadorSolarManual() {
// Tratamento do botão de eixo
estadoBotaoEixo = digitalRead(11);
if (estadoBotaoEixo != estadoBotaoAnteriorEixo) {
if (estadoBotaoEixo == LOW) { // LOW porque o pull-up inverte a lógica
eixo = 1 - eixo; // Alterna o eixo entre 0 e 1
Serial.print("Eixo alterado para: ");
Serial.println(eixo == 0 ? "Esquerda-Direita" : "Cima-Baixo");
}
}
estadoBotaoAnteriorEixo = estadoBotaoEixo;
delay(50); // Atraso para debouncing
if (eixo == 0) { // Controle esquerda-direita
int valorPot = analogRead(A4);
int posicaoServo = map(valorPot, 0, 1023, 0, 180);
servoEsquerdaDireita.write(posicaoServo);
Serial.print("Posição Esquerda-Direita: ");
Serial.println(posicaoServo);
} else { // Controle cima-baixo
int valorPot = analogRead(A4);
int posicaoServo = map(valorPot, 0, 1023, 0, 180);
servoCimaBaixo.write(posicaoServo);
Serial.print("Posição Cima-Baixo: ");
Serial.println(posicaoServo);
}
}
늘 그렇듯이 원문 글을 참고하시려면 이 링크를 따라가세요. 배움을 멈추지 마세요.
아래 논문 참고
https://www.academia.edu/85096380/Arduino_based_low_cost_active_dual_axis_solar_tracker
'메이커 Maker' 카테고리의 다른 글
하루의 남은 시간을 초로 보요주는 기계 Display (1) | 2024.12.25 |
---|---|
ESP32 MPU6050 Gesture Control with Audio DFPlayer Mini Integration (1) | 2024.12.20 |
아두이노 나노 33 BLE로 나만의 전자 주사위 만들기 (1) | 2024.12.11 |
지적재산 디자인권 심사기준 (1) | 2024.12.11 |
2축 태양광 추적기 아두이노 프로젝트 (2) | 2024.12.05 |
태양광 패널 추적 시스템 회로도 (1) | 2024.12.04 |
아두이노 태양광 추적기 (4) | 2024.12.04 |
키보드 자동화 샘플 코드 1 (1) | 2024.11.28 |
더욱 좋은 정보를 제공하겠습니다.~ ^^