Arduino Platform - Differential Gap Control (Solar Tracker)

07:10

Arduino Platform - Differential Gap Control (Solar Tracker)
Cистема для слежения за перемещением солнца.Солнечный трекер.
Солнечный трекер - система, предназначенная для слежения за перемещением солнца, чтобы получить максимальный КПД от солнечных батарей.
Концепция трекера предельно проста - по двум датчикам контроллер заставляет серводвигатель поворачивать платформу с солнечной батареей в ту сторону, где больше света.
 

В проекте используется два датчика-фоторезистора, которые направлены в разные стороны от плоской поверхности на 45°, т.е. относительно друг-друга фоторезисторы сориентированы на 90°. На сами датчики надеты колпачки, чтобы поток света, падающий на них был узконаправленным.

В проекте используется контроллер Arduino. Контроллер периодически считывает значения с двух датчиков и сравнивает их. Если значения с датчиков одинаковы, значит панель наведена на солнце. В случае, если значение одного из датчиков отличается от другого, контроллер дает команду на серводвигатель для поворота платформы. Команда на серво работает до тех пор, пока значения с датчиков не сравняются.
Для предотвращения чрезмерного поворота платформы присутствуют программные лимиты поворота, которые в случае необходимости можно отключить. Также, в коде программы предусмотрена константа deadband, при разности с датчиков меньше значения этой константы, контроллер не будет давать команду на поворот серводвигателя. Т.о. предотвращается дергание платформы (джиттер).
Также, на всякий случай добавлено 2 переменные позволяющие сгладить значения от датчиков. Это помогает отфильтровать "выбросы" и шум.
Скетчи для Arduino

В начальной секции программы описываются подключаемые библиотеки (в нашем случае servo.h), определяются пины и константы
#include <servo.h>


//IO Pins
int pinL = 5; //Left Sensor IO Pin
int pinR = 4; //Right Sensor IO Pin
int pinServo = 11; //Servo PWM pin

int leftValue = 0; //The left Sensor Value
int rightValue = 0; //The right Sensor Value
int error =0; //The Deviation between the 2 sensors
int errorAVG = 0; //Error Average - Rolling 2 Point

int deadband = 10; //Range for which to do nothing with output 10 = -10 to +10
//Servo Stuff
Servo hServo; //The servo object
int Position = 45; //Position to write out

int minPos = 5; //Min Position
int maxPos = 150; //Max Position

float output = (maxPos - minPos) /2; //Initial output Position

В следующей части кода описывается функция Setup(). Данная функция выполняется только один раз при запуске программы или после сброса контроллера. Здесь вы можете вывести в Serial Monitor какие либо данные для отладки, или как в приведенном ниже примере сделать "прогон" серводвигателя по всей траектории до лимитов.

void setup()
{
Serial.begin(9600);

hServo.attach(pinServo);

//Set Servo to Centre for Alignment Purpose
Serial.println("Moving Servo to Minimum Position");
hServo.write(minPos);
delay(5000);
Serial.println("Moving Servo to Maximum Position");
hServo.write(maxPos);
delay(5000);
Serial.println("Moving Servo to Mid-Point");
hServo.write(output);
delay(5000);
Serial.println("Going Live................");
}



Финальная часть кода выполняется в циклической функции loop(). Здесь считываются значения с датчиков, производятся все расчеты и выдаются команды на серводвигатель.


void loop()
{
//Input Reading
leftValue = analogRead(pinL);
rightValue = analogRead(pinR);

Serial.print("L = "); Serial.print(leftValue); Serial.print(" | ");
Serial.print("R = "); Serial.print(rightValue); Serial.print(" | ");
Serial.print("E = "); Serial.print(error); Serial.print(" | ");
Serial.print("Eavg = "); Serial.print(errorAVG);
Serial.println();

//Calculate
error = leftValue - rightValue;
errorAVG = (errorAVG + error) / 2;

float newOutput = output + getTravel();

if (newOutput > maxPos)
{
Serial.println("At Upper Limit");
newOutput = maxPos;
}
else
{
if (newOutput < minPos)
{
Serial.println("At Lower Limit");
newOutput = minPos;
}
}
Serial.println("Writing output");

//Output Writing
hServo.write(newOutput);
output = newOutput;



Также, в программе используется вспомогательная функция getTravel(), которая используется для вычисления, куда поворачивать серво - влево, вправо или вообще ничего не делать. Функция просто возвращает значение: 0 - ничего не происходит, -1 поворот влево, +1 поворот право.



int getTravel()
{
// -1 = Left; +1 = Right

if (errorAVG < (deadband * -1))
{
return 1;
}
else
{
if (errorAVG > deadband)
{
return -1;
}
else
{
//Do not move within deadband
return 0;
}
}
}

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]